Module reference · Robot
Remote Observation & State Capture
The robot-side observation stage. It samples authoritative vehicle state and scene data, publishes typed packages by stream id, and feeds both local robot-side assistance and the delayed downlink.
What
Remote Observation & State Capture turns what the robot knows into observation packages. It reads the Vehicle / Robot Model's authoritative state and any configured scene or sensor source, then publishes each result on a named stream.
The same stage serves two consumers:
- Remote-side Assistance reads a local observation such as pose, heading, terrain, or other vehicle state before it calculates the next command.
- Downlink Communication receives feedback streams such as pose and camera view, then applies the configured communication conditions before the operator sees them.
These are separate packages and separate paths. A study can keep a state stream local while sending only video to the operator; the current TurtleBot reconstruction does not use robot-state.
Why
Observation is not the same as presentation. The robot may have an exact pose and sensor state locally while the operator receives an older camera frame. Keeping capture separate from downlink transport makes that difference explicit.
| Stream | Consumer | Content | Delay |
|---|---|---|---|
robot-pose | Remote-side Assistance and operator | Position and heading | Local for assistance; downlink-configured for operator |
robot-view | Operator | Camera frame | Downlink-configured |
robot-state | No current demo consumer | Position, heading, and realized wheel velocities | Captured locally; not sent through Downlink Communication |
Stream-level configuration lets a study keep local state separate from delayed video, or compare pose and video streams that arrive at different ages.
How
The module uses the same vehicle snapshot twice in a tick: first to
refresh local observations for robot-side decisions, then to package the
updated state for operator feedback. For example, a local
robot-pose package can let SlopeBoundaryGuard
check the next command, while the post-update robot-pose
and robot-view packages describe the result sent through
the downlink.
VehicleSnapshotstate at the start of this tickVehicleSnapshotKinematics, Actuation, and Sensors after the updaterobot-pose · robot-state · robot-viewIn one control tick, the sequence is:
- Read the current snapshot. Remote-side Assistance reads the local observation streams it declares through
ReceiveObservationandTryGetLatestObservation. In the TurtleBot demo,SlopeBoundaryGuardreadsrobot-pose;robot-statehas no current consumer. - Update the vehicle. The Vehicle Model applies that command, updates its kinematics and actuation records, and associates the latest sensor data with the new snapshot.
- Publish the result. Observation & State Capture reads the updated snapshot. Local state is refreshed immediately;
robot-viewand any other configured downlink stream are sent to the operator through Downlink Communication.
So the controller acts on the previous snapshot, while the operator eventually receives feedback about the vehicle's latest action.
Boundary
Owns
- Sampling configured vehicle, scene, and sensor sources.
- Building observation payloads and assigning their stream ids.
- Publishing local observations and downlink feedback packages.
Does not own
- Vehicle motion or sensor simulation — the Vehicle / Robot Model owns that state.
- Command decisions — Remote-side Assistance consumes a local observation when a study assigns one.
- Communication delay — Downlink Communication owns transport and timing.
- Operator-side reconstruction or presentation.
Contract
An observation package is identified by its stream id and carries a study-defined payload. A source can project selected fields from the complete vehicle state, or package a sensor result such as a camera frame. Downstream modules do not need to know how the source captured it.
public abstract class RemoteObservationSource<TObservation>
: RemoteObservationSource
where TObservation : class
{
internal sealed override bool TryCapturePackage(
double timestampSeconds,
out Package package)
{
if (!TryCapture(timestampSeconds, out TObservation observation))
{
package = null;
return false;
}
package = new Package(
observation,
timestampSeconds,
StreamId);
return true;
}
}
Payloadis the pose, camera frame, sensor state, or other observation.SourceTimestampSecondsrecords when the observation was captured.StreamIdroutes the package to the local consumer or downlink channel.PublishToDownlinkcontrols whether the post-control package enters delayed feedback; local assistance can still read it when this is false.
Remote-side Assistance reads a local stream with TryGetLatestObservation<TObservation>. Downlink Communication routes feedback packages by the same stream id and applies its configured channel condition.
Stream ids must match. A controller reading robot-pose receives nothing from a source publishing robot-state unless the study connects those names deliberately.
Examples
Each example projects the same vehicle snapshot into a different observation stream.
robot-pose → remote-side guard and operator. PoseSource reads the latest vehicle state and projects only position and heading. In the TurtleBot demo, SlopeBoundaryGuard reads the local package through TryGetLatestObservation<PosePackage> to check the command against the terrain; Downlink Communication can deliver the same stream to the operator with its own delay.
| Source | Payload | Consumers |
|---|---|---|
PoseSource | PosePackage | SlopeBoundaryGuard, Downlink Communication |
The guard uses the local pose; the operator may receive an older pose because it has crossed the downlink channel.
robot-view → operator. The Vehicle Model owns the camera sensor and includes the captured frame associated with the vehicle snapshot in TurtleBotSnapshot.Sensors.Camera. RobotViewSource projects that sensor payload into ViewFramePackage; it does not own a second camera or capture a separate image. Downlink Communication can apply a different delay, loss, or bandwidth condition to this stream than to robot-pose.
| Stream | Payload | Consumer |
|---|---|---|
robot-view | ViewFramePackage | Downlink Communication → operator presentation |
public sealed partial class RobotViewSource
: VehicleStateObservationSource<TurtleBotState, ViewFramePackage>
{
protected override bool TryCapture(
TurtleBotState state,
double timestamp,
out ViewFramePackage observation)
{
TurtleBot3WafflePiEnhanced vehicle = (TurtleBot3WafflePiEnhanced)Vehicle;
CameraFrameSnapshot camera = state.Snapshot.Sensors.Camera.CapturedFrame;
if (!vehicle.TryCopyCameraFrame(
camera,
out RenderTexture frame,
out TurtleBotState stateAtCapture))
return false;
observation = new ViewFramePackage(
frame,
camera.SampledAt,
camera.Sequence,
camera.WorldToCameraMatrix,
camera.ProjectionMatrix,
stateAtCapture,
vehicle.RecycleCameraFrame);
return true;
}
}This stream does not need to be available to Remote-side Assistance. A study can keep local state separate while the operator receives video only; in the current TurtleBot reconstruction, robot-state has no consumer.
robot-state → optional local study stream. The source projects pose, heading, and realized wheel velocities from TurtleBotSnapshot. It is captured locally, but the current TurtleBot paper reconstruction does not consume it and does not send it through Downlink Communication.
public sealed partial class RobotStateSource
: VehicleStateObservationSource<TurtleBotState, RobotStatePackage>
{
protected override bool TryCapture(
TurtleBotState state,
double timestamp,
out RobotStatePackage observation)
{
observation = new RobotStatePackage(state, timestamp);
return true;
}
}A study-specific local module may consume this stream if it declares it as a dependency. No current demo component does so, and no Downlink Communication channel is configured for it.
Config
- Configure the observation sources. Point pose and any study-defined state sources at the Vehicle / Robot Model's
LatestState; assign the camera source to the robot view. - Give each source a stream id. Use the exact name expected by its consumer, such as
robot-pose,robot-state, orrobot-view. - Connect local assistance when the study uses it. Remote-side Assistance reads only the stream it declares through
TryGetLatestObservation. A local-only state stream needs no downlink channel, but it is unnecessary unless a configured local module consumes it. - Configure feedback channels separately. Add a Downlink Communication channel only for streams the operator should receive, then configure delay, loss, jitter, or bandwidth per stream.
One capture stage, multiple streams. Configure only the observation streams that a study actually consumes. In the TurtleBot paper reconstruction, the remote-side guard reads robot-pose, while robot-view is routed through the downlink to the operator.