Bug report
Required Info:
- Operating System: Ubuntu 24.04 (
osrf/ros:rolling-desktop)
- Installation type: binaries
- Version or commit hash:
rolling (the offending line is still present on the rolling branch, rclpy/parameter.py:565)
- DDS implementation:
rmw_fastrtps_cpp
- Client library (if applicable): rclpy
Description
parameter_dict_from_yaml_file (used by ros2 param load) loads floating-point parameters as strings whenever the value's Python str() representation uses exponent notation, e.g. 0.00001, 5e-06, 1.0e+20. Plain decimals such as 3.14 are unaffected. This also affects double arrays.
Steps to reproduce issue
repro.yaml:
/parameter_blackboard:
ros__parameters:
a_small: 0.00001
b_sci: 5e-06
c_large: 1.0e+20
d_normal: 3.14
e_arr: [1.0e-5, 2.0e-5]
ros2 run demo_nodes_cpp parameter_blackboard &
ros2 param load /parameter_blackboard repro.yaml
for p in a_small b_sci c_large d_normal e_arr; do ros2 param get /parameter_blackboard $p; done
Expected behavior
a_small, b_sci, c_large are doubles and e_arr is a double array — matching what the C++ params-file loader (--params-file) and ros2 param set already produce for the same values.
Actual behavior
a_small -> String value is: 1e-05
b_sci -> String value is: 5e-06
c_large -> String value is: 1e+20
d_normal -> Double value is: 3.14
e_arr -> String values are: ['1e-05', '2e-05']
Root cause
In _unpack_parameter_dict (rclpy/parameter.py):
parameter.value = get_parameter_value(str(param_value))
yaml.safe_load parses the file and already types these values correctly as floats. _unpack_parameter_dict then converts each value back to a string with str() and re-parses it through get_parameter_value → yaml.safe_load. For magnitudes where str(float) yields exponent notation without a decimal point (1e-05, 5e-06, 1e+20), PyYAML's YAML 1.1 implicit resolver does not treat the result as a float (it requires a .), so it returns a str and the parameter is created with type STRING.
The float → str() → YAML round-trip discards the type that yaml.safe_load already determined. Building the ParameterValue from the already-parsed Python value, instead of re-parsing str(param_value), avoids the lossy round-trip.
This is the same underlying problem reported in ros2/ros2cli#834, but the fix is local to rclpy. Happy to open a PR.
Bug report
Required Info:
osrf/ros:rolling-desktop)rolling(the offending line is still present on therollingbranch,rclpy/parameter.py:565)rmw_fastrtps_cppDescription
parameter_dict_from_yaml_file(used byros2 param load) loads floating-point parameters as strings whenever the value's Pythonstr()representation uses exponent notation, e.g.0.00001,5e-06,1.0e+20. Plain decimals such as3.14are unaffected. This also affects double arrays.Steps to reproduce issue
repro.yaml:Expected behavior
a_small,b_sci,c_largeare doubles ande_arris a double array — matching what the C++ params-file loader (--params-file) andros2 param setalready produce for the same values.Actual behavior
Root cause
In
_unpack_parameter_dict(rclpy/parameter.py):yaml.safe_loadparses the file and already types these values correctly as floats._unpack_parameter_dictthen converts each value back to a string withstr()and re-parses it throughget_parameter_value→yaml.safe_load. For magnitudes wherestr(float)yields exponent notation without a decimal point (1e-05,5e-06,1e+20), PyYAML's YAML 1.1 implicit resolver does not treat the result as a float (it requires a.), so it returns astrand the parameter is created with typeSTRING.The float →
str()→ YAML round-trip discards the type thatyaml.safe_loadalready determined. Building theParameterValuefrom the already-parsed Python value, instead of re-parsingstr(param_value), avoids the lossy round-trip.This is the same underlying problem reported in ros2/ros2cli#834, but the fix is local to rclpy. Happy to open a PR.