ROS学习第三节20181228


https://www.ncnynl.com/archives/201610/1033.html

URDF机器人建模

$ catkin_create_pkg mbot_description urdf xacro
#(后面两个是创建该功能包所要依赖的功能包)

mbot_description下的文件夹

文件夹作用
ufdf存放机器人模型的URDF或xacro文件
meshes放置UFDF中引用的模型渲染文件(可通过三维软件导出三维纹理信息)
launch存放启动文件
config保存rviz配置文件

launch文件书写

必备知识:

1.ROS 中的paramrosparam标签:设置ROS系统运行中的参数,存储在参数服务器中(在ROS系统中建立全局变量)
2.param用于设置单独比较少的全局变量
param标签介绍

<param name="robot_description" value="$(find mbot_description)/urdf/mbot_base.urdf" />

3.rosparam用于设置多个全局变量时,把所有变量存放在params.yaml文件中

<rosparam file="params.yaml" command="load" ns="params" />#ns是设置命名空间,避免同其他参数有冲突

4.arg是launch文件内部的局部变量,仅限launch文件使用
定义

<arg name="foo" default="arg-value">

使用

<node name="node" pkg="package" type="type" args="$(arg foo)">

建模launch

<launch>
	<!-- 通过定义全局变量,告知launch文件启动时把全局变量robot_description中存储的模型文件加载到rviz中 -->
	<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(根据上面的关节状态,创建整个机器人的tf关系,并发布到系统中)-->
	<node name="robot_state_publisher" pkg="robot_state_publisher" type="state_publisher" />
	
	<!-- 运行rviz可视化界面(args的参数作用类似于自定义rviz中的显示设置) -->
	<node name="rviz" pkg="rviz" type="rviz" args="-d $(find mbot_description)/config/mbot_urdf.rviz" required="true" />
</launch>

urdf文件

urdf文件简述

关节类型描述
continuous无限旋转关节
revolute有角度极限的旋转关节
prismatic沿某一轴线滑动,带位置极限的滑动关节
planar平面关节,可以在平面正交方向上平移或旋转
floating浮动关节,允许平移、旋转运动的关节
fixed固定关节,不允许运动的特殊关节
<?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"/>#定义(0 0.19 -0.05)位置上绕y轴旋转的joint
    </joint>

    <link name="left_wheel_link">
        <visual>
            <origin xyz="0 0 0" rpy="1.5707 0 0" />#以上面joint的坐标系为参照
            <geometry>
                <cylinder radius="0.06" length = "0.025"/>
            </geometry>
            <material name="white">
                <color rgba="1 1 1 0.9"/>
            </material>
        </visual>
    </link>
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、#省略    
        <link name="kinect_link">
        <visual>
            <origin xyz="0 0 0" rpy="0 0 1.5708"/>
            <geometry>
                <mesh filename="package://mbot_description/meshes/kinect.dae" />#dae文件是kinect的描述文件(删掉)
            </geometry>
        </visual>
    </link>

    <joint name="kinect_joint" type="fixed">
        <origin xyz="0.15 0 0.11" rpy="0 0 0"/>
        <parent link="base_link"/>
        <child link="kinect_link"/>
    </joint>
</robot>
....    

需要是什么模型,找到该dae文件

在这里插入图片描述

使用urdf_to_graphiz生成urdf的link和joint关系位置图

~ cd My_First_catkin_ws/src/mbot_description/urdf 
➜  urdf urdf_to_graphiz mbot_base.urdf 
Created file mbot.gv
Created file mbot.pdf
➜  urdf 

mbot.pdf内容如下
在这里插入图片描述

urdf文件的缺陷:

1.模型冗长,重复内容过多
2.参数修改麻烦,不便于二次开发;
3.没有参数计算功能

xacro文件(对urdf文件缺陷进行改进)

常量与数学运算

常量定义

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

常量使用

#花括号里面可以进行数学运算,所有数学运算都会被转换浮点数进行,以保证进度
<origin xyz="0 0 0" rpy="${M_PI/2} 0 0">

宏定义

宏定义

<xacro:macro name="name" params="A B C">
....
</xacro:macro>

宏使用

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

