Signals
A signal is an object you hold, not a double you fetch:
RotemSignal<Double> yaw = imu.getYaw();
yaw.value(); // 37.4yaw.units(); // "deg"yaw.isValid(); // false if the read failedyaw.status(); // why, if it didyaw.deviceTimestampSeconds(); // when the device sampled ityaw.ageSeconds(now); // how old it isyaw.isStale(now, 0.25); // older than 250 ms, or invalidA bare double has already thrown away everything you need to judge whether the number is worth
acting on. By the time a heading reaches robot code it has crossed a bus that can drop frames, and
the difference between “37.4 degrees, sampled 3 ms ago” and “37.4 degrees, sampled two seconds ago
before the connector fell out” is the difference between working odometry and a robot driving into
a wall with total confidence.
Two timestamps
Section titled “Two timestamps”| Method | Meaning | Use it for |
|---|---|---|
deviceTimestampSeconds() |
when the device sampled the sensor | pose estimation |
receivedTimestampSeconds() |
when the frame reached this robot | judging staleness |
Update frequency
Section titled “Update frequency”Every status frame has an individually configurable rate, including zero to disable it:
imu.setUpdateFrequency(SapphifyProtocol.Api.STATUS_ORIENTATION, 250);Defaults are chosen to be safe on a shared 1 Mbps bus carrying a full robot’s worth of devices. Raise orientation if you are running pose estimation at 250–500 Hz. On a CAN FD bus, prefer the composite frame, which packs the full estimator state into one large frame — the practical limit on Systemcore is frames per second, not bits per second, because its CAN interfaces share SPI controllers.