get_stats(). Same shape, same
contract.
metrics()
The quick check. Everything in it is a number you can print each second.stats()
The full report. A flat list, one entry per subject: the link, the control loop, each joint, each camera, the recorder and the session as a whole. A leader reports its own half, including video sync and how long a frame takes to reach the screen. Every entry is shaped like WebRTC’sgetStats(), so a collector you already run
can scrape it unchanged. Counters are cumulative and never reset, so take two
snapshots and subtract to get a rate. Gauges end in Current.
Print one to see what your own system reports:
What to look for
- Is the link healthy. Round trip time, packet loss, and whether the send buffer is growing. A buffer that climbs means the channel cannot keep up with what you are sending.
- Is the loop keeping its period. Tick jitter and overruns. Rising overruns mean your reads or writes are too slow for the rate you asked for.
- Is the arm tracking. Per joint, the error between where it was told to go and where it got to, alongside how often the speed cap fired. Both large together means the speed limit is what is holding the arm back.
- Is it acting on fresh data. How old an observation was by the time the robot acted on it. This is the number that matters most.
- Is the correlation good. How many commands arrived with a usable observation id. The rest become guessed rows at export time, see Exporting datasets.
- Is the recording keeping up. Queue depth against capacity, and how many rows were dropped.
Why there is no end-to-end latency
Nothing here reports operator-to-motor time, and that is deliberate. It spans two machines with no shared clock, so producing a number would mean subtracting two wall clocks, which is not a latency. What the SDK reports as fact is measured on a single machine, which is why observation-to-applied is exact and anything crossing the network is an estimate.Watching the other end
Each side publishes its report to the other atstats_hz, default 1 Hz.
remote_stats is [] when nothing has arrived, which is a real state and not
an error: the far side may have stats_hz=0. A climbing
remote_stats_age_ms is the other machine going quiet, which the counters
inside the report cannot show because they simply stop.
Set stats_hz=0 to stop publishing. stats() and get_stats() still work.
Dashboard
A live page, served in process off a follower or a leader.str
default:"127.0.0.1"
0.0.0.0 to reach a headless robot host from another machine on the LAN.int
default:"8080"
0 picks a free one, which you read back off .url.float
default:"2.0"
How often it samples stats.
float
default:"10.0"
Camera encode rate for the grid.
0 serves stats with no pictures, for a
host with no CPU to spare.serve(),
which degrades to doing nothing instead of raising:
On ROS 2 the dashboard is a bridge parameter rather than a call. See
Reference.
Related
Troubleshooting
Symptoms, and which of these numbers to read first.
Follower
Where these calls live, and the rest of the class.