版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
ROS2机器人操作系统与Gazebo机器人仿真
第3章ROS2编程基础提纲3.1ROS2项目3.1.1工作空间3.1.2创建功能包 3.1.3编写程序3.1.4编译功能包3.1.5运行功能包3.1.6功能包的结构3.2rclpy库的使用 3.2.1节点 3.2.2话题3.2.3服务3.2.4动作3.2.5参数3.2.6消息接口3.2.7案例:创建话题发布者3.2.8案例:创建话题订阅者3.2.9案例:创建服务器3.2.10案例:创建客户端3.2.11案例:创建动作服务器3.2.12案例:创建动作客户端3.2.13案例:创建参数服务3.2.14案例:创建自定义消息类型3.3坐标系管理3.3.1坐标变换原理3.3.2tf2简介3.3.3案例:发布静态坐标系3.3.4案例:发布动态坐标系3.3.5案例:查询坐标系变换提纲3.4Launch文件3.4.1Launch文件简介3.4.2常用类介绍1LaunchDescription类2Node类3.4.3案例:Launch文件编写3.4.4案例:命名空间与节点名称设置3.4.5案例:参数设置3.4.6案例:话题重映射3.5URDF简介3.5.1
案例:URDF可视化
3.6本章小结
3.3坐标系管理3.3坐标系管理能够运动是机器人最显著的特征,具体体现为位置的变化和自身姿态的变化。机器人的位置和姿态信息对于机器人具重要的作用。在导航中,机器人只有知道自身的准确位置和方向是正确导航的前提;在机械臂抓取物品时各个关节准确的角度是抓取物品的前提;在四足机器人运动中,机器人各关节正确的角度是机器人保持稳定的前提。能够快速、精确的进行位置和姿态的求解在机器人中就变得十分重要。ROS2提供了一个功能包tf2用于管理整个系统中的坐标系,按照坐标系间的相对关系,将所有的坐标系构建为一棵tf树。通过tf树可以高效查询到ROS2中任意两个坐标系间的变换关系,实现高效的坐标变换。如图展示了一个机器人上坐标系。3.3坐标系管理3.3.1坐标变换原理为了描述对象在空间中的位置和姿态,通常需要借助坐标系定位。在三维空间中,一般使用三个轴互相垂直的直角坐标系,三个轴的关系要符合右手定则。直角坐标系中三个轴的交点称为坐标系原点,简称原点。右手定则的含义是将右手四指握拳,大拇指向上,大拇指指尖向上的方向为z轴正方向,四指从指根到指尖的旋转方向就是x轴到y轴的旋转方向,只需要确定x轴和y轴中的一个,另一个就可以由旋转关系得到。3.3坐标系管理3.3.1坐标变换原理在符合右手定则的条件下,空间中直角坐标系的建立是任意的,也就是说坐标系原点的位置随意,三个轴的朝向也随意。如图3.8所示,在空间中建立了两个坐标系A和B,这两个坐标系没有优劣。通常在一个真实机器人世界中存在许多个坐标系。当空间中有许多坐标系时就存在一个严肃的问题:如何描述同一个物体在不同坐标系下坐标和姿态,也就是建立同一个点在不同坐标系下坐标间的变换关系。例如,两人相约到某处,A说需要乘3站公交,B说我需要乘5站公交,那么这个地点在A的坐标看来就是3,而在B的坐标看来就是5。3.3坐标系管理3.3.1坐标变换原理以及与上述问题等价的两个问题:(1)不同坐标系间的关系;(2)一个物体在指定坐标系中经过旋转和平移的运动后新的位置和姿态。坐标变换原理给出了上述问题的解答。下面以不同坐标系间的关系为切入点,介绍坐标变换原理。空间中坐标系间的关系可以分解为旋转和平移。3.3坐标系管理3.3.1坐标变换原理首先介绍坐标系间的旋转变换关系。如图3.29所示,当坐标系A和坐标系B的原点重合时,两个坐标系只具有旋转关系,也就是坐标系A绕空间中某条直线旋转一定角度后会与坐标系B重合。坐标系B由其三个轴上的单位向量{X̂_B,Ŷ_B,(Z)̂_B}所确定,将这三个单位向量分别投影到坐标系A的三个轴上(或者说这三个单位向量的坐标可以用A坐标系表示),即:
3.3坐标系管理
3.3坐标系管理3.3.1坐标变换原理以上计算得到了坐标系B中的三个单位向量在坐标系A下的坐标。通过这些坐标就能够描述坐标系B与A的关系。一般将上述表示写为一个3×3的矩阵:
3.3坐标系管理
3.3坐标系管理
3.3坐标系管理
3.3坐标系管理
3.3坐标系管理
3.3坐标系管理
3.3坐标系管理
3.3坐标系管理3.3.1坐标变换原理按照上述坐标系间变换的链式法则,就可以将整个空间中的所有坐标系关联起来,从而可以求得任意两个坐标系间的变换关系,完成坐标间的变换。基于坐标系在机器人中的重要性,ROS2的tf2功能包就专门用于管理和维护整个程序中的坐标系。谢
谢3.3坐标系管理3.3.2tf2简介ROS2中的tf2功能包就是基于坐标系变换的链式法则对多个坐标系进行管理和维护。为了保证一致性和实用性,tf2使用树结构来管理坐标系而非图结构,具体来说通过选择一个根坐标系(世界坐标系)作为基准,按照坐标系间的变换关系逐渐扩展成一棵由坐标系构成的树,树中任意两个节点(坐标系间)都存在惟一路径,根据链式法则从而可方便地完成坐标系间的变换。tf2是对原tf进行了改进和优化,为了与之前版本区分称为tf2。tf2主要包含两个发布坐标系的功能和接收存储坐标系的功能。为应对随时间变换的坐标系,tf2能够接收和处理异步的信息,并对延时和坐标系丢失具有很强的鲁棒性。tf2在广播坐标系时使用话题通信机制,以话题名/tf进行广播tf树。3.3坐标系管理3.3.2tf2简介在ROS2功能包tf2_ros和tf2_tool提供了有关坐标系的变换功能。两个功能包一般会在ROS2安装时进行安装,也可以使用以下命令安装:sudoaptinstallros-jazzy-tf2-rossudoaptinstallros-jazzy-tf2-tools下面对这两个功能包的功能和使用方法进行介绍。(1)tf2_ros功能包提供了4个功能buffer_server,tf2_echo,static_transform_publisher,tf2_monitor。buffer_server用于启动一个缓存tf坐标系的服务器。tf2_echo用于进行查询坐标系间的变换。static_tranform_publisher向tf2注册一个静态坐标系,静态坐标系就是不随时间变换化的坐标系,例如表示环境中的固定障碍物的位置。tf2_monitor用于监听和显示tf2中活动的坐标系。3.3坐标系管理3.3.2tf2简介下面通过查询坐标系A和坐标系的关系来说明tf2_ros中功能使用方法。首先,启动buffer_server,执行命令:ros2runtf2_rosbuffer_server其次,发布两个以世界坐标系World为基的坐标系A和坐标系B,执行命令:ros2runtf2_rosstatic_transform_publisher--frame-idWorld--child-frame-idAros2runtf2_rosstatic_transform_publisher--frame-idWorld--child-frame-idB--x3--y4--z5以上两个命令发布了坐标系A与坐标系B,坐标系A与世界坐标系World重合,坐标系B位于世界坐标系World的(3,4,5)处,坐标轴与世界坐标系World相同。此外还可以通过--qx,--qy,--qz,--qw参数以四元数的格式添加坐标系的旋转,或通过--roll,--pitch,--yaw参数以欧拉转角的格式添加坐标系的旋转。3.3坐标系管理3.3.2tf2简介再次,查看发布的坐标系A和坐标系B,执行命令:ros2runtf2_rostf2_monitor命令的运行效果如图所示,经过10秒钟的坐标系收集后,正确的显示了以上发布的坐标系A和坐标系B。3.3坐标系管理3.3.2tf2简介最后,查询坐标系B到坐标系A的变换,执行命令:ros2runtf2_rostf2_echoAB上述命令中,在tf2中将参数值为A所在的坐标系称为sourceframe,而参数值为B所在的坐标系称为targetframe。上述命令的运行效果如下页图所示,虽然在发布坐标系时只发布了坐标系A和B与World的关系,在查询坐标系B到A的变换时,tf2会自动根据tf树计算得到变换关系,tf2_echo显示了平移、四元数格式的旋转、欧拉转解RPY格式的旋转,以及变换矩阵等格式的变换信息。3.3坐标系管理3.3.2tf2简介3.3坐标系管理3.3.2tf2简介(2)tf2_tools功能包提供了一个绘制当前系统tf树的程序view_frames。该程序监听系统的tf树5秒,然后根据监听结构将tf树绘制到一个pdf中并保存到当前目录。绘制tf树,执行命令:ros2runtf2_toolsview_frames上述命令执行完成后,会在当前目录下生成一个以frames开头的pdf文件。打开该pdf文件后,显示了命令运行时系统中的tf树,如图所示。3.3坐标系管理3.3.2tf2简介此外,也可以使用RViz来直观的对系统中的坐标系进行可视化,可视化坐标系在三维空间中的关系。具体步骤是:首先,启动RViz,执行命令:rviz2其次,将全局设置(GlobalOptions)下的固定坐标系(FixedFrame)设置为World,添加TF可视化功能后,在三维可视化场景中即可可视化系统中的三个坐标系World,A和B,如下页图所示。
3.3坐标系管理3.3.2tf2简介除了以上tf2命令行工具外,tf2_ros功能包也提供了Python语言的编程接口,提供了发布静态坐标系、动态坐标系和查询坐标变换的功能,从而以更灵活的方式在自定义的节点中处理坐标系。下面通过三个案例详细说明tf2_ros功能包的编程接口使用方法。谢
谢3.3坐标系管理3.3.3案例:发布静态坐标系机器人运行时的固定的障碍物、建筑物等坐标都是不随时间发生变化的,只需要发布一次坐标信息向tf2注册坐标即可。tf2_ros功能包中的static_transform_broadcaster.StaticTransformBroadcaster类提供了静态坐标发布的功能。功能包geometry_msgs中的msg.TransormStamped提供了坐标系的消息类型。首先,在工作空间中创建一个名为tf_test的功能包,用于存放案例的代码。ros2pkgcreate--build-typeament_python--node-namestaticframepub--dependenciesgeometry_msgstf2_ros--licenseMITtf_test3.3坐标系管理3.3.3案例:发布静态坐标系其次,功能包中的在staticframepub.py文件中编写一个发布静态坐标系节点,代码如下:importrclpyimportmathfromgeometry_msgs.msgimportTransformStampedfromrclpy.nodeimportNodefromtf2_ros.static_transform_broadcasterimportStaticTransformBroadcasterdefquaternion_from_euler(ai,aj,ak):#将欧拉角转为四元数表示ai/=2.0aj/=2.0ak/=2.0ci=math.cos(ai)si=math.sin(ai)cj=math.cos(aj)sj=math.sin(aj)3.3坐标系管理3.3.3案例:发布静态坐标系接上页代码。ck=math.cos(ak)sk=math.sin(ak)cc=ci*ckcs=ci*sksc=si*ckss=si*skq=[0]*4q[0]=cj*sc-sj*csq[1]=cj*ss+sj*ccq[2]=cj*cs-sj*scq[3]=cj*cc+sj*ssreturnq3.3坐标系管理3.3.3案例:发布静态坐标系接上页代码。classStaticFramePublisher(Node):"""
静态坐标系发布器"""def__init__(self):super().__init__('static_frame_tf2_broadcaster')self.x=self.declare_parameter('x',3.0).get_parameter_value().double_valueself.y=self.declare_parameter('y',4.0).get_parameter_value().double_valueself.z=self.declare_parameter('z',5.0).get_parameter_value().double_valueself.roll=self.declare_parameter('roll',0.0).get_parameter_value().double_valueself.pitch=self.declare_parameter('pitch',0.0).get_parameter_value().double_valueself.yaw=self.declare_parameter('yaw',0.0).get_parameter_value().double_valueself.child_frame=self.declare_parameter('child_frame','frame_A').get_parameter_value().string_valueself.parent_frame=self.declare_parameter('parent_frame','World').get_parameter_value().string_value3.3坐标系管理3.3.3案例:发布静态坐标系接上页代码。self.tf_static_broadcaster=StaticTransformBroadcaster(self)self.logger=self.get_logger()self.pub_transforms()defpub_transforms(self):t=TransformStamped()t.header.stamp=self.get_clock().now().to_msg()t.header.frame_id=self.parent_framet.child_frame_id=self.child_framet.transform.translation.x=self.xt.transform.translation.y=self.yt.transform.translation.z=self.zquat=quaternion_from_euler(self.roll/180*math.pi,self.pitch/180*math.pi,self.yaw/180*math.pi)3.3坐标系管理3.3.3案例:发布静态坐标系接上页代码。t.transform.rotation.x=quat[0]t.transform.rotation.y=quat[1]t.transform.rotation.z=quat[2]t.transform.rotation.w=quat[3](f'publishstatictf:{t}')self.tf_static_broadcaster.sendTransform(t)defmain(args=None):rclpy.init(args=args)node=StaticFramePublisher()try:rclpy.spin(node)exceptException:rclpy.shutdown()exit(0)if__name__=='__main__':main()3.3坐标系管理3.3.3案例:发布静态坐标系上述代码中,创建了一个发布静态坐标系的节点StaticFramePublisher,在节点的初始化方法__init__()中定义发布坐标系的一些参数,并且创建了一个静态坐标系发布者StaticTransformBroadcaster类的实例,最后调用了pub_transforms()方法进行坐标的发布。在pub_transforms()方法中,创建了一个坐标系消息TransformStamped的实例,根据节点设置的参数设置坐标系,其中quaternion_from_euler()函数实现了将欧拉转角变换为四元数的功能,最后通过静态坐标系发布者的sendTransform()方法发布静态坐标系。注意:坐标系消息TransformStamped的详细结构可以通过ros2interface命令行工具查询,命令为ros2interfaceshowgeometry_msgs/msg/TransformStamped。3.3坐标系管理3.3.3案例:发布静态坐标系经过编译、安装后,即可运行上述编写的静态坐标系发布节点。下面打开两个终端,分别执行下面的命令:ros2runtf_teststaticframepub--ros-args-px:=1.0-py:=0.0-pz:=0.0-pyaw:=90.0-pchild_frame:=frame_Aros2runtf_teststaticframepub--ros-args-px:=1.0-py:=0.0-pz:=0.0-pyaw:=90.0-pchild_frame:=frame_B-pparent_frame:=frame_A上述第一条命令发布了一个坐标系frame_A到默认坐标系World的变换,第二条命令发布了一个以坐标系frame_B到坐标系frame_A的变换。上述命令的执行效果如图所示。3.3坐标系管理3.3.3案例:发布静态坐标系3.3坐标系管理3.3.3案例:发布静态坐标系使用RViz可直观的显示上述静态坐标系的发布结果,可视化坐标系间的关系,如图所示。谢
谢3.3坐标系管理3.3.4案例:发布动态坐标系机器人的关节是活动的,位置和角度会随时间变化,设置在其上的坐标系会不断发生变化。tf2_ros功能包中的TransformBroadcaster类提供了动态坐标的发布功能。消息类型同样使用功能包geometry_msgs中的msg.TransormStamped。首先,在功能包tf_test内创建一个名为framepub.py的文件,用于存放动态坐标系发布节点的代码。其次,在framepub.py文件中编写一个发布动态坐标系节点,代码如下:importrclpyimportmathfromgeometry_msgs.msgimportTransformStampedfromrclpy.nodeimportNodefromtf2_rosimportTransformBroadcaster3.3坐标系管理3.3.4案例:发布动态坐标系接上页代码。defquaternion_from_euler(ai,aj,ak):#将欧拉角转为四元数表示ai/=2.0aj/=2.0ak/=2.0ci=math.cos(ai)si=math.sin(ai)cj=math.cos(aj)sj=math.sin(aj)ck=math.cos(ak)sk=math.sin(ak)cc=ci*ckcs=ci*sksc=si*ckss=si*sk3.3坐标系管理3.3.4案例:发布动态坐标系接上页代码。q=[0]*4q[0]=cj*sc-sj*csq[1]=cj*ss+sj*ccq[2]=cj*cs-sj*scq[3]=cj*cc+sj*ssreturnq
classFramePublisher(Node):"""
动态坐标系发布器"""def__init__(self):super().__init__('frame_tf2_publisher')self.tf_broadcaster=TransformBroadcaster(self)self.num=0self.create_timer(0.03,self.pub_transforms)3.3坐标系管理3.3.4案例:发布动态坐标系接上页代码。defpub_transforms(self):t=TransformStamped()t.header.stamp=self.get_clock().now().to_msg()t.header.frame_id='frame_A't.child_frame_id='frame_B'
theta=self.num/180*math.pit.transform.translation.x=math.cos(theta)*2t.transform.translation.y=math.sin(theta)*2t.transform.translation.z=0.0
quat=quaternion_from_euler(0,0,theta+math.pi/2)t.transform.rotation.x=quat[0]t.transform.rotation.y=quat[1]t.transform.rotation.z=quat[2]t.transform.rotation.w=quat[3]3.3坐标系管理3.3.4案例:发布动态坐标系接上页代码。self.num+=1ifself.num>=360:self.num=0self.tf_broadcaster.sendTransform(t)
defmain(args=None):rclpy.init(args=args)node=FramePublisher()try:rclpy.spin(node)exceptException:rclpy.shutdown()exit(0)
if__name__=='__main__':main()3.3坐标系管理3.3.4案例:发布动态坐标系在上述代码中创建了一个发布动态坐标系的类FramePublisher。在类初始化方法__init__()中创建了一个坐标系发布者TransformBroadcaster类的实例,并创建了一个定时器对于周期性的发布坐标系。定时器回调函数pub_transforms()发布坐标系frame_B到frame_A的坐标系变换,frame_B的坐标系的x和y会随时间作余弦和正弦运动。再次,在功能包的setup.py文件中添加该节点为framepub,代码如下:'framepub=tf_test.framepub:main‘,最后,经过编译、安装后,即可运行上述编写的动态坐标系发布节点。在终端里运行节点,执行命令:ros2runtf_testframepub3.3坐标系管理3.3.4案例:发布动态坐标系在Rviz中可视化坐标系,可以看到坐标系frame_B围绕坐标系frame_A作圆周运动,如图所示。谢
谢3.3坐标系管理3.3.5案例:查询坐标系变换
tf2将系统中的所有坐标系构建了一棵树,可以通过查询这棵树就能以获得树上任意两个坐标系的变换。tf2_ros功能包的transform_listener.TransformListener类提供了监听坐标系的功能。首先,在功能包tf_test内创建一个名为framesub.py的文件,用于存放接收坐标系节点的代码。其次,在framesub.py文件中编写一个接收坐标系并且显示的节点,代码如下:importrclpyfromrclpy.nodeimportNodefromtf2_ros.bufferimportBufferfromtf2_ros.transform_listenerimportTransformListener3.3坐标系管理3.3.5案例:查询坐标系变换接上页代码。classFrameListener(Node):def__init__(self):super().__init__('tf2_frame_listener')self.logger=self.get_logger()self.target_frame=self.declare_parameter('target_frame','frame_B').get_parameter_value().string_valueself.source_frame=self.declare_parameter('source_frame','frame_A').get_parameter_value().string_value
self.tf_buffer=Buffer()self.tf_listener=TransformListener(self.tf_buffer,self)self.logger=self.get_logger()self.timer=self.create_timer(1.0,self.show_t
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- GB/T 47864-2026工业移动机器人调度系统底层数据接口要求
- 2026年高等学校教师职业修养
- 苏打粉企业管理方案
- 苏教版五年级(下册)口算题教材同步
- 数控编程基本知识
- 2026杭州外办面试题目及答案
- 2026河道管养面试题及答案
- 水泥化学知识基础教程
- 水泥行业主要生产工艺、职业病危害因素识别和防护措施
- 当代大学生就业趋势分析
- 基层应急管理培训课件
- 城市建筑群基于弹塑性时程分析的震害评估标准
- (高清版)DG∕TJ 08-207-2008 房屋修缮工程技术规程
- 历年计算机二级MS-Office真题及答案
- 23G409先张法预应力混凝土管桩
- 信访业务知识培训课件
- 微循环课件教学课件
- 不完全肠梗阻护理
- 舞蹈基础知识考试题库150题(含答案)
- 《电力行业企业培训师能力标准与评价规范》
- 铁工电〔2023〕54号国铁集团关于印发《普速铁路工务安全规则》的通知
评论
0/150
提交评论