@(ROS)[ROS|Python|rospy|环境变量]
记录并分析ROS的整个Python系统体系,争取搞清楚内部原理。同时深入学习Python编程。
http://wiki.ros.org/rospy/Overview
PYTHONPATH:
可使用 echo $PYTHONPATH 查看。
init and shutdown
Message generation
Message initialization
遵循Python的语法进行消息变量的实例化。有三种方式:无参数、顺序参数、关键字参数。
No arguments
msg = std_msgs.msg.ColorRGBA( )
msg.b=255
msg.a=121
In-order arguments (*args)
msg = std_msgs.msg.ColorRGBA(255.0, 255.0, 255.0, 128.0)
Keyword arguments (**kwds)
msg = std_msgs.msg.ColorRGBA(b=255)
三种方式各有利弊。官方推荐用keyword方式,能更好的适应message类型定义的变化。
rospy.Publisher initialization
pub = rospy.Publisher(‘topic_name’, std_msgs.msg.String, queue_size=10)
其它参数:
Publisher.publish()
遵循Python语法,有三种方式调用publish()函数:
显式方法:
pub.publish(std_msgs.msg.ColorRGBA(255, 255, 255, 128))
隐式(顺序参数)方法:
pub.publish(255, 255, 255, 128)
隐式(关键字参数)方法:
pub.publish(b=255)
queue_size: 发送模式
因为历史原因向后兼容,rospy中的publish()默认是阻塞式同步发送模式。这将导致连接断开后publish卡死(比如无线连接的publisher和subscriber)。
不过,可以将publish和subscribe的queue_size写入一个大于0的值使publish成为异步模式。
queue_size:
_connection_header
topic连接后,发送的数据中包括header信息,订阅者subscriber可以在回调函数的data中查看header信息:data._connection_header。内部可能包含的内容为:
{‘callerid’: ‘/talker_38321_1284999593611’,
‘latching’: ‘0’,
‘md5sum’: ‘992ce8a1687cec8c8bd883ec73ca41d1’,
‘message_definition’: ‘string data\n\n’,
‘topic’: ‘/chatter’,
‘type’: ‘std_msgs/String’}
发布者talker可以在创建topic时添加自定义的header内容,示例为:
pub = rospy.Publisher(‘topic_demo’, String, headers={‘cookies’:’hello’}, queue_size=10)
Service definitions
srv文件和Python模块的对应关系如下:
my_package/srv/Foo.srv → my_package.srv.Foo
my_package/srv/Foo.srv → my_package.srv.FooRequest
my_package/srv/Foo.srv → my_package.srv.FooResponse
需要source {YOUR_CATKIN_WS}/devel/setup.bash将模块目录添加到PYTHONPATH环境变量中,才能在python代码中用from x.srv import * 的形式引入srv模块。
Service proxy
client端用proxy代理建立同service的通信:
add_two_ints = rospy.ServiceProxy(‘add_two_ints’, AddTwoInts)
可以用rospy.wait_for_service()阻塞等待service存在。
exceptions
service可能抛出3种异常:
Persistent connections
client设置ServiceProxy()参数persistent=True将建立持久连接,否则默认为每次都是连接-通信-断开。
持久连接比较脆弱,不推荐!
Service connection headers
service的server和client通信数据中也带有header信息,client端可自定义添加其它信息到header中。
h = { ‘cookies’ : ‘peanut butter’ }
s = rospy.ServiceProxy(‘foo’, Foo, headers=h)
在request和response中都可以查看header数据:
request._connection_header
response._connection_header
Getting parameters
global_name = rospy.get_param(“/global_name”)
relative_name = rospy.get_param(“relative_name”)
private_param = rospy.get_param(‘~private_name’)
default_param = rospy.get_param(‘default_param’, ‘default_value’)
# fetch a group (dictionary) of parameters
gains = rospy.get_param(‘gains’)
p, i, d = gains[‘P’], gains[‘I’], gains[‘D’]
Setting parameters
rospy.set_param(‘a_string’, ‘baz’)
rospy.set_param(‘~private_int’, 2)
rospy.set_param(‘list_of_floats’, [1., 2., 3., 4.])
rospy.set_param(‘bool_True’, True)
rospy.set_param(‘gains’, {‘p’: 1, ‘i’: 2, ‘d’: 3})
Deleting parameters
rospy.delete_param(param_name)
Parameter existence
执行get_param()和delete_param()前,最好检查一下参数名是否存在。否则会引发KeyError异常。
rospy.has_param(param_name)
Debug | Info | Warn | Error | Fatal | |
---|---|---|---|---|---|
stdout | X | ||||
stderr | X | X | X | ||
log file | X | X | X | X | X |
/rosout | o | X | X | X | X |
time和duration是rospy中两个重要的时间概念。
两者单位一样,直接print则是纳秒。数值形式一样:
int32 secs
int32 nsecs
time指时刻,类型是rospy.Time。
duration指时段,类型是rospy.Duration。
时刻和时段之间的计算关系:
two_hours = rospy.Duration(60*60) + rospy.Duration(60*60)
one_hour = rospy.Duration(2*60*60) - rospy.Duration(60*60)
tomorrow = rospy.Time.now() + rospy.Duration(24*60*60)
negative_one_day = rospy.Time.now() - tomorrow
timer
rospy.Timer(period, callback, oneshot=False)
在callback函数中参数为event:rospy.TimerEvent。TimerEvent的内部属性包括:
除了python体系内的异常类型,rospy还有下面几种exception异常类型:
- ROSException: ROS相关异常的基类。
- ROSSerializationException: ROS消息串行化异常!
- ROSInitException: ROS初始化异常!
- ROSInterruptException:ROS中断异常!
- ROSInternalException:ROS内部异常!
- ServiceException:Service通信异常!
主页:http://wiki.ros.org/rospy_tutorials
源码:https://github.com/ros/ros_tutorials/tree/indigo-devel/rospy_tutorials
rospy_tutorial是ros_tutorial组中的一个package,提供了基本代码示例,便于初学者学习。ros_tutorial在安装desktop-full完整版ros时一并安装了。但是为了便于从源码学习理解,建议删除卸载掉ros_tutorial包及相关依赖包(roscpp_tutorial和rospy_tutorial)。
sudo apt-get remove ros-indigo-ros-tutorial
rospy_tutorial包中包括了rospy的大部分常用概念和示例。可以将这个包下载到自己的catkin_workspace下,运行catkin_make编译。
catkin_make将在devel/lib/python2.7/dist-packages/目录下生成msg和srv的模块py文件。
然后,source devel/setup.bash后,就可以用roslaunch或rosrun运行了。也可以直接用python方式运行py文件,和rosrun一样的效果。
注意:自己创建的python文件需要 chmod +x YOUR.py增加执行权限,才能被rosrun补全tab识别。