具体使用如下:

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

	<!-- PROPERTY LIST -->
	<xacro:property name="M_PI" value="3.141592653"/>
	<xacro:property name="base_radius" value="0.2"/>
	<xacro:property name="base_length" value="0.16"/>

	<xacro:property name="wheel_radius" value="0.06"/>	
	<xacro:property name="wheel_length" value="0.025"/>
	<xacro:property name="wheel_joint_y" value="0.19"/>
	<xacro:property name="wheel_joint_z" value="0.05"/>

	<xacro:property name="caster_radius" value="0.015"/>
	<xacro:property name="caster_joint_x" value="0.18"/>

	<!-- Defining the colors used in this robot -->
	<material name="yellow">
		<color rgba="1 0.4 0 1"/>
	</material>
	<material name="black">
		<color rgba="0 0 0 0.95"/>
	</material>
	<material name="grey">
		<color rgba="0.75 0.75 0.75 1"/>
	</material>
	
	<!-- Macro for robot wheel -->
	<xacro:macro name="wheel" params="prefix reflect">
		<joint name="${prefix}_wheel_joint" type="continuous">
        		<origin xyz="0 ${reflect*wheel_joint_y} ${-wheel_joint_z}" rpy="0 0 0"/>
        		<parent link="base_link"/>
        		<child link="${prefix}_wheel_link"/>
        		<axis xyz="0 1 0"/>
    		</joint>
		<link name="${prefix}_wheel_link">
        		<visual>
            			<origin xyz="0 0 0" rpy="${M_PI/2} 0 0" />
            			<geometry>
                			<cylinder radius="${wheel_radius}" length = "${wheel_length}"/>
            			</geometry>
            			<material name="grey"/>
        		</visual>
    		</link>
	</xacro:macro>

	<!-- Macro for robot caster -->
	<xacro:macro name="caster" params="prefix reflect">
		<joint name="${prefix}_caster_joint" type="continuous">
        		<origin xyz="${reflect*caster_joint_x} 0 -0.095" rpy="0 0 0"/>
        		<parent link="base_link"/>
        		<child link="${prefix}_caster_link"/>
        		<axis xyz="0 1 0"/>
    		</joint>

    		<link name="${prefix}_caster_link">
        		<visual>
            			<origin xyz="0 0 0" rpy="0 0 0"/>
            			<geometry>
                			<sphere radius="${caster_radius}" />
            			</geometry>
            			<material name="black"/>
        		</visual>
    		</link>
	</xacro:macro>

	<xacro:macro name="mbot_base">
		<link name="base_footprint">
			<visual>
				<origin xyz="0 0 0" rpy="0 0 0"/>
				<geometry>
					<box size="0.001 0.001 0.001"/>
				</geometry>
			</visual>
		</link>	

		<joint name="base_footprint_joint" type="fixed">
        		<origin xyz="0 0 ${base_length/2+caster_radius*2}" rpy="0 0 0"/>
        		<parent link="base_footprint"/>
        		<child link="base_link"/>
        		<axis xyz="0 1 0"/>
    		</joint>

		<link name="base_link">
			<visual>
				<origin xyz="0 0 0" rpy="0 0 0"/>
				<geometry>
					<cylinder length="${base_length}" radius="${base_radius}"/>
				</geometry>
				<material name="yellow"/>
			</visual>
		</link>

		<wheel prefix="left" reflect="1"/>
		<wheel prefix="right" reflect="-1"/>
		<caster prefix="front" reflect="1"/>
		<caster prefix="back" reflect="-1"/>

	</xacro:macro>
</robot>

由上可知,这个文件全部是属于宏定义,并没有调用宏(这么做的原因:把这个车体整体当成一个部件,同其它部件一块被调用)

调用宏(新建mbot.xacro文件,内容如下)

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

	<xacro:include filename="$(find mbot_description)/urdf/xacro/mbot_base.xacro"/>
	<mbot_base/>
	<link name="kinect_link">
	        <visual>
	            <origin xyz="0 0 0" rpy="0 0 1.5708"/>
	            <geometry>
	                <mesh filename="package://mbot_description/meshes/kinect.dae" />
	            </geometry>
	        </visual>
	</link>

	<joint name="laser_joint" type="fixed">
	        <origin xyz="0.15 0 0.11" rpy="0 0 0"/>
        	<parent link="base_link"/>
        	<child link="kinect_link"/>
    	</joint>
</robot>

将kinect文件放在mbot_description/meshes里

xacro文件显示

方法一:将xacro文件转化为urdf文件后显示
~ cd My_First_catkin_ws/src/mbot_description/urdf/xacro 
➜  xacro rosrun xacro xacro.py mbot.xacro > mbot.urdf
方法二(常用方法):直接调用xacro解析器

在launch文件中使用xacro解析器

<launch>
	<!-- 添加xacro功能包下的xacro解析器来解析.xacro文件 -->
	<arg name="model" default="$(find xacro)/xacro --inorder '$(find mbot_description)/urdf/xacro/mbot.xacro'"/>
	<arg name="gui" default="true"/>
	
	<param name="robot_description" command="$(arg model)"/>

	<!-- 设置GUI参数,显示关节控制插件 -->
	<param name="use_gui" value="$(arg gui)"/>
	
	<!-- 运行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="robot_state_publisher"/>
	
	<!-- 运行rviz可视化界面 -->
	<node name="rviz" pkg="rviz" type="rviz" args="-d $(find mbot_description)/config/mbot_urdf.rviz" required="true" />
