6.机器人系统仿真
6.1 URDF-RVIZ
6.1.1 URDF集成RVIZ基本流程
依赖只需要导入urdf和xacro
然后建立目录如下
目录介绍:
urdf: 存储 urdf 文件的目录
meshes:机器人模型渲染文件(暂不使用)
config: 配置文件
launch: 存储 launch 启动文件
.urdf文件编写如下
<robot name="mycar">
<link name="base_link">
<visual>
<geometry>
<box size="0.5 0.2 0.1" />
</geometry>
</visual>
</link>
</robot>
launch文件编写如下
<launch>
<!-- 设置参数 -->
<param name="robot_description" textfile="$(find 包名)/urdf/urdf/urdf01_HelloWorld.urdf" />
<!-- 启动 rviz -->
<node pkg="rviz" type="rviz" name="rviz" />
</launch>
ADD RobotModel,将坐标系输入为设置的
6.1.2 优化
每次打开rviz都要手动ADD和设置Fixed Frame,非常麻烦。
但是可以通过保存的方式在启动时自动设置。
File -> Save Config As
选择存储位置,输入名称,Save。(一般保存到同目录的config里)
<launch>
<!-- 设置参数 -->
<param name="robot_description" textfile="$(find 包名)/urdf/urdf/urdf01_HelloWorld.urdf" />
<!-- 启动 rviz -->
<node pkg="rviz" type="rviz" name="rviz" args=" -d $(find 包名)/urdf/config/文件名.rviz" />
</launch>
参数一定要用这个
6.2 URDF标签简介
robot 根标签,类似于 launch文件中的launch标签
link 连杆标签
joint 关节标签
gazebo 集成gazebo需要使用的标签
6.2.1 robot标签
<robot name="xx">
···············
</robot>
6.2.2 URDF_link标签
子标签:
visual ---> 描述外观(对应的数据是可视的)
geometry 设置连杆的形状
标签1: box(盒状)
属性:size=长(x) 宽(y) 高(z)
标签2: cylinder(圆柱)
属性:radius=半径 length=高度
标签3: sphere(球体)
属性:radius=半径
标签4: mesh(为连杆添加皮肤)
属性: filename=资源路径(格式:package://<packagename>/<path>/文件)
origin 设置偏移量与倾斜弧度
属性1: xyz=x偏移 y便宜 z偏移
属性2: rpy=x翻滚 y俯仰 z偏航 (单位是弧度)
metrial 设置材料属性(颜色)
属性: name
标签: color
属性: rgba=红绿蓝权重值与透明度 (每个权重值以及透明度取值[0,1])
collision ---> 连杆的碰撞属性
Inertial ---> 连杆的惯性矩阵
这里只显示可视化部分
<robot name="car">
<link name="base_link">
<visual>
<geometry>
<!-- 立方体 -->
<box size="0.3 0.2 1" />
<!-- 圆柱体 -->
<cylinder radius="0.2" length="1" />
<!-- 球体 -->
<sphere radius="1" />
<!-- 皮肤 -->
<mesh filename="package://包名/meshes/autolabor_mini.stl" />
</geometry>
</visual>
</link>
</robot>
其中皮肤包含了一个模型的很多内容,但是需要提前制作。
6.2.3 设置偏移量与欧拉角
<visual>
<geometry>
<!-- 立方体 -->
<!-- <box size="0.3 0.2 1" /> -->
<!-- 圆柱体 -->
<!-- <cylinder radius="0.2" length="1" /> -->
<!-- 球体 -->
<!-- <sphere radius="1" /> -->
<!-- 皮肤 -->
<mesh filename="package://urdf1_rviz/meshes/autolabor_mini.stl" />
</geometry>
<origin xyz="0 0 0" rpy="1.57 0 1.57" />
</visual>
rpy分别是翻滚,俯仰和偏航(采用弧度制,180°=π≈3.14)
6.2.4 设置颜色
<material name="car_color">
<color rgba="0.5 0.5 0.5 1" />
</material>
RGBA:red,blue,green,透明度(1为不透明)
6.3 joint标签
6.3.1 joint编写
标签:
name —> 为关节命名
type ---> 关节运动形式
continuous: 旋转关节,可以绕单轴无限旋转
revolute: 旋转关节,类似于 continues,但是有旋转角度限制
prismatic: 滑动关节,沿某一轴线移动的关节,有位置极限
planer: 平面关节,允许在平面正交方向上平移或旋转
floating: 浮动关节,允许进行平移、旋转运动
fixed: 固定关节,不允许运动的特殊关节
子标签:
parent(必需的)
parent link的名字是一个强制的属性:
link:父级连杆的名字,是这个link在机器人结构树中的名字。
child(必需的)
child link的名字是一个强制的属性:
link:子级连杆的名字,是这个link在机器人结构树中的名字。
origin
属性: xyz=各轴线上的偏移量 rpy=各轴线上的偏移弧度。
这个偏移量基于父级连杆
axis
属性: xyz用于设置围绕哪个关节轴运动。
<joint name="camera2base" type="continuous">
<parent link="base_link" />
<child link="camera" />
<origin xyz="0.15 0 0.05" rpy="0 0 0" />
<axis xyz="0 0 1" />
</joint>
相对关系:
关节相对于父连杆
子连杆相对于关节
6.3.2 launch编写
记得退出anaconda
<launch>
<param name="robot_description" textfile="$(find urdf1_rviz)/urdf/urdf/test_joint.urdf" />
<node pkg="rviz" type="rviz" name="rviz" args="-d $(find urdf1_rviz)/config/show_car.rviz" />
<node pkg="joint_state_publisher" type="joint_state_publisher" name="joint_state_publisher" />
<node pkg="robot_state_publisher" type="robot_state_publisher" name="robot_state_publisher" />
</launch>
添加如下节点发布节点和机器人坐标信息
6.3.3 关节控制(不常用)
<node pkg="joint_state_publisher_gui" type="joint_state_publisher_gui" name="joint_state_publisher_gui" />
显示图形化界面控制节点运动
6.3.4 底盘优化
因为形状经常是以中心点向外发散的,所以底盘会出现在地下的情况。
经常会设置非常小的footprint连接在底盘下面,让底盘显示在地面上。
<link name="base_footprint">
<visual>
<geometry>
<box size="0.001 0.001 0.001" />
</geometry>
</visual>
</link>
..............................
<joint name="footprint" type="fixed">
<parent link="base_footprint" />
<child link="base_link" />
<origin xyz="0 0 0.05" rpy="0 0 0" />
</joint>
记得rviz的参考坐标系设置为base_footprint
6.3.5 小车练习
原文
编码如下(颜色没调):
<robot name="car">
<link name="base_footprint">
<visual>
<geometry>
<box size="0.001 0.001 0.001" />
</geometry>
</visual>
</link>
<!--base-->
<link name="base_link">
<visual>
<geometry>
<cylinder radius="0.1" length="0.08"/>
</geometry>
<origin xyz="0 0 0" rpy="0 0 0" />
<material name="car_color">
<color rgba="0.8 0.5 0 0.5" />
</material>
</visual>
</link>
<!--base to footprint-->
<joint name="footprint" type="fixed">
<parent link="base_footprint" />
<child link="base_link" />
<origin xyz="0 0 0.055" rpy="0 0 0" />
</joint>
<!--left_wheel-->
<link name="left_wheel">
<visual>
<geometry>
<cylinder radius="0.0325" length="0.015"/>
</geometry>
<origin xyz="0 0 0" rpy="0 0 0" />
<material name="camera_color">
<color rgba="0 0 1 0.5" />
</material>
</visual>
</link>
<!--right_wheel-->
<link name="right_wheel">
<visual>
<geometry>
<cylinder radius="0.0325" length="0.015"/>
</geometry>
<origin xyz="0 0 0" rpy="0 0 0" />
<material name="camera_color">
<color rgba="0 0 1 0.5" />
</material>
</visual>
</link>
<!--left_wheel to base-->
<joint name="left_wheel_joint" type="continuous">
<parent link="base_link" />
<child link="left_wheel" />
<origin xyz="0 0.1 -0.02335" rpy="1.5708 1.5708 0" />
<axis xyz="0 0 1" />
</joint>
<!--right_wheel to base-->
<joint name="right_wheel_joint" type="continuous">
<parent link="base_link" />
<child link="right_wheel" />
<origin xyz="0 -0.1 -0.02335" rpy="1.5708 1.5708 0" />
<axis xyz="0 0 1" />
</joint>
<!--front_wheel-->
<link name="front_wheel">
<visual>
<geometry>
<sphere radius="0.0075"/>
</geometry>
<origin xyz="0 0 0" rpy="0 0 0" />
<material name="camera_color">
<color rgba="0 0 1 0.5" />
</material>
</visual>
</link>
<!--rear_wheel-->
<link name="rear_wheel">
<visual>
<geometry>
<sphere radius="0.0075"/>
</geometry>
<origin xyz="0 0 0" rpy="0 0 0" />
<material name="camera_color">
<color rgba="0 0 1 0.5" />
</material>
</visual>
</link>
<!--front_wheel to base-->
<joint name="front_wheel_joint" type="continuous">
<parent link="base_link" />
<child link="front_wheel" />
<origin xyz="0.1 0 -0.0475" rpy="0 0 0" />
<axis xyz="1 1 1" />
</joint>
<!--rear_wheel to base-->
<joint name="rear_wheel_joint" type="continuous">
<parent link="base_link" />
<child link="rear_wheel" />
<origin xyz="-0.1 0 -0.0475" rpy="0 0 0" />
<axis xyz="1 1 1" />
</joint>
</robot>
内容很浅显,不再解释
6.4 URDF工具
check_urdf
可以用于urdf文件的检查
urdf_to_graphiz
用于生成显示urdf文件内部关系的PDF文件
evince查看
6.6 xacro
xacro是一种面向xml的编程语言,在编程前,需要先写如下一行
<robot name="xxx" xmlns:xacro="http://www.ros.org/wiki/xacro">
6.6.1 属性设置
可以根据固定格式将属性封装
<xacro:property name="PI" value="3.1415927"/>
<xacro:property name="e" value="2.718281828459045"/>
调用格式为${name},可以直接进行数值
<xxx value="${PI}"/>
<xxx value="${e / 2}"/>
可以使用rosrun运行
rosrun xacro xacro xxxx.xacro
结果如下
6.6.2 宏定义
定义:
<xacro:macro name="getSum" params="a b">
<result value="${a + b}"/>
</xacro:macro>
参数不是必须的,也可以没有参数
调用:
<xacro:getSum a="1" b="2"/>
效果:
6.6.3 文件包含
和头文件差不多
<xacro:include filename="macro.urdf.xacro"/>
6.6.4 集成launch文件
法1 解析成urdf
现将xacro解析成urdf文件,再调用urdf文件
rosrun xacro xacro xxx.xacro > xxx.urdf
法2 直接在launch文件里加载
<param name="robot_description" command="$(find xacro)/xacro $(find xxx)/urdf/xacro/xxx.urdf.xacro" />
6.6.5 练习实例
<robot name="car" xmlns:xacro="http://www.ros.org/wiki/xacro">
<xacro:property name="PI" value="3.1415927"/>
<link name="base_footprint">
<visual>
<geometry>
<box size="0.001 0.001 0.001" />
</geometry>
</visual>
</link>
<xacro:property name="car_radius" value="0.1"/>
<xacro:property name="car_length" value="0.08"/>
<link name="base_link">
<visual>
<geometry>
<cylinder radius="${car_radius}" length="${car_length}" />
</geometry>
<origin xyz="0 0 0" rpy="0 0 0" />
<material name="car_color">
<color rgba="0.8 0.5 0 0.5" />
</material>
</visual>
</link>
<xacro:property name="footprint_origin_z" value="0.015"/>
<joint name="footprint" type="fixed">
<parent link="base_footprint" />
<child link="base_link" />
<origin xyz="0 0 ${footprint_origin_z + car_length / 2 }" rpy="0 0 0" />
</joint>
<xacro:property name="wheel_radius" value="0.0325"/>
<xacro:property name="wheel_length" value="0.015"/>
<xacro:macro name="addwheels" params="name radius length material">
<link name="${name}">
<visual>
<geometry>
<cylinder radius="${radius}" length="${length}" />
</geometry>
<origin xyz="0 0 0" rpy="0 0 0" />
<material name="${material}">
<color rgba="0 0 1 0.5" />
</material>
</visual>
</link>
</xacro:macro>
<xacro:addwheels name="left_wheel" radius="${wheel_radius}" length="${wheel_length}" material="left_wheel_color" />
<xacro:addwheels name="right_wheel" radius="${wheel_radius}" length="${wheel_length}" material="right_wheel_color" />
<xacro:macro name="joints" params="name type parent child axis xyz">
<joint name="${name}_joint" type="${type}">
<parent link="${parent}" />
<child link="${child}" />
<origin xyz="${xyz}" rpy="${PI / 2} 0 0"/>
<axis xyz="${axis}"/>
</joint>
</xacro:macro>
<xacro:joints name="left_wheel" type="continuous" parent="base_link" child="left_wheel" axis="0 0 1" xyz="0 ${car_radius} -${car_length / 2 + footprint_origin_z - wheel_radius}"/>
<xacro:joints name="right_wheel" type="continuous" parent="base_link" child="right_wheel" axis="0 0 1" xyz="0 -${car_radius} -${car_length / 2 + footprint_origin_z - wheel_radius}"/>
<xacro:property name="universal_wheel_radius" value="0.0075"/>
<xacro:macro name="add_universal_wheel" params="name radius material">
<link name="${name}" >
<visual>
<geometry>
<sphere radius="${radius}" />
</geometry>
<origin xyz="0 0 0" rpy="0 0 0" />
<material name="${material}" >
<color rgba="0 1 0 0.5" />
</material>
</visual>
</link>
</xacro:macro>
<xacro:add_universal_wheel name="front_wheel" radius="${universal_wheel_radius}" material="front_wheel_color" />
<xacro:add_universal_wheel name="rear_wheel" radius="${universal_wheel_radius}" material="rear_wheel_color" />
<xacro:joints name="front_wheel" type="continuous" parent="base_link" child="front_wheel" axis="1 1 1" xyz="${car_radius} 0 -${car_length / 2 + footprint_origin_z - universal_wheel_radius}"/>
<xacro:joints name="rear_wheel" type="continuous" parent="base_link" child="rear_wheel" axis="1 1 1" xyz="-${car_radius} 0 -${car_length / 2 + footprint_origin_z - universal_wheel_radius}"/>
</robot>
一段······问题很大的代码,实际上写的相当烂
后续有待优化。