ROS 编程入门的介绍
2.1 创建 ROS 功能包
ROS(Robot Operating System)是一种开源的机器人软件框架,广泛用于机器人开发中。通过使用 ROS,开发者可以轻松创建和管理机器人应用程序。在本节中,我们将介绍如何创建一个 ROS 功能包并实现一些基本功能。
2.1.1 使用 ROS 主题
ROS 主题(Topic)是一种发布/订阅机制,允许节点之间进行通信。每个节点可以发布主题消息或订阅主题消息来获取数据。以下是如何使用 ROS 主题的步骤:
创建功能包
首先,我们需要创建一个新的 ROS 功能包。在终端中运行以下命令:
catkin_create_pkg de_ws my_robot rospy roscpp

此命令创建一个名为 my_robot 的功能包,并声明了对 std_msgs、rospy 和 roscpp 的依赖。
创建发布者节点
接下来,我们在功能包中创建一个发布者节点。新建一个名为 talker.py 的文件,并添加以下内容:
#!/usr/bin/env pythonimport 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
此代码定义了一个发布者节点 talker,它每秒钟发布一条 "hello world" 消息到主题 chatter。
2.1.2 创建 ROS 节点
ROS 节点是 ROS 系统中的基本执行单元。每个节点可以执行一个任务,如传感器数据处理、运动控制等。下面我们创建一个订阅者节点来接收 talker 节点发布的消息。
创建订阅者节点
新建一个名为 listener.py 的文件,并添加以下内容:

#!/usr/bin/env pythonimport rospy
from std_msgs.msg import Stringdef callback(data):rospy.loginfo(rospy.get_caller_id() + " I heard %s", data.data)def listener():rospy.init_node('listener', anonymous=True)rospy.Subscriber('chatter', String, callback)rospy.spin()if __name__ == '__main__':listener()
此代码定义了一个订阅者节点 listener,它接收主题 chatter 上的消息并打印出来。
2.1.3 编译节点
在我们运行节点之前,需要编译功能包。确保在功能包的 CMakeLists.txt 和 package.xml 文件中正确配置了依赖项。然后在终端中运行以下命令:
cd ~/catkin_ws
catkin_make
编译完成后,可以运行节点:
roscore
rosrun my_robot talker.py
rosrun my_robot listener.py
此时,你应该可以看到 listener 节点打印出 talker 节点发布的消息。

添加自定义的 .msg 文件和 .srv 文件
在 ROS 中,自定义消息类型和服务类型是很常见的需求。我们可以定义自己的消息和服务文件来满足特定的应用需求。
创建自定义 .msg 文件
首先,在 my_robot 功能包的 msg 目录下创建一个新的消息文件,例如 CustomMessage.msg:
string content
int32 number
然后,在 CMakeLists.txt 文件中添加以下内容:
add_message_files(FILESCustomMessage.msg
)
在 package.xml 文件中添加依赖:
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
最后,重新编译功能包:
catkin_make
创建自定义 .srv 文件
类似地,我们可以在 srv 目录下创建一个新的服务文件,例如 CustomService.srv:
string request
---
string response
然后,在 CMakeLists.txt 文件中添加以下内容:
add_service_files(FILESCustomService.srv
)
在 package.xml 文件中添加依赖:
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
重新编译功能包:
catkin_make
2.3 使用 ROS 服务
ROS 服务是一种请求/响应机制,允许节点之间进行同步通信。
2.3.1 使用 ROS actionlib
actionlib 是 ROS 中用于处理长时间运行任务的库。它提供了一种客户端-服务器架构,允许客户端请求服务器执行某些任务,并在任务完成时收到通知。
创建动作服务器
在 my_robot 功能包中创建一个新的 Python 文件 action_server.py:


