##承接上一篇文章的知识,有下面的实例操作
通过代码新生一个海龟,放置在(5,5)点,命名为turtle2,通过代码订阅turtle2的实时位置并打印在终端,控制turtle2实现旋转运动
步骤:
1.创建一个工作空间和一个功能包,功能包的依赖有rospy turtlesim在功能包里面的src文件创建.py文件用于编写代码,代码如下
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import rospy
from turtlesim.srv import Spawn
from geometry_msgs.msg import Twist
from turtlesim.msg import Pose
def pose_callback(pose):
rospy.loginfo("Turtle2's position: x=%f, y=%f", pose.x, pose.y)
def turtle_mover():
rospy.init_node('turtle_mover', anonymous=True)
# 等待服务 /spawn
rospy.wait_for_service('/spawn')
try:
add_turtle = rospy.ServiceProxy('/spawn', Spawn)
# 在(5,5)创建一个新的turtle
resp = add_turtle(5.0, 5.0, 0, 'turtle2')
except rospy.ServiceException as e:
rospy.logerr("Service call failed: %s", e)
# 订阅turtle2的位置
rospy.Subscriber('/turtle2/pose', Pose, pose_callback)
# 发布turtle2的速度控制
pub = rospy.Publisher('/turtle2/cmd_vel', Twist, queue_size=10)
rate = rospy.Rate(10) # 10Hz
while not rospy.is_shutdown():
# 创建一个旋转的动作
twist = Twist()
twist.linear.x = 0
twist.angular.z = 1.0
pub.publish(twist)
rate.sleep()
if __name__ == '__main__':
try:
turtle_mover()
except rospy.ROSInterruptException:
pass
2.使脚本可执行
chmod +x ~/<workspace_name>/src/<pkg_name>/src/turtle_mover.py
这个很重要啊,当你运行rosrun命令提示找不到功能包时大概率就是因为这一步没有配置成功
3.构建和编译包
cd ~/catkin_ws
catkin_make
source devel/setup.bash
4.启动roscore
5.打开一个新终端,启动turtlesim
rosrun turtlesim turtlesim_node
6.运行脚本
rosrun turtle_control turtle_mover.py
如果成功的话,会有下面的情形:
来自GPT4的代码解释
当然,我会逐行解释您提供的代码。这是一个ROS(Robot Operating System)脚本,用于在`turtlesim`环境中创建并控制一个虚拟的海龟。
```python
#!/usr/bin/env python3
```
这是一个shebang行,告诉系统使用env程序来查找Python 3解释器的位置,从而运行这个脚本。它确保了脚本在不同的环境中可以找到正确的Python解释器。
```python
# -*- coding: utf-8 -*-
```
这行指定了文件的编码格式为UTF-8。这对于在脚本中包含非ASCII字符(如中文注释)是必要的。
```python
import rospy
```
导入`rospy`模块,这是ROS Python客户端库,用于编写ROS节点。
```python
from turtlesim.srv import Spawn
```
从`turtlesim`包导入`Spawn`服务类型。`Spawn`服务用于在`turtlesim`模拟器中创建新的海龟。
```python
from geometry_msgs.msg import Twist
```
从`geometry_msgs`包导入`Twist`消息类型。这种类型通常用于表示速度和旋转。
```python
from turtlesim.msg import Pose
```
从`turtlesim`包导入`Pose`消息类型。它包含了一个海龟的位置和方向信息。
```python
def pose_callback(pose):
rospy.loginfo("Turtle2's position: x=%f, y=%f", pose.x, pose.y)
```
定义了一个回调函数`pose_callback`,它将在每次收到`turtle2`的位置更新时被调用。它接收一个`Pose`消息作为参数,并打印海龟的位置。
```python
def turtle_mover():
```
定义了主要功能的函数`turtle_mover`。
```python
rospy.init_node('turtle_mover', anonymous=True)
```
初始化一个ROS节点,名为`turtle_mover`。`anonymous=True`意味着节点名称将被随机数修改,以确保唯一性。
```python
rospy.wait_for_service('/spawn')
```
在继续之前,等待`/spawn`服务变得可用。
```python
try:
add_turtle = rospy.ServiceProxy('/spawn', Spawn)
```
尝试创建一个服务代理`add_turtle`,用于调用`/spawn`服务,这个服务使用`Spawn`服务类型。
```python
resp = add_turtle(5.0, 5.0, 0, 'turtle2')
```
使用`/spawn`服务在坐标(5, 5)处创建一个新的海龟,命名为`turtle2`。
```python
except rospy.ServiceException as e:
rospy.logerr("Service call failed: %s", e)
```
如果在调用服务时出现异常,打印错误消息。
```python
rospy.Subscriber('/turtle2/pose', Pose, pose_callback)
```
创建一个订阅者,订阅`/turtle2/pose`主题,接收`Pose`消息,并指定`pose_callback`作为回调函数。
```python
pub = rospy.Publisher('/turtle2/cmd_vel', Twist, queue_size=10)
```
创建一个发布者`pub`,用于发布到`/turtle2/cmd_vel`主题,消息类型为`Twist`,用于控制海龟的移动。
```python
rate = rospy.Rate(10) # 10Hz
```
设置一个频率为10Hz的速率对象`rate`。
```python
while not rospy.is_shutdown():
```
在ROS没有关闭的情况下,循环执行以下代码块。
```python
twist = Twist()
twist.linear.x = 0
twist.angular.z = 1.0
pub.publish(twist)
```
创建一个`Twist`消息`twist`,设置线速度为0和角速度为1.0,然后发布这个消息到`/turtle2/cmd_vel`主题,使海龟旋转。
```python
rate.sleep()
```
在循环的每次迭代后休眠,以保持循环以10Hz
的频率运行。
```python
if __name__ == '__main__':
try:
turtle_mover()
except rospy.ROSInterruptException:
pass
```
当脚本被直接运行时,执行`turtle_mover()`函数。如果在运行过程中遇到`rospy.ROSInterruptException`(例如,用户按Ctrl+C),则安静地退出程序。