一、概述:
1.机器人系统仿真:
是通过计算机对实体机器人系统进行模拟的技术,在 ROS 中,仿真实现涉及的内容主要有三:对机器人建模(URDF)、创建仿真环境(Gazebo)以及感知环境(Rviz)等系统性实现。
(1)仿真优势:低成本、高效、高安全性。
(2)仿真缺陷:仿真器所使用的物理引擎目前还不能够完全精确模拟真实世界的物理情况;仿真器构建的是关节驱动器(电机&齿轮箱)、传感器与信号通信的绝对理想情况,目前不支持模拟实际硬件缺陷或者一些临界状态等情形。
2.机器人系统仿真所需组件:
(1)创建机器人模型:
URDF (Unified Robot Description Format,统一(标准化)机器人描述格式) ,以 XML 的方式描述机器人的部分结构,比如底盘、摄像头、激光雷达、机械臂以及不同关节的自由度,该文件可以被 C++ 内置的解释器转换成可视化的机器人模型,是 ROS 中实现机器人仿真的重要组件。
(2)显示各传感器信息:
rviz(ROS Visualization Tool,ROS的三维可视化工具),它的主要目的是以三维方式显示ROS消息,可以将数据进行可视化表达。例如:可以显示机器人模型,可以无需编程就能表达激光测距仪(LRF)传感器中的传感器到障碍物的距离,Kinect或Xtion等三维距离传感器的点云数据(PCD, Point Cloud Data),从相机获取的图像值等。
(3)搭建仿真环境:
Gazebo是一款3D动态模拟器,用于显示机器人模型并创建仿真环境,能够在复杂的室内和室外环境中准确有效地模拟机器人。与游戏引擎提供高保真度的视觉模拟类似,Gazebo提供高保真度的物理模拟,其提供一整套传感器模型,以及对用户和程序非常友好的交互方式。
二、URDF语法讲解:
1.将URDF集成进rviz基本流程:
URDF 不能单独使用,需要结合 Rviz 或 Gazebo。URDF 只是一个文件,需要在 Rviz 或 Gazebo中渲染成图形化的机器人模型。
(1)创建功能包,并导入依赖:
在该功能包下创建四个文件夹:
1)urdf:用于存放机器人模型的URDF或xacro文件;
2)meshes:用于放置URDF中引用的模型渲染文件;
3)launch:用于保存相关启动文件;
4)config:用于保存rviz的配置文件。
(2)编写urdf文件:
在功能包中新建子文件夹:urdf,添加一个.urdf文件,内容如下:
<robot name="mycar">
<link name="base_link">
<visual>
<geometry>
<box size="0.5 0.2 0.1" />
</geometry>
</visual>
</link>
</robot>
(3)在launch文件中集成URDF与rviz:
在功能包中新建子文件夹:launch,添加一个.launch文件,内容如下:
<launch>
<!-- 设置参数 -->
<param name="robot_description" textfile="$((find learning_urdf)/urdf/mycar.urdf" />
<!-- 启动 rviz -->
<node pkg="rviz" type="rviz" name="rviz" />
</launch>
(4)通过launch文件启动rviz,并加载机器人模型:
PS:编译过程中有可能出现因缺少xacro的包导致编译失败
解决方式是输入以下安装指令安装xacro相关包:
sudo apt-get install ros-noetic-xacro
(5)rviz 启动后,会发现并没有机器人模型,这是因为默认情况下没有添加机器人显示组件,需要手动添加,添加方式如下:
(6)Fixed Frame处要将默认值map改为urdf文件中机器人底座的name(此处设置的是base_link):
(7)重复启动launch文件时,Rviz 之前的组件配置信息不会自动保存,需要重复执行步骤4的操作,为了方便使用,可以使用如下方式优化:
1)在功能包中新建子文件夹config:
2)将文件另存为一个.rviz文件:
2.urdf语法:
URDF文件是一个标准的XML文件,在ROS中预定义了一系列的标签用于描述机器人模型机器人模型可能较为复杂,但是ROS的URDF中机器人的组成却是较为简单,URDF中有四类标签:
<robot>:根标签,类似于 launch文件中的launch标签;
<link>:连杆标签;
<joint>:关节标签;
<gazebo>: 集成gazebo需要使用的标签。
(1)<robot>标签:
<robot>标签是完整机器人模型最顶层标签,<link>和<joint>标签都必须包含在<robot>标签内。如下图所示,一个完整的机器人模型由一系列<link>和<joint>组成:
<robot>标签内可以设置机器人的名称,其基本语法如下:
<robot name="<name of the robot>">
<link>......</link>
<link>......</link>
<joint>......</joint>
<joint>......</joint>
</robot>
(2)<link>标签:
<link>标签用于描述机器人某个部件的外观和物理属性,如形状、尺寸、颜色、惯性矩阵、碰撞参数等。机器人的link结构一般如下图所示:
基本的URDF描述语法如下:
<link name="<link name>">
<inertial>......</inertial>
<visual>......</visual>
<collision>......</collision>
</link>
子标签的描述内容如下:
示例:demo02_link.urdf
<link name="base_link">
<visual>
<!--形状-->
<geometry>
<!--长方体的长宽高-->
<!--<box size="0.5 0.3 0.1" />-->
<!--圆柱,半径和长度-->
<!--<cylinder radius="0.5" length="0.1" />-->
<!--球体,半径-->
<!--<sphere radius="0.3" />-->
<!--皮肤-->
<!--<mesh filename="package://learning_urdf/meshes/autolabor_mini.stl" />-->
</geometry>
<!--xyz坐标 rpy翻滚、俯仰、偏航(弧度)-->
<origin xyz="0 0 0" rpy="0 0 0" />
<!--颜色:r=red g=green b=blue a=alpha-->
<material name="black" >
<color rgba="0.7 0.5 0 0.5" />
</material>
</visual>
</link>
(3)<joint>标签:
<joint>标签用于描述机器人关节的运动学和动力学属性,包括关节运动的位置和速度限制。
根据机器人的关节运动形式,可以将其分为六种类型:
与人的关节一样,机器人关节(joint)的主要作用是连接两个刚体(link),这两个link分别称为parent link和child link,如下图所示:
<joint>标签的描述语法如下:
<joint name="<name of the joint>" type="<type of the joint>">
<parent link="parent_link" />
<child link="child_link" />
<calibration .../>
<dynamics damping .../>
<limit effort .../>
...
</joint>
在这些joint的属性中,必须指定joint的parent link和child link,其他属性可选:
1)<parent link>:强制的属性,父级连杆的名字,是这个link在机器人结构树中的名字。
2)<child link>:强制的属性,子级连杆的名字,是这个link在机器人结构树中的名字。
3)<origin>:xyz=各轴线上的偏移量 rpy=各轴线上的偏移弧度。
4)<axis>:xyz用于设置围绕哪个关节轴运动。
5)<calibration>:关节的参考位置,用来校准关节的绝对位置。
6)<dynamics>:用于描述关节的物理属性,例如阻尼值、物理静摩擦力等,经常在动力学仿真中用到。
7)<limit>:用于描述运动的一些极限值,包括关节运动的上下限位置、速度限制、力矩限制等。
8)<mimic>:用于描述该关节与已有关节的关系。
9)<safety_controller>:用于描述安全控制器参数。
(4)<gazebo>标签:
<gazebo>标签用于描述机器人在Gazebo模型中仿真所需要的参数,包括机器人材料的属性、Gazebo插件等。该标签不是机器人模型必须的部分,只有在Gazebo仿真时才需要加入。
基本语法如下:
<gazebo reference="link_1">
<material>Gazebo/Black</material>
</gazebo>
3.(练习)创建机器人模型,底盘为长方体,在长方体的上方安装一摄像头,摄像头可以沿着z轴360度旋转:
(1)编写demo03_joint.urdf文件:
<!--设置机器人底盘,并添加摄像头-->
<robot name="mycar" >
<!--1.底盘 link-->
<link name="base_link">
<visual>
<geometry>
<box size="0.3 0.2 0.1" />
</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>
<!--2.摄像头 link-->
<link name="camera">
<visual>
<geometry>
<box size="0.02 0.05 0.05" />
</geometry>
<origin xyz="0 0 0.025" rpy="0 0 0" />
<material name="camera_color">
<color rgba="0 0 1 0.5" />
</material>
</visual>
</link>
<!--3.关节 joint-->
<joint name="camera2base" type="continuous">
<parent link="base_link" />
<child link="camera" />
<!--设置偏移量-->
<origin xyz="0.13 0 0.05" rpy="0 0 0" />
<!--设置关节旋转参考坐标轴-->
<axis xyz="0 0 1" />
</joint>
</robot>
(2)编写launch文件:
joint_state_publisher节点:可以发布每个joint的状态。
robot_state_publisher节点:将机器人各个link、joint之间的关系,通过TF的形式整理成三维姿态信息发布出去。
<launch>
<!--1.在参数服务器载入urdf文件-->
<param name="robot_description" textfile="$(find learning_urdf)/urdf/demo03_joint.urdf" />
<!--2.启动rviz-->
<node pkg="rviz" type="rviz" name="rviz" args="-d $(find learning_urdf)/config/show_mycar.rviz"/>
<!--rviz显示urdf时,必须发布不同部件之间的坐标系关系-->
<!--ROS中已经提供了机器人模型显示发布的相关节点(两个)-->
<!--关节状态发布节点-->
<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"/>
<!--添加控制关节运动的节点-->
<node pkg="joint_state_publisher_gui" type="joint_state_publisher_gui" name="joint_state_publisher_gui"/>
</launch>
(3)运行:
PS:使用launch文件启动rviz时,可能出现如下报错
解决方案 :缺少依赖包,按指令安装以下依赖包即可
sudo apt-get install ros-noetic-robot-state-publisher
sudo apt-get install ros-noetic-joint-state-publisher
sudo apt-get install ros-noetic-joint-state-publisher-gui
补充完以上依赖包后,通过launch文件打开rviz,发现之前存在的status错误全部解决了。
4.base_footprint优化urdf:
之前实现的机器人模型是半沉到地下的,因为默认情况下: 底盘的中心点位于地图原点上,所以会导致这种情况产生。
优化策略:将初始link设置为一个尺寸极小的link(比如半径为0.001m的球体,或边长0.001m的立方体),然后再在初始 link上添加底盘等刚体,这个初始link一般称之为 base_footprint。
<!--base_footprint-->
<link name="base_footprint">
<visual>
<geometry>
<box size="0.001 0.001 0.001" />
</geometry>
</visual>
</link>
<!--关联baes_link与base_footprint-->
<joint name="link2footprint" type="fixed">
<parent link="base_footprint" />
<child_link="base_link" />
<!--设置偏移量-->
<origin xyz="0 0 0.05" rpy="0 0 0" />
</joint>
base_footprint的相关链接:
DAY5-URDF优化 简单小练习 工具_Zima Blue?的博客-CSDN博客
【ROS_URDF】小车+摄像头+优化footprint的urdf文件,带中文注释_Baily24的博客-CSDN博客
5.(课后作业)urdf文件编写练习:
要求:
(1)新建文件,demo05_test.urdf,并与launch文件集成;
(2)创建一个四轮圆柱状机器人模型,机器人参数如下:底盘为圆柱状,半径 10cm,高 8cm,四轮由两个驱动轮和两个万向支撑轮组成,两个驱动轮半径为 3.25cm,轮胎宽度1.5cm,两个万向轮为球状,半径 0.75cm,底盘离地间距为 1.5cm,与万向轮直径一致(注意joint偏移量的计算)。
作业过程:
(1)创建urdf文件:
<robot name="mycar">
<!-- 设置 base_footprint -->
<link name="base_footprint">
<visual>
<geometry>
<sphere radius="0.001" />
</geometry>
</visual>
</link>
<!-- 添加底盘 -->
<!--
参数
形状:圆柱
半径:10 cm
高度:8 cm
离地:1.5 cm
-->
<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="yellow">
<color rgba="0.8 0.3 0.1 0.5" />
</material>
</visual>
</link>
<joint name="base_link2base_footprint" type="fixed">
<parent link="base_footprint" />
<child link="base_link"/>
<origin xyz="0 0 0.055" />
</joint>
<!-- 添加驱动轮 -->
<!--
驱动轮是侧翻的圆柱
参数
半径: 3.25 cm
宽度: 1.5 cm
颜色: 黑色
关节设置:
x = 0
y = 底盘的半径 + 轮胎宽度 / 2
z = 离地间距 + 底盘长度 / 2 - 轮胎半径 = 1.5 + 4 - 3.25 = 2.25(cm)
axis = 0 1 0
-->
<link name="left_wheel">
<visual>
<geometry>
<cylinder radius="0.0325" length="0.015" />
</geometry>
<origin xyz="0 0 0" rpy="1.5705 0 0" />
<material name="black">
<color rgba="0.0 0.0 0.0 1.0" />
</material>
</visual>
</link>
<joint name="left_wheel2base_link" type="continuous">
<parent link="base_link" />
<child link="left_wheel" />
<origin xyz="0 0.1 -0.0225" />
<axis xyz="0 1 0" />
</joint>
<link name="right_wheel">
<visual>
<geometry>
<cylinder radius="0.0325" length="0.015" />
</geometry>
<origin xyz="0 0 0" rpy="1.5705 0 0" />
<material name="black">
<color rgba="0.0 0.0 0.0 1.0" />
</material>
</visual>
</link>
<joint name="right_wheel2base_link" type="continuous">
<parent link="base_link" />
<child link="right_wheel" />
<origin xyz="0 -0.1 -0.0225" />
<axis xyz="0 1 0" />
</joint>
<!-- 添加万向轮(支撑轮) -->
<!--
参数
形状: 球体
半径: 0.75 cm
颜色: 黑色
关节设置:
x = 自定义(底盘半径 - 万向轮半径) = 0.1 - 0.0075 = 0.0925(cm)
y = 0
z = 底盘长度 / 2 + 离地间距 / 2 = 0.08 / 2 + 0.015 / 2 = 0.0475
axis= 1 1 1
-->
<link name="front_wheel">
<visual>
<geometry>
<sphere radius="0.0075" />
</geometry>
<origin xyz="0 0 0" rpy="0 0 0" />
<material name="black">
<color rgba="0.0 0.0 0.0 1.0" />
</material>
</visual>
</link>
<joint name="front_wheel2base_link" type="continuous">
<parent link="base_link" />
<child link="front_wheel" />
<origin xyz="0.0925 0 -0.0475" />
<axis xyz="1 1 1" />
</joint>
<link name="back_wheel">
<visual>
<geometry>
<sphere radius="0.0075" />
</geometry>
<origin xyz="0 0 0" rpy="0 0 0" />
<material name="black">
<color rgba="0.0 0.0 0.0 1.0" />
</material>
</visual>
</link>
<joint name="back_wheel2base_link" type="continuous">
<parent link="base_link" />
<child link="back_wheel" />
<origin xyz="-0.0925 0 -0.0475" />
<axis xyz="1 1 1" />
</joint>
</robot>
(2) 在launch文件中集成URDF与rviz:
<launch>
<!-- 将 urdf 文件内容设置进参数服务器 -->
<param name="robot_description" textfile="$(find demo01_urdf_helloworld)/urdf/urdf/test.urdf" />
<!-- 启动 rivz -->
<node pkg="rviz" type="rviz" name="rviz_test" args="-d $(find demo01_urdf_helloworld)/config/helloworld.rviz" />
<!-- 启动机器人状态和关节状态发布节点 -->
<node pkg="robot_state_publisher" type="robot_state_publisher" name="robot_state_publisher" />
<node pkg="joint_state_publisher" type="joint_state_publisher" name="joint_state_publisher" />
<!-- 启动图形化的控制关节运动节点 -->
<node pkg="joint_state_publisher_gui" type="joint_state_publisher_gui" name="joint_state_publisher_gui" />
</launch>
(3)编译,通过launch文件启动rviz,并加载机器人模型:
相关链接:文章来源:https://www.toymoban.com/news/detail-487554.html
【基于ROS的URDF练习实例】四轮机器人与摄像头的使用_生如昭诩的博客-CSDN博客
6.urdf工具:
URDF提供了一些命令行工具,可以帮助我们检查、梳理模型文件,需要在终端中独立安装:
sudo apt-get install liburdfdom-tools
(1)check_urdf语法检查:
check_urdf <名称>.urdf
check_urdf会解析urdf文件,并且显示解析过程中发现的错误。如果一切正常,在终端中会输出以下信息:
(2)urdf_to_graphiz结构查看:
urdf_to_graphiz <名称>.urdf
urdf_to_graphiz命令可以查看urdf模型的整体结构。
三、URDF优化—xacro:
1.xacro简介:
urdf构建的机器人模型存在以下问题:
(1)在设计关节的位置时,需要按照一定的公式计算,公式是固定的,但是在 URDF 中依赖于人工计算,存在不便,容易计算失误,且当某些参数发生改变时,还需要重新计算;
(2)URDF 中的部分内容是高度重复的,驱动轮与支撑轮的设计实现,不同轮子只是部分参数不同,形状、颜色、翻转量都是一致的,在实际应用中,构建复杂的机器人模型时,更是易于出现高度重复的设计,按照一般的编程涉及到重复代码应该考虑封装。
在 ROS 中,为解决这样的问题,针对urdf模型产生了另一种精简化、可复用、模块化的描述形式——xacro,它具备如下优势:
(1)精简模型代码:在xacro文件中,可以通过创建宏定义的方式定义常量或复用代码,不仅可以减少代码量,而且可以让模型代码更加模块化、更具可读性;
(2)提供可编程接口:xacro的语法支持一些可编程接口,如常量、变量、数学公式、条件语句等,可以让建模过程更加智能有效。
2.xacro语法讲解:
(1)属性与算术运算:
1)属性定义:
<xacro:property name="xxxx" value="yyyy" />
2)属性调用:
${属性名称}
3)算术运算:
${数学表达式}
(2)宏:
类似于函数实现,提高代码复用率,优化代码结构,提高安全性。
1)宏定义:
<xacro:macro name="宏名称" params="参数列表(多参数之间使用空格分隔)">
......
</xacro:macro>
2)宏调用:
<xacro:宏名称 参数1=xxx 参数2=xxx />
(3)文件包含:
<robot name="xxx" xmlns:xacro="http://wiki.ros.org/xacro">
<xacro:include filename=“xxx.xacro" />
......
</robot>
3.xacro文件编写:
demo01.urdf.xacro
<robot name="mycar" xmlns:xacro="http://wiki.ros.org/xacro">
<!-- 属性封装 -->
<xacro:property name="wheel_radius" value="0.0325" />
<xacro:property name="wheel_length" value="0.0015" />
<xacro:property name="PI" value="3.1415927" />
<xacro:property name="base_link_length" value="0.08" />
<xacro:property name="lidi_space" value="0.015" />
<!-- 宏 -->
<xacro:macro name="wheel_func" params="wheel_name flag" >
<link name="${wheel_name}_wheel">
<visual>
<geometry>
<cylinder radius="${wheel_radius}" length="${wheel_length}" />
</geometry>
<origin xyz="0 0 0" rpy="${PI / 2} 0 0" />
<material name="wheel_color">
<color rgba="0 0 0 0.3" />
</material>
</visual>
</link>
<!-- 3-2.joint -->
<joint name="${wheel_name}2link" type="continuous">
<parent link="base_link" />
<child link="${wheel_name}_wheel" />
<!--
x 无偏移
y 车体半径
z z= 车体高度 / 2 + 离地间距 - 车轮半径
-->
<origin xyz="0 ${0.1 * flag} ${(base_link_length / 2 + lidi_space - wheel_radius) * -1}" rpy="0 0 0" />
<axis xyz="0 1 0" />
</joint>
</xacro:macro>
<xacro:wheel_func wheel_name="left" flag="1" />
<xacro:wheel_func wheel_name="right" flag="-1" />
</robot>
4.xacro文件转换成urdf文件:
命令行进入 xacro文件 所属目录,执行:
rosrun xacro xacro <文件名>.xacro > <文件名>.urdf
这样就将 xacro 文件解析为 urdf 文件,并储存在当前路径。
解析前:
解析后:
5.xacro文件集成launch文件:
<launch>
<!--1.在参数服务器载入urdf文件-->
<param name="robot_description" command="$(find xacro)/xacro $(find learning_urdf)/urdf/demo01.urdf.xacro" />
<!--2.启动rviz-->
<node pkg="rviz" type="rviz" name="rviz" args="-d $(find learning_urdf)/config/show_mycar.rviz" />
<!--3.关节状态发布节点-->
<node pkg="joint_state_publisher" type="joint_state_publisher" name="joint_state_publisher" />
<!--4.机器人状态发布节点-->
<node pkg="robot_state_publisher" type="robot_state_publisher" name="robot_state_publisher" />
</launch>
6.通过launch启动rviz:
(这里笔者做出来的结果总是报错,错误原因应该是demo01.urdf.xacro代码有错误,但笔者尚未找到错误,也尚未在网上找到可用代码)
相关链接:
ROS ERROR_printeger的博客-CSDN博客
使用xacro优化URDF的问题解决_m0_56588389的博客-CSDN博客
四.xacro练习:
1.要求:
(1)将demo05_test.urdf所搭建的机器人,改写为.xacro文件,驱动轮和支撑轮通过宏实现;
(2)将所提供的摄像头与雷达的.xacro文件与机器人底盘组合,用<xacro:include filename=“xxx.xacro” />调用各文件 ;
(3)通过launch文件启动rviz并显示模型。
2.编写xacro文件:
(1)小车底盘的xacro文件:
<!--
使用 xacro 优化 URDF 版的小车底盘实现:
实现思路:
1.将一些常量、变量封装为 xacro:property
比如:PI 值、小车底盘半径、离地间距、车轮半径、宽度 ....
2.使用 宏 封装驱动轮以及支撑轮实现,调用相关宏生成驱动轮与支撑轮
-->
<!-- 根标签,必须声明 xmlns:xacro -->
<robot name="my_base" xmlns:xacro="http://www.ros.org/wiki/xacro">
<!-- 封装变量、常量 -->
<xacro:property name="PI" value="3.141"/>
<!-- 宏:黑色设置 -->
<material name="black">
<color rgba="0.0 0.0 0.0 1.0" />
</material>
<!-- 底盘属性 -->
<xacro:property name="base_footprint_radius" value="0.001" /> <!-- base_footprint 半径 -->
<xacro:property name="base_link_radius" value="0.1" /> <!-- base_link 半径 -->
<xacro:property name="base_link_length" value="0.08" /> <!-- base_link 长 -->
<xacro:property name="earth_space" value="0.015" /> <!-- 离地间距 -->
<!-- 底盘 -->
<link name="base_footprint">
<visual>
<geometry>
<sphere radius="${base_footprint_radius}" />
</geometry>
</visual>
</link>
<link name="base_link">
<visual>
<geometry>
<cylinder radius="${base_link_radius}" length="${base_link_length}" />
</geometry>
<origin xyz="0 0 0" rpy="0 0 0" />
<material name="yellow">
<color rgba="0.5 0.3 0.0 0.5" />
</material>
</visual>
</link>
<joint name="base_link2base_footprint" type="fixed">
<parent link="base_footprint" />
<child link="base_link" />
<origin xyz="0 0 ${earth_space + base_link_length / 2 }" />
</joint>
<!-- 驱动轮 -->
<!-- 驱动轮属性 -->
<xacro:property name="wheel_radius" value="0.0325" /><!-- 半径 -->
<xacro:property name="wheel_length" value="0.015" /><!-- 宽度 -->
<!-- 驱动轮宏实现 -->
<xacro:macro name="add_wheels" params="name flag">
<link name="${name}_wheel">
<visual>
<geometry>
<cylinder radius="${wheel_radius}" length="${wheel_length}" />
</geometry>
<origin xyz="0.0 0.0 0.0" rpy="${PI / 2} 0.0 0.0" />
<material name="black" />
</visual>
</link>
<joint name="${name}_wheel2base_link" type="continuous">
<parent link="base_link" />
<child link="${name}_wheel" />
<origin xyz="0 ${flag * base_link_radius} ${-(earth_space + base_link_length / 2 - wheel_radius) }" />
<axis xyz="0 1 0" />
</joint>
</xacro:macro>
<xacro:add_wheels name="left" flag="1" />
<xacro:add_wheels name="right" flag="-1" />
<!-- 支撑轮 -->
<!-- 支撑轮属性 -->
<xacro:property name="support_wheel_radius" value="0.0075" /> <!-- 支撑轮半径 -->
<!-- 支撑轮宏 -->
<xacro:macro name="add_support_wheel" params="name flag" >
<link name="${name}_wheel">
<visual>
<geometry>
<sphere radius="${support_wheel_radius}" />
</geometry>
<origin xyz="0 0 0" rpy="0 0 0" />
<material name="black" />
</visual>
</link>
<joint name="${name}_wheel2base_link" type="continuous">
<parent link="base_link" />
<child link="${name}_wheel" />
<origin xyz="${flag * (base_link_radius - support_wheel_radius)} 0 ${-(base_link_length / 2 + earth_space / 2)}" />
<axis xyz="1 1 1" />
</joint>
</xacro:macro>
<xacro:add_support_wheel name="front" flag="1" />
<xacro:add_support_wheel name="back" flag="-1" />
</robot>
(2)摄像头的xacro文件:
<!-- 根标签,必须声明 xmlns:xacro -->
<robot name="my_base" xmlns:xacro="http://www.ros.org/wiki/xacro">
<!--摄像头组件-->
<!--参数:自身长宽高,关节属性:xyz偏移量-->
<xacro:property name="camera_length" value="0.02" /> <!-- 厚度x -->
<xacro:property name="camera_width" value="0.025" /> <!-- 宽度y -->
<xacro:property name="camera_height" value="0.04" /> <!-- 高度z -->
<xacro:property name="joint_camera_x" value="0.08" /> <!-- -->
<xacro:property name="joint_camera_y" value="0" /> <!-- -->
<xacro:property name="joint_camera_z" value="${base_link_length / 2 + camera_height / 2}" /> <!-- -->
<!--设计连杆和关节-->
<link name="camera">
<visual>
<geometry>
<box size="${camera_length} ${camera_width} ${camera_height}" />
</geometry>
<material name="black">
<color rgba="0 0 0 0.8" />
</material>
</visual>
</link>
<joint name="camera2base" type="fixed">
<parent link="base_link" />
<child link="camera" />
<origin xyz="${joint_camera_x} ${joint_camera_y} ${joint_camera_z}" rpy="0 0 0" />
</joint>
</robot>
(3)雷达的xacro文件:
<!-- 根标签,必须声明 xmlns:xacro -->
<robot name="my_base" xmlns:xacro="http://www.ros.org/wiki/xacro">
<!--雷达组件-->
<!--支架 参数:半径、高度,关节偏移量xyz-->
<xacro:property name="support_radius" value="0.01" /> <!-- -->
<xacro:property name="support_length" value="0.15" />
<xacro:property name="joint_support_x" value="0" />
<xacro:property name="joint_support_y" value="0" />
<xacro:property name="joint_support_z" value="${base_link_length / 2 + support_length / 2}" />
<!--雷达 参数:半径、高度,关节偏移量xyz-->
<xacro:property name="laser_radius" value="0.03" /> <!-- -->
<xacro:property name="laser_length" value="0.05" />
<xacro:property name="joint_laser_x" value="0" />
<xacro:property name="joint_laser_y" value="0" />
<xacro:property name="joint_laser_z" value="${support_length / 2 + laser_length / 2}" />
<!--支架-->
<link name="support">
<visual>
<geometry>
<cylinder radius="${support_radius}" length="${support_length}" />
</geometry>
<material name="yellow">
<color rgba="0.8 0.1 0.2 0.5" />
</material>
</visual>
</link>
<joint name="support2base" type="fixed">
<parent link="base_link" />
<child link="support" />
<origin xyz="${joint_support_x} ${joint_support_y} ${joint_support_z}" rpy="0 0 0" />
</joint>
<!--雷达-->
<link name="laser">
<visual>
<geometry>
<cylinder radius="${laser_radius}" length="${laser_length}" />
</geometry>
<material name="black">
<color rgba="0 0 0 0.5" />
</material>
</visual>
</link>
<joint name="laser2support" type="fixed">
<parent link="support" />
<child link="laser" />
<origin xyz="${joint_laser_x} ${joint_laser_y} ${joint_laser_z}" rpy="0 0 0" />
</joint>
</robot>
3.组合小车模型文件:
<!-- 组合小车底盘与摄像头与雷达 -->
<robot name="my_car_camera" xmlns:xacro="http://wiki.ros.org/xacro">
<xacro:include filename="demo06_car_base.urdf.xacro" />
<xacro:include filename="demo06_car_camera.urdf.xacro" />
<xacro:include filename="demo06_car_laser.urdf.xacro" />
</robot>
4.编写launch文件:
<launch>
<param name="robot_description" command="$(find xacro)/xacro $(find learning_urdf)/urdf/demo06.urdf.xacro" />
<node pkg="rviz" type="rviz" name="rviz" args="-d $(find learning_urdf)/config/helloworld.rviz" />
<node pkg="joint_state_publisher" type="joint_state_publisher" name="joint_state_publisher" output="screen" />
<node pkg="robot_state_publisher" type="robot_state_publisher" name="robot_state_publisher" output="screen" />
<node pkg="joint_state_publisher_gui" type="joint_state_publisher_gui" name="joint_state_publisher_gui" output="screen" />
</launch>
5.通过launch文件启动rviz:
相关链接:
【ROS进阶篇】第八讲(下) URDF的编程优化Xacro使用_生如昭诩的博客-CSDN博客
五、基于ArbotiX和rviz的仿真器(rviz中控制机器人运动):
1.ArbotiX介绍:
Arbotix是一款控制电机、舵机的控制板,并提供相应的 ros 功能包,这个功能包的功能不仅可以驱动真实的 Arbotix 控制板,它还提供一个差速控制器,通过接受速度控制指令更新机器人的 joint 状态,从而帮助我们实现机器人在 rviz 中的运动。
2.安装ArbotiX:
安装方式一:命令行调用
sudo apt-get install ros-noetic-arbotix
如果命令行安装失败,尝试方式二。
安装方式二:源码安装
git clone https://github.com/vanadiumlabs/arbotix_ros.git
先从 github 下载源码,移至当前工作空间/src下,然后调用catkin_make编译。
3.添加ArbotiX所需的配置文件:
在config文件夹下新建control.yaml文件。
# 该文件是控制器配置,一个机器人模型可能有多个控制器,比如: 底盘、机械臂、夹持器(机械手)....
# 因此,根 name 是 controller
controllers: {
# 单控制器设置
base_controller: {
#类型: 差速控制器
type: diff_controller,
#参考坐标
base_frame_id: base_footprint,
#两个轮子之间的间距
base_width: 0.2,
#控制频率
ticks_meter: 2000,
#PID控制参数,使机器人车轮快速达到预期速度
Kp: 12,
Kd: 12,
Ki: 0,
Ko: 50,
#加速限制
accel_limit: 1.0
}
}
(详细内容参考:http://wiki.ros.org/arbotix_python/diff_controller)
4.launch文件中配置ArbotiX节点:
<launch>
<!--1.在参数服务器载入urdf文件-->
<param name="robot_description" command="$(find xacro)/xacro $(find learning_urdf)/urdf/demo06.urdf.xacro" />
<!--2.启动rviz-->
<node pkg="rviz" type="rviz" name="rviz" args="-d $(find learning_urdf)/config/show_mycar.rviz" />
<!--3.关节状态发布节点-->
<node pkg="joint_state_publisher" type="joint_state_publisher" name="joint_state_publisher" />
<!--4.机器人状态发布节点-->
<node pkg="robot_state_publisher" type="robot_state_publisher" name="robot_state_publisher" />
<!--5.arbotix节点配置-->
<node name="arbotix" pkg="arbotix_python" type="arbotix_driver" output="screen">
<rosparam file="$(find learning_urdf)/config/control.yaml" command="load" />
<param name="sim" value="true" />
</node>
</launch>
(1)<node>调用了arbotix_python功能包下的arbotix_driver节点
(2)<rosparam>arbotix驱动机器人运行时,需要获取机器人信息,可以通过file家在配置文件
(3)<param>在仿真环境下,需要配置sim为true
5.启动launch文件并配置rviz:
6.控制机器人模型运动:
相关链接:
Rviz中控制机器人模型运动(arbotix)_most delay的博客-CSDN博客_rviz控制机器人运动
六、URDF集成Gazebo:
1.urdf与Gazebo集成的基本流程:
(1)创建功能包并导入依赖:
(2)修改urdf文件(这里以盒状的demo01.urdf的基础修改):
<!--
创建一个机器人模型(盒状即可),显示在 Gazebo 中
-->
<robot name="mycar">
<link name="base_link">
<visual>
<geometry>
<box size="0.5 0.2 0.1" />
</geometry>
<origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
<material name="yellow">
<color rgba="0.5 0.3 0.0 1" />
</material>
</visual>
<collision>
<geometry>
<box size="0.5 0.2 0.1" />
</geometry>
<origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
</collision>
<inertial>
<origin xyz="0 0 0" />
<mass value="6" />
<inertia ixx="1" ixy="0" ixz="0" iyy="1" iyz="0" izz="1" />
</inertial>
</link>
<gazebo reference="base_link">
<material>Gazebo/Black</material>
</gazebo>
</robot>
注意, URDF 与 Gazebo 集成时,和 Rviz 有明显区别:
1)必须使用 <collision> 标签,在仿真环境中,必然涉及到碰撞检测,collision 提供碰撞检测的依据,简单的模型,可采用和<visual>标签中一样的内容;
2)必须使用 <inertial> 标签,包含了机器人的质量和惯性矩阵;
3)颜色设置,需要重新使用 <gazebo> 标签标注,<visual>中的颜色设置只能在 rviz 中显示。
(3)launch文件启动Gazebo并显示模型:
1)launch文件:
<launch>
<!-- 将 Urdf 文件的内容加载到参数服务器 -->
<param name="robot_description" textfile="$(find learning_gazebo_urdf)/urdf/demo01.urdf" />
<!-- 启动 gazebo -->
<include file="$(find gazebo_ros)/launch/empty_world.launch" />
<!-- 在 gazebo 中显示机器人模型 -->
<node pkg="gazebo_ros" type="spawn_model" name="model" args="-urdf -model mycar -param robot_description" />
</launch>
最后一句话意思是在Gazebo中加载一个机器人模型,该功能由gazebo_ros下的spawn_model提供:
-urdf 加载的是 urdf 文件
-model car 模型名称是 car
-param robot_description 从参数 robot_description 中载入模型
2)显示模型:
2.urdf集成Gazebo示例:
(1)编写封装惯性矩阵算法的xacro文件:
<robot name="base" xmlns:xacro="http://wiki.ros.org/xacro">
<!-- Macro for inertia matrix -->
<xacro:macro name="sphere_inertial_matrix" params="m r">
<inertial>
<mass value="${m}" />
<inertia ixx="${2*m*r*r/5}" ixy="0" ixz="0"
iyy="${2*m*r*r/5}" iyz="0"
izz="${2*m*r*r/5}" />
</inertial>
</xacro:macro>
<xacro:macro name="cylinder_inertial_matrix" params="m r h">
<inertial>
<mass value="${m}" />
<inertia ixx="${m*(3*r*r+h*h)/12}" ixy = "0" ixz = "0"
iyy="${m*(3*r*r+h*h)/12}" iyz = "0"
izz="${m*r*r/2}" />
</inertial>
</xacro:macro>
<xacro:macro name="Box_inertial_matrix" params="m l w h">
<inertial>
<mass value="${m}" />
<inertia ixx="${m*(h*h + l*l)/12}" ixy = "0" ixz = "0"
iyy="${m*(w*w + l*l)/12}" iyz= "0"
izz="${m*(w*w + h*h)/12}" />
</inertial>
</xacro:macro>
</robot>
(2)为机器人模型中的每一个link添加collision和inertial标签,并且重置颜色属性:
1)底盘文件(demo05_car_base.urdf.xacro):
<!--
使用 xacro 优化 URDF 版的小车底盘实现:
实现思路:
1.将一些常量、变量封装为 xacro:property
比如:PI 值、小车底盘半径、离地间距、车轮半径、宽度 ....
2.使用 宏 封装驱动轮以及支撑轮实现,调用相关宏生成驱动轮与支撑轮
-->
<!-- 根标签,必须声明 xmlns:xacro -->
<robot name="my_base" xmlns:xacro="http://www.ros.org/wiki/xacro">
<!-- 封装变量、常量 -->
<!-- PI 值设置精度需要高一些,否则后续车轮翻转量计算时,可能会出现肉眼不能察觉的车轮倾斜,从而导致模型抖动 -->
<xacro:property name="PI" value="3.1415926"/>
<!-- 宏:黑色设置 -->
<material name="black">
<color rgba="0.0 0.0 0.0 1.0" />
</material>
<!-- 底盘属性 -->
<xacro:property name="base_footprint_radius" value="0.001" /> <!-- base_footprint 半径 -->
<xacro:property name="base_link_radius" value="0.1" /> <!-- base_link 半径 -->
<xacro:property name="base_link_length" value="0.08" /> <!-- base_link 长 -->
<xacro:property name="earth_space" value="0.015" /> <!-- 离地间距 -->
<xacro:property name="base_link_m" value="0.5" /> <!-- 质量 -->
<!-- 底盘 -->
<link name="base_footprint">
<visual>
<geometry>
<sphere radius="${base_footprint_radius}" />
</geometry>
</visual>
</link>
<link name="base_link">
<visual>
<geometry>
<cylinder radius="${base_link_radius}" length="${base_link_length}" />
</geometry>
<origin xyz="0 0 0" rpy="0 0 0" />
<material name="yellow">
<color rgba="0.5 0.3 0.0 0.5" />
</material>
</visual>
<collision>
<geometry>
<cylinder radius="${base_link_radius}" length="${base_link_length}" />
</geometry>
<origin xyz="0 0 0" rpy="0 0 0" />
</collision>
<xacro:cylinder_inertial_matrix m="${base_link_m}" r="${base_link_radius}" h="${base_link_length}" />
</link>
<joint name="base_link2base_footprint" type="fixed">
<parent link="base_footprint" />
<child link="base_link" />
<origin xyz="0 0 ${earth_space + base_link_length / 2 }" />
</joint>
<gazebo reference="base_link">
<material>Gazebo/Yellow</material>
</gazebo>
<!-- 驱动轮 -->
<!-- 驱动轮属性 -->
<xacro:property name="wheel_radius" value="0.0325" /><!-- 半径 -->
<xacro:property name="wheel_length" value="0.015" /><!-- 宽度 -->
<xacro:property name="wheel_m" value="0.05" /> <!-- 质量 -->
<!-- 驱动轮宏实现 -->
<xacro:macro name="add_wheels" params="name flag">
<link name="${name}_wheel">
<visual>
<geometry>
<cylinder radius="${wheel_radius}" length="${wheel_length}" />
</geometry>
<origin xyz="0.0 0.0 0.0" rpy="${PI / 2} 0.0 0.0" />
<material name="black" />
</visual>
<collision>
<geometry>
<cylinder radius="${wheel_radius}" length="${wheel_length}" />
</geometry>
<origin xyz="0.0 0.0 0.0" rpy="${PI / 2} 0.0 0.0" />
</collision>
<xacro:cylinder_inertial_matrix m="${wheel_m}" r="${wheel_radius}" h="${wheel_length}" />
</link>
<joint name="${name}_wheel2base_link" type="continuous">
<parent link="base_link" />
<child link="${name}_wheel" />
<origin xyz="0 ${flag * base_link_radius} ${-(earth_space + base_link_length / 2 - wheel_radius) }" />
<axis xyz="0 1 0" />
</joint>
<gazebo reference="${name}_wheel">
<material>Gazebo/Red</material>
</gazebo>
</xacro:macro>
<xacro:add_wheels name="left" flag="1" />
<xacro:add_wheels name="right" flag="-1" />
<!-- 支撑轮 -->
<!-- 支撑轮属性 -->
<xacro:property name="support_wheel_radius" value="0.0075" /> <!-- 支撑轮半径 -->
<xacro:property name="support_wheel_m" value="0.03" /> <!-- 质量 -->
<!-- 支撑轮宏 -->
<xacro:macro name="add_support_wheel" params="name flag" >
<link name="${name}_wheel">
<visual>
<geometry>
<sphere radius="${support_wheel_radius}" />
</geometry>
<origin xyz="0 0 0" rpy="0 0 0" />
<material name="black" />
</visual>
<collision>
<geometry>
<sphere radius="${support_wheel_radius}" />
</geometry>
<origin xyz="0 0 0" rpy="0 0 0" />
</collision>
<xacro:sphere_inertial_matrix m="${support_wheel_m}" r="${support_wheel_radius}" />
</link>
<joint name="${name}_wheel2base_link" type="continuous">
<parent link="base_link" />
<child link="${name}_wheel" />
<origin xyz="${flag * (base_link_radius - support_wheel_radius)} 0 ${-(base_link_length / 2 + earth_space / 2)}" />
<axis xyz="1 1 1" />
</joint>
<gazebo reference="${name}_wheel">
<material>Gazebo/Red</material>
</gazebo>
</xacro:macro>
<xacro:add_support_wheel name="front" flag="1" />
<xacro:add_support_wheel name="back" flag="-1" />
</robot>
2)相机文件(demo05_car_camera.urdf.xacro):
<!-- 摄像头相关的 xacro 文件 -->
<robot name="my_camera" xmlns:xacro="http://wiki.ros.org/xacro">
<!-- 摄像头属性 -->
<xacro:property name="camera_length" value="0.01" /> <!-- 摄像头长度(x) -->
<xacro:property name="camera_width" value="0.025" /> <!-- 摄像头宽度(y) -->
<xacro:property name="camera_height" value="0.025" /> <!-- 摄像头高度(z) -->
<xacro:property name="camera_x" value="0.08" /> <!-- 摄像头安装的x坐标 -->
<xacro:property name="camera_y" value="0.0" /> <!-- 摄像头安装的y坐标 -->
<xacro:property name="camera_z" value="${base_link_length / 2 + camera_height / 2}" /> <!-- 摄像头安装的z坐标:底盘高度 / 2 + 摄像头高度 / 2 -->
<xacro:property name="camera_m" value="0.01" /> <!-- 摄像头质量 -->
<!-- 摄像头关节以及link -->
<link name="camera">
<visual>
<geometry>
<box size="${camera_length} ${camera_width} ${camera_height}" />
</geometry>
<origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
<material name="black" />
</visual>
<collision>
<geometry>
<box size="${camera_length} ${camera_width} ${camera_height}" />
</geometry>
<origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
</collision>
<xacro:Box_inertial_matrix m="${camera_m}" l="${camera_length}" w="${camera_width}" h="${camera_height}" />
</link>
<joint name="camera2base_link" type="fixed">
<parent link="base_link" />
<child link="camera" />
<origin xyz="${camera_x} ${camera_y} ${camera_z}" />
</joint>
<gazebo reference="camera">
<material>Gazebo/Blue</material>
</gazebo>
</robot>
3)雷达文件(demo05_car_laser.urdf.xacro):
<!--
小车底盘添加雷达
-->
<robot name="my_laser" xmlns:xacro="http://wiki.ros.org/xacro">
<!-- 雷达支架 -->
<xacro:property name="support_length" value="0.15" /> <!-- 支架长度 -->
<xacro:property name="support_radius" value="0.01" /> <!-- 支架半径 -->
<xacro:property name="support_x" value="0.0" /> <!-- 支架安装的x坐标 -->
<xacro:property name="support_y" value="0.0" /> <!-- 支架安装的y坐标 -->
<xacro:property name="support_z" value="${base_link_length / 2 + support_length / 2}" /> <!-- 支架安装的z坐标:底盘高度 / 2 + 支架高度 / 2 -->
<xacro:property name="support_m" value="0.02" /> <!-- 支架质量 -->
<link name="support">
<visual>
<geometry>
<cylinder radius="${support_radius}" length="${support_length}" />
</geometry>
<origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
<material name="red">
<color rgba="0.8 0.2 0.0 0.8" />
</material>
</visual>
<collision>
<geometry>
<cylinder radius="${support_radius}" length="${support_length}" />
</geometry>
<origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
</collision>
<xacro:cylinder_inertial_matrix m="${support_m}" r="${support_radius}" h="${support_length}" />
</link>
<joint name="support2base_link" type="fixed">
<parent link="base_link" />
<child link="support" />
<origin xyz="${support_x} ${support_y} ${support_z}" />
</joint>
<gazebo reference="support">
<material>Gazebo/White</material>
</gazebo>
<!-- 雷达属性 -->
<xacro:property name="laser_length" value="0.05" /> <!-- 雷达长度 -->
<xacro:property name="laser_radius" value="0.03" /> <!-- 雷达半径 -->
<xacro:property name="laser_x" value="0.0" /> <!-- 雷达安装的x坐标 -->
<xacro:property name="laser_y" value="0.0" /> <!-- 雷达安装的y坐标 -->
<xacro:property name="laser_z" value="${support_length / 2 + laser_length / 2}" /> <!-- 雷达安装的z坐标:支架高度 / 2 + 雷达高度 / 2 -->
<xacro:property name="laser_m" value="0.1" /> <!-- 雷达质量 -->
<!-- 雷达关节以及link -->
<link name="laser">
<visual>
<geometry>
<cylinder radius="${laser_radius}" length="${laser_length}" />
</geometry>
<origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
<material name="black" />
</visual>
<collision>
<geometry>
<cylinder radius="${laser_radius}" length="${laser_length}" />
</geometry>
<origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
</collision>
<xacro:cylinder_inertial_matrix m="${laser_m}" r="${laser_radius}" h="${laser_length}" />
</link>
<joint name="laser2support" type="fixed">
<parent link="support" />
<child link="laser" />
<origin xyz="${laser_x} ${laser_y} ${laser_z}" />
</joint>
<gazebo reference="laser">
<material>Gazebo/Black</material>
</gazebo>
</robot>
4)组合底盘、摄像头与雷达的 Xacro 文件(demo05.urdf.xacro):
<!-- 组合小车底盘与摄像头与雷达 -->
<robot name="my_car_camera" xmlns:xacro="http://wiki.ros.org/xacro">
<xacro:include filename="demo05_test.urdf.xacro" />
<xacro:include filename="demo05_car_base.urdf.xacro" />
<xacro:include filename="demo05_car_camera.urdf.xacro" />
<xacro:include filename="demo05_car_laser.urdf.xacro" />
</robot>
(3)在launch文件中启动gazebo并添加机器人模型:
<launch>
<!-- 将 Urdf 文件的内容加载到参数服务器 -->
<param name="robot_description" command="$(find xacro)/xacro $(find learning_gazebo_urdf)/urdf/demo05.urdf.xacro" />
<!-- 启动 gazebo -->
<include file="$(find gazebo_ros)/launch/empty_world.launch" />
<!-- 在 gazebo 中显示机器人模型 -->
<node pkg="gazebo_ros" type="spawn_model" name="model" args="-urdf -model mycar -param robot_description" />
</launch>
3.Gazebo仿真环境搭建:
七、URDF、rviz、Gazebo综合应用:
1.ros_control:
rviz+Arbotix构建的仿真器使用了Arbotix差速控制器实现对机器人模型的控制,但是这款控制器有很大的局限性,无法在ROS丰富的机器人应用中通用。
ros_control是ROS为开发者提供的机器人控制中间件,包含一系列控制器接口、传动装置接口、硬件接口、控制器工具等,可以帮助机器人应用功能包快速落地,提高开发效率。
2.运动控制实现流程:
(1)为已经创建完毕的机器人模型,编写一个单独的xacro文件,添加传动装置以及控制器:
<robot name="my_car_move" xmlns:xacro="http://wiki.ros.org/xacro">
<!-- 传动实现:用于连接控制器与关节 -->
<xacro:macro name="joint_trans" params="joint_name">
<!-- Transmission is important to link the joints and the controller -->
<transmission name="${joint_name}_trans">
<type>transmission_interface/SimpleTransmission</type>
<joint name="${joint_name}">
<hardwareInterface>hardware_interface/VelocityJointInterface</hardwareInterface>
</joint>
<actuator name="${joint_name}_motor">
<hardwareInterface>hardware_interface/VelocityJointInterface</hardwareInterface>
<mechanicalReduction>1</mechanicalReduction>
</actuator>
</transmission>
</xacro:macro>
<!-- 每一个驱动轮都需要配置传动装置 -->
<xacro:joint_trans joint_name="left_wheel2base_link" />
<xacro:joint_trans joint_name="right_wheel2base_link" />
<!-- 控制器 -->
<gazebo>
<plugin name="differential_drive_controller" filename="libgazebo_ros_diff_drive.so">
<rosDebugLevel>Debug</rosDebugLevel>
<publishWheelTF>true</publishWheelTF>
<robotNamespace>/</robotNamespace>
<publishTf>1</publishTf>
<publishWheelJointState>true</publishWheelJointState>
<alwaysOn>true</alwaysOn>
<updateRate>100.0</updateRate>
<legacyMode>true</legacyMode>
<leftJoint>left_wheel2base_link</leftJoint> <!-- 左轮 -->
<rightJoint>right_wheel2base_link</rightJoint> <!-- 右轮 -->
<wheelSeparation>${base_link_radius * 2}</wheelSeparation> <!-- 车轮间距 -->
<wheelDiameter>${wheel_radius * 2}</wheelDiameter> <!-- 车轮直径 -->
<broadcastTF>1</broadcastTF>
<wheelTorque>30</wheelTorque>
<wheelAcceleration>1.8</wheelAcceleration>
<commandTopic>cmd_vel</commandTopic> <!-- 运动控制话题 -->
<odometryFrame>odom</odometryFrame>
<odometryTopic>odom</odometryTopic> <!-- 里程计话题 -->
<robotBaseFrame>base_footprint</robotBaseFrame> <!-- 根坐标系 -->
</plugin>
</gazebo>
</robot>
(2)将move.xacro文件集成进总的机器人模型文件(以demo05.xacro为载体):
<!-- 组合小车底盘与摄像头与雷达 -->
<robot name="my_car_camera" xmlns:xacro="http://wiki.ros.org/xacro">
<xacro:include filename="demo05_test.urdf.xacro" />
<xacro:include filename="demo05_car_base.urdf.xacro" />
<xacro:include filename="demo05_car_camera.urdf.xacro" />
<xacro:include filename="demo05_car_laser.urdf.xacro" />
<xacro:include filename="move.urdf.xacro" />
</robot>
(3)launch文件启动gazebo,加载课程所提供的仿真环境,控制小车运动:
解决方案:
sudo apt-get ros-noetic-teleop-twist-keyboard
结果展示:
3.rviz查看里程计信息:
(1)launch文件启动rviz:
创建demo06_odom.launch文件:
<launch>
<node pkg="rviz" type="rviz" name="rviz" args="-d $(find learning_urdf)/config/demo05_test.rviz" />
<node pkg="joint_state_publisher" type="joint_state_publisher" name="joint_state" />
<node pkg="robot_state_publisher" type="robot_state_publisher" name="robot_state" />
</launch>
(2)在rviz中添加组件:
1)启动demo06_car.launch文件:
2)启动demo06_odom.launch文件:
相关链接:
6.7.1 机器人系统仿真/URDF、Gazebo与Rviz综合运用/机器人运动控制以及里程计信息显示_janedipan的博客-CSDN博客
4.雷达信息仿真及显示:
(1)为机器人添加雷达配置:
<robot name="my_sensors" xmlns:xacro="http://wiki.ros.org/xacro">
<!-- 雷达 -->
<gazebo reference="laser"> //reference要和laser连杆名称一致
<sensor type="ray" name="rplidar"> //type雷达类型 name起名字
<pose>0 0 0 0 0 0</pose> //6D位姿
<visualize>true</visualize> //雷达射线true可视,false不可视
<update_rate>5.5</update_rate> //雷达射线更新频率 次/s
<ray>
<scan>
<horizontal>
<samples>360</samples> //采样个数,雷达旋转一周采样数
<resolution>1</resolution> //分辨率,每N个射线测距一次,设置大一点设备计算压力小,但是损失精度
<min_angle>-3</min_angle> //采样范围,单位是弧度,以机器人朝向为中心
<max_angle>3</max_angle> //逆时针为正,顺时针为负(看下面演示)
</horizontal>
</scan>
<range>
<min>0.10</min> //采样范围 单位 米
<max>30.0</max>
<resolution>0.01</resolution> //采样精度
</range>
<noise> //高斯噪声,数据采集不可能每次都准确
<type>gaussian</type>
<mean>0.0</mean>
<stddev>0.01</stddev>
</noise>
</ray>
<plugin name="gazebo_rplidar" filename="libgazebo_ros_laser.so">
<topicName>/scan</topicName> //雷达发布的话题!!!
<frameName>laser</frameName>
</plugin>
</sensor>
</gazebo>
</robot>
(2)将laser.xacro文件集成进总的机器人模型文件:
<!-- 组合小车底盘与摄像头与雷达 -->
<robot name="my_car_camera" xmlns:xacro="http://wiki.ros.org/xacro">
<xacro:include filename="demo05_test.urdf.xacro" />
<xacro:include filename="demo05_car_base.urdf.xacro" />
<xacro:include filename="demo05_car_camera.urdf.xacro" />
<xacro:include filename="demo05_car_laser.urdf.xacro" />
<xacro:include filename="move.urdf.xacro" />
<xacro:include filename="my_sensors_laser.urdf.xacro" />
</robot>
(3)launch文件启动gazebo和rviz并显示雷达数据:
相关链接:
ros学习笔记之雷达信息仿真及显示_要好好养胃的博客-CSDN博客
5.摄像头信息仿真及显示:
(1)为机器人添加摄像头配置:
<robot name="my_sensors" xmlns:xacro="http://wiki.ros.org/xacro">
<!-- 被引用的link -->
<gazebo reference="camera">
<!-- 类型设置为 camara -->
<sensor type="camera" name="camera_node">
<update_rate>30.0</update_rate> <!-- 更新频率 -->
<!-- 摄像头基本信息设置 -->
<camera name="head">
<horizontal_fov>1.3962634</horizontal_fov>
<image>
<width>1280</width>
<height>720</height>
<format>R8G8B8</format>
</image>
<clip>
<near>0.02</near>
<far>300</far>
</clip>
<noise>
<type>gaussian</type>
<mean>0.0</mean>
<stddev>0.007</stddev>
</noise>
</camera>
<!-- 核心插件 -->
<plugin name="gazebo_camera" filename="libgazebo_ros_camera.so">
<alwaysOn>true</alwaysOn>
<updateRate>0.0</updateRate>
<cameraName>/camera</cameraName>
<imageTopicName>image_raw</imageTopicName>
<cameraInfoTopicName>camera_info</cameraInfoTopicName>
<frameName>camera</frameName>
<hackBaseline>0.07</hackBaseline>
<distortionK1>0.0</distortionK1>
<distortionK2>0.0</distortionK2>
<distortionK3>0.0</distortionK3>
<distortionT1>0.0</distortionT1>
<distortionT2>0.0</distortionT2>
</plugin>
</sensor>
</gazebo>
</robot>
(2)将laser.xacro文件集成进总的机器人模型文件:
<!-- 组合小车底盘与摄像头与雷达 -->
<robot name="my_car_camera" xmlns:xacro="http://wiki.ros.org/xacro">
<xacro:include filename="demo05_test.urdf.xacro" />
<xacro:include filename="demo05_car_base.urdf.xacro" />
<xacro:include filename="demo05_car_camera.urdf.xacro" />
<xacro:include filename="demo05_car_laser.urdf.xacro" />
<xacro:include filename="move.urdf.xacro" />
<xacro:include filename="my_sensors_camera.urdf.xacro" />
</robot>
(3)launch文件启动gazebo和rviz并显示摄像头数据:
1)启动gazebo:
2)打开rviz,添加摄像头:
相关链接:
6.7.3 摄像头信息仿真以及显示_赵虚左的博客-CSDN博客
6.kinect信息仿真及显示:
(1)为机器人添加kinect配置:
<robot name="my_sensors" xmlns:xacro="http://wiki.ros.org/xacro">
<gazebo reference="kinect link名称">
<sensor type="depth" name="camera">
<always_on>true</always_on>
<update_rate>20.0</update_rate>
<camera>
<horizontal_fov>${60.0*PI/180.0}</horizontal_fov>
<image>
<format>R8G8B8</format>
<width>640</width>
<height>480</height>
</image>
<clip>
<near>0.05</near>
<far>8.0</far>
</clip>
</camera>
<plugin name="kinect_camera_controller" filename="libgazebo_ros_openni_kinect.so">
<cameraName>camera</cameraName>
<alwaysOn>true</alwaysOn>
<updateRate>10</updateRate>
<imageTopicName>rgb/image_raw</imageTopicName>
<depthImageTopicName>depth/image_raw</depthImageTopicName>
<pointCloudTopicName>depth/points</pointCloudTopicName>
<cameraInfoTopicName>rgb/camera_info</cameraInfoTopicName>
<depthImageCameraInfoTopicName>depth/camera_info</depthImageCameraInfoTopicName>
<frameName>kinect link名称</frameName>
<baseline>0.1</baseline>
<distortion_k1>0.0</distortion_k1>
<distortion_k2>0.0</distortion_k2>
<distortion_k3>0.0</distortion_k3>
<distortion_t1>0.0</distortion_t1>
<distortion_t2>0.0</distortion_t2>
<pointCloudCutoff>0.4</pointCloudCutoff>
</plugin>
</sensor>
</gazebo>
</robot>
(2)将laser.xacro文件集成进总的机器人模型文件:
<!-- 组合小车底盘与摄像头与雷达 -->
<robot name="my_car_camera" xmlns:xacro="http://wiki.ros.org/xacro">
<xacro:include filename="demo05_test.urdf.xacro" />
<xacro:include filename="demo05_car_base.urdf.xacro" />
<xacro:include filename="demo05_car_camera.urdf.xacro" />
<xacro:include filename="demo05_car_laser.urdf.xacro" />
<xacro:include filename="move.urdf.xacro" />
<xacro:include filename="my_sensors_laser.urdf.xacro" />
<xacro:include filename="my_sensors_camera.urdf.xacro" />
<xacro:include filename="kinect.xacro" />
</robot>
相关链接:
机器人系统仿真(十六)——摄像头和kinect信息仿真以及显示_蔡军帅的博客-CSDN博客文章来源地址https://www.toymoban.com/news/detail-487554.html
到了这里,关于ROS学习笔记16:机器人系统建模与仿真的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!