Susi Server

Full 6-DOF Fusion

Node ID: fullFusion · Role: Filter · Realtime config: no

Description

Unscented Kalman filter fusing IMU with optical tracking into a full 6-DOF pose: position, velocity, orientation, gyro and accelerometer bias, and gravity. Optical measurements are latency-compensated through a delayed-measurement scheme, so it tracks position as well as orientation.

Algorithm notes

How it works

This node blends a high-rate IMU with a lower-rate optical tracker into a single smooth 6-DOF pose. The IMU carries the pose between optical frames and fills in fast motion; the optical tracker supplies the absolute position and orientation that keeps the result from drifting. Because optical frames always arrive a little after the moment they describe, the node remembers what its state looked like at the instant each frame was captured and corrects that instant, then carries the correction forward. Along the way it learns the gyroscope and accelerometer biases and the local gravity direction, so accuracy improves over the first seconds of use.

What you must configure

IMU to Optical Frame must describe how the IMU is mounted relative to the tracked target. If it is wrong, the two sensors disagree about which way the rig is turning and the pose will shake or run away during motion.

Target to IMU Offset is the distance from the tracked optical target to the IMU, in the body frame. Without it, every rotation of the rig injects position error. Measure it from CAD or by hand; centimetre accuracy is enough. If you cannot measure it, enable Estimate Offset Automatically and rotate the rig for a few seconds - rotation is what makes the offset observable. Tighten Offset Prior (m) when you know the value well and only want it refined.

Optical Frame Rate (Hz) and Optical Latency (ms) must match the real tracker. They decide when the node takes its snapshots. Reference to Optical Frame and Reference to Optical Offset are optional: use them to report a point other than the tracked target, for example an eye point or a tool tip.

How it starts

Nothing is output until the first optical frame arrives - that frame anchors the pose. From then on, one pose is emitted per IMU sample. Biases stay frozen until gravity looks right and the rig is nearly still, so leave it stationary briefly after start-up. A large orientation jump against the optical data re-anchors the pose automatically.

Tuning

Troubleshooting

Inputs / Outputs

Config aliases

FullFusionFilter, fullFusionFilter, fullFusion

Required feature

imu_optical_fusion

Properties

Each row shows the setting’s label in the node’s Properties panel and, in code, its key in the node’s settings object in the config file. A setting omitted from the config file uses the default shown here.

PropertyTypeDefaultDescription
IMU to Optical Frame imuToOpticalFrameQuatquaternion{"w":1.0,"x":0.0,"y":0.0,"z":0.0}Quaternion (w,x,y,z) rotating the IMU body frame into the frame the optical tracker reports the rigid body in. Accounts for how the IMU is mounted relative to the optical target. Identity means the two frames coincide.
Reference to Optical Frame referenceToOpticalFrameQuatquaternion{"w":1.0,"x":0.0,"y":0.0,"z":0.0}Quaternion (w,x,y,z) applied to the fused pose on output, right-multiplied so it acts on the body frame. Use it to move the reported orientation from the tracked target to the point of interest.
Reference to Optical Offset referenceToOpticalFrameVecvector3{"x":0.0,"y":0.0,"z":0.0}Lever-arm offset in meters from the tracked optical target to the point of interest, expressed in the body frame. Rotated by the fused orientation and added to the output position.

Optical Tracker

PropertyTypeDefaultDescription
Optical Frame Rate (Hz) opticalFPSnumber90.0Frame rate of the optical tracker. Sets the spacing at which the filter schedules the delayed-measurement snapshots that latency compensation matches incoming frames against.
Optical Latency (ms) opticalLatencyMSnumber25Expected age of an optical frame when it reaches the filter. Used to schedule how far ahead a snapshot is taken; the per-frame latency reported by the source is what each measurement is actually matched with.
Optical Timing Window (ms) opticalTimingWindowMSnumber11How far an arriving optical frame’s capture time may differ from a pending snapshot’s time and still be matched to it. Too small and frames get rejected; too large and they are attributed to the wrong instant.
Optical Expiry Age (ms) opticalExpiryAgeMSnumber—How long a pending snapshot is kept before it is discarded. Must exceed the real optical latency or measurements arrive after their snapshot is gone. Leave empty to derive it from the frame rate plus the expected latency.
Dead Reckoning Max Time (ms) deadReckonMaxTimeMSnumber500How long the filter keeps integrating position from the IMU after optical data stops. Past this it holds position and tracks orientation only, so an occlusion cannot fling the pose away.

Noise Model

PropertyTypeDefaultDescription
Optical Position Error (m) posErrorMnumber0.001One-sigma uncertainty of the optical position measurement. Raise it to trust the IMU more and smooth optical jitter, lower it to follow the tracker more tightly.
Optical Orientation Error (rad) rotErrorRadnumber0.01One-sigma uncertainty of the optical orientation measurement.
Gyro Noise (deg/s) gyroErrorDegSnumber0.1One-sigma gyroscope noise driving the prediction step. Setting it too small makes the filter overconfident in the gyro and pushes the error into the estimated bias.
Accelerometer Noise (m/s^2) accErrorMS2number0.3One-sigma accelerometer noise driving the prediction step.
Use RK4 Integration useRK4booleanfalseIntegrate the state with fourth-order Runge-Kutta instead of Euler. More accurate for fast motion at four times the derivative evaluations per step.
Antipodal Threshold antipodalThresholdnumber0.9Dot-product threshold below which a measured orientation is treated as antipodal to the predicted one and flipped to the equivalent Modified Rodrigues parameters. Guards rotations near 180 degrees.

Lever Arm

PropertyTypeDefaultDescription
Target to IMU Offset (m) leverArmMvector3{"x":0.0,"y":0.0,"z":0.0}Vector in the body frame from the tracked optical target to the IMU. The accelerometer senses motion at the IMU, so without this the rotation of the rig injects position error. Also the starting point when the offset is estimated.
Estimate Offset Automatically estimateLeverArmbooleanfalseSolve for the target-to-IMU offset online instead of trusting the entered value. Needs rotation to observe: turning the rig moves the target relative to the IMU, which is what pins the offset down. Costs three extra state dimensions.
Offset Prior (m) leverArmSigmaMnumber0.05How far the estimated offset may move away from the entered value, one sigma. Lower it when the offset is known from CAD and only needs refining.

Example node definition

A minimal entry in config.json looks like the block below. Paste it under the sinks key, keyed by an instance name of your choice. All settings are optional: anything not listed under settings uses the default from the Properties table above. See The configuration file for how the sections and endpoint wiring work.

{
  "sinks": {
    "fullFusion": {
      "dataEndpoint": "inproc://fullFusion_data",
      "inputEndpoints": [
        "inproc://imu_data",
        "inproc://optical_data"
      ],
      "inputDataFilter": [
        "Imu",
        "Optical"
      ],
      "settings": {}
    }
  }
}
Loading documentation…