Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Table of Contents

Introduction

FusionHub is a software application that has the purpose of combining a number of sensor data inputs to create a higher level information output. LPVR-POS is based on FusionHub and combines odometry, GPS and IMU data from a vehicle to calculate high-accuracy and low-latency global localization information. There is a range of typical applications such as automotive and robot localization.

...

Parameter name

Description

Default

type

Data output format for gnss data source. Currently only NMEA is allowed.

NMEA

port

Serial port number for gnss source.

baudrate

Serial port baudrate to connect to GNSS source.

  • For Linux this parameter needs to be in format /dev/ttyXXX

  • For Windows it is COMxxx

/dev/ttyUSB0

baudrate

Serial port baudrate to connect to GNSS source.

rtcm

Set true to enable RTCM correction data forwarding from RTCM source to gnss module.

false

Odometry

The vehicle source is the data source that reads raw CAN data messages from a given CAN bus interface and parses the vehicle data using to the provided CAN protocol.

This section explains how to set up the configuration for a custom CAN parsing node. Depending on the available information about the vehicle CAN protocol, there are three types of CAN parsing available.

  • Minimal parsing where we only have information about the vehicle speed CAN message.

  • External separate four wheel speed parsing, velocity sign information may be added if the gear stick reading is available.

  • ExternalWithSteering parsing with steering model information, there are two ways to specify the steering tables depending on the information available: steering wheel angle vs (right or left) wheel angles or steering wheel angle vs average wheel angles. Using this data we can perform linear interpolation to compute the wheel angles for any given steering angle and use it for Ackermann steering.

Info

In most cases, having the overall vehicle speed message or the separate wheel speed messages is more than enough and no steering information is needed. If available, the gear stick reading is useful to help identify the reverse driving.

Minimal Vehicle Parsing

This parser only requires information about the overall vehicle speed message. So it only provide this data as input to the fusion algorithm. Even though this can be enough for some use cases, it may be better to provide separate wheel speeds to extract and use the vehicle angular velocity information as well.

...

Parameter name

...

Description

...

Default

...

canInterface

...

CAN bus interface, supported values are "PeakCAN" and "Vector"

...

PeakCAN

...

vehicleType

...

"Minimal"

...

n/a

...

velocityCanId

...

CAN id for the velocities message

...

n/a

...

velocityScale

...

Value to multiply the parsed raw velocity by in order to get velocities in m/s.

...

1.0

...

velocityStartBit

...

Start bit of the vehicle wheel velocity.

...

0

...

velocityBitsLength

...

Number of bits used for wheel velocity encoding.

...

16

Configuration example
Code Block
    "vehicle": {
      "type": "Automotive",
      "vehicleStateEndpoint": "tcp://*:8999",
      "settings": {
        "canInterface": "Internal",
        "canEndpoint": "tcp://localhost:9921",        
        "vehicleType": "Minimal",
        "canProtocol": {
          "velocityCanId": 209,
          "velocityScale": 0.015625012,
          "endianness": "little",
          "velocityBitsLength": 16,
          "velocityStartBit": 0
        }
      }
    }

...

Parameter name

...

Description

...

Default

...

canInterface

...

CAN bus interface, supported values are "PeakCAN" and "Vector"

...

PeakCAN

...

vehicleType

...

Used to specify the parser type, available values are:

"Minimal", "External" and "ExternalWithSteering"

...

n/a

...

wheelBase

...

Distance between front and back wheels.

...

n/a

...

trackWidth

...

Distance between right and left back wheels.

...

n/a

...

velocityCanId

...

CAN id for the velocities message

...

n/a

...

velocityScale

...

Value to multiply the parsed raw velocities by in order to get velocities in m/s.

...

1.0

...

velocityStartBits

...

Within this parameter, one need to specify the starting bits of each wheel velocity "FrontLeftWheel", "FrontRightWheel", "RearLeftWheel"and "RearRightWheel" .

...

0, 16, 32, 48

respectively.

...

velocityBitsLength

...

Number of bits used for each wheel velocity encoding.

...

16

...

endianness

...

Specify if the CAN data endianness is "little" or "big" .

...

little

...

driveModel

...

When no steering information is available, only Differential model can be used.

...

Differential

...

canEndpoint

...

Output endpoint of Vehicle data. This parameter is optional.

...

tcp://*:8802

Configuration example

...

For details about the overall configuration of the RTK-GPS system refer to this section.

GNSS Output Format

JSON