</launch>

ArbotiX+rviz功能仿真

安装ArbotiX(给予kinetic)

~ cd My_First_catkin_ws/src 
➜  src git clone https://github.com/vanadiumlabs/arbotix_ros.git
➜  src cd ..
➜  My_First_catkin_ws catkin_make

注意:arbotix_ros中的python文件需要添加可执行文件权限

➜  My_First_catkin_ws cd src/arbotix_ros 
➜  arbotix_ros git:(indigo-devel) cd arbotix_python/binbin git:(indigo-devel) ls
arbotix_driver  arbotix_gui  arbotix_terminal
➜  bin git:(indigo-devel) sudo chmod +x arbotix_driver 

创建launch文件

名为arbotix_mbot_base_xacro.launch,内容如下

<launch>
	<arg name="model" default="$(find xacro)/xacro --inorder '$(find mbot_description)/urdf/xacro/mbot.xacro'"/>
	<arg name="gui" default="true"/>
	
	<param name="robot_description" command="$(arg model)"/>

	<!-- 设置GUI参数,显示关节控制插件 -->
	<param name="use_gui" value="$(arg gui)"/>

	<node name="arbotix" pkg="arbotix_python" type="arbotix_driver" output="screen">
		<rosparam file="$(find mbot_description)/config/fake_mbot_arbotix.yaml" command="load"/>
		<param name="sim" value="true"/>
	</node>
	
	<!-- 运行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="robot_state_publisher"/>
	
	<!-- 运行rviz可视化界面 -->
	<node name="rviz" pkg="rviz" type="rviz" args="-d $(find mbot_description)/config/mbot_arbotix.rviz.rviz" required="true" />
</launch>

创建yaml文件

在config中创建fake_mbot_arbotix.yaml(格式一定是这样)

controllers: {
   base_controller: {
       type: diff_controller, 
       base_frame_id: base_footprint, 
       base_width: 0.26, 
       ticks_meter: 4100, 
       Kp: 12, 
       Kd: 12, 
       Ki: 0, 
       Ko: 50, 
       accel_limit: 1.0 
    }
}

启动该launch文件

➜  launch roslaunch arbotix_mbot_base_xacro.launch

启动键盘控制

➜  launch roslaunch arbotix_mbot_base_xacro.launch

Gazebo物理仿真环境搭建

配置物理仿真模型

