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

ROS系统(三)编程基础

一、创建功能包。

请查看第一章的前三个知识点。

ROS系统(二)常用工具及命令https://blog.csdn.net/qq_48361010/article/details/146033554?spm=1001.2014.3001.5501

二、发布/订阅节点(C++)

        前期准备:在工作站中新建src文件夹,进入src中新建包,然后回到工作站的目录下编译包会在功能包的目录下自动生成package.xmlCMakeLists.txt。然后进入包的目录下创建src文件夹,进入该目录下,创建c++文件。

1. 编写C++文件。

test_talker.cpp

#include "ros/ros.h"           // ROS 头文件
#include "std_msgs/String.h"    // ROS 标准消息类型 String
#include <sstream>              // C++ 字符串流,用于拼接字符串int main(int argc, char **argv) {// 初始化 ROS 节点,节点名称为 "talker"ros::init(argc, argv, "talker");// 创建节点句柄ros::NodeHandle n;// 创建一个发布者 (Publisher)// 话题名称为 "chatter",消息类型为 std_msgs::String,消息队列大小为 1000ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);// 设定循环频率为 10Hz,即每 0.1 秒运行一次ros::Rate loop_rate(10);int count = 0;  // 计数变量,记录消息发送次数// 进入循环,持续发布消息while (ros::ok()) {  std_msgs::String msg;  // 定义 ROS 消息std::stringstream ss;  // 创建字符串流ss << "hello world " << count;  // 拼接消息内容msg.data = ss.str();  // 赋值给消息的 data 字段// 在终端输出消息内容 (ROS_INFO 相当于 printf 或 cout)ROS_INFO("%s", msg.data.c_str());// 发布消息到 "chatter" 话题chatter_pub.publish(msg);// 处理 ROS 事件(虽然当前节点没有订阅者,但养成调用的习惯)ros::spinOnce();// 休眠以维持 10Hz 运行频率loop_rate.sleep();count++;  // 计数器递增}return 0;  // 结束程序
}

test_listener.cpp

#include "ros/ros.h"        // ROS 头文件
#include "std_msgs/String.h" // 用于发布/订阅字符串消息的标准消息类型// 订阅者回调函数,接收并打印从 "chatter" 主题接收到的消息
void chatterCallback(const std_msgs::String::ConstPtr& msg) {ROS_INFO("I heard: [%s]", msg->data.c_str());  // 使用 c_str() 转换 std::string 为 C 字符串
}int main(int argc, char **argv) {ros::init(argc, argv, "listener"); // 初始化 ROS 节点,命名为 "listener"ros::NodeHandle n;                 // 创建节点句柄// 创建一个订阅者,订阅 "chatter" 主题,队列大小为 1000,回调函数为 chatterCallbackros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);ros::spin();  // 进入循环,等待回调函数处理消息return 0;
}

2. 修改编译规则。   

        返回到功能包目录下,修改CMakelist.txt文件来构建编译规则,该文件内容知识点请查看下面文章。

ROS系统(一)安装及基础知识https://blog.csdn.net/qq_48361010/article/details/146005869?sharetype=blogdetail&sharerId=146005869&sharerefer=PC&sharesource=qq_48361010&spm=1011.2480.3001.8118功能包目录下的CMakelist.txt修改为以下内容。

cmake_minimum_required(VERSION 3.0.2)   # 1. 指定最低 CMake 版本
project(my_ros_tutorials)               # 2. 定义项目名称,与 package.xml 一致find_package(catkin REQUIRED COMPONENTS  # 3. 查找 ROS 依赖组件roscpp    # C++ 版 ROS 运行库rospy     # python 版 ROS 运行库std_msgs  # 使用的消息类型
)catkin_package()  # 4. 声明 catkin 包include_directories(                      # 5. 指定头文件路径include ${catkin_INCLUDE_DIRS}
)add_executable(talker src/test_talker.cpp)     # 6. (要生成的可执行文件  源文件)
target_link_libraries(talker              # 7. 连接 ROS 相关库${catkin_LIBRARIES}
)add_executable(listener src/test_listener.cpp)     # 6. (要生成的可执行文件  源文件)
target_link_libraries(listener               # 7. 连接 ROS 相关库${catkin_LIBRARIES}
)

3. 编译生成可执行文件。

        在工作站目录下,使用命令:catkin_make。如果编译成功,就会在 ~/catkin_ws/devel/lib/包名/ 目录下生成 talker、listener 可执行文件。

4. 运行节点。

        使用命令:roscore开始主节点,然后使用命令:rosrun 包名 talker
,如果运行完成后出现下面内容,说明编写成功!

三、发布/订阅节点(Python)

         编写python代码时,由于不需要被编译,但是为了保持项目的整洁性,应该遵循 ROS 的目录结构,并放在功能包(package)目录下,创建scripts目录来存放python代码。

1. 编写py代码。

talker.py

#!/usr/bin/env python
import rospy
from std_msgs.msg import Stringdef talker():pub = rospy.Publisher("chatter", String, queue_size=10)rospy.init_node("talker", anonymous=True)rate = rospy.Rate(10)  # 10Hzwhile not rospy.is_shutdown():hello_str = "hello world %s" % rospy.get_time()rospy.loginfo(hello_str)pub.publish(hello_str)rate.sleep()if __name__ == '__main__':try:talker()except rospy.ROSInterruptException:pass

listener.py 

#!/usr/bin/env python
import rospy
from std_msgs.msg import String  # std_msgs.msg 的 String 需要大写def callback(data):rospy.loginfo(rospy.get_caller_id() + " I heard: %s", data.data)  # 修正 loginfo 语法错误def listener():rospy.init_node("listener", anonymous=False)  # 修正 init_node 语法错误rospy.Subscriber("chatter", String, callback)  # 修正 String 类型拼写rospy.spin()if __name__ == "__main__":  # 修正 if __name__ 语句错误listener()

2. 运行节点。

        需要先开启主节点,然后使用命令rosrun 包名 talker.py来运行节点。这里C++和python都可以互通,比如运行C++写的talker,再运行python写的listener.py,都是可用互相通信的。

        在 ROS中,C++ 和 Python 节点是可以互通的。这是因为 ROS 中的消息传递是基于发布-订阅(publish-subscribe)模型的,只要 talkerlistener 节点使用相同的消息类型和主题(topic),它们就可以互相通信。而 ROS 提供了多语言支持,使得使用不同语言编写的节点能够通过共享消息格式进行通信。


http://www.mrgr.cn/news/93242.html

相关文章:

  • Docker 学习(一)
  • ubuntu20系统下conda虚拟环境下安装文件存储位置
  • springBoot文件上传、下载
  • 使用Qt调用HslCommunication(C++调用C#库)
  • P3385 【模板】负环
  • 带你从入门到精通——自然语言处理(五. Transformer中的自注意力机制和输入部分)
  • 使用sympy求解给定函数表达式的拉普拉斯变换
  • 十大经典排序算法简介
  • 【Linux跬步积累】—— 线程池详解(有源代码)
  • 选择排序算法
  • 离线地图显示
  • Redis数据结构——list
  • Redis数据结构——set
  • Java多线程与高并发专题——ConcurrentHashMap 在 Java7 和 8 有何不同?
  • C++————引用
  • 递归入手三维动态规划
  • Idea配置注释模板
  • 用CMake编译glfw进行OpenGL配置,在Visual Studio上运行
  • 图解MOE大模型的7个核心问题并探讨DeepSeekMoE的专家机制创新
  • 5年前问题的答案,如何造统计信息