Code Block
"gnssData": {
    "altitude": 0.0,
    "hdop": 0.0,
    "heading": 0,
    "latitude": 0.0,
    "longitude": 0.0,
    "height": 0.0,
    "nSat": 0,
    "orientation": {
        "w": 1.0,
        "x": 0.0,
        "y": 0.0,
        "z": 0.0
    },
    "quality": 0,
    "sensorName": "",
    "timestamp": 0,
    "tmg": 0.0,
    "undulation": 0.0
}

Protobuf

Code Block
message GnssData {
    int64 timestamp = 1;
    double latitude = 3;
    double longitude = 4;
    double period = 5;
    int32 frame_count = 6;
    double latency = 8;
    string sensor_name = 11;
    Quaternion orientation = 12;
    double height = 13;
    double vertical_accuracy = 14;
    double horizontal_accuracy = 15;
    int32 quality = 16;
    int32 n_sat = 17;
    double hdop = 18;
    double tmg = 19;
    double heading = 20;
    double altitude = 21;
    double undulation = 22;
}

Important Output Data

Parameter name

Description

Unit

timestamp

Timestamp of current GNSS data

nanoseconds (in case GPS time is used as clock this is the duration since start of the day in UTC time)

longitude

Longitude part of GPS position

degree

latitude

Latitude part of GPS position

degree

height

The height of the receiver above the earth surface reference ellipsoid

m

quality

Quality of the GPS signal:

0: Fix not valid
1: GPS fix
2: Differential GPS fix
3: Not applicable
4: RTK fixed
5: RTK float
6: INS Dead reckoning

n/a (comment: for RTK enabled systems RTK fix provides the highest cm accuracy. If this quality can’t be reached, the number of visible satellites or connection to base station might be an issue.)

Odometry

The vehicle source is the data source that reads raw CAN data messages from a given CAN bus interface and parses the vehicle data using to the provided CAN protocol.

This section explains how to set up the configuration for a custom CAN parsing node. Depending on the available information about the vehicle CAN protocol, there are three types of CAN parsing available.

  • Minimal parsing where we only have information about the vehicle speed CAN message.

  • External separate four wheel speed parsing, velocity sign information may be added if the gear stick reading is available.

  • ExternalWithSteering parsing with steering model information, there are two ways to specify the steering tables depending on the information available: steering wheel angle vs (right or left) wheel angles or steering wheel angle vs average wheel angles. Using this data we can perform linear interpolation to compute the wheel angles for any given steering angle and use it for Ackermann steering.

Info

In most cases, having the overall vehicle speed message or the separate wheel speed messages is more than enough and no steering information is needed. If available, the gear stick reading is useful to help identify the reverse driving.

Minimal Vehicle Parsing

This parser only requires information about the overall vehicle speed message. So it only provide this data as input to the fusion algorithm. Even though this can be enough for some use cases, it may be better to provide separate wheel speeds to extract and use the vehicle angular velocity information as well.

Parameter name

Description

Default

canInterface

CAN bus interface, supported values are "PeakCAN" and "Vector"

PeakCAN

vehicleType

"Minimal"

n/a

velocityCanId

CAN id for the velocities message

n/a

velocityScale

Value to multiply the parsed raw velocity by in order to get velocities in m/s.

1.0

velocityStartBit

Start bit of the vehicle wheel velocity.

0

velocityBitsLength

Number of bits used for wheel velocity encoding.

16

Configuration example
Code Block
"vehicle": {
	"type": "Automotive",
	"vehicleStateEndpoint": "tcp://*:8999",
	"settings": {
		"canInterface": "Internal",
		"canEndpoint": "tcp://localhost:9921",        
		"vehicleType": "ExternalMinimal",
        "wheelBase": 2.750,
        "trackWidth": 1.595,
        "		"canProtocol": {
          			"velocityCanId": 212209,
          			"velocityScale": 0.015625012,
          			"endianness": "little",
          "velocityStartBits			"velocityBitsLength": {
            "FrontLeftWheel16,
			"velocityStartBit": 0,
		}
           "FrontRightWheel": 16,
            "RearLeftWheel": 32,
            "RearRightWheel": 48
          }  
        }
      }
    }

Additional Parameters

Gear Stick Position for Velocity Sign

If available, the gear stick reading data can be parsed to determine the velocity sign.

...

Parameter name

...

Description

...

Default

...

gearCanId

...

Gear stick message CAN id

...

n/a

...

gearStartBit

...

Gear stick message start bit

...

n/a

...

gearBitsLength

...

Number of bits used for gear stick message encoding.

...

n/a

...

gearReverseValue

...

Reverse driving gear stick value.

...

n/a

