<ROS> 机器人描述--URDF和XACRO

1. 关于URDF的一些杂谈

URDF(Unified Robot Description Format), 是一种特殊的xml文件格式, 作为机器人的一种描述文件, 在ROS里面大量使用. 接触ROS比较久的同学, 应该会经常见到一种类似命名的包(package) – xxx_description. 这个包里面就是包含某个机器人的描述文件. 比如pr2_decription, baxter_descrition, 以及ur_description等. 上述举例的机器人描述包都是可以通过apt-get的方式进行安装. 使用命令格式如斯: sudo apt-get install ros-indigo-pr2-descrition, 其中indigo是你所安装的ROS版本名, 后面就是所需要安装的包名, 下划线用中画线代替.

对机器人使用gazebo进行仿真时, 需要加载的机器人模型就是urdf模型, 当然, 单纯的urdf是不能精确描述机器人以及所需要仿真的世界的. gazebo对其进行了扩展, 感兴趣的朋友可以查看gazebo官网的一些教程. 其中会提供一些标签, 对系统动态, 重心等的设定.

如果想使用开源库moveit对机器人进行路径规划, 在moveit setup assistant教程中, 第一步就是关于如何将机器人模型导入进来, 导入的机器人模型就是urdf(导入xacro格式时也是先将其解析为urdf).

诸如这些应用, 当然还不限于这些应用, 可以看到, 了解URDF以及会使用URDF是一件很重要的事情. 而xacro文件, 是提供了一些更为高级编辑方式的宏文件. 这种格式的文件, 在使用时, 均先会调用rosrun xacro xacro.py xxx.urdf.xacro > xxx.urdf, 将其解析成对应的urdf文件. 然后再使用.

下述内容, 仅仅是对urdf文件编辑和查看由最基础的了解, 以方便能够看得懂机器人描述文件, 以及该怎么利用别人已经写好的描述文件进行组合, 重构得到自己的机器人描述文件. 如果是需要更详细, 精确的描述, 则还需要自己再去对urdf文件进行学习.

2. URDF文件

URDF教程中, 第一个出现的就是下图, 很形象的将URDF要定义的主要内容给展现了出来. 一般, 机器人都是由link和joint进行描述. 都会呈现为树状(想象数据结构里面的树), 如图1, 由一个根link(link1)向上, 分别出现了两个分支–link2和link3, 分别由joint连接link. link4就可以类似的理解.


这里写图片描述

了解机器人的一般描述方式之后, 我们来看一下下图中这个形状的机器人该怎么来描述它.

<robot name="test_robot">
  <link name="link1" />
  <link name="link2" />
  <link name="link3" />
  <link name="link4" />

  <joint name="joint1" type="continuous">
    <parent link="link1"/>
    <child link="link2"/>
  </joint>

  <joint name="joint2" type="continuous">
    <parent link="link1"/>
    <child link="link3"/>
  </joint>

  <joint name="joint3" type="continuous">
    <parent link="link3"/>
    <child link="link4"/>
  </joint>
</robot>

从上述内容可以看到, 机器人最重要的两个内容 – link和joint, 是如何进行定义. 文件都定义了哪些标签, 以及该怎么使用. 其中内容很简单, 我就不浪费篇幅了.

细心的朋友肯定能够感受到, 虽然能够想象的出来大概是一个什么样子, 但是上面的内容是不能够唯一确定一个机器人或者一个…东西…, 因为每个link长什么样子?他们又是一个什么样子的位置关系? 这些在上面的内容中都是没有定义的. 如图中所示, 可能现在每一个不同的同学, 所联想到的样子都是不一样的, 一个仙人掌? 一个两指的夹持器? anythin..当然, 上面所示内容的urdf文件是不能够被正确解析的, 也是不能够可视化出来的. 但上面内容就类似于整个机器人的骨架, 机器人就由这些东西组成. 一共拥有4个link, 和3个joint, 像图中所示的样子连接起来.

