Skip to content

Instantly share code, notes, and snippets.

@sloretz
Created May 11, 2018 21:21
Show Gist options
  • Save sloretz/d30623a26d79ae50d05a82ece6ea51c1 to your computer and use it in GitHub Desktop.
Save sloretz/d30623a26d79ae50d05a82ece6ea51c1 to your computer and use it in GitHub Desktop.
Summarize work for enhancements to rclcpp

[meta] Post Goals

  • summarize work to do for parameters with enhancements to rclcpp api
  • enhancements are generally useful to community
  • identify work that can be done in parallel
  • Be specific about what rclcpp needs from rcl

C++/Python/etc ROS client library responsibilities

  • storage for parameters
  • knowledge of expected vs unexpected parameters
  • initialization of storage including default values
  • parameter constraints/validation

rcl responsibilities

  • parse initial parameter values provided at run-time
  • Creating parameter services and topics
  • Forward request to read/write parameters to client library

Parallel work graph

In general rcl and rclcpp enhancements can happen in parallel. Rclcpp can use it's own implementation of parameters first, and have that replaced with rcl later.

 +-----------+         +----------------+                    +-----------+
 |rcl(1)     +--------->rcl(2)          +-------------------->rcl(3)     |
 |Init params+----+    |parameter topics|                    |constraints|
 +-----------+    |    +----------------+                    +-----------+
                  |
                  |   +-----------+      +--------------+     +------------+
+--------------+  +--->rclcpp(2)  +------>rclcpp(5)     +----->rclcpp(6)   |
|rclcpp(1)     +------>Init params+--+   |Custom Storage|  +-->use_sim_time|
|create_param()+--+   +-----------+  |   +--------------+  |  +------------+
+--------------+  |                  |                     |
                  |                  |   +---------+       |
                  |                  +--->rclcpp(4)+-------+
                  |                      |Read Only|
                  |                      +----v<<--+
                  |                           v ^
                  |                      +---->>^----+
                  +---------------------->rclcpp(3)  |
                                         |Param Proxy|
                                         +-----------+

rclcpp features

part 1: Parameter creation and undefined parameter handling

  • node author can define parameters
    • minimum: name, type, initial value
    • ex: rclcpp::NodeParametersInterface::create_parameter(/* parameter description */)
  • node author defines what happens if an undefined parameter is set at run time
    • minimum: set boolean to allow or disallow undefined parameters
  • parameter updates with mismatched type are rejected

part 2: Initialization of parameters

  • automatically start parameter service in node constructor
  • pass sparse parameter initialization map to node constructor
  • node->create_parameter initializes itself with parameter initialization map or default value

part 3: ParameterProxy convenience class for defining, initializing, and accessing parameters

  • Goals:
    • reduce amount of boilerplate node author has to write
    • turn run-time errors into compile-time errors
  • Wraps node->create_param()
  • Wraps node->get_paremeter() and node->set_parameter() to return correct type

part 4: Read-only constraint on parameter storage

  • A read only parameter may not be changed after initialization
  • node->set_parameter(name) fails if parameter is read only
  • ParameterProxy std::enable_if on set() methods for compile-time error when trying to set read only parameters

part 5: Node author control over parameter storage type

  • Node author specifies type to be used to store parameter value
  • Node author defines how to convert between c structure types and storage type

part 6: Client Library parameters

  • automatically create and initialize use_sim_time
    • boolean, read-only

TODO: Does this stuff fit in anywhere?

  • Multiple allowed types for parameters
  • parameters that can change type
  • Parameter initialization as part of a node's lifecycle

rcl parameter implementation

part 1: Parameter initialization with values from rcl

  • rcl can provide structures with initial params set by a user
    • Available to client library forever after node name and namespace have been remapped
  • rcl handles parsing input from user into structures prior to paramiter initialization

part 2: rcl creates parameter services and topics

  • rcl creates topics/services for parameters
    • parameter initialization structures avilable to client library prior to parameter services/topics
  • rcl notifies client library at run time
    • when a single parameter is set
      • Same as atomically setting parameters with 1 param
    • when a single parameter is retrieved
      • Same as atomically getting parameters with 1 param
    • when a bunch of parameters are atomically set
      • Client library updates parameters in its storage
      • Client library tells rcl if setting values succeeded
    • when a bunch of parameters are non-atomically set
      • Client library tells rcl if getting values succeeded
      • Client library provides rcl with retrieved values

part 3: Run-time visibility into parameter constraints

  • Run time user can ask node about parameter constraints
  • rcl can ask client library about parameter constraints to handle request from user
@wjwwood
Copy link

wjwwood commented May 14, 2018

A few comments/opinions:

  • re: parameter constraints I think those might actually fall into rcl_interfaces and may live in part in rcl, though it's not clear to me what the exact separation would be. The important thing would be to have C++, Python, and any tools agree of the available constraints and how to specify them. So it seems like a natural fit for rcl

  • re: minimum: name, type, initial value maybe I'm being too ambitious, but I feel like name might be the only required thing to define a parameter. The other information might be what we recommend to provide, but I'm not sure they're require. Another way to look at it might be type is "variant" and initial value is optional and the type of the initial value might not constrain the type to that in the future.

  • re: parameter updates with mismatched type are rejected this is fine for "part 1" but it might be too strict to never allow parameter types to change over time, but maybe that's an advanced feature to support later.

  • re: ParameterProxy I'd like to work on the name, not important, but keep in mind some alternative if while working on it something else makes more sense

  • re: Multiple allowed types for parameters I would say it would be nice to get something like this into the message definitions for parameter descriptions, and then if more than one type is supplied raise a not implemented kind of error and then ticket it for future work. So plan for it (imo) but avoid spending time implementing and testing it.

  • re: parameters that can change type as I said above, I believe it will be useful or even necessary, but no need to do it now. Plan for it in the design, but avoid work related to it if possible.

  • re: Parameter initialization as part of a node's lifecycle I don't think this one is as important since we decided that parameters, even read-only ones, can be added anytime so it would be up to the user to ensure that they are initialized before being used. There still might be something here with respect to the /parameter_events topic and/or making sure the "sparse parameter initialization map" is considered any time a parameter is added.

The progression of work in rclcpp looks ok to me. Most of the stuff in rcl seems to overlap more with what Mikael was going to be doing I think, but it's important to consider too.

Thanks for putting this together Shane, it looks great. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment