---
# System prepended metadata

title: 'Day 4: Sensing (Whiteboard)'

---

# Day 4: Sensing (Whiteboard)

## I/O Threads

Let's say we have a serial-based sensor, such as a GPS.

All of the I/O threads inherit from `goby::middleware::io::detail::IOThread`:

- Subscribe to outgoing data (Goby -> sensor): `protobuf::IOData`, group: `line_out_group`
- Handles sync between boost::asio and the Goby interthread transporter
- Uniform error handling (`protobuf::IOStatus` on `line_in_group`)


Implementors must:

- `open_socket()`: (Try to) open the socket
- `async_read()`: Start an asynchronous read from the socket (return a "message")
- `async_write()`: Start an asynchronous write to the socket (free function `basic_async_write`).

### Serial

```mermaid
classDiagram
    IOThread <|-- detail__SerialThread
    detail__SerialThread <|-- SerialThreadLineBased

    class IOThread {
        +initialize()
        +finalize()
        #write()
        #handle_read_success()
        #handle_write_success()
        #handle_read_error()
        #handle_write_error()
        #mutable_socket()
        #mutable_io()
        #socket_is_open()
        #async_read()
        #open_socket() virtual 
        #async_read() virtual
        #async_write() virtual
        -loop()
    }
    class detail__SerialThread {
        #mutable_serial_port()
        -async_write() override
        -open_socket() override
        -publish_status() 
    }
    class SerialThreadLineBased {
        -async_read() override
    }
```

Switch to becoming a user of the IOThreads.

- Each I/O thread is a Goby Thread (by default the `SimpleThread`: interthread/interprocess/intervehicle)

```mermaid
graph TD
    SerialThreadLineBased-->|protobuf::IOData on gps_in|GPSDriver
    GPSDriver-->|protobuf::IOData on gps_out|SerialThreadLineBased
```


### TCP

Let's say our GPS was connected to some remote server which then reserves the data as a TCP server.

## goby_gps

Is a client for the `gpsd` server.

goby_gps publications:

- TPV (**T**ime **P**osition **V**elocity)
- SKY (sky view: satellite)

## Sensor state machines


```mermaid
stateDiagram-v2
    [*] --> StartLogging
    StartLogging --> Logging
    Logging-->StopLogging
    StopLogging-->Sleep
    Sleep-->StartLogging
```

Writing a simulator and a driver for a CTD (**C**onductivity/salinity, **T**emperature, **D**epth/pressure) instrument.

We're going to use `boost::statechart` along with Goby.

 - Uses classes to represent states:
     - constructor = entry
     - destructor = exit
     
```mermaid
stateDiagram-v2
    [*]-->StartLogging
    StartLogging
    Logging
    StopLogging
    Sleep
```

Transitions are driven by "events"

```mermaid
stateDiagram-v2
    [*] --> StartLogging
    StartLogging --> Logging : EvLoggingStarted
    Logging-->StopLogging : EvDoStopLogging
    StopLogging-->Sleep : EvEnterSleep
    Sleep-->StartLogging : EvDoStartLogging
```

Each state can have a list of reactions.

```mermaid
stateDiagram-v2
    [*] --> Sleep
    StartLogging --> Logging : EvLoggingStarted
    Logging-->StopLogging : EvDoStopLogging
    StopLogging-->Sleep : EvEnterSleep
    Sleep-->StartLogging : EvDoStartLogging
```

From the main thread, we might want to know what state the machine is in.

Let's look at the interface for our CTD, based on NMEA-0183:


```
RS-232, 9600 baud
> means message from the control computer to the CTD
< means message from the CTD to the control computer
*CS is the standard NMEA-0183 checksum

Wake up the CTD
> $ZCCMD,WAKE*CS\r\n
Wake received, CTD out of low power mode and ready to commence logging
< $ZCACK,WAKE*CS\r\n

Start logging
> $ZCCMD,START*CS\r\n
Logging started
< $ZCACK,START*CS\r\n

Data (streams at 1 Hz)
< $ZCDAT,<salinity>,<temp, deg C>,<depth, meters>*CS
< $ZCDAT,31.5,10.4,150*CS\r\n
< $ZCDAT,31.5,10.3,151*CS\r\n
< $ZCDAT,31.4,10.2,152*CS\r\n

Stop logging
> $ZCCMD,STOP*CS\r\n
Logging stopped
< $ZCACK,STOP*CS\r\n

Enter low power mode
> $ZCCMD,SLEEP*CS\r\n
< $ZCACK,SLEEP*CS\r\n
```

Given this, let's add a serial thread

## Simulators

Key goals

- Replicate the real behavior *and* the API of the sensor
- Start off by capturing "key behavior" and then iterate.



---
```





```