Movement Sensor Component

Explanation of movement sensor configuration and usage in Viam.

The movement sensor component is an abstraction of a sensor that gives data on where a robot is and how fast it is moving.

We have chosen to abstract these types of sensors into one common API. There are many different types of sensors that can provide data for some or all of the following methods: Position, Orientation, LinearVelocity, AngularVelocity and CompassHeadings. A global positioning system (GPS) can provide position, linear velocity and compass headings. An inertial measurement unit (IMU) can provide angular velocity and orientation. We can further apply algorithms, such as a Kalman filter1, to combine data from both a GPS and an IMU to output the full set of information of the movement sensor methods.

Currently (01 November 2022), the RDK implements GPS, IMU, and visual odometry-based movement sensors. We support two IMU models (manufactured by WitMotion and VectorNav) and two GPS models: NMEA-based2 GPS modules and NTRIP-based3 RTK4 GPS models. The cameramono RDK model is experimental and uses a camera to output data on its position and orientation.

We specifically cover GPS and IMU units in this documentation. Find the more generic sensor component here. Find more information about encoders, another component type, here.

GPS

A global positioning system (GPS) is based on receiving signals from satellites in the earth’s orbit. A GPS is useful for knowing where you are and how fast you’re going. Position, CompassHeading and LinearVelocity data are provided by all GPS modules. Fix and Correction data are available by using the sensor GetReadings method, which is available because GPSes wrap the sensor component.

We have integrated the following GPS modules into Viam’s RDK:

GPS-NMEA

This GPS model uses communication standards set by the National Marine Electronics Association (NMEA). The gps-nmea model can be connected via and send data through a serial connection to any device, or employ an I2C connection to a board:

GPS-NMEA over USB/Serial

{
    "depends_on": ["board"],
    "model": "gps-nmea",
    "name": "UBLOX GPS",
    "type": "movement_sensor",
    "attributes": {
        "connection_type": "serial",
        "serial_attributes": {
            "serial_baud_rate": 115200,
            "serial_path": "/dev/serial/by-path/<device_ID>"
        }
    }
}

Note that the example "serial_path" filepath is specific to serial devices connected to linux systems.

GPS-NMEA over I2C

{
    "depends_on": ["board"],
    "model": "gps-nmea",
    "name": "UBLOX GPS",
    "type": "movement_sensor",
    "attributes": {
        "board": "board",
        "connection_type": "I2C",
        "i2c_attributes": {
            "i2c_baud_rate": 115200,
            "i2c_addr": 111,
            "i2c_bus": "<name_of_bus_on_board>"
        }
    }
}

GPS-NMEA Attributes

NameTypeDefault ValueDescription
boardstring-Required for NMEA over I2C; the board connected to the chip. Not required for serial communication.
disable_nmeaboolfalseOptional. If set to true, changes the NMEA message protocol to RTCM when using a chip as a base station.
connection_typestring-“I2C” or “serial”, respectively

GPS-RTK

This model uses real time kinematic positioning (RTK)4. gps-rtk, a module with a chip (such as one of these from Sparkfun5) capable of generating positional accuracy of 2cm. The chip requires a correction source to get to the required positional accuracy. Our gps-rtk model uses an over-the-internet correction source (NTRIP)3 and sends the data over serial or I2C.

As shown in the examples below, the gps-rtk model requires a name, type (“movement_sensor”), and model (“gps-rtk”). In the attributes section, it requires connection configuration (see “Connection Configuration,” below), correction_source (“ntrip”), and an ntrip_attributes struct containing these:

NameTypeDefault ValueDescription
Required:
ntrip_addrstring-The URL of the NTRIP server from which you get correction data. Connects to a base station (maintained by a third party) for RTK corrections.
ntrip_usernamestring-Username for the NTRIP server
ntrip_passwordstring-Password for the NTRIP server
Optional:
ntrip_connect_attemptsint10no
ntrip_baudintdefaults to serial_baud_rateno

GPS-RTK with NTRIP over USB/Serial

Example config:

{
    "depends_on": ["board"],
    "model": "gps-rtk",
    "name": "UBLOX GPS",
    "type": "movement_sensor",
    "attributes": {
        "connection_type": "serial",
        "correction_source": "ntrip",
        "serial_attributes": {
            "serial_baud_rate": 115200,
            "serial_path": "/dev/serial/by-path/<device_ID>"
        },
        "ntrip_attributes": {
            "ntrip_addr": "<ntrip_address>",
            "ntrip_baud": 38400,
            "ntrip_password": "<password>",
            "ntrip_path": "",
            "ntrip_username": "<username>"
        }
    }
}

GPS-RTK with NTRIP over I2C

Example config:

{
    "depends_on": ["board"],
    "model": "gps-nmea",
    "name": "UBLOX GPS",
    "type": "movement_sensor",
    "attributes": {
        "board": "board",
        "connection_type": "I2C",
        "correction_source": "ntrip",
        "i2c_attributes": {
            "i2c_baud_rate": 115200,
            "i2c_addr": 111,
            "I2c_bus": "<name_of_bus_on_board>",
        },
        "ntrip_attributes": {
 		    "ntrip_addr": "<ntrip_address>",
            "ntrip_baud": 38400,
            "ntrip_password": "<password>",
            "ntrip_username": "<username>"
        }
    }
}

RTK-Station

The experimental rtk-station model allows you to configure your own correction source. This does not provide any movement sensor data on its own, but can be linked to an RTK-ready GPS module on a moving robot and send that robot correction data over your own network, radio, or Bluetooth in areas where internet connectivity is limited, or where an NTRIP server is unavailable. We have implemented this in a way that does not rely on an internet connection to get correction data for a moving GPS.

