ROS机器人的基础概念和术语
发布时间: 2024-01-15 06:56:02 阅读量: 121 订阅数: 35
# 1. 介绍ROS机器人
ROS(Robot Operating System)是一个灵活的框架,用于编写机器人软件。它提供了一系列程序库和工具,用于帮助软件开发者创建复杂和强大的机器人应用。
## 1.1 什么是ROS机器人
ROS是一个开源的机器人软件平台,它提供了一系列工具和库,用于帮助开发者创建机器人软件。ROS提供了一种灵活的架构,使得开发者可以轻松地编写各种不同类型的机器人应用,包括但不限于感知、规划、控制和协作等方面的应用。
## 1.2 ROS机器人的历史
ROS最早是由Willow Garage公司于2007年开始开发,于2008年首次发布。2013年,ROS的维护工作由Open Source Robotics Foundation(OSRF)接管。目前,ROS已经成为全球范围内最受欢迎的机器人软件框架之一。
## 1.3 ROS机器人的应用领域
ROS机器人广泛应用于各种领域,包括工业自动化、服务机器人、医疗机器人、无人系统等。它在机器人领域的应用不断扩展,成为了研究、教育和商业开发的首选平台。
以上是对ROS机器人的基本介绍,接下来我们将深入了解ROS的基础概念。
# 2. ROS基础概念
### 2.1 节点(Nodes)
在ROS中,节点是指一个独立的进程,可以执行特定的任务或功能。节点之间可以进行通信,通过发布和订阅主题实现信息的交流。每个节点都可以拥有多个发布者和订阅者。
节点的创建和初始化由ROS核心(ROS Core)处理。下面是一个使用Python语言创建一个ROS节点的示例:
```python
import rospy
# 创建节点
rospy.init_node('my_node', anonymous=True)
# 执行节点任务
rate = rospy.Rate(10) # 10Hz的频率执行任务
while not rospy.is_shutdown():
# 执行任务代码
rospy.loginfo("Hello, ROS!")
rate.sleep()
```
### 2.2 主题(Topics)
主题是ROS中一种常见的通信机制,用于节点之间的发布和订阅消息。一个节点可以将消息发布到一个主题上,而其他节点可以订阅该主题,接收并处理对应的消息。
每个主题都专注于一个特定的消息类型,通过发布者和订阅者实现节点之间的信息传递。下面是一个使用Python语言发布和订阅主题的示例:
```python
import rospy
from std_msgs.msg import String
# 回调函数,处理接收到的消息
def callback(data):
rospy.loginfo("Received: %s", data.data)
# 创建节点
rospy.init_node('my_node', anonymous=True)
# 创建订阅者,订阅指定主题
rospy.Subscriber('my_topic', String, callback)
# 创建发布者,发布消息到指定主题
pub = rospy.Publisher('my_topic', String, queue_size=10)
# 发布消息
rate = rospy.Rate(10) # 10Hz的发布频率
while not rospy.is_shutdown():
pub.publish("Hello, ROS!")
rate.sleep()
```
### 2.3 消息(Messages)
消息是ROS中的信息载体,用于在主题之间传递数据。每个消息类型都由特定的数据格式和字段组成,可以使用ROS自带的消息类型或自定义消息类型。
ROS使用.msg文件定义消息类型,并使用消息生成工具自动生成相应的代码。下面是一个使用Python语言定义和使用自定义消息的示例:
```python
# 在定义的目录下创建msg文件
# my_package/msg/MyMessage.msg
# ---
# string name
# int32 age
# 编译消息
# 注意修改相应的包路径
$ cd ~/catkin_ws
$ catkin_make
import rospy
from my_package.msg import MyMessage
# 创建节点
rospy.init_node('my_node', anonymous=True)
# 创建发布者和订阅者
pub = rospy.Publisher('my_topic', MyMessage, queue_size=10)
sub = rospy.Subscriber('my_topic', MyMessage, callback)
# 回调函数,处理接收到的消息
def callback(data):
rospy.loginfo("Received: %s, %d", data.name, data.age)
# 发布消息
rate = rospy.Rate(10) # 10Hz的发布频率
while not rospy.is_shutdown():
msg = MyMessage()
msg.name = "John"
msg.age = 25
pub.publish(msg)
rate.sleep()
```
### 2.4 服务(Services)
服务是ROS中一种用于节点之间进行请求和响应的通信机制。一个节点可以提供一个或多个服务,而其他节点可以向提供服务的节点发送请求,等待接收对应的响应。
每个服务都专注于一个特定的请求和响应消息类型,通过服务提供者和请求者实现节点之间的双向通信。下面是一个使用Python语言提供和请求服务的示例:
```python
import rospy
from my_package.srv import MyService, MyServiceResponse
# 回调函数,处理请求并返回响应
def handle_request(req):
rospy.loginfo("Received request: %s", req.data)
# 处理请求并返回响应
response = MyServiceResponse()
response.result = req.data.upper()
return response
# 创建节点
rospy.init_node('my_node', anonymous=True)
# 创建服务提供者,提供指定服务
rospy.Service('my_service', MyService, handle_request)
# 创建服务请求者,请求指定服务
rospy.wait_for_service('my_service')
my_service = rospy.ServiceProxy('my_service', MyService)
response = my_service("Hello, ROS!")
rospy.loginfo("Received response: %s", response.result)
```
### 2.5 动作(Actions)
动作是ROS中一种用于执行长时间任务的通信机制,与服务类似,但可以返回中间结果和进度反馈。一个节点可以作为动作服务器,提供一个或多个动作,而其他节点可以作为动作客户端,发送请求并等待接收响应。
每个动作都由三部分组成:目标(Goal)、反馈(Feedback)和结果(Result)。通过动作服务器和客户端实现节点之间的高级交互。下面是一个使用Python语言创建动作服务器和客户端的示例:
```python
import rospy
import actionlib
from my_package.msg import MyAction, MyActionGoal, MyActionFeedback, MyActionResult
# 回调函数,处理接收到的目标请求
def handle_goal(goal):
rospy.loginfo("Received goal: %s", goal)
# 发布进度反馈
feedback = MyActionFeedback()
feedback.progress = 0.0
server.publish_feedback(feedback)
# 执行任务,并根据进度反馈更新进度
for i in range(10):
# 模拟任务执行
rospy.sleep(1.0)
# 更新进度反馈
feedback.progress = (i + 1) / 10.0
server.publish_feedback(feedback)
# 返回任务结果
result = MyActionResult()
result.result = "Task completed successfully"
server.set_succeeded(result)
# 创建节点
rospy.init_node('my_node', anonymous=True)
# 创建动作服务器,提供指定动作
server = actionlib.SimpleActionServer('my_action', MyAction, handle_goal, False)
server.start()
# 创建动作客户端,请求指定动作
client = actionlib.SimpleActionClient('my_action', MyAction)
client.wait_for_server()
# 创建目标请求
goal = MyActionGoal()
goal.goal = "Perform task"
# 发送目标请求并等待结果
client.send_goal(goal)
client.wait_for_result()
rospy.loginfo("Received result: %s", client.get_result())
```
以上是关于ROS基础概念的介绍,包括节点、主题、消息、服务和动作的概念和使用示例。通过了解这些基本概念,读者可以更好地理解和使用ROS机器人框架。接下来,我们将介绍ROS机器人的核心组件。
# 3. ROS机器人的核心组件
在ROS中,有一些核心的组件是构成一个完整的ROS系统所必需的。了解这些核心组件的功能和作用,对于使用和开发ROS机器人系统非常重要。
#### 3.1 ROS核心(ROS Core)
ROS核心是ROS系统的核心进程,它负责管理ROS系统中的各个节点之间的通信和协调。它提供了一个中央的消息总线,使得节点之间可以通过发布-订阅模式进行数据交流。 ROS核心需要在启动ROS系统时运行,它会创建和管理ROS系统中的其他组件。
#### 3.2 节点管理器(Node Manager)
在ROS中,节点是最基本的运行单元,执行特定的功能。节点管理器负责管理和监控这些节点的创建、销毁和通信。它可以帮助节点之间进行数据交换,发布和接收消息。节点管理器还可以让用户了解当前正在运行的节点以及它们的状态。
#### 3.3 主题发布者与订阅者(Publishers and Subscribers)
主题是ROS中最常用的通信机制之一,它是一种将数据发布给其他节点的方式。发布者负责向主题发布数据,而订阅者则可以监听这些主题并接收数据。主题发布者和订阅者之间的通信是异步的,也就是说,发布者不需要等待订阅者接收数据,而是通过消息队列进行传输。
以下是一个简单的Python代码示例,演示如何创建一个主题发布者和一个主题订阅者。
```python
#!/usr/bin/env python
import rospy
from std_msgs.msg import String
def publisher():
pub = rospy.Publisher('topic_name', String, queue_size=10)
rospy.init_node('publisher_node', anonymous=True)
rate = rospy.Rate(10) # 指定发布频率为10Hz
while not rospy.is_shutdown():
msg = "Hello, ROS!"
rospy.loginfo(msg)
pub.publish(msg)
rate.sleep()
def subscriber():
rospy.init_node('subscriber_node', anonymous=True)
rospy.Subscriber('topic_name', String, callback)
rospy.spin()
def callback(msg):
rospy.loginfo("Received message: %s", msg.data)
if __name__ == '__main__':
try:
publisher()
subscriber()
except rospy.ROSInterruptException:
pass
```
在上面的示例中,publisher函数创建了一个发布者,并将数据发布到名为“topic_name”的主题上。subscriber函数创建了一个订阅者,并订阅了相同的主题。callback函数定义了当收到消息时的回调函数,用于处理接收到的数据。
#### 3.4 服务提供者与请求者(Service Providers and Clients)
除了通过发布-订阅模式进行数据交流外,ROS还提供了另一种通信机制,即服务。服务是一种点对点的通信方式,其中一个节点提供服务,而另一个节点发起请求并等待响应。
服务提供者负责注册和提供服务,而服务请求者则可以请求并接收服务。服务是一种同步通信方式,服务请求者需要等待服务提供者的响应才能继续执行。
以下是一个简单的Python代码示例,演示如何创建一个服务提供者和一个服务请求者。
```python
#!/usr/bin/env python
import rospy
from beginner_tutorials.srv import AddTwoInts, AddTwoIntsResponse
def add_two_ints(req):
rospy.loginfo("Received request to add %s and %s", req.a, req.b)
result = req.a + req.b
rospy.loginfo("Returning result: %s", result)
return AddTwoIntsResponse(result)
def server():
rospy.init_node('server_node')
s = rospy.Service('add_two_ints', AddTwoInts, add_two_ints)
rospy.loginfo("Service is ready to receive requests.")
rospy.spin()
def client():
rospy.wait_for_service('add_two_ints')
try:
add_two_ints = rospy.ServiceProxy('add_two_ints', AddTwoInts)
req = AddTwoIntsRequest()
req.a = 10
req.b = 5
result = add_two_ints(req)
rospy.loginfo("Result received: %s", result.sum)
except rospy.ServiceException as e:
rospy.loginfo("Service call failed: %s", e)
if __name__ == '__main__':
try:
server()
client()
except rospy.ROSInterruptException:
pass
```
在上面的示例中,server函数创建了一个服务提供者,并将服务注册为名为“add_two_ints”的服务。add_two_ints函数定义了如何处理收到的请求,并返回相应的结果。
client函数创建了一个服务请求者,并等待服务“add_two_ints”可用后,调用该服务并传递请求参数。最后,客户端将收到由服务提供者返回的结果。
#### 3.5 动作服务器与客户端(Action Servers and Clients)
动作是ROS中一种更高级的通信机制,它与服务类似,但可以处理长时间运行的任务。动作服务器负责执行任务,并报告任务的进度和状态。动作客户端可以发送请求并接收任务的进度和结果。
动作通信是基于发布-订阅和服务通信的组合模式。动作服务器通过发布主题来报告任务的进度和状态,而动作客户端则通过服务调用来发送请求和接收结果。
了解这些核心组件是使用和开发ROS机器人系统的关键所在。它们提供了一个灵活且强大的框架,用于构建复杂的机器人应用程序。在接下来的章节中,我们将深入探讨ROS机器人的通信、开发环境和进阶概念。
# 4. ROS机器人的通信
在ROS机器人系统中,通信是非常重要的一部分,它使得不同的组件能够相互交流和协作。在这一章节中,我们将介绍ROS机器人系统中的通信机制,包括单播通信、多播通信、参数服务器以及消息传输和序列化。
#### 4.1 单播通信
在ROS中,单播通信是指一对一的通信方式,常见的形式包括节点之间的消息发布和订阅、服务的请求和响应等。例如,一个节点可以发布一个主题,而另一个节点可以订阅该主题来接收消息。
下面是一个简单的Python代码示例,演示了如何创建一个发布者节点和一个订阅者节点来进行单播通信。
```python
# Publisher Node
import rospy
from std_msgs.msg import String
rospy.init_node('publisher_node')
pub = rospy.Publisher('hello_topic', String, queue_size=10)
rate = rospy.Rate(1)
while not rospy.is_shutdown():
hello_str = "Hello, ROS!"
pub.publish(hello_str)
rate.sleep()
```
```python
# Subscriber Node
import rospy
from std_msgs.msg import String
def callback(data):
rospy.loginfo("Received: %s", data.data)
rospy.init_node('subscriber_node')
rospy.Subscriber('hello_topic', String, callback)
rospy.spin()
```
以上代码中,发布者节点创建了一个名为 `hello_topic` 的主题,并以每秒1次的频率向主题发布消息。订阅者节点订阅了 `hello_topic` 主题,并在接收到消息时打印出来。
#### 4.2 多播通信
与单播通信相反,多播通信是指一对多的通信方式,常见的形式包括节点之间的消息广播、参数服务器的多节点访问等。例如,一个节点可以向多个订阅者同时广播消息,或者多个节点可以同时访问参数服务器。
#### 4.3 参数服务器(Parameter Server)
ROS中的参数服务器是用来存储全局变量和配置参数的分布式键值对数据库,它可以被多个节点同时访问和修改。通过参数服务器,节点可以动态地获取和设置参数,实现了节点间通信和协作。
下面是一个简单的Python代码示例,演示了如何使用参数服务器来设置和获取参数。
```python
import rospy
# 设置参数
rospy.set_param('/robot_speed', 0.5)
# 获取参数
speed = rospy.get_param('/robot_speed')
rospy.loginfo("Robot speed: %f", speed)
```
#### 4.4 消息传输和序列化
在ROS中,消息是节点之间进行通信的基本数据单元,它们通过ROS提供的序列化机制进行传输。消息的序列化和反序列化对于通信的高效性和可靠性非常重要。
在ROS中,使用消息的方式很简单,直接调用消息类型的构造函数来创建消息对象,然后通过发布者发布消息,订阅者接收消息即可。
以上就是ROS机器人系统中通信的基本概念和机制,包括单播通信、多播通信、参数服务器以及消息传输和序列化。这些通信机制使得ROS系统能够实现模块化、松耦合的节点间交互,为复杂机器人系统的开发和控制提供了便利。
# 5. ROS机器人的开发环境与工具
在本章中,我们将介绍ROS机器人的开发环境和相关工具。这些工具将帮助开发者更高效地使用ROS进行机器人应用程序的开发和调试。
#### 5.1 ROS安装与配置
要开始使用ROS机器人,首先需要安装并配置ROS开发环境。以下步骤适用于Ubuntu操作系统:
1. 首先,打开终端并执行以下命令以添加ROS存储库到系统中:
```
$ sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
```
2. 接下来,添加ROS GPG密钥以验证软件包的完整性:
```
$ sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654
```
3. 在完成以上步骤后,更新系统的软件包索引:
```
$ sudo apt-get update
```
4. 安装完整版的ROS(包括ROS核心、工具和库):
```
$ sudo apt-get install ros-melodic-desktop-full
```
5. 在安装过程中,您将被要求设置ROS初始化(即设置ROS环境变量)。请按照提示进行操作。
6. 最后,通过运行以下命令来检查ROS安装是否成功:
```
$ roscore
```
如果ROS核心成功启动,说明安装和配置已成功完成。
#### 5.2 ROS开发语言
ROS支持多种编程语言,包括Python、C++、Java等。您可以根据自己的编程需求选择合适的语言进行ROS开发。
在本节中,我们将以Python为例进行介绍。以下是一个简单的Python程序,演示如何创建一个ROS节点并发布一个字符串消息:
```python
#!/usr/bin/env python
import rospy
from std_msgs.msg import String
def talker():
pub = rospy.Publisher('chatter', String, queue_size=10)
rospy.init_node('talker', anonymous=True)
rate = rospy.Rate(10) # 10hz
while not rospy.is_shutdown():
hello_str = "Hello ROS! %s" % rospy.get_time()
rospy.loginfo(hello_str)
pub.publish(hello_str)
rate.sleep()
if __name__ == '__main__':
try:
talker()
except rospy.ROSInterruptException:
pass
```
在上述代码中,我们首先导入了必要的ROS模块、消息类型和函数。然后,我们定义了一个名为`talker`的函数,该函数创建了一个ROS节点,并发布一个名为`chatter`的主题。
我们还定义了一个循环,每秒钟发布一次包含当前时间戳的字符串消息。最后,我们使用`try...except`结构保证节点在收到终止信号时能够正常退出。
#### 代码总结:
- 导入必要的ROS模块和消息类型。
- 定义一个函数用于发布消息。
- 初始化ROS节点,并创建一个主题发布者。
- 在循环中发布消息,并控制发布频率。
- 处理终止信号,确保节点能够正常退出。
#### 结果说明:
运行上述Python程序后,将在终端显示类似以下内容的消息:
```
Hello ROS! 1593427937.087123
Hello ROS! 1593427937.187456
Hello ROS! 1593427937.287789
```
这表示ROS节点成功发布了包含时间戳的字符串消息。
#### 5.3 ROS开发工具
为了更方便地开发和调试ROS机器人应用程序,ROS提供了一些非常有用的开发工具。
- **rospy**:这是ROS的Python库,用于编写ROS节点和处理ROS消息。
- **roscpp**:这是ROS的C++库,类似于rospy,用于C++开发。
- **rqt**:这是ROS的图形用户界面(GUI)工具,用于可视化和调试ROS系统。
- **rviz**:这是ROS的3D可视化工具,用于可视化机器人模型、传感器数据和其他信息。
- **rosbag**:这是ROS的数据记录和回放工具,用于记录和回放ROS主题和消息。
- **rosrun**:这是一个命令行工具,用于运行ROS节点和执行ROS程序。
这些工具对于ROS机器人应用程序的开发和调试非常重要,在后续的开发过程中将会经常用到。
#### 5.4 ROS软件包(Packages)的使用与管理
ROS使用软件包(Packages)来组织和管理代码、数据和依赖项。一个ROS软件包包含了一个或多个节点、主题、服务、动作等。
要使用和管理ROS软件包,可以按照以下步骤进行操作:
1. 创建一个新的ROS软件包:
```
$ catkin_create_pkg my_package std_msgs rospy roscpp
```
在上述命令中,`my_package`是软件包的名称,`std_msgs`、`rospy`和`roscpp`是该软件包的依赖项。
2. 在软件包目录下创建节点、服务、主题等所需的文件。
3. 构建ROS软件包:
```
$ cd ~/catkin_ws
$ catkin_make
```
在上述命令中,`~/catkin_ws`是ROS工作空间的路径。
4. 激活ROS软件包:
```
$ source ~/catkin_ws/devel/setup.bash
```
运行以上命令后,您就可以使用和调试ROS软件包了。
#### 5.5 ROS编程实例
现在,让我们来看一个完整的ROS编程实例,以便更好地理解ROS机器人的开发过程。
以下是一个基于ROS的小乌龟图形界面(GUI)应用程序的示例,使用了Python和turtle模块:
```python
#!/usr/bin/env python
import rospy
from std_msgs.msg import String
import turtle
def callback(data):
turtle.goto(10*float(data.data), 0)
def listener():
rospy.init_node('listener', anonymous=True)
rospy.Subscriber('chatter', String, callback)
turtle.mainloop()
if __name__ == '__main__':
listener()
```
在上述代码中,我们首先导入必要的ROS模块、消息类型和函数,以及turtle模块用于图形界面的绘制。
然后,我们定义了一个回调函数`callback`,当接收到`chatter`主题的消息时,会调用此函数,并根据接收到的消息数据移动小乌龟的位置。
最后,我们初始化ROS节点,并创建一个ROS监听器,用于接收`chatter`主题的消息,并将其传递给回调函数。最后,通过调用`turtle.mainloop()`来启动图形界面。
这是一个简单的例子,演示了如何使用ROS和turtle模块创建一个小乌龟图形界面应用程序。您可以根据需要进行扩展和修改。
以上是ROS机器人的开发环境与工具的基本介绍和示例代码。通过正确安装和配置ROS,选择合适的开发语言,使用相关工具和软件包,您将能够开始开发和调试自己的ROS机器人应用程序。
# 6. ROS机器人的进阶概念
## 6.1 ROS调试与测试
在ROS机器人的开发过程中,调试和测试是非常重要的环节。ROS提供了丰富的工具和方法来帮助开发者进行调试和测试。
### 6.1.1 ROS调试工具
#### 1. roscore
roscore是ROS的核心组件,负责启动ROS Master以及ROS参数服务器。在进行调试时,可以通过运行roscore命令来启动roscore,如果发现有任何与ROS Master或参数服务器相关的问题,可以通过查看roscore的输出信息来进行排查。
#### 2. rostopic
rostopic是一个用于查看和调试ROS主题的命令行工具。可以使用rostopic命令来查看主题的信息、发布的消息以及订阅者的数量。例如,可以使用rostopic list命令来列出当前所有的主题,使用rostopic echo命令来监听并显示某个主题的消息内容。
```python
# 示例代码:使用rostopic命令查看主题的信息
rosrun turtlesim turtlesim_node # 先启动turtlesim节点
rostopic list # 列出所有主题
rostopic echo /turtle1/cmd_vel # 监听并显示/turtle1/cmd_vel主题的消息内容
```
#### 3. rqt
rqt是ROS图形化工具集合,提供了各种GUI工具用于调试和可视化ROS机器人的各个方面。例如,rqt_graph可以用来查看当前ROS系统的节点和主题之间的关系图,rqt_plot可以绘制和查看主题的数据曲线图,rqt_console可以查看ROS日志消息等。
```python
# 示例代码:使用rqt_graph查看当前ROS系统的节点和主题关系图
rosrun turtlesim turtlesim_node # 先启动turtlesim节点
rosrun turtlesim turtle_teleop_key # 启动键盘控制节点
rqt_graph # 打开rqt_graph查看节点和主题之间的关系图
```
### 6.1.2 ROS测试框架
#### 1. rostest
rostest是ROS自带的测试框架,可以用来对ROS系统进行单元测试和集成测试。通过编写测试脚本和测试文件,可以模拟和验证系统的行为,并进行自动化测试。
```python
# 示例代码:编写一个roslaunch文件进行测试
<launch>
<test test-name="my_test" pkg="my_package" type="my_test.py" />
</launch>
# 示例代码:编写一个Python测试脚本
import unittest
class MyTest(unittest.TestCase):
def test_example(self):
self.assertEqual(1 + 1, 2)
if __name__ == '__main__':
import rostest
rostest.rosrun('my_package', 'my_test', MyTest)
```
#### 2.rosbag
rosbag是一个用于记录和回放ROS主题数据的工具。可以将ROS主题的消息记录到一个rosbag文件中,并在之后进行回放以进行离线调试和测试。
```python
# 示例代码:使用rosbag记录和回放主题数据
rosbag record -a # 记录所有主题
rosbag play my_bag.bag # 回放rosbag文件
# 示例代码:编写Python脚本读取rosbag文件
import rosbag
bag = rosbag.Bag('my_bag.bag')
for topic, msg, t in bag.read_messages():
print(topic, msg, t)
bag.close()
```
## 6.2 ROS中的并行与多线程
在ROS机器人的开发中,经常需要处理多个独立的任务和问题。为了提高效率和性能,ROS提供了并行执行和多线程的支持。
### 6.2.1 ROS节点的并行执行
在ROS中,可以同时运行多个节点,并且节点之间可以相互通信和协作。通过将不同的功能模块封装为独立的节点,可以实现并行执行和分布式计算。
### 6.2.2 ROS的多线程编程
在ROS节点的编程中,可以使用多线程来处理复杂的任务和并发操作。通过创建多个线程并让它们同时运行,可以提高系统的响应性能和并行处理能力。
```python
# 示例代码:创建一个多线程节点
import rospy
import threading
def worker():
while not rospy.is_shutdown():
# 执行任务
pass
if __name__ == '__main__':
rospy.init_node('my_node')
# 创建线程并启动
thread = threading.Thread(target=worker)
thread.start()
rospy.spin() # 运行节点的主循环,监听输入和退出信号
```
0
0