Configuration template
Code Block
    "vehicle": {
    ...
      "settings": {
      ...       
        "vehicleType": "External",
        ...
        "canProtocol": {
        ...
          },
          "gearCanId": 1,
          "gearStartBit": 2,
          "gearBitslength": 3,
          "gearReverseValue": 4 
        }
      }
    }

Steering information for Ackermann model

...

	}
}

Vehicle Parsing with Separate Wheel Velocities
Anchor
Vehicle-Parsing-with-Separate-Wheel-Velocities
Vehicle-Parsing-with-Separate-Wheel-Velocities

Parameter name

Description

Default

canInterface

CAN bus interface, supported values are "PeakCAN" and "Vector"

PeakCAN

vehicleType

Used to specify the parser type, available values are:

"Minimal", "External" and "ExternalWithSteering"

n/a

wheelBase

Distance between front and back wheels.

n/a

trackWidth

Distance between right and left back wheels.

n/a

velocityCanId

CAN id for the velocities message

n/a

velocityScale

Value to multiply the parsed raw velocities by in order to get velocities in m/s.

1.0

velocityStartBits

Within this parameter, one need to specify the starting bits of each wheel velocity "FrontLeftWheel", "FrontRightWheel", "RearLeftWheel"and "RearRightWheel" .

0, 16, 32, 48

respectively.

velocityBitsLength

Number of bits used for each wheel velocity encoding.

16

endianness

Specify if the CAN data endianness is "little" or "big" .

little

driveModel

When no steering information is available, only Differential model can be used.

Differential

canEndpoint

Output endpoint of Vehicle data. This parameter is optional.

tcp://*:8802

Configuration example
Code Block
"vehicle": {
	"type": "Automotive",
	"vehicleStateEndpoint": "tcp://*:8999",
	"settings": {
		"canInterface": "PeakCAN",
		"canEndpoint": "tcp://localhost:9921",
		"vehicleType": "External",
		"wheelBase": 2.750,
		"trackWidth": 1.595,
		"canProtocol": {
			"velocityCanId": 212,
			"velocityScale": 0.015625012,
			"endianness": "little",
			"velocityStartBits": {
				"FrontLeftWheel": 0,
				"FrontRightWheel": 16,
				"RearLeftWheel": 32,
				"RearRightWheel": 48
			}  
		}
	}
}

Additional Parameters

Gear Stick Position for Velocity Sign

If available, the gear stick reading data can be parsed to determine the velocity sign.

Parameter name

Description

Default

steeringCanId

gearCanId

CAN id for the steering wheel angle message

Gear stick message CAN id

n/a

gearStartBit

Gear stick message start bit

n/a

steeringScale

Value to multiply the parsed raw steering wheel angle by in order to get angle in degrees.

1.0

steeringWheelAngles

The steering table column containing sample steering wheel angles

gearBitsLength

Number of bits used for gear stick message encoding.

n/a

gearReverseValue

Reverse driving gear stick value.

n/a

Configuration template
Configuration template

...

...

wheelAngleType

...

Specification of provided wheelAngles type, valid options are "Right", "Left" or "Average"

...

n/a

...

wheelAngles

...

Steering table column containing corresponding wheel angle values.

...

n/a

...

driveModel

...

In addition to Differential model, Ackermann or SimpleAckermann can be used. the latter is a version of Ackermann steering that uses the average wheel angles.

...

Differential

Code Block
"vehicle": {
...
	"settings": {
	...       
		"vehicleType": "External",
		"canProtocol": {
			"gearCanId": 1,
			"gearStartBit": 2,
			"gearBitslength": 3,
			"gearReverseValue": 4 
		}
	}
}

Steering information for Ackermann model

If available, the steering wheel message can also be parsed but using it in the drive model requires input about the vehicle steering model as detailed below. Although we provide this option, using simpler drive models proved to work just fine.

Parameter name

Description

Default

steeringCanId

CAN id for the steering wheel angle message

n/a

steeringScale

Value to multiply the parsed raw steering wheel angle by in order to get angle in degrees.

1.0

steeringWheelAngles

The steering table column containing sample steering wheel angles.

n/a

wheelAngleType

Specification of provided wheelAngles type, valid options are "Right", "Left" or "Average"

n/a

wheelAngles

Steering table column containing corresponding wheel angle values.

n/a

driveModel

In addition to Differential model, Ackermann or SimpleAckermann can be used. the latter is a version of Ackermann steering that uses the average wheel angles.

Differential

Configuration template

If the input steering table is like follows (note that the input table should contain values for both right and left turns aka: positive and negative steering wheel angles),

...

The steeringTable configuration block would look something like below.

