参考资料:python
https://www.icourse163.org/course/ISCAS-1002580008?tid=1003713012 //中国大学MOOCgit
https://www.bilibili.com/video/av23401751 //B站github
《ROS操做系统入门讲义》PDF下载算法
连接:https://pan.baidu.com/s/1OCja2WLDRnjYXMrpnZ3-sQ
提取码:mziypython2.7
第七章 rospyide
1、rospy VS roscpp函数
一、位于 /opt/ros/kinetic/lib/python2.7/dist-packages/rospy //能够视为一个python的模块oop
二、区别spa
(1)rospy没有一个NodeHandle,建立publisher、subscriber等操做都被直接封装成了rospy中的函数或类,调用起来简单直观操作系统
(2)一些接口的命名不一致
注:
2、ROS中Python代码的组织方式
一、单独的python脚本:放于script/路径下 //适用于简单程序
your_package
——scripts/
————your_script.py
二、Python模块 //体量较大的程序
your_package
——src/
————your_package/
——————_init_.py
——————modulefiles.py
——scripts/
————your_script.py
——setup.py
注:
3、rospy经常使用API
一、Node相关
二、Topic相关
(1)函数
(2)Publisher类
(3)Subscriber类
三、Service相关
(1)函数
(2)Service类(server)
(3)ServiceProxy类(client)
四、Param相关
(1)函数
五、时钟相关
(1)函数
(2)Time类
(3)Duration类
(4)Rate类
4、topic in rospy
一、自定义消息及模块生成
(1)gps.msg的定义:
string state #工做状态 float32 x #x坐标 float32 y #y坐标
(2)消息模块生成:建立的msg在catkin_make以后会在~/catkin_ws/devel/lib/python2.7/dist-packages/topic_demo下生成msg模块(module);随后能够在python程序中经过 from topic_demo import gps 进行调用
二、消息发布节点
(1)topic_demo/scripts/pytalker.py:
(2)与C++的区别
注:roscpp和rospy的接口并不一致;ROS2中解决了这个问题,不一样的客户端库rclcpp和rclpy等都是基于共同的核心ROS客户端库rcl来开发的
三、消息订阅节点
(1)topic_demo/scripts/pylistener.py:
(2)与C++区别:rospy里没有 spinOnce() ,只有spin()
注:创建完talker和listener以后,通过 catkin_make ,就完成了python版的topic通讯模型
Python是解释性语言,不须要使用Cmake进行编译,能够直接运行,可是“message_generation”须要通过Cmake编译,生成msg类型
5、service in rospy
一、srv文件 Greeting.srv
string name int32 age --- string feedback
注:必须先修改CMakeLists.txt文件,随后catkin编译系统会自动构建自定义的msg、srv和action文件,生成对应的C++、Python、LISP等语言下可用的库或模块
创建了一个msg或srv文件,不能够直接在程序中使用,必须在 CMakeLists.txt 中添加关于消息建立、指定消息/服务文件那几个宏命令
二、提供服务节点(server)
(1)service_demo/scripts/server_demo.py:
(2)与C++区别:server端的处理函数
C++的handle_function()传入的参数是整个srv对象的request和response两部分,返回值是bool型,显示此次服务是否成功地处理
Python的handle_function()传入的只有request,返回值是response
三、服务请求节点(client)
(1)service_demo/scripts/client_demo.py:
6、param与time
一、相比roscpp中有两套对param操做的API,rospy关于param的函数就显得简单多了,包括了增删查改等:
rospy.get_param() , rospy.set_param() , rospy.has_param() , rospy.delete_param() , rospy.search_param() , rospy.get_param_names()
二、param_demo:
三、时钟:rospy中的关于时钟的操做和roscpp是一致的,都有Time、Duration和Rate三个类 //Time标识的是某个时刻,如22:00;而Duration表示的是时长,如一周;
Time和Duration结构相同:
int32 secs #秒
int32 nsecs #纳秒
(1)建立Time和Duration:都是 _init_(self,secs=0, nsecs=0) ,指定秒和纳秒
time_now1 = rospy.get_rostime() #当前时刻的Time对象 返回Time对象 time_now2 = rospy.Time.now() #同上 time_now3 = rospy.get_time() #获得当前时间,返回float 4单位秒 time_4 = rospy.Time(5) #建立5s的时刻 duration = rospy.Duration(3*60) #建立3min时长
注:于Time、Duration之间的加减法和类型转换,和roscpp中的彻底一致
四、sleep
duration.sleep() #挂起 rospy.sleep(duration) #同上,这两种方式效果彻底一致 loop_rate = Rate(5) #利用Rate来控制循环频率 while(rospy.is_shutdown()): loop_rate.sleep() #挂起,会考虑上次loop_rate.sleep的时间
注:Rate类中的sleep主要用来保持一个循环按照固定的频率,会考虑上次sleep的时间,从而使整个循环严格按照指定的频率
五、定时器Timer:不是用句柄来建立,而是直接 rospy.Timer(Duration, callback) ,第一个参数是时长,第二个参数是回调函数
def my_callback(event): #回调函数的传入值是 TimerEvent 类型 print 'Timer called at ' + str(event.current_real)
rospy.Timer(rospy.Duration(2), my_callback) #每2s触发一次callback函数 rospy.spin() #触发回调函数
注:TimerEvent 类型包括如下属性
rospy.TimerEvent
last_expected
理想状况下为上一次回调应该发生的时间
last_real
上次回调实际发生的时间
current_expected
本次回调应该发生的时间
current_real
本次回调实际发生的时间
last_duration
上次回调所用的时间(结束-开始)