2.2 位置

在定义好了机器人的骨架后, 进一步我们可以使用origin子标签进行定义link所应该在的位置. 但是有一点应该注意到, link和link之间是使用joint进行连接, 那么link的位置, 就由连接他的joint确定. 所以, 该子标签是定义在joint内. 在三维空间中, 要精确描述一个刚性体的姿态, 仅仅使用他的xyz坐标是不够的, 还需要使用rpy. rpy角是描述船舶在海中航行时姿态的一种方法. 将船的行驶方向取为z轴, 绕z轴旋转称为滚动(Roll), 绕y轴旋转称为俯仰(Pitch), 绕x轴旋转称为偏转(Yaw). 这种描述方式大量运用于各个领域. 依稀记得, kinect2关于脸部模型匹配的DEMO程序里面, 对脸部的描述就用到了这种描述方式来描述姿态. 在机器人中, 当然运用就更多了. 现在对之前的内容进行扩充. 其中rpy代表的是角度, 用弧度表示.

<robot name="test_robot">
  <link name="link1" />
  <link name="link2" />
  <link name="link3" />
  <link name="link4" />


  <joint name="joint1" type="continuous">
    <parent link="link1"/>
    <child link="link2"/>
    <origin xyz=".5 .3 0.7" rpy="0 0 0" />
  </joint>

  <joint name="joint2" type="continuous">
    <parent link="link1"/>
    <child link="link3"/>
    <origin xyz="-.2 .5 -0.3" rpy="0 0 1.57" />
  </joint>

  <joint name="joint3" type="continuous">
    <parent link="link3"/>
    <child link="link4"/>
    <origin xyz=".5 0 0.2" rpy="0 0 -1.57" />
  </<