Code Block
    "vehicle""vehicle": {
    ...
      	"settings": {
      	...       
        		"vehicleType": "ExternalWithSteering",
        ...
        		"canProtocol": {
        			...
          		},
        		
		"steeringTable": {
            			"steeringWheelAngles": [
            			  -360, -340, -320, -300,
			  ...
           ...
              300			  300, 320, 340, 360],
  		        "wheelAngleType": "Right",
        		  "wheelAngles": [
            			-30.0, -25.5, -20.0, -15.0,
            			...
            			19.0, 26.0, 35.5, 40.0 ]
        }
        }
      }
   		}
	}
}

Predefined Vehicle Parsing

...

See a technical description of FusionHub’s communication interface in one of the following chapters.

JSON

Code Block
{
    "fusedVehiclePose": {
        "acceleration": {
            "x": 0.0,
            "y": 0.0,
            "z": 0.0
        },
        "globalPosition": {
            "x": 0.0,
            "y": 0.0
        },
        "lastDataTime": {
            "timestamp": 0
        },
        "position": {
            "x": 0,
            "y": 0
        },
        "timestamp": {
            "timestamp": 0
        },
        "utmZone": "31T",
        "yaw": 0
      }
}

Protobuf

Code Block
syntax = "proto3";

package Fusion.proto;

message Vector2 {
    double x = 2;
    double y = 3;
}

message Vector {
    double x = 2;
    double y = 3;
    double z = 4;
}

message FusedVehiclePose {
    int64 timestamp = 1;
    Vector2 position = 2;
    Vector2 global_position = 3;
    double yaw = 4;
    string utm_zone = 5;
    int64 timecode = 6; // Optional: if 0 not set.    
    Vector acceleration = 7;
}

message StreamData {
    int32 sequence_number = 1;
    FusedVehiclePose fused_vehicle_pose = 9;
}

...

Parameter name

...

Description

...

Unit

...

acceleration

...

3D acceleration vector as measured by IMU. Describes the orientation of the vehicle in the vehicle coordinate system.

...

m/s^2

...

globalPosition

...

Longitude and latitude in degrees

...

degrees

...

lastDataTime

...

Unused

...

s

...

position

...

Position relative to starting point with X pointing North and Y pointing East in the current UTM frame

...

m

...

timestamp

...

Timestamp of data acquisition

...

ns

...

utmZone

...

UTM zone

...

UTM string

...

yaw

...

Globally referenced yaw angle

...

rad

Info

After starting FusionHub, while the car is static, the filter will not deliver a correct yaw angle. The angle will be adjusted to the correct direction after a few seconds of driving the vehicle.

Fusion Filter Option 2 - High-Dynamics Filter

General

The high dynamics filter combines IMU and GPS data to calculate the global position of a vehicle. Instead of using the odometry it uses IMU data to determine the orientation changes of a car on the X, Y and Z axis. The direction of the vehicle is globally referenced from the GPS system. For increasing the direction reference quality a dual-antenna GPS system can be used.

The high dynamics filter works well for scenarios with agressive driving maneuvers such as drifting and cornering. During such maneuvers the turning motion of the wheels generally doesn’t directly correspond with the direction of the vehicle. Therefore for this filter doesn’t rely on wheel velocity measurements. This filter uses information from the wheels to determine if the car has come to a full stop.

As the filter relies heavily on GPS measurements it doesn’t deliver good results indoors. The better the GPS reception, the better the resulting output of the filter. In it’s current state it therefore only works outdoors. In a future version that combines LD and HD filters, this issue will be resolved.

Notes on Filter Output

The HD filter outputs the following data:

  • fusedVehiclePose (2D pose): Output equivalent to the LD filter output. Includes position in meters relative to starting point, global position (lon, lat) and heading.

  • fusedPose (3D pose): relative to starting point, x, y (in meters) + z (height) + 3D orientation quaternion

  • globalFusedPose: globally referenced 3D position (longitude, latitude, height) + 3D orientation quaternion in ENU frame

Which filter output works best depends on your application. For augmented reality applications we reommend using globalFusedPose.

You can find more information regarding the ENU coordinate system here.

Notes on IMU Arrangement

The used car frame is the Volkswagen (VW) coordinate frame convention:

Code Block
VW frame
x: back
y: right
z: up

...

The IMU sensor can be mounted in any way but the ImuToCarRotation quaternion needs to be provided to transform the IMU data into VW frame. For example, if the IMU is mounted like follows:

Code Block
IMU mounting
x: forward
y: left
z: up

To match the VW frame, we need a 180° rotation around the z axis (clockwise). Therefore, the rotation matrix would be:

Code Block
[ -1,  0,  0;
   0, -1,  0;
   0,  0,  1 ] 

