Nothing this transport carries is timestamped at source. A frame arrives when it arrives, a robot.state notification arrives when it arrives, and a consumer that wants to know when the robot saw or felt something has only its own clock — which, over a relay, measures the network rather than the robot.
That is fine for driving a robot you are watching, and wrong for most of what a remote consumer is interesting for. SLAM is the case that makes it concrete: monocular SLAM on a stream with no capture times runs; the moment somebody wants visual-inertial — the IMU this robot has, at 50 Hz, on the same control channel — the two series cannot be related except by guessing.
Design note: remote-webrtc.md §11.
Two halves, and they are not the same problem
Media. RTP timestamps are relative to a random offset: they order frames and date none of them. The mechanism is the abs-capture-time RTP header extension, which carries a wall-clock capture time per packet. First job is checking what actually surfaces it — whether webrtcsink will negotiate it, and what a browser (RTCRtpReceiver.getSynchronizationSources, getStats) and aiortc expose of it. A header extension nothing on the receiving side surfaces buys nothing, and that determines whether this half is cheap or a fork of somebody's stack.
The control channel. Ours, and cheap: a monotonic reading plus the boot epoch that makes it comparable across processes, on every notification that describes a moment (robot.state first). The cost is a field per message and an argument about which clock — and the answer has to be the same clock the media path ends up dating frames with, or the two series still cannot be joined.
Why it is its own change
It alters what every notification looks like, so it wants its own API_VERSION bump and its own decision rather than riding along with a transport. Deliberately kept out of the remote-access slices (#209, #219).
Done looks like
- A consumer can take a decoded frame and a
robot.state sample and say, with a bounded error it can state, which happened first.
- The error is bounded by something written down, not by the network.
Nothing this transport carries is timestamped at source. A frame arrives when it arrives, a
robot.statenotification arrives when it arrives, and a consumer that wants to know when the robot saw or felt something has only its own clock — which, over a relay, measures the network rather than the robot.That is fine for driving a robot you are watching, and wrong for most of what a remote consumer is interesting for. SLAM is the case that makes it concrete: monocular SLAM on a stream with no capture times runs; the moment somebody wants visual-inertial — the IMU this robot has, at 50 Hz, on the same control channel — the two series cannot be related except by guessing.
Design note:
remote-webrtc.md§11.Two halves, and they are not the same problem
Media. RTP timestamps are relative to a random offset: they order frames and date none of them. The mechanism is the
abs-capture-timeRTP header extension, which carries a wall-clock capture time per packet. First job is checking what actually surfaces it — whetherwebrtcsinkwill negotiate it, and what a browser (RTCRtpReceiver.getSynchronizationSources,getStats) andaiortcexpose of it. A header extension nothing on the receiving side surfaces buys nothing, and that determines whether this half is cheap or a fork of somebody's stack.The control channel. Ours, and cheap: a monotonic reading plus the boot epoch that makes it comparable across processes, on every notification that describes a moment (
robot.statefirst). The cost is a field per message and an argument about which clock — and the answer has to be the same clock the media path ends up dating frames with, or the two series still cannot be joined.Why it is its own change
It alters what every notification looks like, so it wants its own
API_VERSIONbump and its own decision rather than riding along with a transport. Deliberately kept out of the remote-access slices (#209, #219).Done looks like
robot.statesample and say, with a bounded error it can state, which happened first.