当前位置: 首页 > news >正文

【ros-humble】4.C++写法巡场海龟(服务通讯)

新添加通讯类型,可以看到编译后会生成C++和python的库。

float32 target_x #目标x
float32 target_y #目标y
---
int8 SUCCESS = 1
int8 FAIL = 0 
int8 result #结果

创造功能包

ros2 pkg create cpp_service --build-type  ament_cmake  --dependencies chapt4_interfaces rclcpp geometry_msgs turtlesim --license Apache-2.0

创建服务端和话题发布者

/*********************发布*************************** */
#include "rclcpp/rclcpp.hpp"
#include "geometry_msgs/msg/twist.hpp"
#include <chrono>
#include "turtlesim/msg/pose.hpp"
#include "chapt4_interfaces/srv/patrol.hpp"
using namespace std::chrono_literals;
using Partol = chapt4_interfaces::srv::Patrol;class Turtle_Control : public rclcpp::Node
{
public:explicit Turtle_Control(const std::string &node_name);~Turtle_Control();private:/* data */rclcpp::Service<Partol>::SharedPtr _patrol_service;rclcpp::Publisher<geometry_msgs::msg::Twist>::SharedPtr _publisher; // 声明话题发布者指针rclcpp::Subscription<turtlesim::msg::Pose>::SharedPtr _subscriber;  // 声明话题订阅者指针void _pose_subscriber(const turtlesim::msg::Pose::SharedPtr pose);double _target_x{1.0};double _target_y{1.0};double k{1.0};double max_speed{3.0};
};
Turtle_Control::Turtle_Control(const std::string &node_name) : Node(node_name)
{_patrol_service = this->create_service<Partol>("patrol",[&](const Partol::Request::SharedPtr request,Partol::Response::SharedPtr response) -> void{if ((request->target_x > 0) && (request->target_x < 12.0f) && (request->target_y > 0) && (request->target_y < 12.0f)){this->_target_x = request->target_x;this->_target_y = request->target_y;response->result = Partol::Response::SUCCESS;}elseresponse->result = Partol::Response::FAIL;});_publisher = this->create_publisher<geometry_msgs::msg::Twist>("turtle1/cmd_vel", 10); // 创建发布者_subscriber = this->create_subscription<turtlesim::msg::Pose>("/turtle1/pose", 10,std::bind(&Turtle_Control::_pose_subscriber, this, std::placeholders::_1));
}
void Turtle_Control::_pose_subscriber(const turtlesim::msg::Pose::SharedPtr pose)
{auto current_x = pose->x;auto current_y = pose->y;RCLCPP_INFO(get_logger(), "x = %f,y = %f", current_x, current_y);auto distance = std::sqrt((_target_x - current_x) * (_target_x - current_x) +(_target_y - current_y) * (_target_y - current_y));auto angle = std::atan2((_target_y - current_y), (_target_x - current_x)) - pose->theta;auto msg = geometry_msgs::msg::Twist();if (distance > 0.1){if (fabs(angle) > 0.2){msg.angular.z = fabs(angle);}elsemsg.linear.x = k * distance;}if (msg.linear.x > max_speed){msg.linear.x = max_speed;}_publisher->publish(msg);
}Turtle_Control::~Turtle_Control()
{
}int main(int argc, char *argv[])
{rclcpp::init(argc, argv);auto node = std::make_shared<Turtle_Control>("Turtle_Control");rclcpp::spin(node);rclcpp::shutdown();return 0;
}

创造客户端

#include <chrono>
#include <ctime> //创造随机数
#include "rclcpp/rclcpp.hpp"
#include "chapt4_interfaces/srv/patrol.hpp"
using namespace std::chrono_literals;
using Partol = chapt4_interfaces::srv::Patrol;class TurtleControler : public rclcpp::Node
{
private:rclcpp::Client<Partol>::SharedPtr _client;rclcpp::TimerBase::SharedPtr _timer;public:TurtleControler(const std::string &node_name);~TurtleControler();
};TurtleControler::TurtleControler(const std::string &node_name) : Node(node_name)
{srand(time(NULL));_client = this->create_client<Partol>("patrol");_timer = this->create_wall_timer(10s, [&]() -> void{// 等待服务while (!this->_client->wait_for_service(1s)){if (!rclcpp::ok()){RCLCPP_ERROR(this->get_logger(), "等待失败");return;}RCLCPP_INFO(this->get_logger(), "等待上线...");}auto request = std::make_shared<Partol::Request>();request->target_x = rand() % 15;request->target_y = rand() % 15;RCLCPP_INFO(this->get_logger(), "x:%f,y:%f", request->target_x, request->target_y);// 发送请求this->_client->async_send_request(request, [&](rclcpp::Client<Partol>::SharedFuture future_result) -> void {auto response = future_result.get();if(response->result == Partol::Response::SUCCESS){RCLCPP_INFO(this->get_logger(),"request success");}else{RCLCPP_INFO(this->get_logger(),"request error");}}); });
}TurtleControler::~TurtleControler()
{
}int main(int argc, char *argv[])
{rclcpp::init(argc, argv);auto node = std::make_shared<TurtleControler>("turtle_control_client");rclcpp::spin(node);rclcpp::shutdown();return 0;
}

http://www.lryc.cn/news/618097.html

相关文章:

  • Linux运维学习第十四周
  • 【3D Gen 入坑(1)】Hunyuan3D-Paint 2.1 安装 `custom_rasterizer` 报错完整排查
  • PyTorch基础(使用Numpy实现机器学习)
  • Vue 中的 Class 与 Style 绑定详解2
  • ubuntu24.04设置登陆背景图片
  • Pytest项目_day12(yield、fixture的优先顺序)
  • Web安全自动化测试实战指南:Python与Selenium在验证码处理中的应用
  • 【openEuler构建测试环境或部署嵌入式系统】openEuler生态扩容新路径:内网穿透工具cpolar助力多场景落地
  • Linux-FTP服务器搭建
  • 多路转接 select
  • 【数据结构入门】二叉树(1)
  • IoT/实现和分析 NB-IoT+DTLS+PSK 接入华为云物联网平台IoTDA过程,总结避坑攻略
  • 智能合约执行引擎在Hyperchain中的作用
  • 快速搭建前端playwright工程
  • FinQ4Cn: 基于 MCP 协议的中国 A 股量化分析
  • Java -- 集合 --Collection接口和常用的方法
  • Python网络爬虫(一) - 爬取静态网页
  • 爬虫与数据分析结合:中国大学排名案例学习报告
  • TDengine IDMP 基本功能(2.数据建模)
  • 爬虫与数据分析结和
  • 爬虫与数据分析入门:从中国大学排名爬取到数据可视化全流程
  • MySQL详细安装
  • 《算法导论》第 18 章 - B 树
  • 【MYSQL】MySQL中On duplicate key update
  • Dify入门指南(2):5 分钟部署 Dify:云服务 vs 本地 Docker
  • Python自动化测试实战:reCAPTCHA V3绕过技术深度解析
  • 常见鱼饵制作方式
  • Flutter学习笔记(六)---状态管理、事件、路由、动画
  • Vuex和Pina的区别
  • Prompt Engineering 最佳实践:让AI输出更精准的核心技巧