YAML on the ROS command line

Several ROS tools (rostopic, rosservice) use the YAML markup language on the command line. YAML was chosen as, in most cases, it offers a very simple, nearly markup-less solution to typing in typed parameters.

For a quick overview of YAML, please see YAML Overview.

Representing Messages in YAML

ROS Messages can be represented either as a YAML list or dictionary. If represented as a list, the arguments are filled in-order and must align 1-to-1 with the fields of the message. If represented as a dictionary, the dictionary keys are assumed to map onto fields of the same name in the message. Unassigned fields are given default values.

List vs. dictionary ambiguities: the command-line arguments that you type at the console, by default, are represented as a list. For example, if you type:

rosservice call /foo msg/Type 1 2

This will create the list [1, 2], which will then be used to populate a message.

The exception to this is if you type a single dictionary at the command line. for example, if you type:

rosservice call /foo msg/Type '{a: 1, b: 2}'

This will create the dictionary {a: 1, b: 2} with no list wrapper. This enables you to more easily populate the fields of the outer message.

Multiline representation

Assume you have a roscore running, and you listen to a topic e.g. with

rostopic echo /newTopic

You can then send to that topic using rostopic pub <msg-type>. For very simple example, you can try

rostopic pub /newTopic std_msgs/String "test"

std_msgs/String is a predefined type, many other types exist. You should see "test" appearing in the terminal where you launched rostopic echo.

If you want to create a message in the command line spanning several lines, the above will not work, you will have to complete your message with "---", and embed it in a list or dict yaml type, e.g.

rostopic pub /newTopic std_msgs/String 
['test']
---

Again, you should see "test" appearing in the terminal where you launched rostopic echo.

Headers/timestamps

There are two special keys you can use to assist with sending ROS Headers and time values:

  • auto: create a new Header with the timestamp set to the current time. Frame ID will be empty.

  • now: create a new time initialized to the current time

For example:

rostopic pub my_topic my_msgs/StampedMsg '{header: auto}'

or

rostopic pub my_topic my_msgs/StampedMsg '{header: {stamp: now}}'

YAML Syntax + the Command Line

While YAML is simple in most cases, there are some gotchas, especially with Bash. Single-quotes and double-quotes have their own meaning in Bash, so interleaving them with YAML can be difficult.

Type Overrides

YAML uses "tags" to override types, where the YAML syntax may be ambiguous. Common tags are: !!str, !!int, !!float, !!seq and !!map. Most likely you will just need to know about !!str. YAML tags are difficult because ! has its own meaning in Bash, so you have to use single-quotes.

Command-line and Strings

Using empty quotes (\'\' or \"\") will give you the empty string (this is actually null in YAML, but we map null to the empty string).

The !!str tag in YAML lets you override the type to be a string. You may need this when working with strings that look like boolean values (true, false, y, n, yes, no). YAML tags are difficult because ! has its own meaning in Bash, so you have to use single-quotes.

For example:

rosservice call /my_service '!!str true'

Will call /my_service with the string "true".

Command-line and messages (dictionaries)

Messages can be represented as YAML dictionaries on the command-line. YAML uses curly-braces to specify dictionaries.

Empty message:

  • rosservice call /my_service "{}"

Message within a message:

  • rosservice call /myservice "{position: {x: 1., y: 2.}}"

Bash multi-line syntax:

  • rosservice call /myservice "a: 1
    b: 2"

For a more complicated example, lets look at geometry_msg/PointStamped, which is a message with two embedded messages:

Header header
  uint32 seq
  time stamp
  string frame_id
Point point
  float64 x
  float64 y
  float64 z

These are all equivalent ways of publishing the same data:

rostopic pub pt geometry_msgs/PointStamped '{stamp: now, frame_id: base_link}' '[1.0, 2.0, 3.0]'

rostopic pub pt geometry_msgs/PointStamped '[0, now, base_link]' '[1.0, 2.0, 3.0]'

rostopic pub pt geometry_msgs/PointStamped '{header: {stamp: now, frame_id: base_link}, point: [1.0, 2.0, 3.0]}'

rostopic pub pt geometry_msgs/PointStamped '{header: {stamp: now, frame_id: base_link}, point: {x: 1.0, y: 2.0, z: 3.0}}'

Command-line and negative numbers

Negative numbers can confuse command-line option parsing, so you need to pass in an additional -- argument to indicate that command-line option parsing should terminate. For example:

rosservice call /add_two_ints -- -1 -2

will call with negative one as the argument.

Wiki: ROS/YAMLCommandLine (last edited 2011-12-15 03:50:36 by SergeStinckwich)