所有资料均来自于 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.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')
返回值 | 方法 | 作用 |
---|---|---|
[[str, str]] | get_published_topics() | 返回正在被发布的所有topic名称和类型 |
Message | wait_for_message(topic, topic_type, time_out=None) | 等待某个topic的message |
spin() | 触发topic或service的回调/处理函数,会阻塞直到关闭节点 |
注:rospy里没有 spinOnce() 函数
返回值 | 方法 | 作用 |
---|---|---|
__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() #停止发布
返回值 | 方法 | 作用 |
---|---|---|
__init__(self, name, data_class, call_back=None, queue_size=None) | 构造函数 | |
unregister(self, msg) | 停止订阅 |
函数:
返回值 | 方法 | 作用 |
---|---|---|
wait_for_service(service, timeout=None) | 阻塞直到服务可用 |
返回值 | 方法 | 作用 |
---|---|---|
__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;
}
返回值 | 方法 | 作用 |
---|---|---|
__init__(self, name, service_class) | 构造函数,创建client | |
__call__(self, args, *kwds) | 发起请求 | |
call(self, args, *kwds) | 同上 | |
close(self) | 关闭服务的client |
返回值 | 方法 | 作用 |
---|---|---|
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() | 搜索参数 |
返回值 | 方法 | 作用 |
---|---|---|
Time | get_rostime() | 获取当前时刻的Time对象 |
float | get_time() | 返回当前时间,单位秒 |
sleep(duration) | 执行挂起 |
返回值 | 方法 | 作用 |
---|---|---|
__init__(self, secs=0, nsecs=0) | 构造函数 | |
Time | now() | 静态方法 返回当前时刻的Time对象 |
返回值 | 方法 | 作用 |
---|---|---|
__init__(self, secs=0, nsecs=0) | 构造函数 |
注:Time+Time=Duration Time+Duration=Time Duration+Duration=Duration Duration-Duration=Duration Time+Time无意义
返回值 | 方法 | 作用 |
---|---|---|
__init__(self,frequency) | 构造函数 | |
sleep(self) | 挂起 考虑上一次的rate.sleep()的时间 | |
Time | remaining(self) | 成员函数 剩余sleep时间 |
功能描述和步骤和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
#!/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()
#!/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 同前
功能描述和步骤同前。
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
#!/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()
#!/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()