Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs(parameters): add DevOps Dojo: ROS Node Config documentation #367

Merged
merged 11 commits into from
Jun 2, 2023
162 changes: 138 additions & 24 deletions docs/contributing/coding-guidelines/ros-nodes/parameters.md
Original file line number Diff line number Diff line change
@@ -1,36 +1,150 @@
# Parameters
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kminoda

DevOps Dojos is the way we structure work in the Open AD Kit WG. Each dojo addresses a certain topic, in this case the ROS parameters.

Find our Kanban board here.


The ROS packages in Autoware have ROS parameters. You need to customize the parameters depending on your applications.
It is recommended not to set default values when declaring ROS parameters to avoid unintended behaviors due to accidental use of default values.
Instead, set parameters from configuration files named `*.param.yaml`.
Autoware ROS nodes have declared parameters which values are provided during the node start up in the form of a parameter file. All the expected parameters with corresponding values should exist in the parameter file. Depending on the application, the parameter values might need to be modified.

For understanding ROS 2 parameters, also check out the official documentation [Understanding parameters](https://docs.ros.org/en/humble/Tutorials/Beginner-CLI-Tools/Understanding-ROS2-Parameters/Understanding-ROS2-Parameters.html).
Find more information on parameters from the official ROS documentation:

## Parameter files
- [Understanding ROS 2 Parameters](https://docs.ros.org/en/humble/Tutorials/Beginner-CLI-Tools/Understanding-ROS2-Parameters/Understanding-ROS2-Parameters.html)
- [About ROS 2 Parameters](https://docs.ros.org/en/humble/Concepts/About-ROS-2-Parameters.html)

Autoware has the following two types of parameter files for ROS packages:
## JSON Schema
xmfcx marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Contributor

@kminoda kminoda May 25, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As an developer who have not followed the AWF DevOps discussions, here are some high level comments on this modification:

  1. Could you elaborate more on the background of this documentation? As a newbie in this discussion, I could not get the whole idea until following the latest thread in this PR (especially the comment by mitsudome-san). Maybe adding some phrase like "to have a single source of truth" helps. IMHO this section should concisely answer why this JSON Schema is added in the first place.
  2. Putting this section at the very top of this page is confusing. Consider moving this section to the last of this page or creating a separate page for this.

Comments are also welcome from @kaspermeck-arm and others as well!


- **Node parameter file**
- Node parameter files store the default parameters provided for each package in Autoware.
- For example, [the parameter of `behavior_path_planner`](https://github.com/autowarefoundation/autoware.universe/tree/245242cee866de2d113e89c562353c5fc17f1f98/planning/behavior_path_planner/config)
- All nodes in Autoware must have a parameter file if one or more parameters that can be customized by the user are defined.
- For `FOO_package`, the parameter is expected to be stored in `FOO_package/config`.
- The launch file for individual packages must load node parameter by default:
[JSON Schema](https://json-schema.org/understanding-json-schema/index.html) is used the validate the parameter file(s) ensuring that it has the correct structure and content. Using JSON Schema for this purpose is considered best practice for cloud-native development. The schema template below shall be used as a starting point when defining the schema for a ROS node.

```xml
<launch>
<arg name="foo_node_param_path" default="$(find-pkg-share FOO_package)/config/foo_node.param.yaml" />
```json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "INSERT_TITLE",
"type": "object",
"definitions": {
"INSERT_ROS_NODE_NAME": {
"type": "object",
"properties": {
"INSERT_PARAMETER_1_NAME": {
"type": "INSERT_TYPE",
"description": "INSERT_DESCRIPTION",
"default": "INSERT_DEFAULT",
"INSERT_BOUND_CONDITION(S)": "INSERT_BOUND_VALUE(S)"
},
"INSERT_PARAMETER_N_NAME": {
"type": "INSERT_TYPE",
"description": "INSERT_DESCRIPTION",
"default": "INSERT_DEFAULT",
"INSERT_BOUND_CONDITION(S)": "INSERT_BOUND_VALUE(S)"
}
},
"required": ["INSERT_PARAMETER_1_NAME", "INSERT_PARAMETER_N_NAME"]
}
},
"properties": {
"/**": {
"type": "object",
"properties": {
"ros__parameters": {
"$ref": "#/definitions/INSERT_ROS_NODE_NAME"
}
},
"required": ["ros__parameters"]
}
},
"required": ["/**"]
}
```

The schema file path is `INSERT_PATH_TO_PACKAGE/schema/` and the schema file name is `INSERT_NODE_NAME.schema.json`. To adapt the template to the ROS node, replace each `INSERT_...` and add all parameters `1..N`.

See example: _Lidar Apollo Segmentation TVM Nodes_ [schema](https://github.com/autowarefoundation/autoware.universe/blob/main/perception/lidar_apollo_segmentation_tvm_nodes/schema/lidar_apollo_segmentation_tvm_nodes.schema.json)

### Attributes

Parameters have several attributes, some are required and some optional. The optional attributes are highly encouraged when applicable, as they provide useful information about a parameter to the user.

#### Required

- name
- type
- see [JSON Schema types](http://json-schema.org/understanding-json-schema/reference/type.html)
- description

#### Optional

<node pkg="FOO_package" exec="foo_node">
...
<param from="$(var foo_node_param_path)" />
</node>
</launch>
- default
- a tested and verified value, see [JSON Schema default](https://json-schema.org/understanding-json-schema/reference/generic.html)
- bound(s)
- type dependent, e.g., [integer](https://json-schema.org/understanding-json-schema/reference/numeric.html#integer), [range](https://json-schema.org/understanding-json-schema/reference/numeric.html#range) and [size](https://json-schema.org/understanding-json-schema/reference/object.html#size)

## Parameter File

The parameter file is minimal as there is no need to provide the user with additional information, e.g., description or type. This is because the associated JSON Schema provides the additional information. Use the template below as a starting point for a ROS node.

```yaml
/**:
ros__parameters:
INSERT_PARAMETER_1_NAME: INSERT_PARAMETER_1_VALUE
INSERT_PARAMETER_N_NAME: INSERT_PARAMETER_N_VALUE
```

- **Launch parameter file**
- Launch parameter files store the customized parameters for user's vehicle.
- For example, [the customized parameter of `behavior_path_planner` stored under `autoware_launch`](https://github.com/autowarefoundation/autoware_launch/tree/5fa613b9d80bf4f0db77efde03a43f7ede6bac86/autoware_launch/config)
The parameter file path is `INSERT_PATH_TO_PACKAGE/config/` and parameter file name is `INSERT_NODE_NAME.param.yaml`. To adapt the template to the ROS node, replace each `INSERT_...` and add all parameters `1..N`.

See example: _Lidar Apollo Segmentation TVM Nodes_ [parameter file](https://github.com/autowarefoundation/autoware.universe/blob/main/perception/lidar_apollo_segmentation_tvm_nodes/config/lidar_apollo_segmentation_tvm_nodes.param.yaml)

Note: `/**` is used instead of the explicit node namespace, this allows the parameter file to be passed to a ROS node which has been [remapped](https://design.ros2.org/articles/static_remapping.html).

## Launch parameter file

(Original content, will need updating)

- Launch parameter files store the customized parameters for user's vehicle.
- For example, [the customized parameter of `behavior_path_planner` stored under `autoware_launch`](https://github.com/autowarefoundation/autoware_launch/tree/5fa613b9d80bf4f0db77efde03a43f7ede6bac86/autoware_launch/config)
- Launch parameter files are stored under `autoware_launch`.

All the parameter files should have the `.param.yaml` suffix so that the auto-format can be applied properly.
## Declare Parameter Function

It is the [declare_parameter(...)](https://docs.ros.org/en/ros2_packages/humble/api/rclcpp/generated/classrclcpp_1_1Node.html#_CPPv4N6rclcpp4Node17declare_parameterERKNSt6stringERKN6rclcpp14ParameterValueERKN14rcl_interfaces3msg19ParameterDescriptorEb) function which sets the parameter values during a node startup.

```cpp
declare_parameter<INSERT_TYPE>("INSERT_PARAMETER_1_NAME"),
declare_parameter<INSERT_TYPE>("INSERT_PARAMETER_N_NAME")
```

As there is no _default_value_ provided, the function throws an exception if a parameter were to be missing in the provided `*.param.yaml` file. Find the types in the table below.

| ParameterType Enum | C++ Type |
| ------------------------- | -------------------------- |
| `PARAMETER_BOOL` | `bool` |
| `PARAMETER_INTEGER` | `int64_t` |
| `PARAMETER_DOUBLE` | `double` |
| `PARAMETER_STRING` | `std::string` |
| `PARAMETER_BYTE_ARRAY` | `std::vector<uint8_t>` |
| `PARAMETER_BOOL_ARRAY` | `std::vector<bool>` |
| `PARAMETER_INTEGER_ARRAY` | `std::vector<int64_t>` |
| `PARAMETER_DOUBLE_ARRAY` | `std::vector<double>` |
| `PARAMETER_STRING_ARRAY` | `std::vector<std::string>` |

The table has been derived from [Parameter Type](https://github.com/ros2/rcl_interfaces/blob/humble/rcl_interfaces/msg/ParameterType.msg) and [Parameter Value](https://github.com/ros2/rcl_interfaces/blob/humble/rcl_interfaces/msg/ParameterValue.msg).

See example: _Lidar Apollo Segmentation TVM Nodes_ [declare function](https://github.com/autowarefoundation/autoware.universe/blob/f85c90b56ed4c7d6b52e787570e590cff786b28b/perception/lidar_apollo_segmentation_tvm_nodes/src/lidar_apollo_segmentation_tvm_node.cpp#L38)

## Tips and Tricks

Using well established standards enables the use of conventional tooling. Below is an example of how to link a schema to the parameter file(s) using VS Code. This enables convenient features such as auto-complete and parameter bound validation.

In the root directory of where the project is hosted, create a `.vscode` folder with two files; `extensions.json` containing

```json
{
"recommendations": ["redhat.vscode-yaml"]
}
```

and `settings.json` containing

```json
{
"yaml.schemas": {
"./INSERT_PATH_TO_PACKAGE/schema/INSERT_NODE_NAME.schema.json": "**/INSERT_NODE_NAME/config/*.param.yaml"
}
}
```

The RedHat YAML extension enables validation of YAML files using JSON Schema and the `"yaml.schemas"` setting associates the `*.schema.json` file with all `*.param.yaml` files in the `config/` folder.