XLXdemon 2024-06-12 10:19 采纳率: 0%
浏览 28

ros2怎么通过bind给回调传入多个参数

为什么ros2不能像ros1一样用bind实现回调传入多个参数
我在ros2中使用std::bind传入多个参数后编译可以通过但程序不能正常运行

  • 写回答

3条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-06-12 10:19
    关注

    引自免费微信小程序:皆我百晓生

    在ROS 2中,确实与ROS 1相比,在使用std::bind向回调函数传递额外参数时存在差异。ROS 1允许用户直接在订阅者创建时使用std::bind将任意数量的参数绑定到回调函数上。然而,ROS 2采取了不同的方法,主要是为了简化API并提供更安全、更现代的C++编程实践。

    ROS 2推荐使用Lambda表达式来解决此问题,这是因为Lambda表达式提供了捕获列表,可以方便地捕获外围作用域中的变量,并且语法更为简洁。下面是一个示例,展示如何在ROS 2中使用Lambda表达式为回调函数传递多个参数:

    #include "rclcpp/rclcpp.hpp"
    #include "std_msgs/msg/string.hpp"
    
    class ExampleNode : public rclcpp::Node {
    public:
        ExampleNode() : Node("example_node") {
            // 创建一个订阅者,使用Lambda表达式捕获额外参数
            subscription_ = this->create_subscription<std_msgs::msg::String>(
                "topic", 10,
                [this](const std_msgs::msg::String::SharedPtr msg) {
                    processMessage(msg);
                }
            );
        }
    
    private:
        void processMessage(const std_msgs::msg::String::SharedPtr msg) {
            RCLCPP_INFO(this->get_logger(), "Received message: %s", msg->data.c_str());
            // 这里可以访问类成员变量和函数
            // 也可以访问Lambda表达式外部定义的变量
        }
    
        rclcpp::Subscription<std_msgs::msg::String>::SharedPtr subscription_;
    };
    
    int main(int argc, char * argv[]) {
        rclcpp::init(argc, argv);
        rclcpp::spin(std::make_shared<ExampleNode>());
        rclcpp::shutdown();
        return 0;
    }
    

    在这个例子中,processMessage函数接收一个消息指针作为参数,并且可以访问ExampleNode类的所有成员变量和函数。Lambda表达式的[this]捕获方式确保了this指针被正确传递,使得processMessage能够访问类的上下文。

    虽然Lambda表达式是首选方法,但在某些情况下,如果确实需要使用std::bind,可以通过创建一个辅助函数来间接调用目标函数,并将所有必要的参数作为辅助函数的参数。例如:

    #include <functional>
    #include "rclcpp/rclcpp.hpp"
    #include "std_msgs/msg/string.hpp"
    
    void processMessage(const std_msgs::msg::String::SharedPtr msg, int id, float value) {
        RCLCPP_INFO(rclcpp::get_logger("example_node"), "Received message: %s", msg->data.c_str());
        // 使用id和value进行进一步处理
    }
    
    class ExampleNode : public rclcpp::Node {
    public:
        ExampleNode() : Node("example_node") {
            subscription_ = this->create_subscription<std_msgs::msg::String>(
                "topic", 10,
                std::bind(&processMessage, std::placeholders::_1, 42, 3.14f)
            );
        }
    
    private:
        rclcpp::Subscription<std_msgs::msg::String>::SharedPtr subscription_;
    };
    
    int main(int argc, char * argv[]) {
        rclcpp::init(argc, argv);
        rclcpp::spin(std::make_shared<ExampleNode>());
        rclcpp::shutdown();
        return 0;
    }
    

    这里,std::bind用于将processMessage函数与特定值绑定。这种方法虽然有效,但通常不如Lambda表达式简洁和直观。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 6月12日

悬赏问题

  • ¥20 公众号如何实现点击超链接后自动发送文字
  • ¥15 用php隐藏类名和增加类名
  • ¥15 算法设计与分析课程的提问
  • ¥15 用MATLAB汇总拟合图
  • ¥15 智能除草机器人方案设计
  • ¥15 对接wps协作接口实现消息发送
  • ¥15 SQLite 出现“Database is locked” 如何解决?
  • ¥15 已经加了学校的隶属邮箱了,为什么还是进不去github education?😭
  • ¥15 求会做聚类,TCN的朋友有偿线上指导。以下是目前遇到的问题
  • ¥100 无网格伽辽金方法研究裂纹扩展的程序