Data Types & External Applications
FusionHub nodes exchange typed messages over the wires you see in the node editor. This page defines every message type - what it contains, its units and coordinate frames - and explains how to receive these messages in your own application over each of FusionHub’s external interfaces (Protobuf/ZeroMQ, WebSocket, ROS 2, NMEA, UDP, MQTT, VRPN, and more).
The pipeline data model
Everything that flows through a FusionHub pipeline is one of the message types below. The type names are what the node editor shows on input and output handles; a wire carries exactly the types of the handles it connects. What you wire in the editor is what runs - an external consumer sees exactly the types routed into its output node, nothing more.
Conventions shared by all types:
- Timestamps are 64-bit integers, nanoseconds since the Unix epoch (UTC).
- senderId names the node instance that produced the message, so multiple sensors of the same type can share one stream.
- Quaternions are unit quaternions with fields
w,x,y,z. - Vectors are objects with fields
x,y,z(orx,yfor 2D).
| Type | JSON key | Protobuf message | Content |
|---|---|---|---|
Imu | imuData | ImuData | Raw IMU sample: gyroscope, accelerometer, magnetometer, sensor orientation |
Gnss | gnssData | GnssData | GNSS fix: position, quality, velocity, dual-antenna heading |
Optical | opticalData | OpticalData | Pose from an optical tracking system (ART, OptiTrack, VICON, …) |
FusedPose | fusedPose | FusedPose | Fused 6-DOF pose in a local metric frame, with velocity and acceleration |
GlobalFusedPose | globalFusedPose | GlobalFusedPose | Fused pose in geodetic coordinates (WGS84 latitude/longitude/height) |
FusedVehiclePose | fusedVehiclePose | FusedVehiclePose | Legacy 2D vehicle pose (superseded by V2) |
FusedVehiclePoseV2 | fusedVehiclePoseV2 | FusedVehiclePoseV2 | 2D vehicle pose: UTM position, yaw, velocity, plus longitude/latitude |
Odometry | OdometryData | OdometryData | Generic odometry (pose + twist), modeled on ROS 2 nav_msgs/Odometry |
VehicleState | VehicleState | VehicleState | Wheel speeds and steering angles from the vehicle bus |
VehicleSpeed | VehicleSpeed | VehicleSpeed | Scalar vehicle speed and yaw rate |
VelocityMeter | VelocityMeterData | VelocityMeterData | Ground-speed sensor sample (e.g. ACT2535) |
Rtcm | RTCMData | RTCMData | Raw RTCM correction chunk for RTK GNSS |
Can | CANData | CANData | Raw CAN bus frame |
FusionStateInt | FusionStateInt | FusionStateInt | Internal fusion filter state (position, velocity, biases) |
FusionDiagnostics | FusionDiagnostics | FusionDiagnostics | Fusion filter health: sigmas, innovations, status flags |
Timestamp | Timestamp | (sequence-only frame) | Heartbeat carrying the current time |
Reset | Reset | status = STREAM_STATUS_RESET | Tells downstream nodes to reset their state (e.g. on replay restart) |
Image | - | - | Internal camera-source configuration token; never leaves the process |
Data type reference
Field names below are the JSON names; the Protobuf messages use the same names in snake_case (see the Protobuf section).
Imu (imuData)
Raw inertial sample as delivered by an IMU source (LPMS sensor, vehicle IMU).
| Field | Type | Unit | Description |
|---|---|---|---|
senderId | string | - | Producing node instance |
timestamp | int64 | ns | Time of data acquisition |
gyroscope | vector3 | deg/s | Angular velocity, sensor frame |
accelerometer | vector3 | g | Acceleration, sensor frame. Gravity is INCLUDED and points up: a stationary, level sensor reads about +1 on its up axis |
magnetometer | vector3 | uT | Raw magnetic field, sensor frame. Zeros when the sensor does not stream mag data |
magnetometerValid | bool | - | true when magnetometer is a real reading; check this, not the values |
quaternion | quaternion | - | Sensor orientation in the world frame |
euler | vector3 | deg | Same orientation as Euler angles |
Gnss (gnssData)
One GNSS fix from a receiver (or a fused virtual receiver).
| Field | Type | Unit | Description |
|---|---|---|---|
senderId | string | - | Producing node instance |
timestamp | int64 | ns | Time of data acquisition |
latitude, longitude | double | deg | WGS84 position |
altitude | double | m | Altitude above mean sea level |
undulation | double | m | Geoid undulation |
height | double | m | Ellipsoidal height |
quality | int32 | - | GGA-style fix quality: 0 = no fix, 1 = autonomous, 2 = differential, 4 = RTK fixed, 5 = RTK float |
nSat | int32 | - | Number of satellites used |
hdop | double | - | Horizontal dilution of precision |
heading | double | deg | Dual-antenna heading (when the receiver provides one) |
headingQuality | int32 | - | Solution status of the dual-antenna heading, same enum as quality. Independent of quality: the heading can degrade while the position fix stays good, and vice versa |
headingQualityValid | bool | - | true when the receiver reported headingQuality. Do not treat 0 as “no heading fix” unless this is set |
pitchDeg | double | deg | Dual-antenna pitch |
pitchDegValid | bool | - | true when pitchDeg is a real measurement |
velocity | vector3 | m/s | Receiver-supplied velocity in local ENU |
velocityValid | bool | - | true when velocity is a real measurement, false when it is the default zero |
tmg | double | deg | Track made good |
diffAge | double | s | Age of differential corrections |
orientation | quaternion | - | Receiver-derived orientation (identity when not available) |
Optical (opticalData)
Rigid-body pose from an optical tracking system.
| Field | Type | Unit | Description |
|---|---|---|---|
senderId | string | - | Producing node instance (one per tracked body) |
timestamp | int64 | ns | Time of data acquisition |
position | vector3 | m | Position in the tracking system’s world frame |
orientation | quaternion | - | Orientation in the tracking system’s world frame |
angularVelocity | vector3 | deg/s | Angular velocity, body frame |
quality | double | - | Tracking confidence, 0.0 to 1.0 (1.0 = full confidence) |
FusedPose (fusedPose)
The main output of the 6-DOF fusion filters (IMU-Optical Fusion, Full 6-DOF Fusion, Marine Heading, …). A full pose in a local metric frame: for optical fusion this is the tracking system’s world frame; for GNSS-based fusion it is a local ENU frame (x east, y north, z up).
| Field | Type | Unit | Description |
|---|---|---|---|
senderId | string | - | Producing node instance |
timestamp | int64 | ns | Time the pose is valid for |
transmissionTime | int64 | ns | Time the message was sent |
lastDataTime | int64 | ns | Time of the most recent sensor sample incorporated into this pose |
position | vector3 | m | Position in the local world frame |
orientation | quaternion | - | Orientation in the local world frame |
velocity | vector3 | m/s | Linear velocity, world frame |
acceleration | vector3 | m/s^2 | Linear acceleration |
angularVelocity | vector3 | deg/s | Angular velocity, body frame |
Example JSON:
{
"fusedPose": {
"senderId": "fusion",
"timestamp": 1772137433109455200,
"transmissionTime": 1772137433109455200,
"lastDataTime": 1772137433109455200,
"position": { "x": 0.0, "y": 0.0, "z": 0.0 },
"orientation": { "w": 1.0, "x": 0.0, "y": 0.0, "z": 0.0 },
"velocity": { "x": 0.0, "y": 0.0, "z": 0.0 },
"acceleration": { "x": 0.0, "y": 0.0, "z": 0.0 },
"angularVelocity": { "x": 0.0, "y": 0.0, "z": 0.0 }
}
}
GlobalFusedPose (globalFusedPose)
The same fused state expressed in geodetic coordinates. Filters that know their global position (GNSS-based fusion, Marine Heading) emit this alongside FusedPose; the global variant is only published while a GNSS fix is available.
| Field | Type | Unit | Description |
|---|---|---|---|
senderId | string | - | Producing node instance |
timestamp | int64 | ns | Time the pose is valid for |
transmissionTime | int64 | ns | Time the message was sent |
position.latitude | double | deg | WGS84 latitude |
position.longitude | double | deg | WGS84 longitude |
position.height | double | m | Height |
orientation | quaternion | - | Orientation (same attitude as the paired FusedPose) |
Note that GlobalFusedPose carries no velocity, acceleration, or angular velocity - subscribe to FusedPose if you need those.
FusedVehiclePoseV2 (fusedVehiclePoseV2)
Output of the vehicle fusion filters (Full Vehicle Fusion, Vehicular Fusion). A 2D pose that carries both a local metric position and the global position in one message.
| Field | Type | Unit | Description |
|---|---|---|---|
senderId | string | - | Producing node instance |
timestamp | int64 | ns | Time the pose is valid for |
transmissionTime | int64 | ns | Time the message was sent |
position | vector2 | m | Position within the UTM zone named by utmZone |
utmZone | string | - | UTM zone, e.g. "54S" |
globalPosition | vector2 | deg | x = longitude, y = latitude |
yaw | double | rad | Vehicle yaw; converted to degrees it is used as the heading in NMEA output |
velocity | vector2 | m/s | Velocity in the UTM frame |
acceleration | vector2 | m/s^2 | Acceleration |
angularVelocity | double | rad/s | Yaw rate |
internalFrameCount | int64 | - | Monotonic frame counter |
FusedVehiclePose (without V2) is the legacy single-frame variant of the same message; new integrations should use V2.
Odometry (OdometryData)
Generic odometry input/output, modeled on ROS 2 nav_msgs/Odometry. Produced by visual-odometry sources (e.g. Isaac ROS Visual SLAM) and consumed by fusion filters as a velocity measurement.
| Field | Type | Unit | Description |
|---|---|---|---|
senderId | string | - | Producing node instance |
timestamp | int64 | ns | Time of data acquisition |
position | vector3 | m | Position in the world frame |
orientation | quaternion | - | Orientation in the world frame |
linearVelocity | vector3 | m/s | Linear velocity, body frame (ROS twist convention) |
angularVelocity | vector3 | rad/s | Angular velocity, body frame |
poseValid, twistValid | bool | - | Which halves of the message carry real data |
Vehicle bus and speed sensors
VehicleState (VehicleState) - wheel speeds and steering, decoded from CAN: wheelBase (m), trackWidth (m), steeringAngleL / steeringAngleR (rad), wheelFR / wheelFL / wheelRR / wheelRL (wheel speeds).
VehicleSpeed (VehicleSpeed) - scalar speed: linear (m/s), angular (yaw rate), validAngular (bool).
VelocityMeter (VelocityMeterData) - optical ground-speed sensor sample: counter, velocity, distance, material, dopplerLevel, outputStatus.
Raw transport types
Rtcm (RTCMData) - a chunk of RTCM correction data on its way to a GNSS receiver: chunk (bytes), length.
Can (CANData) - one CAN frame: id, isExtended, data (bytes), length.
Diagnostics and control
FusionStateInt (FusionStateInt) - internal filter state for debugging: position, velocity, gravity, imuOrientation, omegaBias, accelBias, imuPosition, timeDelay.
FusionDiagnostics (FusionDiagnostics) - filter health: per-state sigmas (sigmaPosition, sigmaVelocity, sigmaOrientation, sigmaGyroBias, sigmaAccelBias, sigmaAntennaOffset, …), GNSS innovations, and status flags (hasGnssUpdate, rtkFixActive, filterInitialized, waitingForConvergence).
Timestamp / Reset - control messages. Timestamp is a heartbeat; Reset tells downstream nodes to clear their state, e.g. when a replay restarts. External consumers can usually ignore both, but should skip unknown frames gracefully.
FusedPose vs GlobalFusedPose vs FusedVehiclePoseV2
The three pose outputs answer different questions:
FusedPose | GlobalFusedPose | FusedVehiclePoseV2 | |
|---|---|---|---|
| Position | 3D, meters, local frame (optical world or local ENU) | WGS84 latitude / longitude / height | 2D, meters, UTM zone + longitude/latitude |
| Orientation | Full quaternion | Full quaternion | Yaw only |
| Velocity / acceleration | Yes (3D) | No | Yes (2D) |
| Angular velocity | Yes (3D, deg/s) | No | Yaw rate only |
| Emitted | Always while the filter runs | Only while a GNSS fix is available | Always while the filter runs |
| Typical consumer | Game engines, SteamVR, robotics (local navigation) | Maps, geodetic logging, NMEA/ROS NavSatFix | Automotive applications |
Filters that are globally referenced (GNSS fusion, Marine Heading) emit FusedPose and GlobalFusedPose as a pair from the same filter tick: same timestamp, same attitude, one position local metric and one geodetic.
Encodings
JSON
JSON messages are a single-key object: the key names the type, the value holds the fields listed above.
{ "imuData": { ... } }
{ "fusedPose": { ... } }
{ "globalFusedPose": { ... } }
JSON is used by the WebSocket Sink, the MQTT Publisher, the File Logger (one JSON object per line), and data recordings.
Protobuf
The binary encoding is Protocol Buffers (proto3), package Fusion.proto, defined in stream_data.proto (full definition below). Every frame on the wire is one StreamData envelope:
message StreamData {
int32 sequence_number = 1;
StreamStatus status = 17; // NORMAL or RESET
ImuData imu_data = 2;
OpticalData optical_data = 3;
FusedPose fused_pose = 4;
GnssData gnss_data = 5;
// ... exactly one payload field is set per frame
}
sequence_numberincrements by one per frame from each publisher; gaps tell you frames were dropped.- Exactly one payload field is set; check which one with
HasField/ presence. - Some messages carry extra legacy fields (
timecode,recorded_time,sensor_name,object_name, …) kept for compatibility with older consumers:timecodemirrorstimestampandsensor_name/object_namemirrorsender_id.
Getting data into your application
Each interface below is a sink node you add in the node editor (except the Foxglove bridge and the REST API, which are process-wide). The node reference pages linked in each section document all config properties.
External Output - Protobuf over ZeroMQ
The primary machine-readable interface, and the same protocol FusionHub’s own external components (SteamVR drivers, Unity clients) use. Add a TCP Output node in the editor, set its endpoint (for example tcp://*:9000), and wire in the streams you want to expose. The external consumer sees exactly the types wired into that node. See External Output.
Transport details:
- ZeroMQ PUB socket; connect with a SUB socket and an empty subscription filter.
- One
Fusion.proto.StreamDataprotobuf message per ZeroMQ frame. No extra framing, no topic prefix - ZeroMQ preserves message boundaries. - TCP outputs are lossy by design (bounded send queue): a slow or stalled consumer drops frames instead of stalling the pipeline. Detect drops via
sequence_numbergaps. After a delivery pause, drain the socket and keep only the newest pose rather than processing the backlog.
Minimal Python consumer (pip install pyzmq protobuf, then generate the bindings with protoc --python_out=. stream_data.proto):
import zmq
import stream_data_pb2
ctx = zmq.Context()
sock = ctx.socket(zmq.SUB)
sock.connect("tcp://127.0.0.1:9000") # your TCP Output endpoint
sock.setsockopt(zmq.SUBSCRIBE, b"")
while True:
frame = sock.recv()
msg = stream_data_pb2.StreamData()
msg.ParseFromString(frame)
if msg.HasField("fused_pose"):
p = msg.fused_pose
print(p.timestamp, p.position.x, p.position.y, p.position.z)
elif msg.HasField("global_fused_pose"):
g = msg.global_fused_pose
print(g.position.latitude, g.position.longitude)
For C#/Unity, the same pattern works with NetMQ and Google.Protobuf.
WebSocket Sink - JSON
Streams every wired-in message as a JSON text frame to all connected WebSocket clients. Easiest interface for browsers, dashboards, and quick scripting - new WebSocket("ws://host:8080") and parse each message with JSON.parse. Default port 8080. See WebSocket Sink.
Zenoh Publisher - ROS 2
Publishes standard ROS 2 messages through a bundled zenoh-bridge-ros2dds process, so they appear as native DDS topics to any ROS 2 node (default ROS_DOMAIN_ID 0, bridge spawned automatically). See Zenoh Publisher.
The node’s input handles accept FusedPose, FusedVehiclePoseV2, and GlobalFusedPose, and each becomes a different ROS 2 message:
| Input | Zenoh key (default) | ROS 2 topic | Message type | Content |
|---|---|---|---|---|
FusedPose | fusionhub/pose | /fusionhub/pose | geometry_msgs/PoseStamped | Local Cartesian position (m) + quaternion |
FusedPose | tf | /tf | tf2_msgs/TFMessage | Same pose as a transform, with configurable position/rotation offsets |
FusedVehiclePoseV2 | fusionhub/pose + tf | as above | as above | 2D position with z = 0, yaw as quaternion about Z |
GlobalFusedPose | fusionhub/gnss | /fusionhub/gnss | sensor_msgs/NavSatFix | Latitude / longitude / height only |
Things to know when consuming these topics:
FusedPoseandGlobalFusedPoseare input data types, not topic names. The topic names are the configurable Zenoh keys above.PoseStampedcarries position and orientation only - the velocity, acceleration, and angular velocity inFusedPoseare not part of the ROS message. Consume the protobuf stream if you need them.GlobalFusedPosebecomesNavSatFixonly (its orientation is not published, and no PoseStamped/TF is derived from it, since latitude/longitude are not Cartesian).- By default headers are stamped with wall-clock time at publish (
stampWithWallClock); turn it off to keep the original data timestamps. - The
/tftransform applies the configuredtfRotationOffset(default a 90 degree yaw for REP-103 alignment); the PoseStamped topic does not./fusionhub/poseis therefore in the same frame as FusionHub’s native output,/tfmay be rotated relative to it. - One
maxRateHzbudget (default 200 Hz) covers all three publications of the node.
Same data, different pipes: the FusedPose published here is the same pipeline message the LPVIZ SteamVR output sends - one is re-encoded as CDR ROS messages, the other as protobuf over ZeroMQ. If both sinks are wired to the same filter output they carry identical poses.
For PX4 drones, the PX4 DDS Sink publishes GlobalFusedPose as px4_msgs/SensorGps on the PX4 uXRCE-DDS topic (fmu/in/sensor_gps), letting FusionHub act as the GPS input of a PX4 flight controller.
NMEA Output
Generates NMEA 0183 sentences, so any application that can read a GPS receiver can read FusionHub. Transport is a serial port (real or virtual) or UDP. See NMEA Output.
| Input | Sentences per sample |
|---|---|
FusedVehiclePoseV2 | $GPGGA, $GPRMC, $GPVTG, $GPHDT |
GlobalFusedPose | $GPGGA, $GPRMC |
Sentences use the GP talker ID and end with the standard *checksum and CRLF. The optional Timestamp Suffix setting appends a non-standard ,T=<nanoseconds> field after the checksum for latency measurements; leave it off (the default) for standard NMEA consumers.
GlobalFusedPose UDP Output
Minimal-overhead binary UDP stream for embedded consumers: each GlobalFusedPose becomes one 24-byte little-endian packet, [latitude f64][longitude f64][heading_deg f64]. Default destination 127.0.0.1:5005. See GlobalFusedPose UDP Output.
MQTT Publisher
Publishes wired-in messages as JSON to an MQTT broker (default localhost:1883, topic fusionhub/output, QoS 1). Useful for IoT-style deployments where consumers are decoupled from the vehicle network. See MQTT Publisher.
VRPN Output
Runs a VRPN server (default port 3883, device name FusionHub) exposing wired-in poses as VRPN tracker channels - the standard route into Unreal Engine, MotionBuilder, and other VRPN-aware tools. Up to 10 tracker slots are mapped by senderId; axis remapping is configurable on the node. Available on Windows builds. See VRPN Output.
To use it in Unreal Engine:
- Enable the LiveLink and LiveLinkVRPN plugins.
- Add a LiveLink VRPN source with the device name configured on the node (e.g.
FusionHub@localhost) and the tracker/subject name. - Assign the LiveLink subject to an actor (e.g. a Cine Camera) via a LiveLink Controller component.
DTrack Output (Proxy)
Re-publishes poses in ART DTrack’s ASCII UDP format (6d lines, millimeters), so software that already ingests DTrack data can consume FusionHub output without modification. See DTrack Output (Proxy).
SteamVR outputs
Two dedicated protobuf/ZeroMQ endpoints feed LP-Research’s SteamVR drivers: LPVIZ SteamVR Output publishes FusedPose on tcp://*:9921 for the LPVIZ display driver, and SteamVR Tracker Output publishes Optical poses on tcp://*:9923 for LPVR virtual trackers (one tracker per senderId). They speak the exact same protocol as External Output, so they double as ready-made pose feeds for custom consumers.
Foxglove / Lichtblick bridge
When started with --foxglove-port 8765 (or FUSIONHUB_FOXGLOVE_PORT), FusionHub serves the foxglove.websocket.v1 protocol and advertises every node’s output as a typed, protobuf-encoded channel named /<type>/<node> (e.g. /fused_pose/fusion). Connect Foxglove Studio or Lichtblick to ws://host:8765 to plot and inspect any stream live - no configuration in the pipeline needed.
ALVR and Varjo bridges
The ALVR Bridge and Varjo HMD filter nodes are bidirectional ZeroMQ/protobuf links to the LPALVR streamer and the LPVR Varjo Base plugin. They use the same StreamData protocol on fixed local ports and are configured through their node properties; they are product integrations rather than general-purpose outputs.
Controlling FusionHub externally
The web UI’s REST API (default port 19359) is available to any HTTP client and replaces the WebSocket configuration API of the classic C++ FusionHub:
| Method and path | Action |
|---|---|
GET /api/config | Get the in-memory configuration |
POST /api/config | Merge changes into the in-memory configuration |
POST /api/config/save | Save the in-memory configuration to disk |
POST /api/restart | Restart the pipeline |
POST /api/pause, POST /api/resume | Pause / resume processing |
GET /api/version | Version info |
GET /api/logs | Recent log lines |
GET /api/events | Server-sent events stream (status, logs, live updates) |
Example:
curl http://localhost:19359/api/version
curl -X POST http://localhost:19359/api/config -H "Content-Type: application/json" \
-d '{"sinks": {"fusion": {"settings": {"oriBlendWeight": 0.001}}}}'
Appendix: stream_data.proto
Copy this file into your project and compile it with protoc for your language (also available as a download: stream_data.proto).
syntax = "proto3";
package Fusion.proto;
enum StreamStatus {
STREAM_STATUS_NORMAL = 0;
STREAM_STATUS_RESET = 1;
}
message Vector2 {
double x = 2;
double y = 3;
}
message Vector {
double x = 2;
double y = 3;
double z = 4;
}
message GpsPoint {
double longitude = 2;
double latitude = 3;
double height = 4;
}
message Quaternion {
double w = 1;
double x = 2;
double y = 3;
double z = 4;
}
message ImuData {
int64 timecode = 1;
int64 recorded_time = 2;
Vector gyroscope = 3;
Vector accelerometer = 4;
double period = 5;
int32 frame_count = 6;
int32 sensor_time = 7;
double latency = 8;
int64 start_tick = 9;
bool fake_timecode = 10;
string sensor_name = 11;
Quaternion quaternion = 12;
Vector euler = 13;
int64 timestamp = 14;
string sender_id = 15;
Vector linear_velocity = 16;
Vector magnetometer = 17;
bool magnetometer_valid = 18;
}
message GnssData {
int64 timecode = 1;
int64 recorded_time = 2;
double latitude = 3;
double longitude = 4;
double period = 5;
int32 frame_count = 6;
int32 sensor_time = 7;
double latency = 8;
int64 start_tick = 9;
bool fake_timecode = 10;
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;
int64 timestamp = 23;
string sender_id = 24;
double diff_age = 25;
Vector velocity = 26;
bool velocity_valid = 27;
double pitch_deg = 28;
bool pitch_deg_valid = 29;
int32 heading_quality = 30;
bool heading_quality_valid = 31;
}
message OpticalData {
int64 timecode = 1;
int64 recorded_time = 2;
Vector position = 3;
Quaternion orientation = 4;
Vector angular_velocity = 5;
double quality = 6;
double frame_rate = 7;
int32 frame_number = 8;
double latency = 9;
bool fake_timecode = 10;
string object_name = 11;
int64 timestamp = 12;
string sender_id = 13;
}
message FusedPose {
int64 timestamp = 1;
Vector position = 2;
Quaternion orientation = 3;
Vector angular_velocity = 4;
int64 timecode = 5;
string sender_id = 6;
Vector velocity = 7;
Vector acceleration = 8;
int64 frame_number = 9;
int64 transmission_time = 10;
double latency = 11;
string object_name = 12;
reserved 13, 14;
}
message RTCMData {
bytes chunk = 1;
int32 length = 2;
int64 timestamp = 3;
string sender_id = 4;
}
message CANData {
int64 timecode = 1;
int64 recorded_time = 2;
bool is_extended = 3;
uint32 id = 4;
bytes data = 5;
int32 length = 6;
int64 timestamp = 7;
string sender_id = 8;
}
message VehicleState {
int64 timecode = 1;
int64 recorded_time = 2;
double wheel_base = 3;
double track_width = 4;
double steering_angle_l = 5;
double steering_angle_r = 6;
double wheel_fr = 7;
double wheel_fl = 8;
double wheel_rr = 9;
double wheel_rl = 10;
int64 timestamp = 11;
string sender_id = 12;
}
message FusedVehiclePose {
int64 timestamp = 1;
Vector2 position = 2;
Vector2 global_position = 3;
double yaw = 4;
string utm_zone = 5;
int64 timecode = 6;
Vector acceleration = 7;
}
message FusedVehiclePoseV2 {
int64 timestamp = 1;
Vector2 position = 2;
Vector2 global_position = 3;
double yaw = 4;
string utm_zone = 5;
int64 timecode = 6;
Vector2 acceleration = 7;
string sender_id = 8;
Vector2 velocity = 9;
double angular_velocity = 10;
int64 transmission_time = 11;
int64 internal_frame_count = 12;
}
message GlobalFusedPose {
int64 timestamp = 1;
GpsPoint position = 2;
Quaternion orientation = 3;
string sender_id = 4;
int64 timecode = 5;
int64 transmission_time = 6;
}
message VehicleSpeed {
int64 timecode = 1;
int64 recorded_time = 2;
double linear = 3;
double angular = 4;
bool valid_angular = 5;
int64 timestamp = 6;
string sender_id = 7;
}
message VelocityMeterData {
int64 timestamp = 1;
string sender_id = 2;
int32 counter = 3;
double velocity = 4;
double distance = 5;
double material = 6;
double doppler_level = 7;
int32 output_status = 8;
}
message FusionStateInt {
int64 recorded_time = 1;
Vector position = 2;
Vector velocity = 3;
double gravity = 4;
Quaternion imu_orientation = 5;
Vector omega_bias = 6;
Vector accel_bias = 7;
Vector imu_position = 8;
int64 timecode = 9;
int64 timestamp = 10;
string sender_id = 11;
}
message FusionDiagnostics {
int64 timestamp = 1;
string sender_id = 2;
Vector sigma_position = 3;
Vector sigma_velocity = 4;
double sigma_gravity = 5;
Vector sigma_orientation = 6;
Vector sigma_gyro_bias = 7;
Vector sigma_accel_bias = 8;
Vector sigma_antenna_offset = 9;
Vector gnss_position_innovation = 10;
double gnss_orientation_innovation = 11;
bool has_gnss_update = 12;
bool has_orientation_update = 13;
bool rtk_fix_active = 14;
bool filter_initialized = 15;
bool waiting_for_convergence = 16;
}
message OdometryData {
string sender_id = 1;
int64 timestamp = 2;
double latency = 3;
Vector position = 4;
Quaternion orientation = 5;
Vector linear_velocity = 6;
Vector angular_velocity = 7;
bool pose_valid = 8;
bool twist_valid = 9;
}
message StreamData {
int32 sequence_number = 1;
StreamStatus status = 17;
ImuData imu_data = 2;
OpticalData optical_data = 3;
FusedPose fused_pose = 4;
GnssData gnss_data = 5;
RTCMData rtcm_data = 6;
CANData can_data = 7;
VehicleState vehicle_state = 8;
FusedVehiclePose fused_vehicle_pose = 9;
GlobalFusedPose global_fused_pose = 10;
VehicleSpeed vehicle_speed = 11;
FusionStateInt fusion_state_int = 12;
FusedVehiclePoseV2 fused_vehicle_pose_v2 = 13;
VelocityMeterData velocity_meter_data = 14;
reserved 15;
FusionDiagnostics fusion_diagnostics = 16;
OdometryData odometry_data = 18;
}