In this exercise, we will look at ROS Parameters for configuring nodes


By this point in these tutorials (or your career), you’ve probably typed the words int main(int argc, char** argv) more times than you can count. The arguments to main are the means by which a system outside scope and understanding of your program can configure your program to do a particular task. These are command line parameters.

The ROS ecosystem has an analogous system for configuring nodes. It’s a key-value storage model that is associated with each node individually. It’s best used to pass configuration parameters to nodes at run-time (e.g. to identify which camera a node should subscribe to), but it can be used for much more complicated items.

Reference Example

Using Parameters

Further Information and Resource

Understanding ROS2 parameters

Scan-N-Plan Application: Problem Statement

In previous exercises, we added a service with the following definition:

# request
string base_frame
# response
geometry_msgs/Pose pose
bool success

So far we haven’t used the request field, base_frame, for anything. In this exercise we’ll use ROS parameters to set this field. You will need to:

  1. Declare inside the class that the Node uses a base_frame parameter of string type.
  2. Load the parameter base_frame and store it in a local string object.
    • If no parameter is provided, default to the parameter to "world".
  3. When making the service call to the vision_node, use this parameter to fill out the Request::base_frame field.
  4. Add a parameters arguments to your launch file to initialize the new value.

Scan-N-Plan Application: Guidance

  1. Open up myworkcell_node.cpp for editing.

  2. Inside the ScanNPlan class constructor, add a call to declare_parameter:

    this->declare_parameter("base_frame", "world");
    • The first argument is the parameter name, the second is the default value if the parameter is not set.
    • The parameter type is fixed from the type of the default value. You may safely assume any value you get when accessing the base_frame parameter is a string.
  3. In the main function, after creating the node but before calling start, create a temporary string object, std::string base_frame;, and then use get_parameter to load the parameter "base_frame".

    std::string base_frame = app->get_parameter("base_frame").as_string();
    • The declare_parameter function actually returns the parameter value as well, so if you want to declare and get a parameter in the same place, you can do it with one line.
  4. Also prior to calling start, insert a call to sleep for a few seconds. Without this, the service will be called immediately when the node starts and if the nodes all start together, there is a good chance the vision_node won’t have received any data from the fake_ar_publisher yet:

    //Wait for the vision node to receive data
  5. Add an argument to your myworkcell_node “start” function of a string named base_frame, and assign the value from the argument into the service request. Make sure to update the app->start call in your main() routine to pass through the base_frame value you obtained.

    void start(const std::string& base_frame)
      request->base_frame = base_frame;
      RCLCPP_INFO_STREAM(get_logger(), "Requesting pose in base frame: " << base_frame);
    int main(...)
  6. Now we’ll add myworkcell_node to the existing file, so we can set the base_frame parameter from a launch file. We’d like the vision_node to return the position of the target relative to the world frame, for motion-planning purposes. Even though that’s the default value, we’ll specify it in the launch-file anyway:

        parameters=[{'base_frame': 'world'}],
    • Note that the parameters arguments provides the names and values to use as a list of dictionaries.
  7. Try it out by re-building and running the system.

    ros2 launch myworkcell_support
    • Press Ctrl+C to kill the running nodes
    • Edit the launch file to change the base_frame parameter value (e.g. to “test2”)
    • Re-launch, and observe that the “request frame” has changed
      • If you didn’t build with the --symlink-install option, you will need to re-build after editing the launch file, to copy the updates into the “install” directory.
      • The response frame doesn’t change, because we haven’t updated vision_node (yet) to handle the request frame. Vision_node always returns the same frame (for now).
    • Set the base_frame back to “world”

Challenge Exercise

  • Imagine a human is cooporating with the robot in this scenario. Try adding a new parameter for the human-operational frame.