And the orientation quaternion woud be [x, y, z, w] = [ 0, 0, 1, 0 ] which can be specified in the configuration like below:

Code Block
"imuToCarRotation": {
    "w": 0,
    "x": 0,
    "y": 0,
    "z": 1
}  

Check this page for more information on how to calculate the orientation quaternion.

Configuration Block

Insert the following configuration block into your config.json file in the sinks section to activate the HD filter. The filter's node name is gnssImuFusion.

Code Block
..
  "sinks

Parameter name

Description

Unit

acceleration

3D acceleration vector as measured by IMU. Describes the orientation of the vehicle in the vehicle coordinate system.

m/s^2

globalPosition

Longitude and latitude in degrees

degrees

lastDataTime

Unused

s

position

Position relative to starting point with X pointing North and Y pointing East in the current UTM frame

m

timestamp

Timestamp of data acquisition

ns

utmZone

UTM zone

UTM string

yaw

Globally referenced yaw angle

rad

Info

After starting FusionHub, while the car is static, the filter will not deliver a correct yaw angle. The angle will be adjusted to the correct direction after a few seconds of driving the vehicle.

Fusion Filter Option 2 - High-Dynamics Filter

General

The high dynamics filter combines IMU and GPS data to calculate the global position of a vehicle. Instead of using the odometry it uses IMU data to determine the orientation changes of a car on the X, Y and Z axis. The direction of the vehicle is globally referenced from the GPS system. For increasing the direction reference quality a dual-antenna GPS system can be used.

The high dynamics filter works well for scenarios with agressive driving maneuvers such as drifting and cornering. During such maneuvers the turning motion of the wheels generally doesn’t directly correspond with the direction of the vehicle. Therefore this filter doesn’t rely on wheel velocity measurements for localization like the low-dynamics (LD) filter. This filter uses information from the wheels to determine if the car has come to a full stop.

As the filter relies heavily on GPS measurements it doesn’t deliver good results indoors. The better the GPS reception, the better the resulting output of the filter. In it’s current state it therefore only works outdoors. In a future version that combines LD and HD filters, this issue will be resolved.

Notes on Filter Output

The HD filter outputs the following data:

  • fusedVehiclePose (2D pose): Output equivalent to the LD filter output. Includes position in meters relative to starting point, global position (lon, lat) and heading.

  • fusedPose (3D pose): relative to starting point, x, y (in meters) + z (height in meters) + 3D orientation quaternion

  • globalFusedPose: globally referenced 3D position (longitude, latitude, height in meters) + 3D orientation quaternion in ENU frame

Which filter output works best depends on your application. For augmented reality applications we recommend using globalFusedPose.

You can find more information regarding the ENU coordinate system here.

Notes on IMU Arrangement

For the car frame we use the Volkswagen (VW) coordinate frame convention:

Code Block
VW frame
x: back
y: right
z: up

Image Added

The IMU sensor can be mounted in any way but the ImuToCarRotation quaternion needs to be provided to transform the IMU data into VW frame. For example, if the IMU is mounted like follows:

Code Block
IMU mounting
x: forward
y: left
z: up

To match the VW frame, we need a 180° rotation around the z axis (clockwise). Therefore, the rotation matrix would be:

Code Block
[ -1,  0,  0;
   0, -1,  0;
   0,  0,  1 ] 

And the orientation quaternion woud be [w, x, y, z] = [ 0, 0, 0, 1 ] which can be specified in the configuration like below:

Code Block
"imuToCarRotation": {
    "w": 0,
    "x": 0,
    "y": 0,
    "z": 1
}  

Check this page for more information on how to calculate the orientation quaternion.

Note: The orientation of the IMU for a unity quaternion [ 1, 0, 0, 0 ] would be

Code Block
IMU mounting
x: backwards
y: right
z: up

Configuration Block

Insert the following configuration block into your config.json file in the sinks section to activate the HD filter. The filter's node name is gnssImuFusion.

