← 算法与课程

实验1:ROS入门

Jiangshan He · 算法与课程 · 阅读与实践记录

本教程中我们将会用到ros-tutorials程序包,请先在命令行输入以下命令进行安装:

sudo apt-get install ros-kinetic-ros-tutorials

image.png

rospack

image.png

rosed

使用指令

$ rosed roscpp Logger.msg

image.png

使用 rqt_console 和 roslaunch

安装rqt 和 turtlesim这两个程序包

$ sudo apt-get install ros-kinetic-rqt ros-kinetic-rqt-common-plugins ros-kinetic-turtlesim

使用rqt_console和rqt_logger_level

roscore

image.png|425

rqt

image.png|325

rqt_logger_level

image.png|375

turtlesim

image.png|450

在rqt_console可以看到turtlesim节点的输出信息 image.png|500

将等级修改为warn后,在新终端运行新指令

$ rostopic pub /turtle1/cmd_vel geometry_msgs/Twist -r 1 -- '[2.0, 0.0, 0.0]' '[0.0, 0.0, 0.0]'
![image.png 650](https://cdn.jsdelivr.net/gh/Thomas333333/MyPostImage/Images/20230912152814.png)

使用roslaunch

  • 创建程序包
    cd ~/catkin_ws/src
    catkin_create_pkg beginner_tutorials std_msgs rospy roscpp
    
  • cd切换到新创建的程序包下
  • 再创建一个luanch文件夹 image.png
  • 创建一个名为turtlemimic.launch的launch文件并复制以下内容
    • ns是命名,都使用同一个包turtlesim
    • 启动模仿节点,使turtlesim2模仿turtlesim1 ```xml
+  启动launch文件
```bash
$ roslaunch beginner_tutorials turtlemimic.launch

image.png

  • 然后我们让turtlesim1运行,会发现turtlesim2也会运行
    $ rostopic pub /turtlesim1/turtle1/cmd_vel geometry_msgs/Twist -r 1 -- '[2.0, 0.0, 0.0]' '[0.0, 0.0, -1.8]'
    

    image.png

rqt

可以通过rqt来更好地理解launch文件,运行rqt_graph。

圆形的就是节点,/minic就是launch文件中新建的模仿节点,输入为turtlesim1的pose,输出为turtlesim2。 image.png

roswtf

安装检查(没有运行roscore)

image.png

启动roscore后检查

image.png

错误报告

  • 在ROS_PACKAGE_PATH 环境变量中设置一个 bad值
    • 显示bad不存在 image.png

ROS程序包

catkin_make

image.png|500

创建beginner_tutorials文件夹

image.png

查看程序包依赖关系

image.png

所有文件在运行前需要打开roscore

image.png

实验6

Num.msg

image.png

插入build_depend 和exec_depend

image.png

修改CMakeLists.txt

rosmsg show 显示消息

image.png

修改CMakeLists.txt

rossrv show 显示消息

image.png

image.png

利用catkin_make重新编译 image.png

编写简单的服务器和客户端

将代码写入scripts/add_two_ints_server.py image.png

#!/usr/bin/env python

from beginner_tutorials.srv import AddTwoInts,AddTwoIntsResponse
import rospy

def handle_add_two_ints(req):
    print "Returning [%s + %s = %s]"%(req.a, req.b, (req.a + req.b))
    return AddTwoIntsResponse(req.a + req.b)

def add_two_ints_server():
    rospy.init_node('add_two_ints_server')#声明节点
    s = rospy.Service('add_two_ints', AddTwoInts, handle_add_two_ints)#声明服务 服务类型:AddTwoInts
    print "Ready to add two ints."
    rospy.spin()#防止代码退出,直到服务关闭“

if __name__ == "__main__":
    add_two_ints_server()

编写client节点

image.png

#!/usr/bin/env python

import sys
import rospy
from beginner_tutorials.srv import *

def add_two_ints_client(x, y):
    rospy.wait_for_service('add_two_ints') #直到服务器端可用
    try:
        add_two_ints = rospy.ServiceProxy('add_two_ints', AddTwoInts)
        resp1 = add_two_ints(x, y)
        return resp1.sum
    except rospy.ServiceException, e:
        print "Service call failed: %s"%e

def usage():
    return "%s [x y]"%sys.argv[0]

if __name__ == "__main__":
    if len(sys.argv) == 3:
        x = int(sys.argv[1])
        y = int(sys.argv[2])
    else:
        print usage()
        sys.exit(1)
    print "Requesting %s+%s"%(x, y)
    print "%s + %s = %s"%(x, y, add_two_ints_client(x, y))

编译节点

image.png

对servicer和client进行测试

启动server image.png

启动client 并测试 image.png 其中server端返回 image.png

录制和回放数据

rosbag image.png 生成记录文件 image.png

rosbag info image.png

rosbag play xx 乌龟会在没有操控的情况下自动回放

![image.png 475](https://cdn.jsdelivr.net/gh/Thomas333333/MyPostImage/Images/20230919161636.png)

只录取指定内容

rosbag record -O subset /turtle1/cmd_vel /turtle1/pose

image.png

TurtleBot导航仿真

gazebo界面 image.png

rviz界面 image.png

控制机器人移动 jl分别是左右转向,,是前进,i是后退 image.png

保存地图 image.png

发布器和订阅器

发布器源代码

#!/usr/bin/env python
# license removed for brevity
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 创建一个Rate对象rate 每秒循环十次
    while not rospy.is_shutdown():
        hello_str = "hello world %s" % rospy.get_time()
        rospy.loginfo(hello_str) # 消息被打印到屏幕,它被写入节点的日志文件,并被写入rosout
        pub.publish(hello_str)
        rate.sleep()

if __name__ == '__main__':
    try:
        talker()
    except rospy.ROSInterruptException:
        pass

订阅器源代码

#!/usr/bin/env python
import rospy
from std_msgs.msg import String

def 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)
	#这声明你的节点订阅了类型为std_msgs.string的chatter主题。当接收到新消息时,将以消息作为第一个参数调用回调。
    rospy.spin()

if __name__ == '__main__':
    listener()

image.png

编写完代码后进行编译 image.png

测试发布器和订阅器

发布器 image.png

订阅器 image.png