工作空间和功能包 工作空间 主要结构 1.代码空间src 2.编译空间build 3.开发空间devel 4.安装空间install
基本操作 1 2 3 4 5 6 7 8 9 10 11 12 #创建代码空间 mkdir src #进入代码空间 cd src #创建工作空间 catkin_init_workspace #回到上一级 cd .. #编译 catkin_make #生成install空间 catkin_make install
环境变量 1 2 3 4 #设置环境变量 source devel/setup.bash #检查环境变量 echo $ROS_PACKAGE_PATH
如果不想每次设置也可以修改/home/triority
内的文件.bashrc
, 在source /opt/ros/melodic/setup.bash
下一行加入:source /home/triority/桌面/ROS_learning/devel/setup.bash
创建功能包 在src
文件夹内:
1 catkin_create_pkg <包名> <依赖>
1 2 #创建依赖roscpp[用于编写c++程序],rospy[用于编写python程序],std_msgs[ros标准消息结构]等依赖的的一个名为learning的功能包[应创建在src文件夹内] catkin_create_pkg learning roscpp rospy std_msgs geometry_msgs turtlesim message_generation
话题:发布与订阅 Publisher 功能包代码 在learning功能包内新建scripts
文件夹,创建python文件: 代码来自古月居 velocity_publisher.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 import rospyfrom geometry_msgs.msg import Twistdef velocity_publisher (): rospy.init_node('velocity_publisher' , anonymous=True ) turtle_vel_pub = rospy.Publisher('/turtle1/cmd_vel' , Twist, queue_size=10 ) rate = rospy.Rate(10 ) while not rospy.is_shutdown(): vel_msg = Twist() vel_msg.linear.x = 0.5 vel_msg.angular.z = 0.2 turtle_vel_pub.publish(vel_msg) rospy.loginfo("Publsh turtle velocity command[%0.2f m/s, %0.2f rad/s]" , vel_msg.linear.x, vel_msg.angular.z) rate.sleep() if __name__ == '__main__' : try : velocity_publisher() except rospy.ROSInterruptException: pass
执行 启动ROS Master
打开海龟仿真器
1 rosrun turtlesim turtlesim_node
启动publisher
1 rosrun learning velocity_publisher.py
然后就能看见海龟开始做圆周运动。
Subscriber 功能包代码 在scripts
文件夹内,创建python文件: 代码来自古月居 pose_subscriber.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 import rospyfrom turtlesim.msg import Posedef poseCallback (msg ): rospy.loginfo("Turtle pose: x:%0.6f, y:%0.6f" , msg.x, msg.y) def pose_subscriber (): rospy.init_node('pose_subscriber' , anonymous=True ) rospy.Subscriber("/turtle1/pose" , Pose, poseCallback) rospy.spin() if __name__ == '__main__' : pose_subscriber()
执行 启动ROS Master
打开海龟仿真器
1 rosrun turtlesim turtlesim_node
启动publisher
1 rosrun learning velocity_publisher.py
启动Subscriber
1 rosrun learning pose_subscriber.py
即可看到海龟的实时坐标
自定义话题消息 消息定义 在功能包文件夹内创建msg文件夹,并新建Person.msg文件,在里面写入
1 2 3 4 5 6 7 string name uint8 age uint8 sex uint8 unknown = 0 uint8 male = 1 uint8 female = 2
添加依赖 在package.xml
文件内添加依赖:
1 2 <build_depend>message_generation</build_depend> <exec_depend>message_runtime</exec_depend>
在CMakeLists.txt
内加入:
1 2 3 4 5 6 7 8 9 add_message_files( FILES Person.msg ) generate_messages( DEPENDENCIES std_msgs )
并把
1 # CATKIN_DEPENDS geometry_msgs roscpp rospy std_msgs turtlesim
改为
1 CATKIN_DEPENDS geometry_msgs roscpp rospy std_msgs turtlesim message_runtime
实验程序 在功能包scripts
文件夹内创建: person_publisher.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 #!/usr/bin/env python # -*- coding: utf-8 -*- ######################################################################## #### Copyright 2020 GuYueHome (www.guyuehome.com). ### ######################################################################## # 该例程将发布/person_info话题,自定义消息类型learning_topic::Person import rospy from learning.msg import Person def velocity_publisher(): # ROS节点初始化 rospy.init_node('person_publisher', anonymous=True) # 创建一个Publisher,发布名为/person_info的topic,消息类型为learning_topic::Person,队列长度10 person_info_pub = rospy.Publisher('/person_info', Person, queue_size=10) #设置循环的频率 rate = rospy.Rate(10) while not rospy.is_shutdown(): # 初始化learning_topic::Person类型的消息 person_msg = Person() person_msg.name = "Tom"; person_msg.age = 18; person_msg.sex = Person.male; # 发布消息 person_info_pub.publish(person_msg) rospy.loginfo("Publsh person message[%s, %d, %d]", person_msg.name, person_msg.age, person_msg.sex) # 按照循环频率延时 rate.sleep() if __name__ == '__main__': try: velocity_publisher() except rospy.ROSInterruptException: pass
person_subscriber.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 #!/usr/bin/env python # -*- coding: utf-8 -*- ######################################################################## #### Copyright 2020 GuYueHome (www.guyuehome.com). ### ######################################################################## # 该例程将订阅/person_info话题,自定义消息类型learning_topic::Person import rospy from learning.msg import Person def personInfoCallback(msg): rospy.loginfo("Subcribe Person Info: name:%s age:%d sex:%d", msg.name, msg.age, msg.sex) def person_subscriber(): # ROS节点初始化 rospy.init_node('person_subscriber', anonymous=True) # 创建一个Subscriber,订阅名为/person_info的topic,注册回调函数personInfoCallback rospy.Subscriber("/person_info", Person, personInfoCallback) # 循环等待回调函数 rospy.spin() if __name__ == '__main__': person_subscriber()
分别启动后即可看见收发的文件
服务:服务端与客户端 Client 功能包代码 person_client.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 import sysimport rospyfrom learning_service.srv import Person, PersonRequestdef person_client (): rospy.init_node('person_client' ) rospy.wait_for_service('/show_person' ) try : person_client = rospy.ServiceProxy('/show_person' , Person) response = person_client("Tom" , 20 , PersonRequest.male) return response.result except rospy.ServiceException, e: print "Service call failed: %s" %e if __name__ == "__main__" : print "Show person result : %s" %(person_client())
执行 1.打开ros master
2.启动海龟仿真器
1 rosrun turtlesim turtlesim_node
3.启动程序
1 rosrun learning turtle_spawn.py
即可看到产生了一个新的海龟
Server 功能包代码 person_server.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 import rospyfrom learning_service.srv import Person, PersonResponsedef personCallback (req ): rospy.loginfo("Person: name:%s age:%d sex:%d" , req.name, req.age, req.sex) return PersonResponse("OK" ) def person_server (): rospy.init_node('person_server' ) s = rospy.Service('/show_person' , Person, personCallback) print "Ready to show person informtion." rospy.spin() if __name__ == "__main__" : person_server()
执行 1.打开ros master
2.启动海龟仿真器
1 rosrun turtlesim turtlesim_node
3.启动程序
1 rosrun learning turtle_command_server.py
4.发布信息
1 rosservice call /turtle_command "{}"
发送即可看到海龟开始运动,再次发布即停止
查看服务数据定义
返回内容---
之上为request,之下为responce
自定义服务数据 服务数据定义 新建srv文件夹并写入Person.srv
1 2 3 4 5 6 7 8 9 10 string name uint8 age uint8 sex uint8 unknown = 0 uint8 male = 1 uint8 female = 2 --- string result
添加依赖 在package.xml
添加:
1 2 <build_depend>message_generation</build_depend> <exec_depend>message_runtime</exec_depend>
在CMakeList.txt
添加:
1 2 3 4 5 6 7 8 9 add_service_files( FILES Person.srv ) generate_messages( DEPENDENCIES std_msgs )
实验程序 person_server.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #!/usr/bin/env python # -*- coding: utf-8 -*- ######################################################################## #### Copyright 2020 GuYueHome (www.guyuehome.com). ### ######################################################################## # 该例程将执行/show_person服务,服务数据类型learning_service::Person import rospy from learning.srv import Person, PersonResponse def personCallback(req): # 显示请求数据 rospy.loginfo("Person: name:%s age:%d sex:%d", req.name, req.age, req.sex) # 反馈数据 return PersonResponse("OK") def person_server(): # ROS节点初始化 rospy.init_node('person_server') # 创建一个名为/show_person的server,注册回调函数personCallback s = rospy.Service('/show_person', Person, personCallback) # 循环等待回调函数 print "Ready to show person informtion." rospy.spin() if __name__ == "__main__": person_server()
person_client.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 #!/usr/bin/env python # -*- coding: utf-8 -*- ######################################################################## #### Copyright 2020 GuYueHome (www.guyuehome.com). ### ######################################################################## # 该例程将请求/show_person服务,服务数据类型learning_service::Person import sys import rospy from learning.srv import Person, PersonRequest def person_client(): # ROS节点初始化 rospy.init_node('person_client') # 发现/spawn服务后,创建一个服务客户端,连接名为/spawn的service rospy.wait_for_service('/show_person') try: person_client = rospy.ServiceProxy('/show_person', Person) # 请求服务调用,输入请求数据 response = person_client("Tom", 20, PersonRequest.male) return response.result except rospy.ServiceException, e: print "Service call failed: %s"%e if __name__ == "__main__": #服务调用并显示调用结果 print "Show person result : %s" %(person_client())
执行 1.ros master
2.服务端
1 rosrun learning person_server.py
3.客户端
1 rosrun learning person_client.py
即可看到客户端与服务端相互通信
参数:全局字典 命令行的使用 1.列出参数
2.获取参数值
3.修改参数
4.保存参数为文件
5.从文件加载参数
6.删除参数
1 rosparam delete xxx.yaml
用python程序对参数操作 parameter_config.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 import sysimport rospyfrom std_srvs.srv import Emptydef parameter_config (): rospy.init_node('parameter_config' , anonymous=True ) red = rospy.get_param('/turtlesim/background_r' ) green = rospy.get_param('/turtlesim/background_g' ) blue = rospy.get_param('/turtlesim/background_b' ) rospy.loginfo("Get Backgroud Color[%d, %d, %d]" , red, green, blue) rospy.set_param("/turtlesim/background_r" , 255 ); rospy.set_param("/turtlesim/background_g" , 255 ); rospy.set_param("/turtlesim/background_b" , 255 ); rospy.loginfo("Set Backgroud Color[255, 255, 255]" ); red = rospy.get_param('/turtlesim/background_r' ) green = rospy.get_param('/turtlesim/background_g' ) blue = rospy.get_param('/turtlesim/background_b' ) rospy.loginfo("Get Backgroud Color[%d, %d, %d]" , red, green, blue) rospy.wait_for_service('/clear' ) try : clear_background = rospy.ServiceProxy('/clear' , Empty) response = clear_background() return response except rospy.ServiceException, e: print "Service call failed: %s" %e if __name__ == "__main__" : parameter_config()
launch 文件语法 根元素 用<launch>
标签定义 以</launch>
结尾
启动节点 <node pkg="package_name" name="executable_name" name="node_name" />
pkg:节点所在功能包名称 type:可执行文件名称 name:节点运行时名称 output,respawn,……参数
添加参数 <param name="output_frame value="pdom" />
name:参数名 value:参数值 还有<ary>
添加参数,仅供launch内部使用
重映射(重命名) <remap from="/a/b" to="/c" />
from:原名称 to:映射后的命名
嵌套 包含其他launch文件<include file="path">
file:其他launch文件路径
实例
1 2 3 4 <launch > <node pkg ="learning_topic" type ="person_subscriber" name ="talker" output ="screen" /> <node pkg ="learning_topic" type ="person_publisher" name ="listener" output ="screen" /> </launch >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <launch > <node pkg ="turtlesim" type ="turtlesim_node" name ="sim" /> <node pkg ="turtlesim" type ="turtle_teleop_key" name ="teleop" output ="screen" /> <node name ="turtle1_tf_broadcaster" pkg ="learning_tf" type ="turtle_tf_broadcaster.py" > <param name ="turtle" type ="string" value ="turtle1" /> </node > <node name ="turtle2_tf_broadcaster" pkg ="learning_tf" type ="turtle_tf_broadcaster.py" > <param name ="turtle" type ="string" value ="turtle2" /> </node > <node pkg ="learning_tf" type ="turtle_tf_listener.py" name ="listener" /> </launch >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <launch > <param name ="/turtle_number" value ="2" /> <node pkg ="turtlesim" type ="turtlesim_node" name ="turtlesim_node" > <param name ="turtle_name1" value ="Tom" /> <param name ="turtle_name2" value ="Jerry" /> <rosparam file ="$(find learning_launch)/config/param.yaml" command ="load" /> </node > <node pkg ="turtlesim" type ="turtle_teleop_key" name ="turtle_teleop_key" output ="screen" /> </launch >
1 2 3 4 5 6 7 8 9 <launch > <include file ="$(find learning_launch)/launch/simple.launch" /> <node pkg ="turtlesim" type ="turtlesim_node" name ="turtlesim_node" > <remap from ="/turtle1/cmd_vel" to ="/cmd_vel" /> </node > </launch >
ROS命令行工具 ROS Master 1.启动ROS Master
信息查询 2.可视化查看节点关系
3.查看节点信息rosnode
1 2 3 4 5 6 7 #查看全部节点 rosnode list #查看节点详细信息 rosnode info <节点名> #......
4.查看话题rostopic
1 2 3 4 5 6 7 8 9 #打印话题列表 rostopic list #给话题发布数据 rostopic pub <话题名> <数据内容> ##数据内容可用两次tab补全默认格式 ##可加参数 -r <频率(Hz)> 来连续发布 #......
5.查看消息rosmsg
1 2 3 4 #查看消息数据结构 rosmsg show <话题名> #......
6.查看服务rosservice
1 2 3 4 5 6 7 #查看所有服务 rosservice list #发布服务请求 rosservice call <服务名> #......
信息记录 7.记录工具 1 2 3 4 5 6 #记录话题数据 rosbag record -a -O <压缩数据包名> ##其中-a表示all保存全部数据,-O表示保存成压缩包 #复现话题数据 rosbag paly <复现文件名>
常用工具 rqt 日志输出工具rqt_console
计算图可视化工具rqt_graph
数据绘图工具rqt_plot
图像渲染工具rqt_image_view
rviz,gazebo emmm可能以后再讲吧