ros、c++基于类的编程基础

基于class的编程结构,中间穿插ros的话题发布机制。
首先建立功能包:

catkin_create_pkg control   geometry_msgs message_generation message_runtime nav_msgs roscpp rospy std_msgs

以上依赖基本上是大多数的ros消息所需要的依赖了。
然后确定我们的文件结构:
在这里插入图片描述
一般而言,为实现更好的模块化开发和代码复用,一般会将类的定义和实现分开。
总体来说,就是.h文件定义类:

#include <ros/ros.h>
#include <geometry_msgs/Twist.h>
#include <nav_msgs/Path.h>
#include <hybrid_a_star/PathSpeedCtrlInterface.h> // 
#include <hybrid_a_star/GpsImuInterface.h> // class AutonomousDrivingNode {
public:AutonomousDrivingNode();void pathCallback(const nav_msgs::Path::ConstPtr& msg);void gpsCallback(const hybrid_a_star::GpsImuInterface::ConstPtr& msg);void Run();private:ros::NodeHandle nh_;ros::Publisher control_test_pub_;ros::Publisher cmd_vel_pub_;ros::Subscriber path_sub_;ros::Subscriber gps_sub_;void publishControlTest();void publishCmdVel();
};

hybrid_a_star.cpp类的具体实现:

