赞
踩
本人使用版本为ROS2-dashing版本。
由于学习ROS2时十分匆忙,只把它当成一个通讯工具,所以看官方文档时并没有仔细思考,目的是能用就行,到具体报错时才不得不去看源代码找答案。即便写代码时知道Node,Executor如何定义,但对于这两个东西的内部实现并不了解。直到使用官方文档(service and client)的Client代码抄出了问题…
以下是我浅显的想法,如果有问题欢迎指正。
rclcpp::Node的成员变量有一些interface,例如
rclcpp::init(argc, argv);
rclcpp::executors::SingleThreadedExecutor executor;
auto node = std::make_shared<robotis::localization::LocalizationNode>(rclcpp::NodeOptions());
executor.add_node(node);
std::atomic_bool & has_executor = node->get_node_base_interface()->get_associated_with_executor_atomic();
//此时会成功输出,因为上面的executor已成功添加node
if (has_executor.exchange(true)) {
printf("yes yes yes yes yes yes\n");
}
executor.spin();
rclcpp::shutdown();
return EXIT_SUCCESS;
我的service定义
string data
---
Int32 num
接收到一个随便的std_msgs::msg::Int32数据后调用mySubCallback函数,在其中call service
void mySubCallback(const std_msgs::msg::Int32::SharedPtr msg){ printf("recieve a msg:%d\n",msg->data); std::string data =std::to_string(pose_msg->data); auto request = std::make_shared<my_msgs::srv::MyService::Request>(); request->data = data; while (!my_client_->wait_for_service(std::chrono::seconds(1))) { if (!rclcpp::ok()) { RCLCPP_ERROR(nh_->get_logger(), "Interrupted while waiting for the service. Exiting."); return; } RCLCPP_INFO(nh_->get_logger(), "service not available, waiting again..."); } auto result = my_client_->async_send_request(request); //以下报错 if (rclcpp::spin_until_future_complete(nh_, result) == rclcpp::executor::FutureReturnCode::SUCCESS){ int num= int(result.get()->num); printf("result:num:%d\n",num); } else { RCLCPP_ERROR(nh_->get_logger(), "Failed to call service"); } }
执行到rclcpp::spin_until_future_complete(nh_, result)时会报错"Node has already been added to an executor"。原因是spin_until_future_complete函数内部会创建一个executor,添加nh_这个Node,但一个node不允许被多个executor添加,所以报了错。
由于这个Node已经在main函数中被添加,所以直接接收response即可
void mySubCallback(const std_msgs::msg::Int32::SharedPtr msg){ printf("recieve a msg:%d\n",msg->data); std::string data =std::to_string(pose_msg->data); auto request = std::make_shared<my_msgs::srv::MyService::Request>(); request->data = data; while (!my_client_->wait_for_service(std::chrono::seconds(1))) { if (!rclcpp::ok()) { RCLCPP_ERROR(nh_->get_logger(), "Interrupted while waiting for the service. Exiting."); return; } RCLCPP_INFO(nh_->get_logger(), "service not available, waiting again..."); } //成功执行 using ServiceResponseFuture = rclcpp::Client<my_msgs::srv::MyService>::SharedFuture; auto response_received_callback = [this](ServiceResponseFuture future) { RCLCPP_INFO(nh_->get_logger(), "Got result: [%d]", future.get()->num); }; auto future_result = my_client_->async_send_request(request, response_received_callback); }
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。