ROS2 多线程

举报
Hermit_Rabbit 发表于 2022/11/29 22:08:39 2022/11/29
【摘要】 0. 简介我们在开发ROS2程序时会发现,当面对只有一个node节点时,程序的调用是线性的,这个时候就会有两种解决方式,一种就是使用rclcpp_components来完成对子节点的注册,并完成类似ROS1中Nodelets的操作。另外一种就是使用执行器和回调组完成多线程的创建。 1. ROS2中多线程–callback_group相较于ROS1中使用MultiThreadedSpinne...

0. 简介

我们在开发ROS2程序时会发现,当面对只有一个node节点时,程序的调用是线性的,这个时候就会有两种解决方式,一种就是使用rclcpp_components来完成对子节点的注册,并完成类似ROS1中Nodelets的操作。另外一种就是使用执行器和回调组完成多线程的创建。

1. ROS2中多线程–callback_group

相较于ROS1中使用MultiThreadedSpinner完成多线程调用而言,ROS2在程序中自带了callback_group。callback_group为所有的callback分了组别,分别为:

  • MutuallyExclusive;互斥,即这个组别中每时刻只允许1个线程,一个callback在执行时,其他只能等待
  • Reentrant;可重入,这个组别中每时刻允许多个线程,一个Callback在执行时,其他callback可开启新的线程

这样也以为这我们可以有效地对ROS2中的callback程序进行控制。在ROS2的node中默认组别是MutuallyExclusive类型,即便使用了multiThreadedExecutor,也依然默认MutuallyExclusive类型,所以我们可以按照我们的需求来进行设置。

Node::create_subscription(
  const std::string & topic_name,  //topic名称
  const rclcpp::QoS & qos,
  CallbackT && callback,
  const SubscriptionOptionsWithAllocator<AllocatorT> & options,  //选项
  typename rclcpp::message_memory_strategy::MessageMemoryStrategy<
    typename rclcpp::subscription_traits::has_message_type<CallbackT>::type, AllocatorT>::SharedPtr
  msg_mem_strat)
//-------->
this->create_subscription<std_msgs::msg::Int32>("int1",qos,
			std::bind(&PathSearcherNode::int1Sub, this,
	        std::placeholders::_1),
			rclcpp::SubscriptionOptions());

值得一提的是当我们不依赖ros时,可以选择thread完成多线程的创立。具体的操作可以从众多的SLAM项目中总结出来。

2. 多线程的大致流程

在这里插入图片描述
上面的图片展示了多线程的整体流程,回调组会在程序创立时初始化。

// 声明回调组
rclcpp::CallbackGroup::SharedPtr callback_group_service_;
// 实例化回调组,类型为:互斥的
callback_group_service_ = this->create_callback_group(rclcpp::CallbackGroupType::MutuallyExclusive);

在后面会实例化回调组,通过服务端完成对回调组的调用,从而告诉ROS2的执行器,当你要调用回调函数处理请求时,请把它放到单独线程的回调组中。

// 声明占位符
using std::placeholders::_1;
using std::placeholders::_2;
// 声明服务端
// 声明一个服务端
rclcpp::Service<village_interfaces::srv::SellNovel>::SharedPtr server_;
// 实例化卖二手书的服务
server_ = this->create_service<village_interfaces::srv::SellNovel>("sell_novel",
                            std::bind(&SingleDogNode::sell_book_callback,this,_1,_2),
                            rmw_qos_profile_services_default,
                            callback_group_service_);

最后一步就是将单线程执行器换为多线程执行器

auto node = std::make_shared<SingleDogNode>("wang2");
/* 运行节点,并检测退出信号*/
rclcpp::executors::MultiThreadedExecutor exector;
exector.add_node(node);
exector.spin();

…详情请参照古月居

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。