1.为link添加惯性参数
2.为link添加gazebo标签,之前设置的颜色是在rviz中显示,但是无法在gazebo中显示
建立xacro文件如下
3.为joint添加传动装置
4.添加gazebo控制器插件(相当于驱动板1)

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

    <!-- PROPERTY LIST -->
    <xacro:property name="M_PI" value="3.1415926"/>
    <xacro:property name="base_mass"   value="20" /> 
    <xacro:property name="base_radius" value="0.20"/>
    <xacro:property name="base_length" value="0.16"/>

    <xacro:property name="wheel_mass"   value="2" />
    <xacro:property name="wheel_radius" value="0.06"/>
    <xacro:property name="wheel_length" value="0.025"/>
    <xacro:property name="wheel_joint_y" value="0.19"/>
    <xacro:property name="wheel_joint_z" value="0.05"/>

    <xacro:property name="caster_mass"    value="0.5" /> 
    <xacro:property name="caster_radius"  value="0.015"/> <!-- wheel_radius - ( base_length/2 - wheel_joint_z) -->
    <xacro:property name="caster_joint_x" value="0.18"/>

    <!-- Defining the colors used in this robot -->
    <material name="yellow">
        <color rgba="1 0.4 0 1"/>
    </material>
    <material name="black">
        <color rgba="0 0 0 0.95"/>
    </material>
    <material name="gray">
        <color rgba="0.75 0.75 0.75 1"/>
    </material>
    
    <!-- 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>

    <!-- Macro for robot wheel -->
    <xacro:macro name="wheel" params="prefix reflect">
        <joint name="${prefix}_wheel_joint" type="continuous">
            <origin xyz="0 ${reflect*wheel_joint_y} ${-wheel_joint_z}" rpy="0 0 0"/>
            <parent link="base_link"/>
            <child link="${prefix}_wheel_link"/>
            <axis xyz="0 1 0"/>
        </joint>

        <link name="${prefix}_wheel_link">
            <visual>
                <origin xyz="0 0 0" rpy="${M_PI/2} 0 0" />
                <geometry>
                    <cylinder radius="${wheel_radius}" length = "${wheel_length}"/>
                </geometry>
                <material name="gray" />
            </visual>
            <collision>
                <origin xyz="0 0 0" rpy="${M_PI/2} 0 0" />
                <geometry>
                    <cylinder radius="${wheel_radius}" length = "${wheel_length}"/>
                </geometry>
            </collision>
            <cylinder_inertial_matrix  m="${wheel_mass}" r="${wheel_radius}" h="${wheel_length}" />
        </link>

        <gazebo reference="${prefix}_wheel_link">
            <material>Gazebo/Gray</material>
        </gazebo>

        <!-- Transmission is important to link the joints and the controller -->
        <transmission name="${prefix}_wheel_joint_trans">
            <type>transmission_interface/SimpleTransmission</type>
            <joint name="${prefix}_wheel_joint" >
                <hardwareInterface>hardware_interface/VelocityJointInterface</hardwareInterface>
            </joint>
            <actuator name="${prefix}_wheel_joint_motor">
                <hardwareInterface>hardware_interface/VelocityJointInterface</hardwareInterface>
                <mechanicalReduction>1</mechanicalReduction>
            </actuator>
        </transmission>
    </xacro:macro>

    <!-- Macro for robot caster -->
    <xacro:macro name="caster" params="prefix reflect">
        <joint name="${prefix}_caster_joint" type="continuous">
            <origin xyz="${reflect*caster_joint_x} 0 ${-(base_length/2 + caster_radius)}" rpy="0 0 0"/>
            <parent link="base_link"/>
            <child link="${prefix}_caster_link"/>
            <axis xyz="0 1 0"/>
        </joint>

        <link name="${prefix}_caster_link">
            <visual>
                <origin xyz="0 0 0" rpy="0 0 0"/>
                <geometry>
                    <sphere radius="${caster_radius}" />
                </geometry>
                <material name="black" />
            </visual>
            <collision>
                <origin xyz="0 0 0" rpy="0 0 0"/>
                <geometry>
                    <sphere radius="${caster_radius}" />
                </geometry>
            </collision>      
            <sphere_inertial_matrix  m="${caster_mass}" r="${caster_radius}" />
        </link>

        <gazebo reference="${prefix}_caster_link">
            <material>Gazebo/Black</material>
        </gazebo>
    </xacro:macro>

    <xacro:macro name="mbot_base_gazebo">
        <link name="base_footprint">
            <visual>
                <origin xyz="0 0 0" rpy="0 0 0" />
                <geometry>
                    <box size="0.001 0.001 0.001" />
                </geometry>
            </visual>
        </link>
        <gazebo reference="base_footprint">
            <turnGravityOff>false</turnGravityOff>
        </gazebo>

        <joint name="base_footprint_joint" type="fixed">
            <origin xyz="0 0 ${base_length/2 + caster_radius*2}" rpy="0 0 0" />        
            <parent link="base_footprint"/>
            <child link="base_link" />
        </joint>

        <link name="base_link">
            <visual>
                <origin xyz=" 0 0 0" rpy="0 0 0" />
                <geometry>
                    <cylinder length="${base_length}" radius="${base_radius}"/>
                </geometry>
                <material name="yellow" />
            </visual>
            <collision>
                <origin xyz=" 0 0 0" rpy="0 0 0" />
                <geometry>
                    <cylinder length="${base_length}" radius="${base_radius}"/>
                </geometry>
            </collision>   
            <cylinder_inertial_matrix  m="${base_mass}" r="${base_radius}" h="${base_length}" />
        </link>

        <gazebo reference="base_link">
            <material>Gazebo/Blue</material>
        </gazebo>

        <wheel prefix="left"  reflect="-1"/>
        <wheel prefix="right" reflect="1"/>

        <caster prefix="front" reflect="-1"/>
        <caster prefix="back"  reflect="1"/>

        <!-- controller -->
        <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_wheel_joint</leftJoint>
                <rightJoint>right_wheel_joint</rightJoint>
                <wheelSeparation>${wheel_joint_y*2}</wheelSeparation>
                <wheelDiameter>${2*wheel_radius}</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> 
    </xacro:macro>

</robot>

创建仿真环境

1.直接添加环境模型
2.使用Building Editor

传感器仿真

摄像头仿真

<gazebo reference="${prefix}_link">#把之前定义的link仿真成摄像头
            <sensor type="camera" name="camera_node">
                <update_rate>30.0</update_rate>#摄像头一秒钟发布30次图像信息
                <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">#加载gazebo插件
                    <alwaysOn>true</alwaysOn>
                    <updateRate>0.0</updateRate>
                    <cameraName>/camera</cameraName>
                    <imageTopicName>image_raw</imageTopicName>#发布的话题名
                    <cameraInfoTopicName>camera_info</cameraInfoTopicName>
                    <frameName>camera_link</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>

在xacro文件中为传感器
1.添加sensor标签(描述传感器 )
2.添加标签(描述摄像头参数)
3.添加标签(加载摄像头仿真插件libgazebo_ros_camera.so)

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值