鱼香ROS社区
    • 版块
    • 最新
    • 未解决
    • 已解决
    • 群组
    • 注册
    • 登录
    紧急通知:禁止一切关于政治&VPN翻墙等话题,发现相关帖子会立马删除封号
    提问前必看的发帖注意事项: 社区问答规则(小鱼个人)更新 | 高质量帖子发布指南

    修改其他节点参数的代码简化

    已定时 已固定 已锁定 已移动
    ROS2机器人开发:从入门到实践
    ros2 ros2通信
    2
    2
    185
    正在加载更多帖子
    • 从旧到新
    • 从新到旧
    • 最多赞同
    回复
    • 在新帖中回复
    登录后回复
    此主题已被删除。只有拥有主题管理权限的用户可以查看。
    • liusiyu_alex_nuaaL
      liusiyu_alex_nuaa
      最后由 编辑

      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的赋值方式

      1 条回复 最后回复 回复 引用 0
      • 小伊小
        机器人小伊
        最后由 编辑

        确实,如你所述,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 的数值
        

        注意事项

        1. 可读性:虽然直接赋值数值可以简化代码,但可能会牺牲一定的可读性,特别是对于不熟悉 ROS 2 ParameterType 枚举的人来说。因此,在团队项目中,最好保持一致的代码风格,并在必要时添加注释来解释这些数值的含义。

        2. 维护性:如果 ROS 2 未来更新了 ParameterType 枚举,并且改变了这些数值,那么直接赋值数值的代码可能需要更新。使用枚举可以在一定程度上减少这种风险,因为编译器或解释器可以在编译时检查枚举值的正确性。

        3. 错误处理:在简化代码中,确保在赋值前已经正确初始化了 param 和 param.value,以避免潜在的未定义行为或崩溃。

        综上所述,虽然直接赋值数值可以简化代码,但在实际项目中需要根据具体情况权衡可读性和维护性。


        以上为生成回答,仅供参考~

        我是小伊,已接入ChatGpt,所有回复,仅供参考~

        1 条回复 最后回复 回复 引用 0
        • 第一个帖子
          最后一个帖子
        皖ICP备16016415号-7
        Powered by NodeBB | 鱼香ROS