#include "hybrid_a_star/hybrid_a_star.h"
AutonomousDrivingNode::AutonomousDrivingNode() {control_test_pub_ = nh_.advertise<hybrid_a_star::PathSpeedCtrlInterface>("control_test", 10);cmd_vel_pub_ = nh_.advertise<geometry_msgs::Twist>("cmd_vel", 10);path_sub_ = nh_.subscribe("path", 10, &AutonomousDrivingNode::pathCallback, this);gps_sub_ = nh_.subscribe("gps", 10, &AutonomousDrivingNode::gpsCallback, this);
}void AutonomousDrivingNode::pathCallback(const nav_msgs::Path::ConstPtr& msg) {for (const auto& point : msg->poses) {// 处理每个路径点// 示例:输出路径点的坐标ROS_INFO("Path Point: x=%f, y=%f", point.pose.position.x, point.pose.position.y);}
}void AutonomousDrivingNode::gpsCallback(const hybrid_a_star::GpsImuInterface::ConstPtr& msg)
{// 处理gps消息// 示例:获取GPS数据double x = msg->x;double y = msg->y;double z = msg->z;float pitch = msg->pitch;float roll = msg->roll;float yaw = msg->yaw;float vel = msg->vel;float lat = msg->lat;float lon = msg->lon;bool state_ndt = msg->state_ndt;std::string nav_flag_g = msg->nav_flag_g;
}void AutonomousDrivingNode::Run() 
{hybrid_a_star::PathSpeedCtrlInterface msg_ctrl;msg_ctrl.Target_velocity = 10.0;  // 示例:设置目标速度为10 m/smsg_ctrl.Target_steering_angle = 0.5;  // 示例:设置目标转角为0.5弧度msg_ctrl.Target_gear = 3;  // 示例:设置目标档位为前进档control_test_pub_.publish(msg_ctrl);geometry_msgs::Twist msg_cmd;// 填充msg_cmdmsg_cmd.linear.x = 0.5;  // 示例:设置线速度为0.5 m/smsg_cmd.angular.z = 0.1;  // 示例:设置角速度为0.1 rad/s    control_test_pub_.publish(msg_ctrl);cmd_vel_pub_.publish(msg_cmd);}
void AutonomousDrivingNode::publishControlTest() {hybrid_a_star::PathSpeedCtrlInterface msg;// 填充msgcontrol_test_pub_.publish(msg);
}void AutonomousDrivingNode::publishCmdVel() {geometry_msgs::Twist msg;// 填充msgcmd_vel_pub_.publish(msg);
}

最后再run.cpp中创建类的对象并调用成员函数:

#include "ros/ros.h"
#include "hybrid_a_star/hybrid_a_star.h"int main(int argc, char **argv) {ros::init(argc, argv, "autonomous_driving_node");AutonomousDrivingNode node;ros::Rate rate(10);while (ros::ok()) {node.Run();ros::spinOnce();rate.sleep();}ros::shutdown();return 0;
}

这里遇到了也顺便说一下ros里面这些已有的函数该怎么用:

ros::Rate looprate(10);  // 定义ros::Rate对象,设置节点的循环频率。
looprate.sleep();  // 根据之前设置的频率暂停程序执行直到下一个循环周期开始
ros::spinOnce(); //处理一次ros的消息回调—>话说回调函数是可以强制进去是吗?如果没有发布的话?(值得尝试)
ros::spin(); //进入 ROS 事件循环,让节点一直运行。
ros::shutdown(); //停止 ROS 节点的运行。
ros::ok(); //检查 ROS 节点的运行状态。
ros::NodeHandle nh; //创建一个 ROS 节点句柄,用于访问 ROS 系统中的资源。
ros::NodeHandle nh("~"); //创建一个私有节点句柄,用于访问节点的私有参数。
ros::Publisher pub = nh.advertise<msg_type>("topic_name", queue_size); //话题发布
ros::Subscriber sub = nh.subscribe("topic_name", queue_size, callback); //话题订阅
ros::ServiceServer srv = nh.advertiseService("service_name", callback); //服务服务端
ros::ServiceClient cli = nh.serviceClient<srv_type>("service_name"); // 服务客户端
nh.getParam("param_name", value); // 从参数服务器读取
nh.setParam("param_name", value); // 向参数服务器写入
ros::Time now = ros::Time::now(); // 获取ROS的时间系统

理清一些很像的东西:
ros::spinOnce() 和 ros::spin() 是两种不同的 ROS 节点编程模式,它们不能同时存在于同一个节点中。

 int main(int argc, char** argv) {ros::init(argc, argv, "my_node");ros::NodeHandle nh;// 创建发布者和订阅者ros::Publisher pub = nh.advertise<std_msgs::String>("topic_name", 10);ros::Subscriber sub = nh.subscribe("another_topic", 10, callback);ros::Rate loop_rate(10); // 10 Hz 循环频率while (ros::ok()) {// 执行其他操作publishSomeData(pub);// 处理消息回调ros::spinOnce();// 控制循环频率loop_rate.sleep();}return 0;
}
int main(int argc, char** argv) {ros::init(argc, argv, "my_node");ros::NodeHandle nh;// 创建发布者和订阅者ros::Publisher pub = nh.advertise<std_msgs::String>("topic_name", 10);ros::Subscriber sub = nh.subscribe("another_topic", 10, callback);// 其他操作放在单独的线程中执行std::thread other_thread(doOtherStuff, pub);// 进入 ROS 事件循环ros::spin();other_thread.join();return 0;
}void doOtherStuff(ros::Publisher& pub) {// 执行其他操作,比如发布数据while (ros::ok()) {publishSomeData(pub);ros::Duration(1.0).sleep(); // 每秒发布一次}
}

它们的区别非常细微,需要理解清楚。
还有全局句柄和私有节点句柄:

int main(int argc, char** argv) {ros::init(argc, argv, "my_node");ros::NodeHandle nh;       // 全局节点句柄ros::NodeHandle nh_private("~"); // 私有节点句柄// 使用全局节点句柄发布话题ros::Publisher pub = nh.advertise<std_msgs::String>("topic_name", 10);// 使用私有节点句柄读取参数std::string param_value;nh_private.getParam("param_name", param_value);// 执行其他操作while (ros::ok()) {ros::spinOnce();}ros::shutdown(); // 停止节点运行return 0;
}

这里最重要的就是参数服务器了,也就是你使用的是什么句柄。一般来说发布话题是一定要使用全局句柄的,毕竟私有句柄限制很多,主要是在节点内部可以有私有句柄来修改参数:

<launch>// 全局参数<param name="global_param" value="global_value" /><node pkg="my_package" type="my_node" name="my_node"><!-- 私有参数 --><param name="param_name" value="private_value" /></node>
</launch>

这里就很好的展示了私有句柄和全局句柄应该怎么设置参数。

以上就是一些基本的基于类的结构化编程思路,下次在python中尝试以上内容。
最后附上我的cmakeLists和package.xml:

cmake_minimum_required(VERSION 3.0.2)
project(hybrid_a_star)find_package(catkin REQUIRED COMPONENTSgeometry_msgsmessage_generationmessage_runtimenav_msgsroscpprospystd_msgs
)add_message_files(FILESGpsImuInterface.msgPathSpeedCtrlInterface.msg
)## Generate services in the 'srv' folder
# add_service_files(
#   FILES
#   Service1.srv
#   Service2.srv
# )## Generate actions in the 'action' folder
# add_action_files(
#   FILES
#   Action1.action
#   Action2.action
# )generate_messages(DEPENDENCIESgeometry_msgsnav_msgsstd_msgs
)catkin_package(CATKIN_DEPENDS geometry_msgs message_generation message_runtime nav_msgs roscpp rospy std_msgs
)include_directories(include${catkin_INCLUDE_DIRS}
)add_executable(hybrid_a_star  src/run.cpp src/hybrid_a_star.cpp)add_dependencies(hybrid_a_star  ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})target_link_libraries(hybrid_a_star ${catkin_LIBRARIES}
)
<?xml version="1.0"?>
<package format="2"><name>hybrid_a_star</name><version>0.0.0</version><description>The hybrid_a_star package</description><maintainer email="cyun@todo.todo">cyun</maintainer><license>TODO</license><buildtool_depend>catkin</buildtool_depend><build_depend>geometry_msgs</build_depend><build_depend>message_generation</build_depend><build_depend>message_runtime</build_depend><build_depend>nav_msgs</build_depend><build_depend>roscpp</build_depend><build_depend>rospy</build_depend><build_depend>std_msgs</build_depend><build_export_depend>geometry_msgs</build_export_depend><build_export_depend>nav_msgs</build_export_depend><build_export_depend>roscpp</build_export_depend><build_export_depend>rospy</build_export_depend><build_export_depend>std_msgs</build_export_depend><exec_depend>geometry_msgs</exec_depend><exec_depend>message_runtime</exec_depend><exec_depend>nav_msgs</exec_depend><exec_depend>roscpp</exec_depend><exec_depend>rospy</exec_depend><exec_depend>std_msgs</exec_depend><exec_depend>message_generation</exec_depend><export></export>
</package>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2868519.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

