ROS学习笔记---搭建自己的仿真机器人模型(URDF、xacro、Arbotix、rviz、ros_control & gazebo)

一.ROS的单位长度和坐标惯例

在参照框架中工作时:

ROS确定坐标轴方向使用的是如下图所示的右手系:

食指指向x轴正方向,中指指向y轴正方向,而拇指指向z轴正方向。

ROS确定旋转方向是由下图所示的右手法则来定义的:

右手握拳,拇指指向某一坐标轴的正方向,其他手指卷曲的方向则是旋转的正方向。

对于使用ROS的移动机器人,x轴指向前方,y轴指向左方,z轴指向上方。根据右手法则(从机器人的上方往下看),当机器人绕z轴做正方向旋转时是在逆时针旋转,而做反向旋转时是在顺时针旋转。

 

ROS系统使用公制作为计量系统:

线速度通常使用米/秒(m/s)来作为单位,而角速度通常使用弧度/秒(rad/s)来作为单位。

对于室内机器人来说0.5m/s(约等于1.1mph)的线速度是比较快的速度,而1.0rad/s相当于6秒旋转1圈或者说每分钟旋转10圈。当你不确定该设定什么速度时,请用较慢的速度启动并慢慢提升速度。

二.URDF

Unified Robot Description Format,统一机器人描述格式,简称为URDF。ROS中的urdf功能包包含一个URDF的C++解析器,URDF文件使用XML格式描述机器人模型。

具体的可参看:

https://blog.csdn.net/weixin_41070687/article/details/88615737

http://wiki.ros.org/urdf/Tutorials

后面第四点直接上手实战

三.xacro

使用urdf模型搭建机器人,我们会发现我们创建了一个十分冗长的模型文件,其中很多内容除了参数,几乎都是重复的内容。但是urdf文件并不支持代码复用的特性。ROS自然不会容忍这种冗长重复的情况,因为它的设计目标就是提高代码复用率。于是针对URDF模型产生了另一种精简化、可复用、模块化的描述形式---xacro。

优势

  • 精简模型代码:xacro是一个精简版本的URDF文件,在xacro文件中,可以通过创建宏定义的方式定义常量或者复用代码,不仅可以减少代码量,而且可以让模型代码更加模块化、更具可读性。
  • 提供可编程接口:xacro的语法支持一些可编程接口,如常量、变量、数学公式、条件语句等,可以让建模过程更加智能有效。

xacro是URDF的升级版,模型文件的后缀名由.urdf变为.xacro,而且在模型<robot>标签中需要加入xacro的声明

<?xml version="1.0"?>
<robot name="robot_name" xmlns:xacro="http://www.ros.org/wiki/xacro">

1.定义常量

在URDF模型中有很多尺寸、坐标等常量的使用,但是这些常量分布在整个文件中,不仅可读性差,而且后期修改起来十分困难。xacro提供了一种常量属性的定义方式:

<xacro:property name="常量名" value="常量值" />

2.调用常量

<origin xyz="..." rpy="${常量名} . ." />

调用的时候:${  } 

例如:

定义一个名为M_PI的常量,值为3.14159

<xacro:property name="M_PI" value="3.14159" />

调用该常量

<origin xyz="0 0 0" rpy="${M_PI/2} 0 0" />

在“${}”语句中,不仅可以调用常量,还可以使用一些常用的数学运算,包括加、减、乘、除、负号、括号等

注:所有的数学运算都会转换成浮点数进行,以保证运算的精度

3.宏定义

xacro文件可以使用宏定义来声明重复使用的代码模块,而且可以包含输入参数,类似编程中的函数概念。

定义:

<xacro:macro name="宏定义名称" params="A B C">
...
...
...
</xacro:macro>

调用:

<name A="A_value" B="B_value" C="C_value" />

具体的后面在第五点实践中说明

四.创建自己的机器人URDF模型

