Describe¶
describe produces a NoDL document from a running ROS 2 node — the
“NoDL backward” workflow. It is the interpret half of a two-step
split:
Observe records everything, unfiltered. Describe interprets.
nodl_observe captures a live node at full fidelity into a rosgraph_msgs/Node
message (every endpoint, raw RMW QoS integers, type hashes, all auto-declared
infrastructure). describe consumes that Node and emits a NoDL document: it
drops observation-only noise, maps RMW integers to NoDL string enums, recovers
the action type, filters framework infrastructure, and produces something that
validates against the schema.
It is a pure data transform with zero graph access — given the same Node
message it always produces the same document, so it can run offline against a
captured observation with no ROS graph.
Usage¶
ros2 nodl describe NODE_NAME [--from FILE] [--no-params] [--keep-hidden]
[--strict] [--raw] [--timeout SEC] [--topic NAME]
[-o OUT.{yaml,json}]
Option |
Effect |
|---|---|
|
Fully-qualified name of the target node, e.g. |
|
Interpret a previously captured |
|
Drop the |
|
Skip the infrastructure filter so auto-declared endpoints/params survive (debugging). |
|
Treat any gap (or an invalid document) as failure → nonzero exit. For CI / “is this node fully describable” checks. |
|
Emit the raw |
|
Live only: max time to wait for discovery and observation. |
|
Live only: latched topic the observation is published on (default |
|
Write to |
# Describe a live node to stdout
$ ros2 nodl describe /ns/talker
# Interpret a captured observation offline, writing JSON
$ ros2 nodl describe /ns/talker --from talker.mcap -o talker.json
A draft generator¶
describe is a best-effort draft generator, not a guaranteed-final spec. It
reliably recovers every field it can infer from an observation, so in practice
the output validates and is ready to commit. Where a field is genuinely
unknowable from a running node, describe does not guess: it records a gap.
By default, gaps are reported on stderr and the verb still exits
0— a usable draft was produced; a human finishes the unknowable parts (e.g. a nodedescription).--strictturns any gap, or a document that fails validation, into a nonzero exit.
The unknowable fields are intentionally left for the author rather than invented (see Limitations).
What gets mapped¶
Node identity is dropped: a NoDL document never declares its own
name/namespace (Node identity). Empty interface arrays are
omitted, so a minimal node yields just nodl_version: 2.
Topics — publishers & subscriptions¶
|
NoDL |
|---|---|
|
|
|
|
|
|
QoS¶
RMW integer policies are mapped to NoDL’s string enums. NoDL excludes the RMW
*_UNKNOWN values, so a non-introspectable policy is handled per its
requiredness:
Policy |
Requiredness |
|
|---|---|---|
|
required |
|
|
required |
|
|
optional |
omitted |
|
optional |
omitted |
depthis emitted only whenhistoryisKEEP_LAST(the schema requires it there, and it is meaningless otherwise).Durations (
deadline,lifespan,liveliness_lease_duration) become*_nsintegers. An infinite/unset duration (or zero) is omitted — absent already means “not enforced / never expires”.
Services — servers & clients¶
|
NoDL |
|---|---|
|
|
|
|
|
omitted — service QoS is not observable |
Actions — servers & clients¶
NoDL models an action as one opaque endpoint (name + type); its constituent
goal/result/cancel services and feedback/status topics are not re-emitted.
rosgraph_msgs/Action carries no top-level type field, so describe recovers
the action type from the auto-generated constituent service type — e.g.
example_interfaces/action/Fibonacci_SendGoal → example_interfaces/action/Fibonacci.
Parameters¶
Keyed by name, from the observed descriptor and its current value:
Source |
NoDL |
|---|---|
descriptor |
|
current value |
|
|
passed through |
|
|
Infrastructure filter¶
Every node carries machinery the framework declares for it. describe drops it
so the document reflects the authored interface, matching on both the
unqualified name and the type (so a user endpoint that merely reuses one of these
names survives):
Publishers:
rosout,parameter_eventsSubscriptions:
parameter_eventsServices: the six
~/*_parametersservices and~/get_type_descriptionParameters:
use_sim_time,start_type_description_service,qos_overrides.*
Use --keep-hidden to retain them.
Limitations¶
describe reports what is observable; it never asserts a value it did not see.
The following are intentionally absent from the output:
Service QoS — not introspectable at runtime (always
UNKNOWN).Type hashes — observation-only; no NoDL field.
Action QoS —
action_endpointhas no QoS field; default action QoS is assumed by consumers.Descriptions — node- and endpoint-level text is not observable.
Parameter
dynamic_typingand byte-array values — no NoDL representation.
Note
Status: v2 development. The describe verb and the observation contract are
not yet stable. The field-by-field normative mapping (and open design questions,
such as QoS requiredness) lives with the project’s design notes.