1.如何实现服务端的多线程回调函数
在ROS2节点的私有成员内定义一个回调组(这里类似与C++线程池)
// 声明一个服务回调组,ROS2中要使用多线程执行器和回调组来实现多线程
rclcpp::CallbackGroup::SharedPtr callback_group_service_;//多线程操作
// 声明一个服务端
rclcpp::Service<village_interfaces::srv::SellNovel>::SharedPtr server_;
我们定义好了一个回调组我们需要对回调组进行定义,如果不定义为MutuallyExclusive类型,那还是会顺序执行,和单线程一样。
// 实例化回调函数组
callback_group_service_ = this->create_callback_group(rclcpp::CallbackGroupType::MutuallyExclusive);//只需要传递一个参数,传递函数组的类型
// 实例化卖二手书的服务
server_ = this->create_service<village_interfaces::srv::SellNovel>("sell_novel",
std::bind(&SingleDogNode::sell_novel_callback,this,_1,_2),//因为这个callback有两个参数故这里需要两个占位符
rmw_qos_profile_services_default,//因为我们需要对第四个参数回调函数组赋值,所以第三个默认参数我们也补充一下
callback_group_service_);//因为我们需要对第四个参数是定义一个callback组进行调用说明我们把上面的sell_novel_callback放进了这个组里以后,这样就不会和topiccallback起冲突了
这样将服务端启动之后,内部的&SingleDogNode::sell_novel_callback回调函数会被放在回调组内去进行执行,不会影响到其他回调函数。
2.多线程节点在一个CPP文件中这样的话就必须先创建一个MultiThreadedExecutor的exector实例化对象,我们通过自带的add_node(node)方法将节点node放到多线程中,然后使用 exector.spin();去执行。
int main(int argc, char **argv)
{
rclcpp::init(argc, argv);
/*产生一个Wang2的节点*/
auto node = std::make_shared<SingleDogNode>("wang2");
/* 运行节点,并检测退出信号*/
rclcpp::executors::MultiThreadedExecutor exector;//在这里面创建一个多线程执行器,可以同时运行callback组里面的callback
exector.add_node(node);
//下面我们也可以运行多个节点,例如再加一个 exector.add_node(node2);
exector.spin();//但是exector.spin();只用一次就行
rclcpp::shutdown();
return 0;
}
这里再补充一下,在学习经验三中,介绍了python的服务sever回调函数,其中的两个参数request和response我们都没有定义但是python可以自动识别,但是在C++可不可以哦。(ps:我不太确定auto智能指针是否可以,我感觉可以哈哈哈,本人没有去试)所以我们在学服务回调函数的时候需要这么去定义函数。
void sell_novel_callback(const village_interfaces::srv::SellNovel::Request::SharedPtr request,
const village_interfaces::srv::SellNovel::Response::SharedPtr response)
{
}
然后去再进写回调函数。