【ROS2多进程】

【ROS2多进程】

执行器(Executor)

调用订阅、定时器、服务的回调,以响应收到的消息和事件

rclcpp::spin(node)

->拓展

//创建单线程执行器
rclcpp::executors::SingleThreadedExecutor executor;
//添加节点
executor.add_node(node);
//运行节点
executor.spin();

Executor

//单线程执行器
SingleThreadedExecutor
//多线程执行器:创建额外进程并行处理消息/事件
MultiThreadedExecutor
//静态单线程执行器:调用添加节点函数时,扫描节点结构,确定节点订阅和定时器
StaticSingleThreadedExecutor

回调组

配合多线程执行器

public:
service_callback_group_=this->create_callback_group(
	rclcpp::CallbackGroupType::MutuallyExclusive);//互斥回调组
	rclcpp::CallbackGroupType::Reentrant//可重入回调组
	// 依赖上下文/需要处理顺序的场景:不要使用可重入回调组
service_=this->create_service<example_interfaces::srv::AddTwoInts>(
	"add_two_ints",
	std::bind(&LearnExecutorNode::add_two_ints_callback,this,
		std::placeholders::_1,std::placeholders::_2),
		rmw_qos_profile_services_default,service_callback_group_);

private:
rclcpp::CallbackGroup::SharedPtr service_callback_group_;

使用

#include"example_interfaces/srv/add_two_ints.hpp"
#include"rclcpp/rclcpp.hpp"
#include"std_msgs/msg/string.hpp"
#include<sstream>
class LearnExecutorNode : public rclcpp::Node{
    public:
        LearnExecutorNode() : Node("learn_executor"){
            //发布者
            publisher_ = this->create_publisher<std_msgs::msg::String>("string_topic",10);
            //定时器
            timer_=this->create_wall_timer(std::chrono::seconds(1),
                std::bind(&LearnExecutorNode::timer_callback,this));
            //服务端
            service_=this->create_service<example_interfaces::srv::AddTwoInts>(
                "add_two_ints",std::bind(&LearnExecutorNode::add_two_ints_callback,this,
                std::placeholders::_1,std::placeholders::_2)
            );
        }

    private:
        void timer_callback(){
            auto msg=std_msgs::msg::String();
            msg.data="话题发布:"+thread_info();
            RCLCPP_INFO(this->get_logger(),msg.data.c_str());
            publisher_->publish(msg);
        }
        std::string thread_info(){
            std::ostringstream thread_str;
            thread_str<<"线程ID:"<<std::this_thread::get_id();
            return thread_str.str();
        }
        void add_two_ints_callback(
            const std::shared_ptr<example_interfaces::srv::AddTwoInts::Request> request,
            std::shared_ptr<example_interfaces::srv::AddTwoInts::Response> response
        )
        {
            RCLCPP_INFO(this->get_logger(),"服务开始处理:%s",thread_info().c_str());
            std::this_thread::sleep_for(std::chrono::seconds(10));
            response->sum=request->a+request->b;
            RCLCPP_INFO(this->get_logger(),"服务处理完成:%s",thread_info().c_str());
        }
        rclcpp::Publisher<std_msgs::msg::String>::SharedPtr publisher_;
        rclcpp::TimerBase::SharedPtr timer_;
        rclcpp::Service<example_interfaces::srv::AddTwoInts>::SharedPtr service_;
};
int main(int argc,char** argv){
    rclcpp::init(argc,argv);
    auto node=std::make_shared<LearnExecutorNode>();
    auto executor=rclcpp::executors::SingleThreadedExecutor();//使用单线程执行器对节点事件进行处理
    executor.add_node(node);
    executor.spin();
    rclcpp::shutdown();
    return 0;
}

->main中单线程

auto executor=rclcpp::executors::SingleThreadedExecutor();

->运行结果单线程

ros2 service call /add_two_ints example_interfaces/srv/AddTwoInts "{}"

image
->修改为多进程

auto executor=rclcpp::executors::MultiThreadedExecutor();

image
->修改默认进程数量

//修改进程数量
size_t N=3;//设置进程数量
auto options=rclcpp::ExecutorOptions();
auto executor=rclcpp::executors::MultiThreadedExecutor(options,N);

服务处理和定时器无法同时运行/无法并行处理请求:
不指定回调组时,ros2会采用默认回调组->定时器和服务处理都在同一回调组
->使用互斥回调组
image
image
->可并行进行:在处理服务时同步发布话题
->并行处理:使用可重入回调组

posted @ 2025-01-08 16:25  White_ink  阅读(214)  评论(0)    收藏  举报