From 6be43596cccd177d9d30e6232688c778d98cd4ae Mon Sep 17 00:00:00 2001 From: aryanputta <176622462+aryanputta@users.noreply.github.com> Date: Fri, 26 Jun 2026 04:46:58 -0400 Subject: [PATCH] Improve Python custom validator example --- README.md | 28 +++++++++++++++++++ .../custom_validation.py | 18 +++++++++++- .../parameters.yaml | 3 +- 3 files changed, 46 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5beb24f8..816c0319 100644 --- a/README.md +++ b/README.md @@ -334,6 +334,34 @@ validation: "my_project::integer_equal_value": [3] ``` +For Python modules, pass the validation module to `generate_parameter_module` in `setup.py`. +The functions receive the generated `rclpy.Parameter` as the first argument and return an +empty string when the parameter is valid. Any non-empty string is treated as the validation +error message. + +```python +generate_parameter_module( + module_name, + yaml_file, + validation_module='generate_parameter_module_example.custom_validation', +) +``` + +The Python example includes custom validators such as: + +```python +import math + + +def validate_damping_ratio(param, lower_bound, upper_bound): + for value in param.value: + if not math.isfinite(value) or value <= 0.0: + return f"Parameter '{param.name}' must contain finite positive damping ratios" + if value < lower_bound or value > upper_bound: + return f"Value {value} in parameter '{param.name}' must be within bounds" + return '' +``` + ### Nested structures After the top-level key, every subsequent non-leaf key will generate a nested C++ struct. The struct instance will have the same name as the key. diff --git a/example_python/generate_parameter_module_example/custom_validation.py b/example_python/generate_parameter_module_example/custom_validation.py index ae50ef7c..8b6a9e3d 100644 --- a/example_python/generate_parameter_module_example/custom_validation.py +++ b/example_python/generate_parameter_module_example/custom_validation.py @@ -26,10 +26,26 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +import math + def no_args_validator(param): return '' -def validate_double_array_custom_func(param, arg1, arg2): +def validate_damping_ratio(param, lower_bound, upper_bound): + if len(param.value) != 6: + return f"Parameter '{param.name}' must contain six damping ratio values" + + for value in param.value: + if not math.isfinite(value) or value <= 0.0: + return ( + f"Parameter '{param.name}' must contain finite positive damping ratios" + ) + if value < lower_bound or value > upper_bound: + return ( + f"Value {value} in parameter '{param.name}' must be within " + f"[{lower_bound}, {upper_bound}]" + ) + return '' diff --git a/example_python/generate_parameter_module_example/parameters.yaml b/example_python/generate_parameter_module_example/parameters.yaml index 9a5d334b..fa1abb4c 100644 --- a/example_python/generate_parameter_module_example/parameters.yaml +++ b/example_python/generate_parameter_module_example/parameters.yaml @@ -246,8 +246,7 @@ admittance_controller: The values are calculated as damping can be used instead: zeta = D / (2 * sqrt( M * S ))" validation: fixed_size<>: 6 - "custom_validators::validate_double_array_custom_func": [ 20.3, 5.0 ] - element_bounds<>: [ 0.1, 10.0 ] + "custom_validators::validate_damping_ratio": [ 0.1, 10.0 ] stiffness: type: double_array