Skip to content

Commit 4ad0857

Browse files
authored
Add "additional_constraints" support (#221)
1 parent cbf4971 commit 4ad0857

File tree

13 files changed

+105
-48
lines changed

13 files changed

+105
-48
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
11
**/__pycache__
2+
build
3+
install
4+
log
5+
*.egg-info

README.md

Lines changed: 47 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -175,35 +175,37 @@ cpp_namespace:
175175
type: int
176176
default_value: 3
177177
read_only: true
178+
additional_constraints: "{ type: 'number', multipleOf: 3 }"
178179
description: "A read-only integer parameter with a default value of 3"
179180
validation:
180181
# validation functions ...
181182
```
182183

183184
A parameter is a YAML dictionary with the only required key being `type`.
184185

185-
| Field | Description |
186-
|---------------|---------------------------------------------------------------|
187-
| type | The type (string, double, etc) of the parameter. |
188-
| default_value | Value for the parameter if the user does not specify a value. |
189-
| read_only | Can only be set at launch and are not dynamic. |
190-
| description | Displayed by `ros2 param describe`. |
191-
| validation | Dictionary of validation functions and their parameters. |
186+
| Field | Description |
187+
| ---------------------- | -------------------------------------------------------------------------------------------------------------- |
188+
| type | The type (string, double, etc) of the parameter. |
189+
| default_value | Value for the parameter if the user does not specify a value. |
190+
| read_only | Can only be set at launch and are not dynamic. |
191+
| description | Displayed by `ros2 param describe`. |
192+
| validation | Dictionary of validation functions and their parameters. |
193+
| additional_constraints | Additional constraints that end up on the ParameterDescriptor but are not used for validation by this package. |
192194

193195
The types of parameters in ros2 map to C++ types.
194196

195-
| Parameter Type | C++ Type |
196-
|-----------------|-----------------------------|
197-
| string | `std::string` |
198-
| double | `double` |
199-
| int | `int` |
200-
| bool | `bool` |
201-
| string_array | `std::vector<std::string>` |
202-
| double_array | `std::vector<double>` |
203-
| int_array | `std::vector<int>` |
204-
| bool_array | `std::vector<bool>` |
205-
| string_fixed_XX | `FixedSizeString<XX>` |
206-
| none | NO CODE GENERATED |
197+
| Parameter Type | C++ Type |
198+
| --------------- | -------------------------- |
199+
| string | `std::string` |
200+
| double | `double` |
201+
| int | `int` |
202+
| bool | `bool` |
203+
| string_array | `std::vector<std::string>` |
204+
| double_array | `std::vector<double>` |
205+
| int_array | `std::vector<int>` |
206+
| bool_array | `std::vector<bool>` |
207+
| string_fixed_XX | `FixedSizeString<XX>` |
208+
| none | NO CODE GENERATED |
207209

208210
Fixed-size types are denoted with a suffix `_fixed_XX`, where `XX` is the desired size.
209211
The corresponding C++ type is a data wrapper class for conveniently accessing the data.
@@ -240,36 +242,36 @@ Some of these validators work only on value types, some on string types, and oth
240242
The built-in validator functions provided by this package are:
241243

242244
**Value validators**
243-
| Function | Arguments | Description |
244-
|------------------------|---------------------|---------------------------------------|
245-
| bounds<> | [lower, upper] | Bounds checking (inclusive) |
246-
| lt<> | [value] | parameter < value |
247-
| gt<> | [value] | parameter > value |
248-
| lt_eq<> | [value] | parameter <= value |
249-
| gt_eq<> | [value] | parameter >= value |
250-
| one_of<> | [[val1, val2, ...]] | Value is one of the specified values |
245+
| Function | Arguments | Description |
246+
| -------- | ------------------- | ------------------------------------ |
247+
| bounds<> | [lower, upper] | Bounds checking (inclusive) |
248+
| lt<> | [value] | parameter < value |
249+
| gt<> | [value] | parameter > value |
250+
| lt_eq<> | [value] | parameter <= value |
251+
| gt_eq<> | [value] | parameter >= value |
252+
| one_of<> | [[val1, val2, ...]] | Value is one of the specified values |
251253

252254
**String validators**
253-
| Function | Arguments | Description |
254-
|------------------------|---------------------|-------------------------------------------------|
255-
| fixed_size<> | [length] | Length string is specified length |
256-
| size_gt<> | [length] | Length string is greater than specified length |
257-
| size_lt<> | [length] | Length string is less less specified length |
258-
| not_empty<> | [] | String parameter is not empty |
259-
| one_of<> | [[val1, val2, ...]] | String is one of the specified values |
255+
| Function | Arguments | Description |
256+
| ------------ | ------------------- | ---------------------------------------------- |
257+
| fixed_size<> | [length] | Length string is specified length |
258+
| size_gt<> | [length] | Length string is greater than specified length |
259+
| size_lt<> | [length] | Length string is less less specified length |
260+
| not_empty<> | [] | String parameter is not empty |
261+
| one_of<> | [[val1, val2, ...]] | String is one of the specified values |
260262

261263
**Array validators**
262-
| Function | Arguments | Description |
263-
|------------------------|---------------------|------------------------------------------------------|
264-
| unique<> | [] | Contains no duplicates |
265-
| subset_of<> | [[val1, val2, ...]] | Every element is one of the list |
266-
| fixed_size<> | [length] | Number of elements is specified length |
267-
| size_gt<> | [length] | Number of elements is greater than specified length |
268-
| size_lt<> | [length] | Number of elements is less less specified length |
269-
| not_empty<> | [] | Has at-least one element |
270-
| element_bounds<> | [lower, upper] | Bounds checking each element (inclusive) |
271-
| lower_element_bounds<> | [lower] | Lower bound for each element (inclusive) |
272-
| upper_element_bounds<> | [upper] | Upper bound for each element (inclusive) |
264+
| Function | Arguments | Description |
265+
| ---------------------- | ------------------- | --------------------------------------------------- |
266+
| unique<> | [] | Contains no duplicates |
267+
| subset_of<> | [[val1, val2, ...]] | Every element is one of the list |
268+
| fixed_size<> | [length] | Number of elements is specified length |
269+
| size_gt<> | [length] | Number of elements is greater than specified length |
270+
| size_lt<> | [length] | Number of elements is less less specified length |
271+
| not_empty<> | [] | Has at-least one element |
272+
| element_bounds<> | [lower, upper] | Bounds checking each element (inclusive) |
273+
| lower_element_bounds<> | [lower] | Lower bound for each element (inclusive) |
274+
| upper_element_bounds<> | [upper] | Upper bound for each element (inclusive) |
273275

274276
### Custom validator functions
275277
Validators are functions that return a `tl::expected<void, std::string>` type and accept a `rclcpp::Parameter const&` as their first argument and any number of arguments after that can be specified in YAML.

example/src/parameters.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ admittance_controller:
33
type: double
44
default_value: 0.00000000001
55
description: "Test scientific notation"
6+
additional_constraints: "Any string can be here. For example, you might want to embed JSON schema"
67
interpolation_mode:
78
type: string
89
default_value: "spline"
@@ -89,6 +90,7 @@ admittance_controller:
8990
command_interfaces:
9091
type: string_array
9192
description: "specifies which command interfaces to claim"
93+
additional_constraints: "some additional constraints"
9294
read_only: true
9395

9496
state_interfaces:

example_python/generate_parameter_module_example/parameters.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ admittance_controller:
2424
type: string_array
2525
default_value: ["x", "y", "rz"]
2626
description: "specifies which joints will be used by the controller"
27+
additional_constraints: "Any string can be here. For example, you might want to embed JSON schema"
2728

2829
__map_joints:
2930
__map_dof_names:

generate_parameter_library_py/generate_parameter_library_py/generate_markdown.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ def __str__(self):
103103
'type': self.declare_parameters.code_gen_variable.defined_type,
104104
'default_value': self.declare_parameters.code_gen_variable.lang_str_value,
105105
'constraints': constraints,
106+
'additional_constraints': self.declare_parameters.parameter_additional_constraints,
106107
# remove leading whitespace from description, this is necessary for correct indentation of multi-line descriptions
107108
'description': re.sub(
108109
r'(?m)^(?!$)\s*',
@@ -139,6 +140,7 @@ def __str__(self):
139140
'type': self.declare_parameters.code_gen_variable.defined_type,
140141
'default_value': self.declare_parameters.code_gen_variable.lang_str_value,
141142
'constraints': constraints,
143+
'additional_constraints': self.declare_parameters.parameter_additional_constraints,
142144
'description': self.declare_parameters.parameter_description,
143145
}
144146

generate_parameter_library_py/generate_parameter_library_py/jinja_templates/cpp/declare_parameter

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ if (!parameters_interface_->has_parameter(prefix_ + "{{parameter_name}}")) {
33
rcl_interfaces::msg::ParameterDescriptor descriptor;
44
descriptor.description = {{parameter_description | valid_string_cpp}};
55
descriptor.read_only = {{parameter_read_only}};
6+
{%- if parameter_additional_constraints|length %}
7+
descriptor.additional_constraints = {{parameter_additional_constraints | valid_string_cpp}};
8+
{% endif -%}
69
{%- for validation in parameter_validations if ("bounds" in validation.function_name or "lt" in validation.function_name or "gt" in validation.function_name) %}
710
{%- if "DOUBLE" in parameter_type %}
811
{%- if validation.arguments|length == 2 %}

generate_parameter_library_py/generate_parameter_library_py/jinja_templates/cpp/declare_runtime_parameter

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ if (!parameters_interface_->has_parameter(param_name)) {
1919
rcl_interfaces::msg::ParameterDescriptor descriptor;
2020
descriptor.description = {{parameter_description | valid_string_cpp}};
2121
descriptor.read_only = {{parameter_read_only}};
22+
{%- if parameter_additional_constraints|length %}
23+
descriptor.additional_constraints = {{parameter_additional_constraints | valid_string_cpp}};
24+
{% endif -%}
2225
{%- for validation in parameter_validations if ("bounds" in validation.function_name or "lt" in validation.function_name or "gt" in validation.function_name) %}
2326
{%- if "DOUBLE" in parameter_type %}
2427
{%- if validation.arguments|length == 2 %}

generate_parameter_library_py/generate_parameter_library_py/jinja_templates/markdown/parameter_detail

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,9 @@
99

1010
*Constraints:*
1111
{{constraints}}
12+
13+
*Additional Constraints:*
14+
{{additional_constraints}}
15+
1216
{% else %}
1317
{% endif %}

generate_parameter_library_py/generate_parameter_library_py/jinja_templates/python/declare_parameter

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
if not self.node_.has_parameter(self.prefix_ + "{{parameter_name}}"):
22
{%- filter indent(width=4) %}
33
descriptor = ParameterDescriptor(description="{{parameter_description|valid_string_python}}", read_only = {{parameter_read_only}})
4+
{%- if parameter_additional_constraints|length %}
5+
descriptor.additional_constraints = "{{parameter_additional_constraints|valid_string_python}}"
6+
{% endif -%}
47
{%- for validation in parameter_validations if ("bounds" in validation.function_name or "lt" in validation.function_name or "gt" in validation.function_name) %}
58
{%- if "DOUBLE" in parameter_type %}
69
{%- if validation.arguments|length == 2 %}

generate_parameter_library_py/generate_parameter_library_py/jinja_templates/python/declare_runtime_parameter

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ param_name = f"{self.prefix_}{% for map in parameter_map%}{value_{{loop.index}}}
1616
if not self.node_.has_parameter(self.prefix_ + param_name):
1717
{%- filter indent(width=4) %}
1818
descriptor = ParameterDescriptor(description="{{parameter_description|valid_string_python}}", read_only = {{parameter_read_only}})
19+
{%- if parameter_additional_constraints|length %}
20+
descriptor.additional_constraints = "{{parameter_additional_constraints|valid_string_python}}"
21+
{% endif -%}
1922
{%- for validation in parameter_validations if ("bounds" in validation.function_name or "lt" in validation.function_name or "gt" in validation.function_name) %}
2023
{%- if "DOUBLE" in parameter_type %}
2124
{%- if validation.arguments|length == 2 %}

0 commit comments

Comments
 (0)