ROS学习笔记16:机器人系统建模与仿真

这篇具有很好参考价值的文章主要介绍了ROS学习笔记16:机器人系统建模与仿真。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、概述:

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)创建功能包,并导入依赖:

ROS学习笔记16:机器人系统建模与仿真

        在该功能包下创建四个文件夹:

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>

ROS学习笔记16:机器人系统建模与仿真

ROS学习笔记16:机器人系统建模与仿真

(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>

ROS学习笔记16:机器人系统建模与仿真

ROS学习笔记16:机器人系统建模与仿真

(4)通过launch文件启动rviz,并加载机器人模型:

ROS学习笔记16:机器人系统建模与仿真

ROS学习笔记16:机器人系统建模与仿真

PS:编译过程中有可能出现因缺少xacro的包导致编译失败

ROS学习笔记16:机器人系统建模与仿真

 解决方式是输入以下安装指令安装xacro相关包:

sudo apt-get install ros-noetic-xacro

ROS学习笔记16:机器人系统建模与仿真

(5)rviz 启动后,会发现并没有机器人模型,这是因为默认情况下没有添加机器人显示组件,需要手动添加,添加方式如下:ROS学习笔记16:机器人系统建模与仿真

 (6)Fixed Frame处要将默认值map改为urdf文件中机器人底座的name(此处设置的是base_link): ROS学习笔记16:机器人系统建模与仿真

 (7)重复启动launch文件时,Rviz 之前的组件配置信息不会自动保存,需要重复执行步骤4的操作,为了方便使用,可以使用如下方式优化:

1)在功能包中新建子文件夹config:

ROS学习笔记16:机器人系统建模与仿真

2)将文件另存为一个.rviz文件:

ROS学习笔记16:机器人系统建模与仿真

ROS学习笔记16:机器人系统建模与仿真

2.urdf语法:

        URDF文件是一个标准的XML文件,在ROS中预定义了一系列的标签用于描述机器人模型机器人模型可能较为复杂,但是ROS的URDF中机器人的组成却是较为简单,URDF中有四类标签:

        <robot>:根标签,类似于 launch文件中的launch标签;

        <link>:连杆标签;

        <joint>:关节标签;

        <gazebo>: 集成gazebo需要使用的标签。

(1)<robot>标签:

        <robot>标签是完整机器人模型最顶层标签,<link>和<joint>标签都必须包含在<robot>标签内。如下图所示,一个完整的机器人模型由一系列<link>和<joint>组成:

ROS学习笔记16:机器人系统建模与仿真

         <robot>标签内可以设置机器人的名称,其基本语法如下:

<robot name="<name of the robot>">
  <link>......</link>
  <link>......</link>
  <joint>......</joint>
  <joint>......</joint>
</robot>

(2)<link>标签:

        <link>标签用于描述机器人某个部件的外观和物理属性,如形状、尺寸、颜色、惯性矩阵、碰撞参数等。机器人的link结构一般如下图所示:

ROS学习笔记16:机器人系统建模与仿真

        基本的URDF描述语法如下:

<link name="<link name>">
  <inertial>......</inertial>
  <visual>......</visual>
  <collision>......</collision>
</link>

      子标签的描述内容如下:

ROS学习笔记16:机器人系统建模与仿真

示例: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>标签用于描述机器人关节的运动学和动力学属性,包括关节运动的位置和速度限制。

        根据机器人的关节运动形式,可以将其分为六种类型:

ROS学习笔记16:机器人系统建模与仿真

        与人的关节一样,机器人关节(joint)的主要作用是连接两个刚体(link),这两个link分别称为parent linkchild link,如下图所示:

ROS学习笔记16:机器人系统建模与仿真

         <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>

ROS学习笔记16:机器人系统建模与仿真