.创建一个工作空间(本人使用的是zsh终端,https://blog.csdn.net/weixin_41070687/article/details/83215785)

mkdir -p ~/catkin_ws/src
cd ~/catkin_ws
catkin_make
echo "source ~/catkin_ws/devel/setup.zsh" >> ~/.zshrc
source ~/.zshrc

在src目录下创建一个描述机器人模型的功能包mbot_description,依赖项是urdf和xacro。在ROS的工作空间中,功能包名为xxx_description的一般都是描述机器人模型的功能包,我们通常也是这么命名的

cd ~/catkin_ws/src
catkin_create_pkg mbot_description urdf xacro
cd ..
catkin_make
source ~/.zshrc

然后,在mbot_description目录下创建四个文件夹(mbot_description是一个元功能包),直接右击鼠标新建文件夹即可

urdf:用来存放机器人模型的URDF文件

meshes:放置URDF中引用的模型渲染文件,如外观纹理,logo等

launch:保存相关的启动文件

config:保存rviz的配置文件

.我们先在launch功能包下编写一个launch文件,名称为display_mbot_base_urdf.launch,用于启动显示我们后面编写的urdf模型文件.

这个launch文件也是一个框架,可以把这个launch文件框架记住。我们自己在编写时完全可以照搬这个程序,只需要根据自己的实际情况,更改第二行里面的textfile的内容即可。textfile="$(find mbot_description) / urdf文件的路径"

<launch>
	<param name="robot_description" textfile="$(find mbot_description)/urdf/mbot_base.urdf" />
	
	<!-- 设置GUI参数,显示关节控制插件 -->
	<param name="use_gui" value="true"/>
	
	<!-- 运行joint_state_publisher节点,发布机器人的关节状态  -->
	<node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" />
	
	<!-- 运行robot_state_publisher节点,发布tf  -->
	<node name="robot_state_publisher" pkg="robot_state_publisher" type="state_publisher" />

		<!-- 运行rviz可视化界面 -->
	<node name="rviz" pkg="rviz" type="rviz" args="-d $(find mbot_description)/config/mbot_urdf.rviz" required="true" />

</launch>

.接下来开始编写机器人的URDF模型:

urdf功能包下新建一个mbot_base.urdf文件

urdf文件的最外层框架:

<?xml version="1.0" ?>  
<robot name="mbot">>
    ...
    ...
    ...
</robot>

第一行:声明该文件使用XML描述

第二行:使用<robot>根标签定义一个机器人模型,并定义该模型的名称为“mbot”

编写机器人模型的主体部分:

<?xml version="1.0" ?>
<robot name="mbot">

    <link name="base_link">
        <visual>        
            <origin xyz=" 0 0 0" rpy="0 0 0" />
            <geometry>
                <cylinder length="0.16" radius="0.20"/>
            </geometry>
            <material name="yellow">
                <color rgba="1 0.4 0 1"/>
            </material>
        </visual>
    </link>

</robot>

link标签用于描述机器人的某个刚体部分的外观属性和物理属性,名称为“base_link”

visual标签用于描述机器人的link部分的外观参数

origin标签定义了“base_link”的坐标,长度的单位是米,角度的的单位是弧度

  • 当指定x、y、z参数时,x轴指向机器人前方,y轴指向机器人左方,z轴指向机器人上方。
  • 当给旋转变量r、p、y赋值时,参数roll(r)表示的是围绕x轴旋转的角度,参数pitch(p)表示的是围绕y轴旋转的角度,参数yaw(y)表示的是围绕z轴旋转的角度。

geometry标签定义了这一部分的几何形状:

  • <box> 矩形,大小属性包含三个边长,原点在其中心。
  • <cylinder> 圆柱,指定半径和长度,原点在其中心。
  •  <sphere> 球体,指定半径,原点在其中心。
  •  <mesh filename="package://pkg_description/meshs/name.dae" /> 通过该标签可以导入该模型的mesh文件。

material标签定义了机器人底盘的颜色,rgb颜色的RGB值,a是指透明度,值的范围在0-1

可以先保存运行,看一下效果:主体是一个圆柱

在终端输入

roslaunch mbot_description  display_mbot_base_urdf.launch

我们可以更改一下urdf文件中的一些参数值,加深理解。

例如:将origin标签中的rpy的参数值更改成“1.5707 0 0”,即r=1.5707,p和y均为0,即主体部分绕x轴旋转90°

更改rgb的参数值换颜色:

给机器人添加两个轮子:

两个link之间需要一个joint连接

<?xml version="1.0" ?>
<robot name="mbot">

    <link name="base_link">
        <visual>        
            <origin xyz=" 0 0 0" rpy="0 0 0" />
            <geometry>
                <cylinder length="0.16" radius="0.20"/>
            </geometry>
            <material name="yellow">
                <color rgba="1 0.4 0 1"/>
            </material>
        </visual>
    </link>
  
    <joint name="left_wheel_joint" type="continuous">
    	<origin xyz="0 0.19 -0.05" rpy="0 0 0"/>
    	<parent link="base_link"/>
    	<child link="left_wheel_link"/>
    	<axis xyz="0 1 0"/>
    </joint>
	    
    <link name="left_wheel_link">
    	<visual>
    		<origin xyz="0 0 0" rpy="1.5707 0 0" />
    		<geometry>
    			<cylinder radius="0.06" length="0.025"/>
    		</geometry>
    		<material name="white">
    			<color rgbd="1 1 1 0.9"/>
    		</material>
    	</visual>
    </link>        
       
    <joint name="right_wheel_joint" type="continuous">
    	<origin xyz="0 -0.19 -0.05" rpy="0 0 0"/>
    	<parent link="base_link"/>
    	<child link="right_wheel_link"/>
    	<axis xyz="0 1 0"/>
    </joint>
    
    <link name="right_wheel_link">
    	<visual>
    		<origin xyz="0 0 0" rpy="1.5707 0 0"/>
    		<geometry>
    			<cylinder radius="0.06" length="0.025"/>
    		</geometry>
    		<material name="white">
    			<color rgba="1 1 1 0.9"/>
    		</material>
    	</visual>
    </link>

</robot>

对joint标签部分进行解读:

    <joint name="left_wheel_joint" type="continuous">
    	<origin xyz="0 0.19 -0.05" rpy="0 0 0"/>
    	<parent link="base_link"/>
    	<child link="left_wheel_link"/>
    	<axis xyz="0 1 0"/>
    </joint>

joint标签用于描述机器人关节的运动学和动力学属性,包括关节运动的位置和速度限制。它有两个属性:name和type

 type一共有六种类型:

  • revolute - 旋转关节,可绕单轴旋转,但有旋转的角度极限。
  • continuous - 旋转关节,可以绕单轴无限旋转。
  • prismatic - 滑动关节,可以沿着一个轴滑动,有最大值和最小值限制。
  • fixed - 这不是一个实际的关节,因为它无法运动,所有的自由度都被锁定。这种类型的关节不需要指定轴、动力学特征、标度和最大值最小值限制。
  • floating - 浮动关节,允许进行平移、旋转运动(是一个具有6个自由度的关节)。
  • planar - 此关节在一个平面内运动,垂线是运动轴。

子元素中parent和child标签是必须要有的,link是名称。如图所示:

axis标签定义joint的旋转轴。在此段代码中joint的类型是continuous型,即可以绕单轴无限旋转,在机器人运动过程中轮子就是可绕单轴无限旋转。在axis参数中x、y、z代表了三个旋转轴,其中x和z的值都是0,只有y为1,即表示该joint的旋转轴是正y轴,轮子在运动时会绕y轴旋转。

再一次保存运行一下看看效果:

机器人主体添加了两个轮子,运行后还会有一个小框joint_state_publisher,这个是之前在launch文件中启动的joint_state_publisher节点,用于发布机器人的关节状态。移动横条可以是轮子转动。

给机器人前后各添加一个支撑轮:

    <joint name="front_caster_joint" type="continuous">
    	<origin xyz="0.18 0 -0.095" rpy="0 0 0"/>
    	<parent link="base_link"/>
    	<child link="front_caster_link"/>
    	<axis xyz="0 1 0"/>
    </joint>

    <link name="front_caster_link">
    	<visual>
    		<origin xyz="0 0 0" rpy="0 0 0"/>
    		<geometry>
    			<sphere radius="0.015" />
    		</geometry>
    		<material name="black">
    			<color rgba="0 0 0 0.95"/>
    		</material>
    	</visual>
    </link>
    
    <joint name="back_caster_joint" type="continuous">
    	<origin xyz="-0.18 0 -0.095" rpy="0 0 0"/>
    	<parent link="base_link"/>
    	<child link="back_caster_link"/>
    	<axis xyz="0 1 0"/>
    </joint>
    
    <link name="back_caster_link">
    	<visual>
    		<origin xyz="0 0 0" rpy="0 0 0"/>
    		<geometry>
    			<sphere radius="0.015" />
    		</geometry>
    		<material name="black">
    			<color rgba="0 0 0 0.95"/>
    		</material>
    	</visual>
    </link>

支撑轮是球体,机器人运动时支撑轮绕y轴正方向旋转。

整个urdf文件内容如下

<?xml version="1.0" ?>
<robot name="mbot">

    <link name="base_link">
        <visual>        
            <origin xyz=" 0 0 0" rpy="0 0 0" />
            <geometry>
                <cylinder length="0.16" radius="0.20"/>
            </geometry>
            <material name="yellow">
                <color rgba="1 0.4 0 1"/>
            </material>
        </visual>
    </link>
  
    <joint name="left_wheel_joint" type="continuous">
    	<origin xyz="0 0.19 -0.05" rpy="0 0 0"/>
    	<parent link="base_link"/>
    	<child link="left_wheel_link"/>
    	<axis xyz="0 1 0"/>
    </joint>
	    
    <link name="left_wheel_link">
    	<visual>
    		<origin xyz="0 0 0" rpy="1.5707 0 0" />
    		<geometry>
    			<cylinder radius="0.06" length="0.025"/>
    		</geometry>
    		<material name="white">
    			<color rgbd="1 1 1 0.9"/>
    		</material>
    	</visual>
    </link>        
       
    <joint name="right_wheel_joint" type="continuous">
    	<origin xyz="0 -0.19 -0.05" rpy="0 0 0"/>
    	<parent link="base_link"/>
    	<child link="right_wheel_link"/>
    	<axis xyz="0 1 0"/>
    </joint>
    
    <link name="right_wheel_link">
    	<visual>
    		<origin xyz="0 0 0" rpy="1.5707 0 0"/>
    		<geometry>
    			<cylinder radius="0.06" length="0.025"/>
    		</geometry>
    		<material name="white">
    			<color rgba="1 1 1 0.9"/>
    		</material>
    	</visual>
    </link>
     
    <joint name="front_caster_joint" type="continuous">
    	<origin xyz="0.18 0 -0.095" rpy="0 0 0"/>
    	<parent link="base_link"/>
    	<child link="front_caster_link"/>
    	<axis xyz="0 1 0"/>
    </joint>
    
    <link name="front_caster_link">
    	<visual>
    		<origin xyz="0 0 0" rpy="0 0 0"/>
    		<geometry>
    			<sphere radius="0.015" />
    		</geometry>
    		<material name="black">
    			<color rgba="0 0 0 0.95"/>
    		</material>
    	</visual>
    </link>
    
    <joint name="back_caster_joint" type="continuous">
    	<origin xyz="-0.18 0 -0.095" rpy="0 0 0"/>
    	<parent link="base_link"/>
    	<child link="back_caster_link"/>
    	<axis xyz="0 1 0"/>
    </joint>
    
    <link name="back_caster_link">
    	<visual>
    		<origin xyz="0 0 0" rpy="0 0 0"/>
    		<geometry>
    			<sphere radius="0.015" />
    		</geometry>
    		<material name="black">
    			<color rgba="0 0 0 0.95"/>
    		</material>
    	</visual>
    </link>
      
</robot>

再次运行指令查看整体效果:

五.用xacro优化URDF模型

 

 

 

 

 

六.基于Arbotix和rviz的仿真器

 

 

 

七.ros_control框架

 

 

 

 

 

八.Gazebo仿真

 

 

 

参考:

胡春旭:《ROS机器人开发实践》

http://www.guyuehome.com/372

http://wiki.ros.org/xacro

http://wiki.ros.org/urdf/Tutorials

http://wiki.ros.org/ros_control

https://blog.csdn.net/weixin_41070687/article/details/88615737

 

 

 

  • 2
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
搭建自己的机器人模型需要进行以下步骤: 1. 安装ROS仿真工具包 2. 创建ROS包和机器人模型 3. 编写机器人控制程序 4. 启动仿真环境并加载机器人模型 5. 运行机器人控制程序,观察仿真结果 下面是一个简单的机器人模型搭建示例,使用ROS Kinetic和Gazebo仿真工具包: 1. 安装ROS仿真工具包 在Ubuntu系统中使用以下命令安装ROS Kinetic和Gazebo仿真工具包: ``` sudo apt-get update sudo apt-get install ros-kinetic-desktop-full sudo apt-get install ros-kinetic-gazebo-ros-pkgs ros-kinetic-gazebo-ros-control ``` 2. 创建ROS包和机器人模型 使用以下命令创建一个名为my_robot的ROS包,并在其中创建一个名为urdf的目录用于存放机器人模型文件: ``` mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src catkin_create_pkg my_robot cd my_robot mkdir urdf ``` 在urdf目录中创建一个名为my_robot.urdf机器人模型文件,内容如下: ```xml <?xml version="1.0"?> <robot name="my_robot" xmlns:xacro="http://www.ros.org/wiki/xacro"> <link name="base_link"> <visual> <geometry> <box size="0.3 0.3 0.1"/> </geometry> </visual> </link> <joint name="base_joint" type="fixed"> <parent link="world"/> <child link="base_link"/> <origin xyz="0 0 0.05"/> </joint> <link name="left_wheel_link"> <visual> <geometry> <cylinder length="0.05" radius="0.1"/> </geometry> </visual> </link> <joint name="left_wheel_joint" type="continuous"> <parent link="base_link"/> <child link="left_wheel_link"/> <origin xyz="0.15 0 -0.05"/> <axis xyz="0 1 0"/> </joint> <link name="right_wheel_link"> <visual> <geometry> <cylinder length="0.05" radius="0.1"/> </geometry> </visual> </link> <joint name="right_wheel_joint" type="continuous"> <parent link="base_link"/> <child link="right_wheel_link"/> <origin xyz="0.15 0 0.05"/> <axis xyz="0 1 0"/> </joint> </robot> ``` 这个机器人模型由一个长方体的底座和两个圆柱形的轮子组成,使用URDF格式描述。其中base_link表示机器人的底座,left_wheel_link和right_wheel_link分别表示左右两个轮子。 3. 编写机器人控制程序 在ROS包的src目录中创建一个名为my_robot_control.cpp的控制程序文件,内容如下: ```cpp #include <ros/ros.h> #include <geometry_msgs/Twist.h> int main(int argc, char** argv) { ros::init(argc, argv, "my_robot_control"); ros::NodeHandle nh; ros::Publisher cmd_vel_pub = nh.advertise<geometry_msgs::Twist>("cmd_vel", 10); ros::Rate loop_rate(10); while (ros::ok()) { geometry_msgs::Twist cmd_vel; cmd_vel.linear.x = 0.1; cmd_vel.angular.z = 0.5; cmd_vel_pub.publish(cmd_vel); ros::spinOnce(); loop_rate.sleep(); } return 0; } ``` 这个控制程序使用ROS的Twist消息类型发布机器人的线速度和角速度,以控制机器人的运动。在这个示例中,机器人线速度为0.1,角速度为0.5。 4. 启动仿真环境并加载机器人模型 使用以下命令启动Gazebo仿真环境,并加载机器人模型: ``` roslaunch my_robot my_robot.launch ``` 在my_robot包中创建一个名为my_robot.launch的启动文件,内容如下: ```xml <?xml version="1.0"?> <launch> <arg name="model" default="$(find my_robot)/urdf/my_robot.urdf"/> <param name="robot_description" textfile="$(arg model)" /> <node name="spawn_urdf" pkg="gazebo_ros" type="spawn_model" args="-urdf -model my_robot -param robot_description -x 0 -y 0 -z 0"/> <node name="my_robot_control" type="my_robot_control" pkg="my_robot"/> <node name="gazebo_gui" pkg="gazebo" type="gazebo"/> </launch> ``` 这个启动文件首先将机器人模型文件加载到ROS参数服务器中,然后使用gazebo_ros包的spawn_model节点将机器人模型加载到Gazebo仿真环境中。同时运行my_robot_control程序节点控制机器人运动。最后启动Gazebo仿真环境的GUI界面。 5. 运行机器人控制程序,观察仿真结果 使用以下命令运行my_robot_control程序节点,控制机器人运动: ``` rosrun my_robot my_robot_control ``` 可以观察到仿真环境中的机器人开始运动,同时在控制程序的终端输出中可以看到机器人的线速度和角速度。 下图为搭建自己的机器人模型的结果截图: ![ROS机器人仿真结果截图](https://i.imgur.com/lv9v5a1.png)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值