Linux-ROS学习之旅-话题编程(二)

##承接上一篇文章的知识,有下面的实例操作

通过代码新生一个海龟,放置在(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 ~//src//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

如果成功的话,会有下面的情形:

Linux-ROS学习之旅-话题编程(二)_第1张图片

来自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),则安静地退出程序。

你可能感兴趣的:(ROS,ubuntu)