前言
本文针对一个仿真做一次总结,把整个过程顺一遍
文件结构
模仿的是RRBOT的文件结构,具体结构如下
my_arm_control,放控制配置文件,加载控制器的launch文件
config,控制器文件
launchmy_arm_description,放机器人的urdf文件,和传感器、gazebo配置文件等
config ,rviz配置文件
launch
mesh,机器人的外壳文件
urdfmaterials.xacro ,xacro文件的颜色属性
my_arm.gazebo,放每个连杆的gazebo文件,传感器plugin等
my_arm.xacro,机器人配置文件my_arm_gazebo
launch
worlds,gazebo的world文件
urdf与rviz
本节对应description文件,一共有三个文件,首先是重要的机器人urdf文件,由连杆和铰链组成,代码如下:
<robot name="my_arm" xmlns:xacro="http://www.ros.org/wiki/xacro">
<xacro:include filename="$(find my_arm_description)/urdf/my_arm.gazebo" />
<xacro:include filename="$(find my_arm_description)/urdf/materials.xacro" />
<xacro:property name="height1" value="1" />
<xacro:property name="height2" value="1.6" />
<xacro:property name="width" value="0.5" />
<xacro:property name="mass" value="1" />
<!-- Used for fixing robot to Gazebo 'base_link' -->
<link name="world"/>
<joint name="fixed" type="fixed">
<parent link="world"/>
<child link="base_link"/>
</joint>
<link name="base_link">
<visual>
<origin xyz="0 0 ${height1/2}" rpy="0 0 0" />
<geometry>
<box size="${width} ${width} ${height1}" />
</geometry>
<material name="green" />
</visual>
<collision>
<origin xyz="0 0 ${height1/2}" rpy="0 0 0" />
<geometry>
<box size="${width} ${width} ${height1}" />
</geometry>
</collision>
<inertial>
<origin xyz="0 0 ${height1/2}" rpy="0 0 0"/>
<mass value="1"/>
<inertia
ixx="${mass / 12.0 * (width*width + height1*height1)}" ixy="0.0" ixz="0.0"
iyy="${mass / 12.0 * (height1*height1 + width*width)}" iyz="0.0"
izz="${mass / 12.0 * (width*width + width*width)}"/>
</inertial>
</link>
<link name="link1">
<visual>
<origin xyz="0 0 ${height2/2}" rpy="0 0 0" />
<geometry>
<box size="${width} ${width} ${height2}" />
</geometry>
<material name="blue" />
</visual>
<collision>
<origin xyz="0 0 ${height2/2}" rpy="0 0 0" />
<geometry>
<box size="${width} ${width} ${height1}" />
</geometry>
</collision>
<inertial>
<origin xyz="0 0 ${height2/2}" rpy="0 0 0"/>
<mass value="1.1"/>
<inertia
ixx="${mass / 12.0 * (width*width + height2*height2)}" ixy="0.0" ixz="0.0"
iyy="${mass / 12.0 * (height2*height2 + width*width)}" iyz="0.0"
izz="${mass / 12.0 * (width*width + width*width)}"/>
</inertial>
</link>
<joint name="joint1" type="continuous">
<parent link="base_link"/>
<child link="link1"/>
<origin xyz="0 ${width} ${height1 - 0.1}" rpy="0 0 0"/>
<axis xyz="0 1 0"/>
<dynamics damping="0.7"/>
</joint>
</robot>
需要注意,为了在gazebo中仿真,我们需要第一个连杆固定在世界坐标系(就是让两连杆别倾倒),需要加一个world坐标系。
有了这样一个xacro文件,就可以在rviz中查看该机器人,可以编写相应的launch文件,如下:
<launch>
<param name="robot_description" command="$(find xacro)/xacro $(find my_arm_description)/urdf/my_arm.xacro" />
<node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" />
<node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" />
<node name="rviz" pkg="rviz" type="rviz" args="-d $(find my_arm_description)/config/my_arm.rviz" />
</launch>
在rviz文件中查看是否有错误
gazebo
为了让urdf可以在gazebo中仿真,还需要对urdf文件做一些修改,在文件结构中,有一个my_arm.gazebo,可以在里边加一些gazebo的设置,代码如下:
<robot>
<gazebo reference="base_link">
<material>Gazebo/Orange</material>
</gazebo>
<gazebo reference="link1">
<material>Gazebo/Red</material>
</gazebo>
</robot>
至此可以在gazebo的launch文件中,编写相应的launch文件,打开gazebo世界,载入urdf文件,spawn机器人文件,代码如下:
<launch>
<include file="$(find gazebo_ros)/launch/empty_world.launch">
<arg name="world_name" value="$(find my_arm_gazebo)/world/my_arm.world" />
</include>
<param name="robot_description" command="$(find xacro)/xacro $(find my_arm_description)/urdf/my_arm.xacro" />
<node name="urdf_spawner" pkg="gazebo_ros" type="spawn_model" respawn="false"
output="screen" args="-urdf -model my_arm -param robot_description" />
</launch>
control
为了让机器人可以被控制,需要在一些关节分配Robot hardware,具体就是首先在urdf中加入transmission文件,本文使用的关节是力控制关节,因此配置成EffortJointInterface,也有位置控制和速度控制。
<transmission name="tran1">
<type>transmission_interface/SimpleTransmission</type>
<joint name="joint1">
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
</joint>
<actuator name="motor1">
<hardwareInterface>hardware_interface/EffortJointInterface</hardwareInterface>
</actuator>
</transmission>
有了硬件结构可以配置相应的控制器,在control的config中可以编写相应的yaml文件,代码如下:
my_arm:
joint_state_controller:
type: joint_state_controller/JointStateController
publish_rate: 50
joint1_position_controller:
type: effort_controllers/JointPositionController
joint: joint1
pid: {p: 100.0, i: 0.01, d: 10.0}
最后需要在gazebo文件中家在ros_control插件
<gazebo>
<plugin name="gazebo_ros_control" filename="libgazebo_ros_control.so">
<robotNamespace>/my_arm</robotNamespace>
<robotSimType>gazebo_ros_control/DefaultRobotHWSim</robotSimType>
</plugin>
</gazebo>
可以使用launch文件,来给机器人家在controller,launch文件编写如下:
<launch>
<rosparam file="$(find my_arm_control)/config/my_arm.yaml" command="load" />
<node name="controller_spwaner" pkg="controller_manager" type="spawner"
respawn="false" ns="/my_arm" args="joint_state_controller
joint1_position_controller" />
<node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" >
<remap from="/joint_states" to="/my_arm/joint_states" />
</node>
</launch>
传感器
传感器的plugin在这里
可以给本机器人中唯一的关节加入一个六轴传感器,在gazebo文件中,加入以下代码:
<gazebo
reference="joint1">
<provideFeedback>true</provideFeedback>
</gazebo>
<!-- 添加ft_sensor插件 -->
<gazebo>
<plugin name="ft_sensor" filename="libgazebo_ros_ft_sensor.so">
<updateRate>100.0</updateRate>
<topicName>ft_sensor_topic</topicName>
<jointName>joint1</jointName>
</plugin>
</gazebo>
可以在rostopic中看到制定的sensor_topic。