參考資料: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 上次回調所用的時間(結束-開始)