For all of the following RTK-station configurations, children is the list of one or more other GPS components that can take RTCM corrections.

RTK-Station using NTRIP

{
    "model": "rtk-station",
    "name": "my-rtk-station",
    "type": "movement_sensor",
    "children": [
        "gps1"
    ],
    "attributes": {
        "connection_type": "serial",
        "ntrip_attributes": {
            "ntrip_addr": "<NTRIP_address>",
            "ntrip_baud": 38400,
            "ntrip_password": "<password>",
            "ntrip_path": "",
            "ntrip_username": "<username>"
        },
        "correction_source": "ntrip"
    }
}

RTK-Station using I2C

{
    "model": "rtk-station",
    "name": "my-rtk-station",
    "type": "movement_sensor",
    "children": [
        "gps1"
    ],
    "attributes": {
        "board": "board",
        "connection_type": "serial",
        "i2c_attributes": {
            "i2c_baud_rate": 115200,
            "i2c_addr": 111,
            "i2c_bus": "<name_of_bus_on_board>",
       },
        "correction_source": "I2C",
        "loc_accuracy": 10,
        "svin": "time",
        "time_accuracy": 60
    }
}

RTK-Station using Serial/USB

{
    "children": [
        "gps1"
    ],
    "attributes": {
        "board": "board",
        "connection_type": "serial",
        "serial_attributes": {
        	"serial_baud_rate": 115200,
 		    "serial_path": "/dev/serial/by-path/<device_ID>"
        },
        "correction_source": "serial"
    }
}

Connection Configuration

Use connection_type(string) to specify “serial” or “I2C” connection in the main attributes config. Then create a struct within attributes for either serial_attributes or i2c_attributes, respectively.

Serial Config Attributes

For a movement sensor communicating over serial, you’ll need to include a serial_attributes field containing:

NameTypeDefault ValueDescription
serial_pathstring-The name of the port through which the IMU communicates with the computer.
serial_baud_rateint115200The rate at which data is sent to the IMU. Optional.

{
    "name": "<my-movement-sensor-name>",
    "type": "<TYPE>",
    "model": "<MODEL>",
    "attributes": {
        "<whatever other attributes>": "<example>",
        "connection_type": "serial",
        "serial_attributes": {
        	"serial_baud_rate": 115200,
 		    "serial_path": "<PATH>"
        }
    }
}

I2C Config Attributes

For a movement sensor communicating over I2C, you’ll need a i2c_attributes field containing:

NameTypeDefault ValueDescription
i2c_busstring-The name of the port through which the IMU communicates with the computer.
i2c_addrint-
i2c_baud_rateint115200The rate at which data is sent to the IMU. Optional.

{
    "name": "<my-movement-sensor-name>",
    "type": "<TYPE>",
    "model": "<MODEL>",
    "attributes": {
        "<whatever other attributes>": "<example>",
        "connection_type": "I2C",
        "i2c_attributes": {
            "i2c_addr": 111,
            "i2c_bus": "1"
        }
    }
}

IMU

An inertial measurement unit (IMU) can provide AngularVelocity, Orientation, and CompassHeading methods out of the box (ordered from most common to least common). Acceleration and Magnetometer data are available by using the Sensor GetReadings method, which IMUs wrap. We have included IMUs from two manufacturers in our RDK.

IMU Configuration

An IMU will be configured with type movement sensor. Viam currently (01 November 2022) supports two IMU models, manufactured by WitMotion and VectorNav. They are configured with model imu-wit or imu-vectornav, respectively.

IMU-WIT

Example IMU-WIT config:

{
    "name": "myIMU",
    "type": "movement_sensor",
    "model": "imu-wit",
    "attributes": {
        "serial_path": "<PATH>",
        "serial_baud_rate": 115200
    },
    "depends_on": []
}

IMU-VectorNav

Example IMU-VectorNav config:

{
    "name": "myIMU",
    "type": "movement_sensor",
    "model": "imu-vectornav",
    "attributes": {
        "board": "local",
        "spi": "1",
        "spi_baud_rate": 3800,
        "polling_freq_hz": 80,
        "chip_select_pin": "36"
  },
  "depends_on": []
}
IMU-VectorNav Attributes
NameTypeDefault ValueDescription
boardstring-The name of the board to which the device is wired
spistringThe name of the SPI bus over which the device communicates with the board. On a Raspberry Pi, people often use the bus named “1.”
chip_select_pinstring-The board pin (other than the SPI bus pins) connected to the IMU chip. Used to tell the chip whether the current SPI message is meant for it or for another device.
spi_baud_rateint115200The rate at which data is sent to the IMU.
polling_frequency_hzint

Cameramono

We have integrated an experimental package that uses a visual odometry algorithm with dead reckoning to track the Position, Orientation, LinearVelocity and AngularVelocity of the camera’s frame. The cameramono model can use any single camera with this algorithm.

In a Viam configuration file, a camera used as a movement sensor will require a camera type component and then a movementsensor type component that depends on the camera component, and a motion_estimation_config based on the camera properties.

{
    "components": [
        {
            "attributes": {},
            "depends_on": [],
            "model": "pi",
            "name": "example-board",
            "type": "board"
        },
        {
            "name": "myCamera",
            "type": "camera",
            "model": "webcam",
            "attributes": {},
            "depends_on": []
        },
        {
            "name": "movementCamera",
            "type": "movementsensor",
            "model": "cameramono",
            "attributes": {
                "camera": "myCamera",
                "motion_config": "see_vision_documentation"
                },
            "depends_on": [
            "myCamera"
            ]
        }
    ]
}

Software Implementation

Python SDK Documentation