#!/usr/bin/env pythonimport rospy
import actionlib
from my_robot.msg import CustomAction, CustomActionFeedback, CustomActionResultclass CustomActionServer(object):_feedback = CustomActionFeedback()_result = CustomActionResult()def __init__(self):self._as = actionlib.SimpleActionServer("custom_action", CustomAction, self.execute_cb, False)self._as.start()def execute_cb(self, goal):rospy.loginfo('Executing goal: %s', goal)success = Truefor i in range(1, goal.order):if self._as.is_preempt_requested():rospy.loginfo('Goal preempted')self._as.set_preempted()success = Falsebreakself._feedback.sequence = iself._as.publish_feedback(self._feedback)rospy.sleep(1.0)if success:self._result.sequence = goal.orderself._as.set_succeeded(self._result)if __name__ == '__main__':rospy.init_node('custom_action_server')server = CustomActionServer()rospy.spin()创建动作客户端在 my_robot 功能包中创建一个新的 Python 文件 action_client.py:#!/usr/bin/env pythonimport rospy
import actionlib
from my_robot.msg import CustomAction, CustomActionGoaldef feedback_cb(feedback):rospy.loginfo('Feedback: %s', feedback)if __name__ == '__main__':rospy.init_node('custom_action_client')client = actionlib.SimpleActionClient('custom_action', CustomAction)client.wait_for_server()goal = CustomActionGoal()goal.order = 10client.send_goal(goal, feedback_cb=feedback_cb)client.wait_for_result()rospy.loginfo('Result: %s', client.get_result())
2.3.2 编译 ROS 动作服务器和客户端
在编译功能包之前,确保在 CMakeLists.txt 和 package.xml 中添加了对 actionlib 和自定义消息的依赖。
然后在终端中运行以下命令:
catkin_make
启动动作服务器和客户端:
rosrun my_robot action_server.py
rosrun my_robot action_client.py
2.4 创建启动文件
启动文件用于同时启动多个 ROS 节点,简化了复杂系统的启动过程。
创建一个新的启动文件 my_robot.launch:
<launch><node pkg="my_robot" type="talker.py" name="talker" output="screen"/><node pkg="my_robot" type="listener.py" name="listener" output="screen"/>
</launch>
运行启动文件:
roslaunch my_robot my_robot.launch
2.5 主题、服务和 actionlib 的应用
在实际应用中,主题、服务和 actionlib 可以结合使用,实现复杂的机器人行为。例如,一个机器人可以通过主题获取传感器数据,通过服务进行路径规划,通过 actionlib 执行长时间的导航任务。
以下是一个综合应用示例:
-
主题用于发布传感器数据。
-
服务用于路径规划。
-
actionlib 用于执行导航任务。
2.6 总结
本文介绍了如何创建 ROS 功能包,并使用主题、服务和 actionlib 实现机器人功能。通过这些基础知识,您可以构建复杂的机器人应用程序。
2.7 问题
在学习和使用 ROS 的过程中,可能会遇到以下问题:
-
功能包无法编译:检查依赖是否正确添加。
-
节点无法通信:确保主题和服务名称一致。
-
动作服务器和客户端无法连接:检查 actionlib 配置是否正确。
相关文章:
ROS 编程入门的介绍
2.1 创建 ROS 功能包 ROS(Robot Operating System)是一种开源的机器人软件框架,广泛用于机器人开发中。通过使用 ROS,开发者可以轻松创建和管理机器人应用程序。在本节中,我们将介绍如何创建一个 ROS 功能包并实现一些…...
第十一章 抽象类与接口
一、抽象类和抽象方法 抽象类:使用abstract修饰的类 抽象方法:在类中没有方法体的方法,称为抽象方法,抽象方法用abstract修饰 抽象类中可以没有抽象方法,包含抽象方法的类必是抽象类 如果子类没有实现父类中的全部…...
请问企业的八大金刚系统是哪些?有什么共同点和区别?
我的理解的八大金刚包括:MES、ERP、WMS、OMS、CRM、SCM、SRM、PLM。 这些系统的主要功能及运用领域是哪些方面?他们互相之前有什么区别?选择时哪些是企业可能根据自身需求选择的必选项目或可选项目? 由于某些系统的必选性取决于企业的具体业…...
【入门】配置 Java 应用程序的完整指南
前言: Java 是一种广泛使用的编程语言,具备跨平台的特性,使得其应用程序可以在多种环境中高效运行。本文将介绍如何将 Java 应用程序从开发环境部署到生产环境,确保其能够稳定、稳定地运行运行。 确定运行环境 Java程序可以运行…...
flutter widget 设置GestureDetector点击无效
有可能是被上层的widget挡住了,虽然你看得到这个widget,但是操作不到。使用相对布局Stack要特别注意,这种布局会和Android一样,先写的布局放在下层,后写的,如果范围较大的话,会盖在之前的widget…...
基于SpringBoot的在线教育平台的设计与实现
文未可获取一份本项目的java源码和数据库参考。 选题的背景与意义: 随着互联网时代信息技术的不断发展,线下已经产生了很多IT技术的培训机构,但是价格却十分昂贵并且需要人们持续不断的去具体培训地点学习,因此更需要一个课程优…...
Django_Vue3_ElementUI_Release_004_使用nginx部署
1. nginx安装配置 1.1 下载nginx Download nginx 1.2 测试一下 1.3 进入nginx用命令操作 2. 部署 2.1 前端部署 2.1.1 修改nginx监听配置 …conf/nginx.conf http {... # 这里不进行修改server {listen 8010; # 监听 80 端口server_name 192.168.10.24; # 输入服务器 ip…...
Java抽象类的案例
抽象类的特点总结 不能实例化:抽象类不能直接创建实例。它只能被继承。即,你不能用 new 关键字创建抽象类的对象。 可以包含抽象方法:抽象类可以包含一个或多个抽象方法(没有方法体),这些方法必须在子类中…...
运维工程师面试整理-数据库
在运维工程师的面试中,数据库管理和优化是一个非常重要的环节。面试官可能会通过数据库相关的问题来评估你在数据库部署、管理、备份、性能优化以及故障排除方面的能力。以下是关于数据库部分的详细内容,帮助你更好地准备面试。 1. 数据库基础 ● 常见数据库类型 ○ 关系型数…...
comfyui一键抠图工作流:让你告别PS!
前言 本文涉及的工作流和插件,需要的朋友请扫描免费获取哦~ 在当今的数字时代,图像处理已经成为许多行业的日常需求。无论是电商产品展示、广告设计,还是个人照片编辑,去除背景都是一个常见且重要的步骤。 然而,使用…...
【Hot100】LeetCode—4. 寻找两个正序数组的中位数
目录 1- 思路题目识别二分 2- 实现⭐4. 寻找两个正序数组的中位数——题解思路 3- ACM 实现 原题链接:4. 寻找两个正序数组的中位数 1- 思路 题目识别 识别1 :给定两个数组 nums1 和 nums2 ,找出数组的中位数 二分 思路 将寻找中位数 —…...
【LLM text2sql】浅看大模型用于text2sql的综述
前言 之前笔者分享了text2sql & LLM & KG的有机结合实现KBQA的问答, 《【LLM & RAG & text2sql】大模型在知识图谱问答上的核心算法详细思路及实践》、 《【开源分享】KBQA核心技术及结合大模型SPARQL查询生成问答实践》。 我们再来看看大模型在te…...
Node js介绍
目录 概要**对Node的认识****Node的概念理解****Node和浏览器区别****Node的架构图** **Node的应用场景****Node的安装****安装Node的LTS版本****Node的版本管理工具nvm(了解)** **Node的输入和输出**Node程序传递参数Node的输出 **Node的全局对象****特殊的全局对象****其他的…...
企业编辑抖音百科词条有什么用?
企业编辑抖音百科词条有什么用? 百科词条创建对企业,品牌以及个人的重要性!#百科词条创建#百科营销#百科词条费用# 企业编辑百科词条主要是有以下这些好处,首先是丰富企业在网络上的信息,提高企业的知名度。 百科词条…...
数据结构-链式二叉树-四种遍历
博客主页:【夜泉_ly】 本文专栏:【数据结构】 欢迎点赞👍收藏⭐关注❤️ 数据结构-链式二叉树-四种遍历 1.前言2.前、中、后序遍历2.1前序遍历2.1中、后序遍历 3.层序遍历3.1递归实现3.2队列实现关于在Pop之后为什么还能用tmp访问节点&#x…...
【YashanDB知识库】数据库获取时间和服务器时间不一致
本文转自YashanDB官网,具体内容可见数据库获取时间和服务器时间不一致 【问题分类】功能使用 【关键字】服务器时间、数据库时间 【问题描述】数据库获取的时间和服务器时间不一致。 【问题原因分析】YashanDB并没有时区的概念,数据库的时间以数据库启…...
十大排序之:冒泡排序
目录 一、简介 实现过程 时间复杂度 二、代码实现 函数声明 Swap函数 单趟 多趟 测试 优化 一、简介 冒泡排序是一种简单的排序算法,它重复地比较相邻的两个元素,如果顺序错误就交换它们,直到没有元素需要交换为止。这个过程类…...
【MPC】无人机模型预测控制复现Data-Driven MPC for Quadrotors项目(Part 1)
无人机模型预测控制复现Data-Driven MPC for Quadrotors项目 参考链接背景和问题方法与贡献实验结果安装ROS创建工作空间下载RotorS仿真器源码和依赖创建Python虚拟环境下载data_driven_mpc仓库代码下载并配置ACADO求解器下载并配置ACADO求解器的Python接口下载并配置rpg_quadr…...
微信小程序开发——比较两个数字大小
在这里我们使用的工具是 需要自行安装和配置。 在微信小程序中比较两个数字大小有以下几种方式: 一、普通条件判断 在小程序的.js 文件中,先定义两个数字,如let num1 5; let num2 3;。通过if - else if - else语句,根据num1与…...
Java多线程3
1.有序性在并发编程中的含义。 有序性在并发编程中指的是在多线程环境下,程序的执行顺序应与单线程情况下保持一致,以避免出现不确定或错误的执行结果。 2.为何需要使用多线程进行程序设计? 使用多线程可以提高程序的效率,利用…...
变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析
一、变量声明设计:let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性,这种设计体现了语言的核心哲学。以下是深度解析: 1.1 设计理念剖析 安全优先原则:默认不可变强制开发者明确声明意图 let x 5; …...
【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
HBuilderX安装(uni-app和小程序开发)
下载HBuilderX 访问官方网站:https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本: Windows版(推荐下载标准版) Windows系统安装步骤 运行安装程序: 双击下载的.exe安装文件 如果出现安全提示&…...
【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...
JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.
ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #:…...
Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)
引言 工欲善其事,必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后,我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集,就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...