(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>

ROS学习笔记16:机器人系统建模与仿真

(3)运行:

ROS学习笔记16:机器人系统建模与仿真

 ROS学习笔记16:机器人系统建模与仿真

ROS学习笔记16:机器人系统建模与仿真

PS:使用launch文件启动rviz时,可能出现如下报错

ROS学习笔记16:机器人系统建模与仿真

解决方案 :缺少依赖包,按指令安装以下依赖包即可

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

ROS学习笔记16:机器人系统建模与仿真ROS学习笔记16:机器人系统建模与仿真ROS学习笔记16:机器人系统建模与仿真ROS学习笔记16:机器人系统建模与仿真

        补充完以上依赖包后,通过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>

ROS学习笔记16:机器人系统建模与仿真

(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>

ROS学习笔记16:机器人系统建模与仿真

 (3)编译,通过launch文件启动rviz,并加载机器人模型:

ROS学习笔记16:机器人系统建模与仿真ROS学习笔记16:机器人系统建模与仿真

相关链接:

【基于ROS的URDF练习实例】四轮机器人与摄像头的使用_生如昭诩的博客-CSDN博客

6.urdf工具:

        URDF提供了一些命令行工具,可以帮助我们检查、梳理模型文件,需要在终端中独立安装:

sudo apt-get install liburdfdom-tools

ROS学习笔记16:机器人系统建模与仿真

(1)check_urdf语法检查:

check_urdf <名称>.urdf

        check_urdf会解析urdf文件,并且显示解析过程中发现的错误。如果一切正常,在终端中会输出以下信息:

ROS学习笔记16:机器人系统建模与仿真

(2)urdf_to_graphiz结构查看:

urdf_to_graphiz <名称>.urdf

        urdf_to_graphiz命令可以查看urdf模型的整体结构。

ROS学习笔记16:机器人系统建模与仿真

ROS学习笔记16:机器人系统建模与仿真

ROS学习笔记16:机器人系统建模与仿真

三、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 文件,并储存在当前路径。

 解析前:

ROS学习笔记16:机器人系统建模与仿真

 解析后:

ROS学习笔记16:机器人系统建模与仿真

ROS学习笔记16:机器人系统建模与仿真

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>

ROS学习笔记16:机器人系统建模与仿真

6.通过launch启动rviz:

ROS学习笔记16:机器人系统建模与仿真

(这里笔者做出来的结果总是报错,错误原因应该是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>

ROS学习笔记16:机器人系统建模与仿真

(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>

ROS学习笔记16:机器人系统建模与仿真

(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>

ROS学习笔记16:机器人系统建模与仿真

3.组合小车模型文件:

ROS学习笔记16:机器人系统建模与仿真

<!-- 组合小车底盘与摄像头与雷达 -->
<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文件:

ROS学习笔记16:机器人系统建模与仿真

<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学习笔记16:机器人系统建模与仿真

ROS学习笔记16:机器人系统建模与仿真

 相关链接:

【ROS进阶篇】第八讲(下) URDF的编程优化Xacro使用_生如昭诩的博客-CSDN博客

五、基于ArbotiX和rviz的仿真器(rviz中控制机器人运动):

1.ArbotiX介绍:

        Arbotix是一款控制电机、舵机的控制板,并提供相应的 ros 功能包,这个功能包的功能不仅可以驱动真实的 Arbotix 控制板,它还提供一个差速控制器,通过接受速度控制指令更新机器人的 joint 状态,从而帮助我们实现机器人在 rviz 中的运动。

2.安装ArbotiX:

安装方式一:命令行调用

sudo apt-get install ros-noetic-arbotix

ROS学习笔记16:机器人系统建模与仿真

        如果命令行安装失败,尝试方式二。

安装方式二:源码安装

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 
    }
}

ROS学习笔记16:机器人系统建模与仿真

(详细内容参考: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

ROS学习笔记16:机器人系统建模与仿真

5.启动launch文件并配置rviz:

ROS学习笔记16:机器人系统建模与仿真

ROS学习笔记16:机器人系统建模与仿真

6.控制机器人模型运动:

ROS学习笔记16:机器人系统建模与仿真

ROS学习笔记16:机器人系统建模与仿真

ROS学习笔记16:机器人系统建模与仿真

ROS学习笔记16:机器人系统建模与仿真

相关链接:

Rviz中控制机器人模型运动(arbotix)_most delay的博客-CSDN博客_rviz控制机器人运动

六、URDF集成Gazebo:

1.urdf与Gazebo集成的基本流程:

(1)创建功能包并导入依赖:

ROS学习笔记16:机器人系统建模与仿真

ROS学习笔记16:机器人系统建模与仿真

(2)修改urdf文件(这里以盒状的demo01.urdf的基础修改):

ROS学习笔记16:机器人系统建模与仿真

<!-- 
    创建一个机器人模型(盒状即可),显示在 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文件:

ROS学习笔记16:机器人系统建模与仿真

<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)显示模型:

ROS学习笔记16:机器人系统建模与仿真

ROS学习笔记16:机器人系统建模与仿真

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>

ROS学习笔记16:机器人系统建模与仿真

(2)为机器人模型中的每一个link添加collision和inertial标签,并且重置颜色属性:

ROS学习笔记16:机器人系统建模与仿真

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并添加机器人模型:

ROS学习笔记16:机器人系统建模与仿真

<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>

ROS学习笔记16:机器人系统建模与仿真

3.Gazebo仿真环境搭建:

ROS学习笔记16:机器人系统建模与仿真

ROS学习笔记16:机器人系统建模与仿真

ROS学习笔记16:机器人系统建模与仿真

七、URDF、rviz、Gazebo综合应用:

1.ros_control:

        rviz+Arbotix构建的仿真器使用了Arbotix差速控制器实现对机器人模型的控制,但是这款控制器有很大的局限性,无法在ROS丰富的机器人应用中通用。

        ros_control是ROS为开发者提供的机器人控制中间件,包含一系列控制器接口、传动装置接口、硬件接口、控制器工具等,可以帮助机器人应用功能包快速落地,提高开发效率。

ROS学习笔记16:机器人系统建模与仿真

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>

ROS学习笔记16:机器人系统建模与仿真

(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>

ROS学习笔记16:机器人系统建模与仿真

(3)launch文件启动gazebo,加载课程所提供的仿真环境,控制小车运动:

ROS学习笔记16:机器人系统建模与仿真

解决方案:

sudo apt-get ros-noetic-teleop-twist-keyboard

ROS学习笔记16:机器人系统建模与仿真

 结果展示:

ROS学习笔记16:机器人系统建模与仿真

 ROS学习笔记16:机器人系统建模与仿真

ROS学习笔记16:机器人系统建模与仿真

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>

ROS学习笔记16:机器人系统建模与仿真

(2)在rviz中添加组件:

1)启动demo06_car.launch文件:

ROS学习笔记16:机器人系统建模与仿真

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>

ROS学习笔记16:机器人系统建模与仿真

(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>

ROS学习笔记16:机器人系统建模与仿真

(3)launch文件启动gazebo和rviz并显示雷达数据:

ROS学习笔记16:机器人系统建模与仿真

ROS学习笔记16:机器人系统建模与仿真

相关链接:

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>

ROS学习笔记16:机器人系统建模与仿真

(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>

ROS学习笔记16:机器人系统建模与仿真

(3)launch文件启动gazebo和rviz并显示摄像头数据:

1)启动gazebo:

ROS学习笔记16:机器人系统建模与仿真

2)打开rviz,添加摄像头:

ROS学习笔记16:机器人系统建模与仿真

相关链接:

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>

ROS学习笔记16:机器人系统建模与仿真

(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>

ROS学习笔记16:机器人系统建模与仿真

相关链接:

机器人系统仿真(十六)——摄像头和kinect信息仿真以及显示_蔡军帅的博客-CSDN博客文章来源地址https://www.toymoban.com/news/detail-487554.html

到了这里,关于ROS学习笔记16:机器人系统建模与仿真的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • ROS gazebo 机器人仿真,环境与robot建模,添加相机 lidar,控制robot运动

    b站上有一个非常好的ros教程234仿真之URDF_link标签简介-机器人系统仿真_哔哩哔哩_bilibili,推荐去看原视频。 视频教程的相关文档见:6.7.1 机器人运动控制以及里程计信息显示 · Autolabor-ROS机器人入门课程《ROS理论与实践》零基础教程 本文对视频教程第六章的主要内容做一个总

    2024年02月03日
    浏览(35)
  • ROS学习笔记08、机器人导航仿真(slam、map_server、amcl、move_base与导航消息介绍)

    马上开学,目前学校很多实验室都是人工智能这块,大部分都是和机器人相关,然后软件这块就是和cv、ros相关,就打算开始学习一下。 本章节是虚拟机安装Ubuntu18.04以及安装ROS的环境。 学习教程:【Autolabor初级教程】ROS机器人入门,博客中一些知识点是来源于赵老师的笔记

    2023年04月12日
    浏览(33)
  • ROS入门21讲 | ROS机器人入门教程 【简明笔记】

    古月·ROS入门21讲 | 一学就会的ROS机器人入门教程 ROS = 通信机制+开发工具+应用功能+生态系统 通信机制 : Node :完成具体功能的进程、独立运行的可执行文件。可用多种语言py、c++。节点在系统中的名称唯一。 ROS Master :为节点提供命名注册服务;跟踪和记录话题、服务通信

    2024年02月09日
    浏览(50)
  • ROS:机器人系统仿真

    通过计算机对实体机器人系统进行模拟的技术,在 ROS 中,仿真实现涉及的内容主要有三:对机器人建模(URDF)、创建仿真环境(Gazebo)以及感知环境(Rviz)等系统性实现。 仿真在机器人系统研发过程中占有举足轻重的地位,在研发与测试中较之于实体机器人实现,仿真有如下几点的

    2024年02月15日
    浏览(36)
  • 【ROS 06】机器人系统仿真

    对于ROS新手而言,可能会有疑问:学习机器人操作系统,实体机器人是必须的吗?答案是否定的,机器人一般价格不菲,为了降低机器人学习、调试成本,在ROS中提供了系统的机器人仿真实现,通过仿真,可以实现大部分需求,本章主要就是围绕“仿真”展开的,比如,本章会

    2024年02月09日
    浏览(24)
  • 【ros2 control 机器人驱动开发】简单双关节机器人学习-example 1

    【ros2 control 机器人驱动开发】简单双关节机器人学习-example 1 本系列文件主要有以下目标和内容: 为系统、传感器和执行器创建 HardwareInterface 以URDF文件的形式创建机器人描述 加载配置并使用启动文件启动机器人 控制RRBot的两个关节(两旋转关节机器人) 六自由度机器人的

    2024年02月04日
    浏览(41)
  • 工业机器人控制系统的设计——张晓辉,学习笔记

    视频链接: https://www.aiimooc.com/mall/show-htm-itemid-228-chapterNo-1-segmentNo-1.html   涉及知识   加工过程的控制技术:将机器人作为加工过程的一个节点,让其与其他的节点进行高效智能的交互。   机器人控制技术:机器人作为独立的个体如何提高其自身功能。   机器人电气

    2023年04月18日
    浏览(85)
  • 仿真机器人-深度学习CV和激光雷达感知(项目2)day03【机器人简介与ROS基础】

    💫你好,我是辰chen,本文旨在准备考研复试或就业 💫本文内容是我为复试准备的第二个项目 💫欢迎大家的关注,我的博客主要关注于考研408以及AIoT的内容 🌟 预置知识:基本Python语法,基本linux命令行使用 以下的几个专栏是本人比较满意的专栏 (大部分专栏仍在持续更新

    2024年01月19日
    浏览(35)
  • 如何利用蓝桥云课提升学习ROS机器人的效率

    合适再深入学习,不合适一个网页简单使用也能了解其中大部分功能,免除繁琐配置的时间成本。 如果学习和试用一下ROS机器人(ROS1为例)最方便的办法就是打开如下网页: 课程编号854,已经学习人数超过1.6万。 可以通过蓝桥云课上的ROS机器人相关课程学习,结合实践操

    2023年04月09日
    浏览(35)
  • 嵌入式机器人系统ROS入门相关知识点介绍

    本文旨在收集整理linux系统、ROS系统、树莓派、ssh软件的相关基础知识。 重点是ROS系统相关的知识,根据该实验课程的要求,最后修改的代码,都是由ROS组织起来,运行在ROS环境下的。 1、ssh软件–mobaXterm ssh:SSH通过在网络中创建安全隧道来实现SSH客户端与服务器之间的连接

    2024年02月06日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包