导图社区 机器人建模与仿真
ROS技术基础及应用中关于机器人建模与仿真的部分,希望这份脑图会对你有所帮助。
编辑于2023-06-12 11:29:32 江苏省机器人建模与仿真
统一机器人描述格式——URDF
URDF(Unified Robot Description Format,统一机器人描述格式)
URDF文件中常用的XML标签
<link>标签
<link>标签用于描述机器人某个刚体部分的外观和物理属性,包括尺寸(size)、颜色(color)、形状 (shape)、惯性矩阵(inertial matrix)、碰撞参数(collision properties)等
其基本的URDF描述语法如下
<link name="<link name>"> <inertial> . . . . . . </inertial> <visual> . . . . . . </visual> <collision> . . . . . . </collision> </link>
<visual>标签用于描述机器人link部分的外观参数
<inertial>标签用于描述link的惯性参数
<collision>标签用于描述link的碰撞属性
检测碰撞的link区域大于外观可视的区域,意味着只要有其他物体与collision区域相交,就认为link发生碰撞
<joint>标签
用于描述机器人关节的运动学和动力学属性
描述语法如下
<joint name="<name of the joint>"> <parent link="parent_link"/> <child link="child_link"/> <calibration .... /> <dynamics damping ..../> <limit effort .... /> .... </joint>
其中必须指定joint的parent link和child link,还可以设置关节的其他属性
<calibration>:关节的参考位置,用来校准关节的绝对位置
<dynamics>:用于描述关节的物理属性,例如阻尼值、物理静摩擦力等,经常在动力学仿真中用到
<limit>:用于描述运动的一些极限值,包括关节运动的上下限位置、速度限制、力矩限制等
<mimic>:用于描述该关节与已有关节的关系
<safety_controller>:用于描述安全控制器参数
<robot>标签
<robot>是完整机器人模型的最顶层标签
一个完整的机器人模型由一系列<link>和<joint>组成
<robot>标签内可以设置机器人的名称,其基本语法如下
<robot name="<name of the robot>"> <link> ....... </link> <link> ....... </link> <joint> ....... </joint> <joint> ....... </joint> </robot>
<gazebo>标签
<gazebo>标签用于描述机器人模型在Gazebo中仿真所需要的参数
包括机器人材料的属性、Gazebo插件等
该标签的基本语法如下
<gazebo reference="link_1"> <material>Gazebo/Black</material> </gazebo>
创建机器人URDF模型
机器人的模型一般放在RobotName_description功能包下
创建机器人描述功能包
使用如下命令创建一个新的功能包
catkin_create_pkg mrobot_description urdf xacro
mrobot_description功能包中包含四个文件夹
urdf:用于存放机器人模型的URDF或xacro文件
meshes:用于放置URDF中引用的模型渲染文件
launch:用于保存相关启动文件
config:用于保存rviz的配置文件
创建URDF模型
URDF提供了一些命令行工具,可以帮助我们检查、梳理模型文件
终端安装
sudo apt-get install liburdfdomtools
使 用 check_urdf 命 令 对mrobot_chassis.urdf文件进行检查
check_urdf mrobot_chassis.urdf
check_urdf命令会解析URDF文件,并且显示解析过程中发现的错误
urdf_to_graphiz命令查看URDF模型的整体结构
urdf_to_graphizmrobot_chassis.urdf
在当前目录下生成一个pdf文件
URDF模型解析
首先需要声明该文件使用XML描述,然后使用<robot>根标签定义一个机器人模型,并定义该机器人模型的名称是“mrobot_chassis”。根标签内的内容即为对机器人模型的详细定义
这一段代码定义了第一个关节joint,用来连接机器人底盘和左边驱动电机,joint的类型是fixed类型,这种类型的joint是固定的,不允许关节发生运动
<origin>标签定义了joint的起点
要定义电机和轮子之间的joint。joint的类型是continuous型,这种类型的joint可以围绕一个轴进行旋转,很适合轮子这种模型
<axis>标签定义该joint的旋转轴是正y轴,轮子在运动时就会围绕y轴旋转
在rviz中显示模型
打开终端运行该launch文件
roslaunch mrobot_description display_mrobot_chassis_urdf.launch
运行成功后,不仅启动了rviz,而且出现了一个名为“joint_state_publisher_gui”的UI
在 启 动 文 件 中 启 动 了joint_state_publisher_gui节点,该节点可以发 布每个joint(除fixed类型)的状态
launch文件还会启动一个名为“robot_state_publisher”的节点
的功能是将机器人各个link、joint之间的关系,通过TF的形式整理成三维姿态信息发布出去
改进URDF模型
添加物理和碰撞属性
在base_link中加入<inertial>和<collision>标签,描述机器人的物理惯性属性和碰撞属性
惯性参数的设置主要包含质量和惯性矩阵
<collision>标签中的内容和<visual>标签中的内容几乎一致
使用的简单规则模型
为了减少碰撞检测时的计算量,<collision>中往往使用简化后的机器人模型
使用xacro优化URDF
是URDF文件并不支持代码复用的特性
针对URDF模型产生了一种精简化、可复用、模块化的描述形式——xacro
优势
精简模型代码
可以通过创建宏定义的方式定义常量或者复用代码
提供可编程接口
xacro的语法支持一些可编程接口,如常量、变量、数学公式、条件语句等
模型文件的后缀名由.urdf变为.xacro,而且在模型<robot>标签中需要加入xacro的声明
<?xml version="1.0"?> <robot name="robot_name" xmlns:xacro="http://www.ros.org/wiki/xacro>"
使用常量定义
一种常量属性的定义方式
<xacro:property name="M_PI" value="3.14159"/>
当需要使用该常量时,使用如下语法调用即可
<origin xyz="0 0 0" rpy="${M_PI/2} 0 0" />
调用数学公式
在“${}”语句中,不仅可以调用常量,还可以使用一些常用的数学运算
<origin xyz="0 ${(motor_length+wheel_length)/2} 0" rpy="0 0 0"/>
所有数学运算都会转换成浮点数进行,以保证运算精度
使用宏定义
xacro文件可以使用宏定义来声明重复使用的代码模块,而且可以包含输入参数,类似编程中的函数概念
xacro文件引用
改进后的机器人模型文件是mrobot_description/urdf/mrobot.urdf.xacro
<robot>标签之间只有两行代码
机器人的模型文件全部是在mrobot_body.urdf.xacro中使用一个宏来描述
为 什 么 还 需 要mrobot.urdf.xacro来包含调用呢
是因为我们把机器人本体看作一个模块,如果需要与其他模块集成,使用这种方法就不需要修改机器人的模型文件,只需要在上层实现一个拼装模块的顶层文件即可
显示优化后的模型
将xacro文件转换成URDF文件
rosrun xacro xacro.py mrobot.urdf.xacro > mrobot.urdf
直接调用xacro文件解析器
直接在启动文件中调用xacro解析器,自动将xacro转换成URDF文件
在launch文件中使用如下语句进行配置
<arg name="model" default="$(find xacro)/xacro -- inorder '$(find mrobot_description)/urdf/mrobot.urdf.xacro'" /> <param name="robot_description" command="$(arg model)" />
在终端中运行修改之后的launch文件mrobot_description/launch/display_mrobot.launch
roslaunch mrobot_description display_mrobot.launch
ros_control
ros_control就是ROS为开发者提供的机器人控制中间件,包含一系列控制器接口、传动装置接口、硬件接口、控制器工具箱等
ros_control框架
针对不同类型的机器人( 移 动 机 器 人、 机 械 臂等),ros_control可以提供 多 种 类 型 的 控 制
ros_control还提供一个硬件抽象层,负责机器人硬件资源的管理
数据流图
控制器管理器(ControllerManager)
提供一种通用的接口来管理不同的控制器
控制器(Controller)
控制器可以完成每个joint的控制,读取硬件资源接口中的状态,再发布控制命令,并且提供PID控制器
硬件资源(Hardware Resource)
为上下两层提供硬件资源的接口
机器人硬件抽象(RobotHW
机器人硬件抽象和硬件资源直接打交道,通过write和read方法完成硬件操作
真实机器人(Real Robot)
真实机器人上也需要有自己的嵌入式控制器,将接收到的命令反映到执行器上
控制器
ros_controllers功能包提供了控制器
硬件接口
基本与控制器的种类相互对应
可以自己创建需要的接口
传动系统
可以将机器人的关节指令转换成执行器的控制信号
在机器人的URDF模型文件中按照以下方法配置
<transmission name="simple_trans"> <type>transmission_interface/SimpleTransmission</type> <joint name="foo_joint"> <hardwareInterface>EffortJointInterface</hardwareInterface> </joint> <actuator name="foo_motor"> <mechanicalReduction>50</mechanicalReduction> <hardwareInterface>EffortJointInterface</hardwareInterface> </actuator> </transmission>
关节约束
是硬件抽象层中的一部分,维护一个关节约束的数据结构,这些约束数据可以从机器人的URDF文件中加载,也可以在ROS的参数服务器上加载(需要先用YAML配置文件导入ROS参数服务器)
包含关节速度、位置、加速度、加加速度、力矩、安全作用的位置软限位、速度边界(k_v)和位置边界(k_p)等
使用如下方式在URDF中设置Joint Limits参数
<joint name="$foo_joint" type="revolute"> <!-- other joint description elements --> <!-- Joint limits --> <limit lower="0.0" upper="1.0" effort="10.0" ="5.0" /> <!-- Soft limits --> <safety_controller k_position="100" k_velocity="10" soft_lower_limit="0.1" soft_upper_limit="0.9" /> </joint>
一些参数需要通过YAML配置文件事先加载到参数服务器中
查看控制控制器
查看某个控制器的状态,可以使用如下命令
rosrun controller_manager controller_manager <command>
支持的<command>如下
list:根据执行顺序列出所有控制器,并显示每个控制器的状态。
list-types:显示所有控制器的类型
reload-libraries:以插件的形式重载所有控制器的库,不需要重新启动,方便对控制器的开发和测试。
reload-libraries--restore:以插件的形式重载所有控制器的库,并恢复到初始状态。
使用spawner命令一次控制多个控制器:
rosrun controller_manager spawner [--stopped] name1 name2 name3
上面的命令可以自动加载、启动控制器,如果加上--stopped参数,那么控制器则只会被加载,但是并不会开始运行
如果想要停止一系列控制器,但是不需要卸载,可以使用如下命令
rosrun controller_manager unspawner name1 name2 name3
launch工具
在launch文件中,同样可以通过运行controller_manager命令,加载和启动一系列控制器:
可视化工具rqt_controller_manager
Gazebo仿真
使用xacro设计的机器人URDF模型已经描述了机器人的外观特征和物理特性
如何开始仿真
为link添加<gazebo>标签
需要对每一个link添加<gazebo>标签,包含的属性仅有material
material属性的作用与link里<visual>中material属性的作用相同
Gazebo无法通过<visual>中的material参数设置外观颜色,所以需要单独设置
Gazebo无法通过<visual>中的material参数设置外观颜色,所以需要单独设置
例
<gazebo reference="wheel_${lr}_link"> <material>Gazebo/Black</material> </gazebo>
添加传动装置
我们的机器人模型是一个两轮差速驱动的机器人,通过调节两个轮子的速度比例,完成前进、转向、倒退等动作
为了使用ROS控制器驱动机器人,需要在模型中加入<transmission>元素,将传动装置与joint绑定
<transmission name="wheel_${lr}_joint_trans"> <type>transmission_interface/SimpleTransmission</type> <joint name="base_to_wheel_${lr}_joint" /> <actuator name="wheel_${lr}_joint_motor"> <hardwareInterface>VelocityJointInterface</hardwareInterface> <mechanicalReduction>1</mechanicalReduction> </actuator> </transmission>
<joint name="">定义了将要绑定驱动器的joint,<type>标签声明了所使用的传动装置类型,<hardwareInterface>定义了硬件接口的类型
添加Gazebo控制器插件
(1)为<robot>元素添加插件
<gazebo> <plugin name="unique_name" filename="plugin_name.so"> ... plugin parameters ... </plugin> </gazebo>
(2)为<link>、<joint>标签添加插件
<gazebo reference="your_link_name"> <plugin name=" unique_name " filename="plugin_name.so"> ... plugin parameters ... </plugin> </gazebo>
Gazebo已经提供了一个用于差速控制的插件libgazebo_ros_diff_drive.so
在mrobot_gazebo/urdf/mrobot_body.urdf.xacro文件中添加如下插件声明
加载差速控制器插件的过程中,需要配置一系列参数,其中比较关键的参数如下
·<robotNamespace>机器人的命名空间,插件所有数据的发布、订阅都在该命名空间下
·<leftJoint>和<rightJoint>:左右轮转动的关节joint,控制器插件最终需要控制这两个 joint转动。
·<wheelSeparation><wheelDiameter>:这是机器人模型的相关尺寸,在计算差速参数时需要用到。
·<wheelAcceleration>:车轮转动的加速度
<commandTopic>:控制器订阅的速度控制指令,ROS中一般都命名为cmd_vel,生成全局命名时需要结合<robotNamespace>中设置的命名空间。
·<odometryFrame>:里程计数据的参考坐标系,ROS中一般都命名为odom
在Gazebo中显示机器人模型
launch文件主要做了两项工作
启动机器人的状态发布节点,同时加载带有Gazebo属 性的机器人URDF模型
启动Gazebo,并且将机器人模型加载到Gazebo仿真环 境中
控制机器人在Gazebo中运动
查看系统当前的话题列表可以看到,Gazebo仿真中已经开始订阅cmd_vel话题了。接下来可以运行键盘控制节点,发布该话题的速度控制消息,机器人就会在Gazebo中开始运动了