小鱼 ROS 2 新书上线!点击链接查看, 新书配套视频点击链接查看。
提问前必看的发帖注意事项—— 提问前必看!不符合要求的问题拒绝回答!!
社区使用指南—如何添加标签修改密码
修改其他节点参数的代码简化
-
4.5.3修改其他节点的参数 和 4.4.3客户端代码实现课程中该两节构造参数时采用的是
- C++
param.name = "k"; auto param_value = rcl_interfaces::msg::ParameterValue(); param_value.type = rcl_interfaces::msg::ParameterType::PARAMETER_DOUBLE; param.value = param_value;
- Python
param = Parameter() param.name = 'model' param_value = ParameterValue() param_value.string_value = model param_value.type = ParameterType.PARAMETER_STRING param.value = param_value
根据的是ROS2中rcl_interfaces/srv/SetParameters消息接口类型
在终端中输入ros2 interfaces show rcl_interfaces/srv/SetParameters
得到消息接口的具体信息
# A list of parameters to set. Parameter[] parameters string name ParameterValue value uint8 type bool bool_value int64 integer_value float64 double_value string string_value byte[] byte_array_value bool[] bool_array_value int64[] integer_array_value float64[] double_array_value string[] string_array_value --- # Indicates whether setting each parameter succeeded or not and why. SetParametersResult[] results bool successful string reason
上传服务端的消息应为Parameter类型的数组
Parameter类型的消息又包含 string name 和 ParameterValue value两部分
string name通过下发代码完成赋值param.name = "k"; c++ param.name = 'model' python
ParameterValue value中除了一般的数值外,有一特殊变量 uint8 type
在终端中输入ros2 interface show rcl_interfaces/msg/ParameterType
得到信息
uint8 PARAMETER_NOT_SET=0 uint8 PARAMETER_BOOL=1 uint8 PARAMETER_INTEGER=2 uint8 PARAMETER_DOUBLE=3 uint8 PARAMETER_STRING=4 uint8 PARAMETER_BYTE_ARRAY=5 uint8 PARAMETER_BOOL_ARRAY=6 uint8 PARAMETER_INTEGER_ARRAY=7 uint8 PARAMETER_DOUBLE_ARRAY=8 uint8 PARAMETER_STRING_ARRAY=9
可以看到 uint8 type 的取值已经被ROS2规定好,因此课程中采用的赋值方式为
auto param_value = rcl_interfaces::msg::ParameterValue(); param_value.type = rcl_interfaces::msg::ParameterType::PARAMETER_DOUBLE; param_value.double_value = k; param.value = param_value;
即先创建一个新的ParameterValue类型变量param_value,对其type和double_value进行赋值,再传递给param.value。python的赋值方式类似,此处不再赘述
但,注意到type的取值,对应变量有其数值表示,例如PARAMETER_DOUBLE=3
因此上述代码可以简化为param.name = "k"; param.value.type = 3; param.value.double_value = k;
省去中间变量和宏定义的ParameterType的赋值方式
-
确实,如你所述,ROS 2 中的
rcl_interfaces/msg/ParameterValue
的type
字段已经被预定义了具体的数值,因此可以通过直接赋值这些数值来简化代码。这种简化不仅减少了代码的复杂性,还使得代码更加直观和易于维护。以下是你提供的简化思路在 C++ 和 Python 中的实现:C++ 简化版
原代码:
param.name = "k"; auto param_value = rcl_interfaces::msg::ParameterValue(); param_value.type = rcl_interfaces::msg::ParameterType::PARAMETER_DOUBLE; param_value.double_value = k; param.value = param_value;
简化后:
param.name = "k"; param.value.type = 3; // 直接赋值 PARAMETER_DOUBLE 的数值 param.value.double_value = k;
Python 简化版
原代码:
param = Parameter() param.name = 'model' param_value = ParameterValue() param_value.string_value = model param_value.type = ParameterType.PARAMETER_STRING param.value = param_value
简化后:
param = Parameter() param.name = 'model' param.value.string_value = model param.value.type = 4 # 直接赋值 PARAMETER_STRING 的数值
注意事项
-
可读性:虽然直接赋值数值可以简化代码,但可能会牺牲一定的可读性,特别是对于不熟悉 ROS 2
ParameterType
枚举的人来说。因此,在团队项目中,最好保持一致的代码风格,并在必要时添加注释来解释这些数值的含义。 -
维护性:如果 ROS 2 未来更新了
ParameterType
枚举,并且改变了这些数值,那么直接赋值数值的代码可能需要更新。使用枚举可以在一定程度上减少这种风险,因为编译器或解释器可以在编译时检查枚举值的正确性。 -
错误处理:在简化代码中,确保在赋值前已经正确初始化了
param
和param.value
,以避免潜在的未定义行为或崩溃。
综上所述,虽然直接赋值数值可以简化代码,但在实际项目中需要根据具体情况权衡可读性和维护性。
以上为生成回答,仅供参考~
-