我的机器人模型:<!-- 组合小车底盘与传感器 --> <robot name="my_car_camera" xmlns:xacro="http://wiki.ros.org/xacro"> <xacro:include filename="my_head.urdf.xacro" /> <xacro:include filename="my_base.urdf.xacro" /> <xacro:include filename="my_laser.urdf.xacro" /> <xacro:include filename="move.urdf.xacro" /> <!-- 雷达仿真的 xacro 文件 --> <xacro:include filename="my_sensors_laser.urdf.xacro" /> </robot> 请帮我修改my_sensors_laser.urdf.xacro:<robot name="my_sensors" xmlns:xacro="http://wiki.ros.org/xacro"> <!-- 雷达(VLP-16) --> <gazebo reference="laser"> <sensor type="gpu_ray" name="vlp16"> <pose>0 0 0 0 0 0</pose> <visualize>true</visualize> <update_rate>10</update_rate> <ray> <scan> <horizontal> <samples>2000</samples> <resolution>0.18</resolution> <min_angle>-3.1415926535</min_angle> <max_angle>3.1415926535</max_angle> </horizontal> <vertical> <samples>16</samples> <resolution>0.2</resolution> <min_angle>-0.261799</min_angle> <max_angle>0.261799</max_angle> </vertical> </scan> <range> <min>0.10</min> <max>100.0</max> <resolution>0.03</resolution> </range> <noise> <type>gaussian</type> <mean>0.0</mean> <stddev>0.03</stddev> </noise> </ray> <plugin name="gazebo_vlp16" filename="libgazebo_ros_gpu_laser.so"> <topicName>/velodyne_points</topicName> <frameName>laser</frameName> <min_range>0.10</min_range> <max_range>100.0</max_range> <hmin>-3.1415926535</hmin> <hmax>3.1415926535</hmax> <vmin>-0.261799</vmin> <vmax>0.261799</vmax> <samples>2000</samples> <resolution>1.0</resolution> <gpu>true</gpu> </plugin> </sensor> </gazebo> </robot>让rostopic info /velodyne_points Type: sensor_msgs/LaserScan 输出的类型为Pointcloud2
04-02
修改正确下列代码 <?xml version="1.0"?> <robot name="husky_robot" xmlns:xacro="http://ros.org/wiki/xacro"> <!-- 引入xacro支持(后续扩展方便) --> <!-- 1. 底盘定义(保留原结构,补充物理属性) --> <link name="base_link"> <!-- 视觉模型(不变) --> <visual> <geometry> <box size="0.8 0.4 0.2"/> <!-- 长宽高: 0.8m x 0.4m x 0.2m --> </geometry> <material name="black"> <color rgba="0 0 0 1"/> </material> </visual> <!-- 碰撞模型(不变) --> <collision> <geometry> <box size="0.8 0.4 0.2"/> </geometry> </collision> <!-- 惯性参数(原参数基础上优化,更符合20kg小车物理特性) --> <inertial> <mass value="20"/> <!-- 总质量20kg,合理 --> <!-- 惯性矩阵:根据长方体公式 Ixx = (m/12)(y²+z²),适配0.8x0.4x0.2尺寸 --> <inertia ixx="0.2267" ixy="0" ixz="0" iyy="0.8533" iyz="0" izz="1.0267"/> </inertial> </link> <!-- 2. 通用车轮宏定义(减少重复代码,统一车轮参数) --> <xacro:macro name="wheel" params="name parent x y"> <link name="${name}_link"> <visual> <geometry> <cylinder length="0.1" radius="0.15"/> <!-- 厚度0.1m,半径0.15m(直径0.3m,合理) --> </geometry> <material name="gray"> <color rgba="0.5 0.5 0.5 1"/> </material> <!-- 车轮视觉模型绕X轴旋转90度(确保圆柱轴线沿Y轴,符合车轮旋转方向) --> <origin rpy="${pi/2} 0 0"/> </visual> <collision> <geometry> <cylinder length="0.1" radius="0.15"/> </geometry> <origin rpy="${pi/2} 0 0"/> </collision> <!-- 车轮惯性参数(2kg单轮,符合实际) --> <inertial> <mass value="2"/> <!-- 圆柱惯性矩阵:Ixx=Iyy=(m/12)(3r²+l²),Izz=(m/2)r² --> <inertia ixx="0.02625" ixy="0" ixz="0" iyy="0.02625" iyz="0" izz="0.045"/> </inertial> </link> <!-- 车轮关节(连续转动关节,添加物理阻尼避免抖动) --> <joint name="joint_${name}" type="continuous"> <parent link="${parent}"/> <child link="${name}_link"/> <!-- 车轮安装位置:x/y由宏参数传入,z=-0.15(底盘底部到地面,半径0.15m,刚好触地) --> <origin xyz="${x} ${y} -0.15" rpy="0 0 0"/> <axis xyz="0 1 0"/> <!-- 绕Y轴旋转(车轮滚动方向正确) --> <!-- 物理阻尼:添加关节摩擦阻尼,避免Gazebo中车轮无阻力滑动 --> <dynamics damping="0.1" friction="0.05"/> </joint> </xacro:macro> <!-- 3. 实例化4个车轮(调用宏定义,指定位置) --> <xacro:wheel name="left_front" parent="base_link" x="0.3" y="0.2"/> <!-- 右前轮:x=0.3(前),y=0.2(右) --> <xacro:wheel name="right_front" parent="base_link" x="0.3" y="-0.2"/> <!-- 左前轮:x=0.3,y=-0.2(左) --> <xacro:wheel name="left_rear" parent="base_link" x="-0.3" y="0.2"/> <!-- 右后轮:x=-0.3(后),y=0.2 --> <xacro:wheel name="right_rear" parent="base_link" x="-0.3" y="-0.2"/> <!-- 左后轮:x=-0.3,y=-0.2 --> <!-- 4. 关键:添加Gazebo差速驱动插件(接收cmd_vel,控制车轮转动) --> <gazebo> <plugin name="gazebo_ros_diff_drive" filename="libgazebo_ros_diff_drive.so"> <!-- 1. 车轮关节名称(与上面定义的关节名完全匹配) --> <left_joint>joint_left_front</left_joint> <left_joint>joint_left_rear</left_joint> <right_joint>joint_right_front</right_joint> <right_joint>joint_right_rear</right_joint> <!-- 2. 小车物理参数(必须与URDF尺寸匹配) --> <wheel_separation>0.4</wheel_separation> <!-- 轮距:左右车轮Y方向距离(0.2 - (-0.2) = 0.4m) --> <wheel_diameter>0.3</wheel_diameter> <!-- 车轮直径:半径0.15m × 2(必须与URDF一致) --> <max_velocity>2.0</max_velocity> <!-- 最大线速度2m/s(ArduPilot控制时需匹配此值) --> <max_angular_velocity>3.14</max_angular_velocity> <!-- 最大角速度1rad/s(约57度/s,转向灵活) --> <!-- 3. ROS通信配置(与ArduPilot-MAVROS桥接节点匹配) --> <command_topic>/cmd_vel</command_topic> <!-- 接收速度指令的话题(必须是/cmd_vel) --> <odometry_topic>/odom</odometry_topic> <!-- 发布里程计数据(反馈小车位置/速度) --> <odometry_frame>odom</odometry_frame> <!-- 里程计坐标系 --> <robot_base_frame>base_link</robot_base_frame> <!-- 小车底盘坐标系 --> </plugin> </gazebo> <!-- 5. 关键:添加IMU传感器插件(提供姿态数据,ArduPilot依赖) --> <gazebo> <plugin name="gazebo_ros_imu" filename="libgazebo_ros_imu.so"> <imuName>imu_sensor</imuName> <updateRate>100.0</updateRate> <!-- 100Hz更新频率,满足控制实时性 --> <bodyName>base_link</bodyName> <!-- IMU安装在底盘上 --> <topicName>/imu/data</topicName> <!-- 发布IMU数据的话题(MAVROS需订阅此话题) --> <frameName>base_link</frameName> <!-- IMU坐标系与底盘一致 --> <!-- 传感器噪声配置(模拟真实IMU,避免数据过于理想) --> <gyroOffsetX>0.001</gyroOffsetX> <gyroOffsetY>0.001</gyroOffsetY> <gyroOffsetZ>0.001</gyroOffsetZ> <accelOffsetX>0.01</accelOffsetX> <accelOffsetY>0.01</accelOffsetY> <accelOffsetZ>0.01</accelOffsetZ> </plugin> </gazebo> <!-- 6. 关键:添加GPS传感器插件(提供位置数据,ArduPilot依赖) --> <gazebo> <plugin name="gazebo_ros_gps" filename="libgazebo_ros_gps.so"> <gpsName>gps_sensor</gpsName> <updateRate>10.0</updateRate> <!-- GPS通常10Hz更新,合理 --> <bodyName>base_link</bodyName> <!-- GPS安装在底盘上 --> <topicName>/gps/fix</topicName> <!-- 发布GPS数据的话题(MAVROS需订阅此话题) --> <frameName>base_link</frameName> <!-- GPS噪声配置(模拟真实GPS精度,如1m级) --> <horizError>1.0</horizError> <!-- 水平误差1m --> <vertError>2.0</vertError> <!-- 垂直误差2m --> <velError>0.1</velError> <!-- 速度误差0.1m/s --> </plugin> </gazebo> <!-- 7. 可选:添加地面摩擦力配置(避免小车打滑) --> <gazebo> <link name="base_link"> <surface> <friction> <ode> <mu>1.0</mu> <!-- 静摩擦系数1.0(地面抓地力正常) --> <mu2>1.0</mu2> <fdir1>0 1 0</fdir1> </ode> </friction> </surface> </link> </gazebo> <!-- 8. 全局参数定义(xacro宏依赖) --> <xacro:property name="pi" value="3.141592653589793"/> </robot>
09-16
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值