When nothing happens

A symptom-to-cause table for the failures that stop people on their first afternoon.

Almost every one of these is a correct behaviour presenting as a broken one. The SDK reports what it can, but a great deal of the system communicates by silence: a command that landed on the wrong robot, a topic name with a typo, and a simulator that is not playing all look the same from inside your loop.

Two commands answer most of it before you read any further:

cargo run -p vrobots-sdk --bin vrobots -- topic list
cargo run -p vrobots-sdk --bin vrobots -- --version

Symptoms and causes

SymptomLikely causeWhat to doWhere it is explained
topic list shows (no topics)The simulator is not in Play modePress Play; loading the project is not enoughFirst contact
The simulator is on another machinePass --router tcp/<host>:7447Two transports, one simulator
zenoh discovery had too short a windowRetry with -t 5The vrobots command
A -k filter excluded everythingDrop the flagThe vrobots command
connect hangs, then times outThe sys_id does not exist in this sceneRead the ids out of topic list; ids are reallocated on every scene loadSystem ids
connect(type, None) was refused by the scene's catalogOnly multirotor, truck and msd are creatable in the sandbox; attach to the rest by idRobot lifecycle
The first state sample never arrived within probe_timeoutRun with RUST_LOG=vrobots_sdk=debug to see which of the four connect steps stalledWhat connect actually does
A command has no visible effectIt reached a different robotCompare the sys_id you connected with against topic listSystem ids
The value is inside the band but does nothing useful, for example 1501 on a multirotorWatch s.actuator.pwm: if it echoes your value, the command landed and the plant is the questionHello control
The array length is wrong for that robotThe simulator logs and ignores it, keeping the previous latched value; the SDK cannot see that logCommands latch
Nothing acts on that command id yetSET_MR_THROTTLE and the body wrench commands are on the wire and unimplementedCommands nothing acts on
A service acked ok and refused the valueOnly srv/skin ever answers ok = false; measure the result in the state stream instead of trusting the ackFive rules that explain everything
Camera frames never arriveThe simulator is not on this hosticeoryx2 is shared memory: frames cannot cross machines even when zenoh canTwo transports, one simulator
The iceoryx2 pin differs from the simulator'sCompare vrobots --version against the simulator build; a patch mismatch delivers nothing and raises nothingVersions and pins
open_camera was given a name, resolution or format that does not match the publisherCopy the stream key from topic list and split it back into its three partsMount, open and unmount
You are calling fresh() faster than frames arriveThat is correct: fresh() returns None until a new frame lands. Use latest() if you want the current one regardlessFreshness
Fields look like garbageSchema drift between the SDK and the simulatorCompare vrobots_msgs and schema_version from vrobots --version against the simulator buildVersions and pins
A vector was read in the wrong frameRead s.coord_frame_id: the truck publishes fru while the multirotor and the Global Hawk publish frd, so the third component means opposite thingsFrames, axes and units
The quaternion was unpacked as [w, x, y, z]The order is [x, y, z, w], matching the wire's Vec4 field orderFrames, axes and units
Pose and twist were assumed to share a framePose is world frame, twist and acceleration are body frame, in both the truth and the estimate blocksKinematics
An unconverged estimator is mirroring truthCheck estimate.valid before trusting estimate.kinTruth, measured and believed
A created multirotor will not moveSimulator bug: its rigidbody never integratesAttach to the scene's multirotor by id instead of creating oneSee the callout below
The numbers stopped changingThe simulator stopped, and states() keeps returning the last snapshot foreverDetect it with wait_new_state(timeout), not by expecting an errorStream health
The loop stutters at the right average rateSamples are being droppedtopic hz reports max interval and gap count, which is what a mean rate hidesMeasuring rates

Sim bug. In simulator v3.0.0 a client-created multirotor does not move. Its rigidbody never integrates, so it hangs where it spawned and ignores every pulse width and even a direct body force, while its actuator echo and rotor-speed model answer perfectly normally. Created trucks and mass-spring-dampers have live physics, and the scene's own multirotor flies. See issues/created-multirotor-frozen-dynamics.md. The examples that need a multirotor to move take an optional sys_id so you can attach to the scene's one instead.

When the table does not have it

Turn the logs up. RUST_LOG overrides whatever filter the program passed to init_logging, and the SDK's own tracing events name each connect step as it happens.

RUST_LOG=vrobots_sdk=debug cargo run -p vrobots-examples --bin ex01_hello_states

RUST_LOG reaches the Rust core, so the other two surfaces turn the volume up in their own idiom instead. Python routes the same events into the standard logging module, so vrsdk.init_logging("debug") (or raising the vrobots_sdk logger's level yourself) is the equivalent. C++ registers a handler with vrsdk::set_log_callback and then calls vrsdk::set_log_level(vrsdk::LogLevel::Debug). Logging covers all three.

Add zenoh's own view with RUST_LOG=vrobots_sdk=debug,zenoh=info. iceoryx2 logs to stderr outside tracing entirely and is controlled by IOX2_LOG_LEVEL, which the SDK defaults to errors only.

Two counters are worth printing from inside a loop that misbehaves without failing: stats() carries received, decode error, sequence gap and missed sample counts, and last_error() holds the most recent decode error. Neither tears down the session, which is the point: a malformed payload is counted and the loop keeps running.

Next: Concepts

See also: Logging, Appendix C: Error reference, Known simulator issues