腾讯云轻量2核4G5M服务器卡不卡?性能怎么样?

腾讯云轻量2核4G5M带宽服务器支持多少人在线访问&#xff1f;5M带宽下载速度峰值可达640KB/秒&#xff0c;阿腾云以搭建网站为例&#xff0c;假设优化后平均大小为60KB&#xff0c;则5M带宽可支撑10个用户同时在1秒内打开网站&#xff0c;并发数为10&#xff0c;经阿腾云测试&a…

力扣题目训练(20)

2024年2月13日力扣题目训练 2024年2月13日力扣题目训练594. 最长和谐子序列598. 区间加法 II599. 两个列表的最小索引总和284. 窥视迭代器287. 寻找重复数135. 分发糖果 2024年2月13日力扣题目训练 2024年2月13日第二十天编程训练&#xff0c;今天主要是进行一些题训练&#x…

居民健康监测小程序|基于微信小程序的居民健康监测小程序设计与实现(源码+数据库+文档)

居民健康监测小程序目录 目录 基于微信小程序的居民健康监测小程序设计与实现 一、前言 二、系统设计 三、系统功能设计 1、用户信息管理 2、健康科普管理 5.3公告类型管理 3、论坛信息管理 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推…

详解命令docker run -d --name container_name -e TZ=Asia/Shanghai your_image

docker run 是Docker的主要命令&#xff0c;用于从镜像启动一个新的容器。下面详细解释并举例说明 -d, --name, -e TZ 参数的用法&#xff1a; -d 或 --detach&#xff1a; 这个标志告诉Docker以守护进程&#xff08;后台&#xff09;模式运行容器。这意味着当你执行 docker ru…

[数据集][目标检测]智能手机屏幕缺陷检测数据集VOC+YOLO格式1200张3类别油斑划痕两点三类

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;1200 标注数量(xml文件个数)&#xff1a;1200 标注数量(txt文件个数)&#xff1a;1200 标注…

‘pro‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件。

https://blog.csdn.net/weixin_48877626/article/details/135308016https://blog.csdn.net/weixin_48877626/article/details/135308016

一文搞懂分布式事务解决方案

前言 在当今的分布式系统中&#xff0c;分布式事务管理是一个关键挑战。在面对跨多个服务的复杂业务流程时&#xff0c;确保数据一致性和事务的原子性变得至关重要。本文将深入探讨分布式事务的概念、原理、实现方式以及在Java领域的应用。 什么是分布式事务 分布式事务是指涉…

【Javascript编程实操06】1、反转数组和字符串 2、将二维数组转一维数组

前言 1、反转数组和字符串 代码&#xff1a; 实现效果&#xff1a; 2、将二维数组转一维数组 代码&#xff1a; 实现效果&#xff1a; 总结 前言 本次主要是针对Javascript阶段的字符串与数组的实操练习&#xff0c;共有2个实操&#xff0c;大家可以在实操的过程中更加深…

阅读 - 二维码扫码登录原理

在日常生活中&#xff0c;二维码出现在很多场景&#xff0c;比如超市支付、系统登录、应用下载等等。了解二维码的原理&#xff0c;可以为技术人员在技术选型时提供新的思路。对于非技术人员呢&#xff0c;除了解惑&#xff0c;还可以引导他更好地辨别生活中遇到的各种二维码&a…

