所有資料均來自于 https://www.icourse163.org/learn/ISCAS-1002580008#/learn/announce 和
https://github.com/DroidAITech/ROS-Academy-for-Beginners 和
https://sychaichangkun.gitbooks.io/ros-tutorial-icourse163/content/
rospy具體接口:https://docs.ros.org/api/rospy/html/
ROS Wiki rospy介紹:https://wiki.ros.org/rospy
rospy中和 Node Topic Service Param Time 相關的函數
rospy_Node 相關
傳回值 | 方法 | 作用 |
---|---|---|
rospy.init_node(name, argv=None, anonymous=False) | 注冊和初始化node | |
MasterProxy | rospy.get_master() | 擷取master的句柄 |
bool | rospy.is_shutdown() | 節點是否關閉 |
rospy.on_shutdown(fn) | 在節點關閉時調用fn函數 | |
str | get_node_uri() | 傳回節點的URI |
str | get_name() | 傳回本節點的全名 |
str | get_namespace() | 傳回本節點的名字空間 |
初始化node
import rospy
rospy.init_node('my_node')
rospy_Topic 相關
函數:
傳回值 | 方法 | 作用 |
---|---|---|
[[str, str]] | get_published_topics() | 傳回正在被釋出的所有topic名稱和類型 |
Message | wait_for_message(topic, topic_type, time_out=None) | 等待某個topic的message |
spin() | 觸發topic或service的回調/處理函數,會阻塞直到關閉節點 |
注:rospy裡沒有 spinOnce() 函數
Publisher類:
傳回值 | 方法 | 作用 |
---|---|---|
__init__(self, name, data_class, queue_size=None) | 構造函數 | |
publish(self, msg) | 釋出消息 | |
str | unregister(self) | 停止釋出 |
pub = rospy.Publisher('topic_name',msg_type,queue_size = None) #若queue_size是 None 則為同步通信方式,若為整數則為異步通信方式
pub.publish(msg) #釋出消息
pub.unregister() #停止釋出
Subscriber類:
傳回值 | 方法 | 作用 |
---|---|---|
__init__(self, name, data_class, call_back=None, queue_size=None) | 構造函數 | |
unregister(self, msg) | 停止訂閱 |
rospy-Service相關
函數:
傳回值 | 方法 | 作用 |
---|---|---|
wait_for_service(service, timeout=None) | 阻塞直到服務可用 |
Service類(server):
傳回值 | 方法 | 作用 |
---|---|---|
__init__(self, name, service_class, handler) | 構造函數,handler為處理函數,service_class為srv類型 | |
shutdown(self) | 關閉服務的server |
關于回調函數handle,在rospy中傳入參數是request 傳回參數是response:
def handler(req):
....
return res
而在roscpp中傳入參數是request和response,傳回參數是一個布爾值:
bool handler(req,res)
{
...
return bool;
}
ServiceProxy類(client):
傳回值 | 方法 | 作用 |
---|---|---|
__init__(self, name, service_class) | 構造函數,建立client | |
__call__(self, args, *kwds) | 發起請求 | |
call(self, args, *kwds) | 同上 | |
close(self) | 關閉服務的client |
rospy-Param相關
函數:
傳回值 | 方法 | 作用 |
---|---|---|
XmlRpcLegalValue | get_param(param_name, default=_unspecified) | 擷取參數的值 |
[str] | get_param_names() | 擷取參數的名稱 |
set_param(param_name, param_value) | 設定參數的值 | |
delete_param(param_name) | 删除參數 | |
bool | has_param(param_name) | 參數是否存在于參數伺服器上 |
str | search_param() | 搜尋參數 |
rospy-Time相關
函數:
傳回值 | 方法 | 作用 |
---|---|---|
Time | get_rostime() | 擷取目前時刻的Time對象 |
float | get_time() | 傳回目前時間,機關秒 |
sleep(duration) | 執行挂起 |
Time類:(時刻)
傳回值 | 方法 | 作用 |
---|---|---|
__init__(self, secs=0, nsecs=0) | 構造函數 | |
Time | now() | 靜态方法 傳回目前時刻的Time對象 |
Duration類:(一段時間)
傳回值 | 方法 | 作用 |
---|---|---|
__init__(self, secs=0, nsecs=0) | 構造函數 |
注:Time+Time=Duration Time+Duration=Time Duration+Duration=Duration Duration-Duration=Duration Time+Time無意義
Rate類:
傳回值 | 方法 | 作用 |
---|---|---|
__init__(self,frequency) | 構造函數 | |
sleep(self) | 挂起 考慮上一次的rate.sleep()的時間 | |
Time | remaining(self) | 成員函數 剩餘sleep時間 |
Topic_demo
(https://github.com/DroidAITech/ROS-Academy-for-Beginners/tree/master/topic_demo)
功能描述和步驟和roscpp的Topic_demo相同
gps.msg檔案在經過catkin_make後,會在以下路徑生成py檔案
~/catkin_ws/devel/lib/python2.7/dis-pacakges/topic_demo/msg/__init__.py
引用格式如下:
from topic_demo.msg import gps
pylistener.py
#!/usr/bin/env python
#coding=utf-8
import rospy
import math
#導入mgs
from topic_demo.msg import gps
#回調函數輸入的應該是msg
def callback(gps):
distance = math.sqrt(math.pow(gps.x, 2)+math.pow(gps.y, 2))
rospy.loginfo('Listener: GPS: distance=%f, state=%s', distance, gps.state)
def listener():
rospy.init_node('pylistener', anonymous=True)
#Subscriber函數第一個參數是topic的名稱,第二個參數是接受的資料類型 第三個參數是回調函數的名稱
rospy.Subscriber('gps_info', gps, callback)
rospy.spin()
if __name__ == '__main__':
listener()
pytalker.py
#!/usr/bin/env python
#coding=utf-8
import rospy
#導入自定義的資料類型
from topic_demo.msg import gps
def talker():
#Publisher 函數第一個參數是話題名稱,第二個參數 資料類型,現在就是我們定義的msg 最後一個是緩沖區的大小
#queue_size: None(不建議) #這将設定為阻塞式同步收發模式!
#queue_size: 0(不建議)#這将設定為無限緩沖區模式,很危險!
#queue_size: 10 or more #一般情況下,設為10 。queue_size太大了會導緻資料延遲不同步。
pub = rospy.Publisher('gps_info', gps , queue_size=10)
rospy.init_node('pytalker', anonymous=True)
#更新頻率是1hz
rate = rospy.Rate(1)
x=1.0
y=2.0
state='working'
while not rospy.is_shutdown():
#計算距離
rospy.loginfo('Talker: GPS: x=%f ,y= %f',x,y)
pub.publish(gps(state,x,y))
x=1.03*x
y=1.01*y
rate.sleep()
if __name__ == '__main__':
talker()
CMakeList.txt 和 package.xml 同前
service_demo
(https://github.com/DroidAITech/ROS-Academy-for-Beginners/tree/master/service_demo)
功能描述和步驟同前。
Greeting.srv檔案在經過catkin_make後,會在以下路徑生成py檔案
~/catkin_ws/devel/lib/python2.7/dis-pacakges/service_demo/srv/__init__.py
引用格式如下:
from service_demo.srv import * #import的有 Greeting GreetingResponse GreetingRequest
server_demo.py
#!/usr/bin/env python
#coding=utf-8
import rospy
from service_demo.srv import *
def server_srv():
# 初始化節點,命名為 "greetings_server"
rospy.init_node("greetings_server")
# 定義service的server端,service名稱為"greetings", service類型為Greeting
# 收到的request請求資訊将作為參數傳遞給handle_function進行處理
s = rospy.Service("greetings", Greeting, handle_function)
rospy.loginfo("Ready to handle the request:")
# 阻塞程式結束
rospy.spin()
def handle_function(req):
# 注意我們是如何調用request請求内容的,是将其認為是一個對象的屬性,在我們定義
# 的Service_demo類型的service中,request部分的内容包含兩個變量,一個是字元串類型的name,另外一個是整數類型的age
rospy.loginfo( 'Request from %s with age %d', req.name, req.age)
# 傳回一個Service_demo.Response執行個體化對象,其實就是傳回一個response的對象,其包含的内容為我們在Service_demo.srv中定義的
# response部分的内容,我們定義了一個string類型的變量feedback,是以,此處執行個體化時傳入字元串即可
return GreetingResponse("Hi %s. I' server!"%req.name)
# 如果單獨運作此檔案,則将上面定義的server_srv作為主函數運作
if __name__=="__main__":
server_srv()
client_demo.py
#!/usr/bin/env python
# coding:utf-8
import rospy
from service_demo.srv import *
def client_srv():
rospy.init_node('greetings_client')
# 等待有可用的服務 "greetings"
rospy.wait_for_service("greetings")
try:
# 定義service用戶端,service名稱為“greetings”,service類型為Greeting
greetings_client = rospy.ServiceProxy("greetings",Greeting)
# 向server端發送請求,發送的request内容為name和age,其值分别為"HAN", 20
# 此處發送的request内容與srv檔案中定義的request部分的屬性是一緻的
#resp = greetings_client("HAN",20)
resp = greetings_client.call("HAN",20)
rospy.loginfo("Message From server:%s"%resp.feedback)
except rospy.ServiceException, e:
rospy.logwarn("Service call failed: %s"%e)
# 如果單獨運作此檔案,則将上面函數client_srv()作為主函數運作
if __name__=="__main__":
client_srv()