Code Block
..
  "sinks": {
    ..,
    "gnssImuFusion": {
        "echoFusedPose": false,
        "endpoint": "tcp://*:8803",
        "fuser": {
            "fitModel": "ModelGnssImu",
            "accelError": 0.01,
            "omegaError": 0.02,
            "measurementError": 0.05,
            "imuToCarRotation": {
    ..,     "gnssImuFusion": {
        "echoFusedPosew": false1,
         "endpoint": "tcp://*:8803",      "x": 0,
 "fuser":  {             "fitModely": "ModelGnssImu"0,
                "accelErrorz": 0.01,
            "omegaError": 0.02},
            "measurementErroroutputWhenFilterNotReady": 0.05false,
            "imuToCarRotationretainStateWhenStopped": {
   true,
            "wsmoothFit": 1true,
   
            "xglobalOrigin": 0,{
                "ylongitude": 0139.73226516666668,
                "zlatitude": 035.657632
            }
        }
    }
..

See below a description of the parameter options for the HD filter.

Parameter name

Description

Default

echoFusedPose

fusedVehiclePose output is printed to command line

false

endpoint

Output port for the fusion result

8801

fitModel

Model to use for fusion.

ModelGnssImu

accelError

Acceleration error for Kalman filter. Keep default value.

0.01

omegaError

Omega error for Kalman filter. Keep default value.

0.02

measurementError

Measurement error for Kalman filter. Keep default value.

0.05

imuToCarRotation

Orientation quaternion of IMU relative to car frame

1, 0, 0, 0

smoothFit

Enable this option to prevent filter output from jumping between IMU data and GPS measurement. Keep enabled.

true

singleEndpoint

  • If enabled, the different fusion output messages will be published to the same port "endpoint"

  • If disabled, the "endpoint" parameter above, is the output port for the FusedVehiclePose msg type only.

true

poseEndpoint

Output port for the FusedPose msg type.

8804 if singleEndpoint=false

globalPoseEndpoint

Output port for the GlobalFusedPose msg type.

8805 if singleEndpoint=false

outputRawGnssData

Publishes raw Gnss data position instead of the fusion output. Useful for debugging.

false

outputWhenFilterNotReady

Publishes a temporary raw Gnss data output while the filter is initializing. Useful for a minimal check before moving the vehicle.

falseoutput. Useful for debugging.

false

outputWhenFilterNotReady

Publishes temporary raw Gnss data output while the filter is initializing. Useful for a sanity check before moving the vehicle.

false

retainStateWhenStopped

If the vehicle is detected to be stationary by looking at data from CAN bus, then the current filter state (position, rotation etc.) will be automatically retained until motion is detected.

true

globalOrigin

A global position as longitude and latitude: For fusedPose output this will be the starting point. All position outputs will be relative to this point.

{ 0, 0 }

Output Data Format

FusedVehiclePose

JSON
Code Block
{
    "fusedVehiclePose": {
        "acceleration": {
            "x": 0.0,
            "y": 0.0,
            "z": 0.0
        },
        "globalPosition": {
            "x": 0.0,
            "y": 0.0
        },
        "lastDataTime": {
            "timestamp": 0
        },
        "position": {
            "x": 0.0,
            "y": 0.0
        },
        "timestamp": {
            "timestamp": 0
        },
        "utmZone": "31T",
        "yaw": 0.0
    }
}
Protobuf
Code Block
syntax = "proto3";

package Fusion.proto;

message Vector2 {
  double x = 2;
  double y = 3;
}

message Vector {
  double x = 2;
  double y = 3;
  double z = 4;
}

message FusedVehiclePose {
  int64 timestamp = 1;
  Vector2 position = 2;
  Vector2 global_position = 3;
  double yaw = 4;
  string utm_zone = 5;
  int64 timecode = 6; // Optional: if 0 not set.
  Vector acceleration = 7;
}

message StreamData {
  int32 sequence_number = 1;
  FusedVehiclePose fused_vehicle_pose = 9;
}

Parameter name

Description

Unit

acceleration

3D acceleration vector as measured by IMU. Describes the orientation of the vehicle.

m/s^2

globalPosition

Longitude and latitude in degrees

degrees

lastDataTime

Unused

s

position

Position within UTM zone

m

timestamp

Timestamp of data acquisition

ns

utmZone

UTM zone

UTM string

yaw

Globally referenced yaw angle

rad

FusedPose

JSON
Code Block
{
	"fusedPose": {
		"lastDataTime": {
			"timestamp": 0
		},
		"orientation": {
			"w": 1.0,
			"x": 0.0,
			"y": 0.0,
			"z": 0.0
		},
		"position": {
			"x": 0.0,
			"y": 0.0,
			"z": 0.0
		},
		"timestamp": {
			"timestamp": 0
		}
    }
}
Protobuf
Code Block
syntax = "proto3";

package Fusion.proto;

message Quaternion {
  double w = 1;
  double x = 2;
  double y = 3;
  double z = 4;
}

message Vector {
  double x = 2;
  double y = 3;
  double z = 4;
}

message FusedPose {
  int64 timestamp = 1;
  Vector position = 2;
  Quaternion orientation = 3;
  Vector angular_velocity = 4;
  int64 timecode = 5; // Optional: if 0 not set.  
}

message StreamData {
  int32 sequence_number = 1;
  FusedPose fused_pose = 4;
}

Parameter name

Description

Unit

lastDataTime

Unused

s

orientation

Orientation quaternion in ENU coordinate frame

without unit

position

X, y position + height

m

timestamp

Time of data acqusition

ns

GlobalFusedPose

JSON
Code Block
{
    "globalFusedPose" {
        "orientation": {
			"w": 1.0,
			"x": 0.0,
			"y": 0.0,
			"z": 0.0
		},
        "timestamp": {
			"timestamp": 0
		},
        "position": {
            "longitude": 0.0,
            "latitude": 0.0,
            "height": 0.0
		}
	}
}
Protobuf
Code Block
syntax = "proto3";

package Fusion.proto;

message Quaternion {
  double w = 1;
  double x = 2;
  double y = 3;
  double z = 4;
}

message GpsPoint {
  double longitude = 2;
  double latitude = 3;
  double height = 4;
}

message GlobalFusedPose {
  int64 timecode = 5; // Optional: if 0 not set.
  int64 timestamp = 1;
  GpsPoint position = 2;
  Quaternion orientation = 3;
}

message StreamData {
  int32 sequence_number = 1;
  GlobalFusedPose global_fused_pose = 10;
}

...

Parameter name

...

Description

...

Unit

...

orientation

...

Orientation quaternion

...

without unit

...

position

...

Longitude, latitude, height

...

deg, deg, m

...

timestamp

...

Time of data acqusition

...

ns

Recording and Replaying Data

Data Recording

You can record the output from FusionHub to a file by adding the following lines to the sink section of config.json. All JSON output that's printed to the screen during the operation of FusionHub will be written into the log file.

Code Block
"record": {
    "filename": "driveData.json",
    "format": "json"
}

...

Parameter name

...

Description

...

Default

...

filename

...

Filename of the file to be recorded.

...

driveData.json

...

format

...

The file format. At the moment only JSON is possible.

...

json

Data Replay

Replay executable

In order to replay data from a JSON file a separate application ReplayExecutable.exe that we deliver with LPVR-POS is used. The replay executable reads the JSON data from a defined file, pushes the data to a replay queue and sends them to the network (tcp://localhost:9921 by default). To run the ReplayExecutable use the following command:

Code Block
ReplayExecutable.exe -r <path/to/file.json> [--replay-speed 1] [--queue-size 100] [--echo-data] [--verbose]

...

Key

...

Description

...

Type

...

Example value

...

-r

...

Path to read in file

...

String

...

“log.json”

...

--replay-speed

...

Speed to the actual recording

...

Double

...

1

...

--queue-size

...

The size of queue that file reader would stop pushing new data to the replay queue.

Increase this value when you see lots of data is published at the same time when running with --verbose

...

Integer

...

100

...

--echo-data

...

Listen to the publishing endpoint and display the replayed data

...

N/A

...

N/A

...

--verbose

...

Print the debugging information, i.e., the timestamp a packet is added to the replay queue, replayed from the replay queue, and discarded from the replay queue.

...

N/A

...

N/A

FusionHub can receive data from the replay application by adding the replay application’s endpoint source to the configuration file:

Code Block
languagejson
{
    ...,
    "sources": {
        "endpoints": ["tcp://localhost:9921"]
    }
}
Info

The Replay executable allows to replay the recorded data in order to use it as input to the fusion nodes. For that please keep the same “sinks“ block that was used in the live testing. The “sources“ block should be replaced by just the replay endpoint as shown above instead of the different hardware data sources.

Compatibility with old data recordings

Starting from 19/10/2023, the odometry message type used as input to the filter nodes has changed.

Panel
panelIconIdatlassian-warning
panelIcon:warning:
bgColor#FFFAE6
To be able to replay data recorded with older FusionHub versions, please make sure to include the "vehicle" source block in the sources in addition to the replay endpoint and change "canInterface" to "Internal".
/ Optional: if 0 not set.
  int64 timestamp = 1;
  GpsPoint position = 2;
  Quaternion orientation = 3;
}

message StreamData {
  int32 sequence_number = 1;
  GlobalFusedPose global_fused_pose = 10;
}

Parameter name

Description

Unit

orientation

Orientation quaternion

without unit

position

Longitude, latitude, height

deg, deg, m

timestamp

Time of data acqusition

ns

Recording and Replaying Data

Data Recording

You can record the output from FusionHub to a file by adding the following lines to the sink section of config.json. All JSON output that's printed to the screen during the operation of FusionHub will be written into the log file.

Code Block
"record": {
    "filename": "driveData.json",
    "format": "json"
}

Parameter name

Description

Default

filename

Filename of the file to be recorded.

driveData.json

format

The file format. At the moment only JSON is possible.

json

Data Replay

Replay executable

In order to replay data from a JSON file a separate application ReplayExecutable.exe that we deliver with LPVR-POS is used. The replay executable reads the JSON data from a defined file, pushes the data to a replay queue and sends them to the network (tcp://localhost:9921 by default). To run the ReplayExecutable use the following command:

Code Block
ReplayExecutable.exe -r <path/to/file.json> [--replay-speed 1] [--queue-size 100] [--echo-data] [--verbose]

Key

Description

Type

Example value

-r

Path to read in file

String

“log.json”

--replay-speed

Speed to the actual recording

Double

1

--queue-size

The size of queue that file reader would stop pushing new data to the replay queue.

Increase this value when you see lots of data is published at the same time when running with --verbose

Integer

100

--echo-data

Listen to the publishing endpoint and display the replayed data

N/A

N/A

--verbose

Print the debugging information, i.e., the timestamp a packet is added to the replay queue, replayed from the replay queue, and discarded from the replay queue.

N/A

N/A

FusionHub can receive data from the replay application by adding the replay application’s endpoint source to the configuration file:

Code Block
languagejson
{
    ...,
    "sources": {
        "endpoints": ["tcp://localhost:9921"]
    }
}
Info

The Replay executable allows to replay the recorded data in order to use it as input to the fusion nodes. For that please keep the same “sinks“ block that was used in the live testing. The “sources“ block should be replaced by just the replay endpoint as shown above instead of the different hardware data sources.

Compatibility with old data recordings

Starting from 19/10/2023, the odometry message type used as input to the filter nodes has changed.

Panel
panelIconIdatlassian-warning
panelIcon:warning:
bgColor#FFFAE6

To be able to replay data recorded with older FusionHub versions, please make sure to include the "vehicle" source block in the sources in addition to the replay endpoint.
Update the added vehicle configuration by changing "canInterface" to "Internal" and setting the "canEndpoint" same as the replay endpoint.

Code Block
  "vehicle": {
      "type": "Automotive",
      "vehicleStateEndpoint": "tcp://*:8999",
      "settings": {
        "canInterface": "Internal",
        "canEndpoint": "tcp://localhost:9921",
      ...
      }
    }

This way the recorded CAN messages are reprocessed to produce the expected input.

...

Quality flag value

Name

Result

2

DGPS

The GNSS unit is operating as normal GPS unit. It is not receiving correction information from an NTRIP server or other RTCM source.

4

RTK fixed

The RTK-GPS system is locked and operating with ~2cm positioning accuracy. This is the desired state.

5

RTK float

The GNSS unit is receiving correction information from an RTCM source, but so far hasn’t been able to lock to high precision mode. There might not be enough satellites in view or the system needs more time to stabilize.

Preferably we always want the system to operate in Fix mode. This requires working connection to the NTRIP caster, decent antenna placement and a sufficient number of satellites in view of the car’s antenna and the base station antenna.

As for LPVR-POS we are using a multi-channel GPS system, performance should be relatively robust. Check the output of the Emlid software to check the number of satellites the base station is seeing.

...

satellites in view or the system needs more time to stabilize.

Preferably we always want the system to operate in Fix mode. This requires working connection to the NTRIP caster, decent antenna placement and a sufficient number of satellites in view of the car’s antenna and the base station antenna.

As for LPVR-POS we are using a multi-channel GPS system, performance should be relatively robust. Check the output of the Emlid software to check the number of satellites the base station is seeing.

  • If you managed to get an RTK-GPS fix, your LPVR-POS system is now ready to operate with RTK-GPS as global centimeter-accurate position reference.

Using Alternate NTRIP Servers

In principle the FusionHub RTCM node can be used with any NTRIP server. We’ve so far only tested it using the Emlid caster described above and the Softbank Ichimili service in Japan. When configuring FusionHub for an alternate NTRIP server make sure to correctly modify all fields of the RTCM node. Make sure that the initialLatitude and initialLongitude coordinates point roughly to the area where you would like to operate the system. Check the command line output of FusionHub, if the connection to the NTRIP server was successful:

  • There should be a line saying "Output to NTRIP server: .." with the initial GET command that's sent to the NTRIP server

  • The output "Successfully connected to NTRIP Caster" should follow a few lines further on

If you see these messages, we know that FusionHub connected correctly to the NTRIP server. Check the GnssData message as described above for connection state.

References

Emlid caster documentation

...