2024批量导出公众号所有文章生成目录,这下方便找文章了

公众号历史文章太多&#xff0c;手机上翻起来太费劲&#xff0c;怎么快速找到某一天的文章呢&#xff1f;比如深圳卫健委这个号从2014到2024发布近万篇文章。 公众号历史文章太多&#xff0c;手机上翻起来太费劲&#xff0c;怎么快速找到某一天的文章&#xff1f; 如果要找2020…

主干网络篇 | YOLOv8更换主干网络之ShuffleNetV2(包括完整代码+添加步骤+网络结构图)

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。ShuffleNetV2是一种轻量级的神经网络架构&#xff0c;用于图像分类和目标检测任务。它是ShuffleNet的改进版本&#xff0c;旨在提高模型的性能和效率。ShuffleNetV2相比于之前的版本&#xff0c;在保持模型轻量化的同时&am…

用户视角的比特币和以太坊外围技术整理

1. 引言 要点&#xff1a; 比特币L2基本强调交易内容的隐蔽性&#xff0c;P2P交易&#xff08;尤其是支付&#xff09;成为主流&#xff0c;给用户带来一定负担&#xff08;闪电网络&#xff09;在以太坊 L2 中&#xff0c;一定程度上减少了交易的隐蔽性&#xff0c;主流是实…

【Linux进程状态】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 一、直接谈论Linux的进程状态 看看Linux内核源代码怎么说 1.1、R状态 -----> 进程运行的状态 1.2、S状态 -----> 休眠状态(进程在等待“资源”就绪) 1.3、T状…

突破编程_前端_JS编程实例(工具栏组件)

1 开发目标 工具栏组件旨在模拟常见的桌面软件工具栏&#xff0c;所以比较适用于 electron 的开发&#xff0c;该组件包含工具栏按钮、工具栏分割条和工具栏容器三个主要角色&#xff0c;并提供一系列接口和功能&#xff0c;以满足用户在不同场景下的需求&#xff1a; 点击工具…

Vue+SpringBoot打造音乐平台

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统展示 四、核心代码4.1 查询单首音乐4.2 新增音乐4.3 新增音乐订单4.4 查询音乐订单4.5 新增音乐收藏 五、免责说明 一、摘要 1.1 项目介绍 基于微信小程序JAVAVueSpringBootMySQL的音乐平台&#xff0c;包含了音乐…

tigramite教程(五)使用TIGRAMITE 进行自助聚合和链接置信度量化

使用TIGRAMITE 进行自助聚合和链接置信度量化 自助聚合&#xff08;Bagging&#xff09;和置信度估计例子数据生成模型基本的PCMCIBagged-PCMCI使用优化后的pc_alpha进行自举聚合使用优化的pc_alpha进行CMIknn的自举聚合 TIGRAMITE是一个用于时间序列分析的Python模块。它基于P…

如何批量获取公众号所有文章的阅读数点赞数和留言数导出excel?

如何批量获取公众号所有文章的阅读数点赞数和留言数导出excel&#xff1f;我写了个脚本批量抓取&#xff0c;导出的excel文章数据包含文章日期&#xff0c;文章标题&#xff0c;文章链接&#xff0c;文章简介&#xff0c;文章作者&#xff0c;文章封面图&#xff0c;是否原创&a…

《圣斗士星矢:纵横宇宙》(上)AI制作真人版大电影

《圣斗士星矢&#xff1a;纵横宇宙》&#xff08;上&#xff09;AI制作真人版大电影 平行宇宙&#xff0c;黑暗来袭&#xff0c;十二件黄金圣衣合体成为究极秘密武器&#xff01; 《圣斗士星矢&#xff1a;纵横宇宙》&#xff08;上&#xff09;电影开场&#xff0c;星矢等一众…

网络通信与网络协议

网络编程是指利用计算机网络实现程序之间通信的一种编程方式。在网络编程中&#xff0c;程序需要通过网络协议(如 TCP/IP)来进行通信&#xff0c;以实现不同计算机之间的数据传输和共享。在网络编程中&#xff0c;通常有三个基本要素 IP 地址:定位网络中某台计算机端口号port:定…

Nginx高级技术: 代理缓存配置

一、缓存说明 Nginx缓存&#xff0c;Nginx 提供了一个强大的反向代理和 HTTP 服务器功能&#xff0c;同时也是一个高效的缓存服务器。一般情况下系统用到的缓存有以下三种&#xff1a; 1、服务端缓存&#xff1a;缓存存在后端服务器&#xff0c;如 redis。 2、代理缓存&#…