MYRAbot model for simulation (urdf+gazebo)
Contents
Components of MYRAbot model
We have started creating a model of the MYRAbot's structure and we have added the mobile base Roomba, the kinect camera, the arm model and the webcam Logitech Webcam Pro 9000.
First, we will create a new package with the necessary dependences for our programs (urdf std_msgs sensor_msgs tf roscpp). We will execute the next commands in a terminal:
cd ~/ros_workspace
roscreate-pkg myrabot_fer_modelo urdf std_msgs sensor_msgs tf roscpp
URDF MYRAbot's structure
We have made the 3D model of the structure with a CAD software from which we use the parts with a complex geometry.
We have divided the model in two files, main file and macros file. For the main file, we will create a file named "estructura-myrabot.xacro" within the folder "urdf" of the created package with the content that is shown below:
<?xml version="1.0"?>
<robot>
<include filename="$(find myrabot_fer_modelo)/urdf/estructura-myrabot-macros.xacro" />
<macro name="estructura_myrabot" params="parent *origin">
<joint name="world_joint" type="fixed">
<parent link="${parent}"/>
<child link="e_base_1_link"/>
<insert_block name="origin" />
</joint>
<link name="e_base_1_link">
<inertial>
<mass value="0.05"/>
<origin rpy="0 0 0" xyz="0.135 0.135 ${0.015/2}"/>
<default_inertia_e />
</inertial>
<visual>
<origin rpy="0 0 0" xyz="0.135 0.135 ${0.015/2}"/>
<geometry>
<cylinder radius="0.135" length="0.015" />
</geometry>
<material name="wood">
<color rgba="${205/255} ${133/255} ${63/255} 1" />
</material>
</visual>
<collision>
<origin rpy="0 0 0" xyz="0.135 0.135 ${0.015/2}"/>
<geometry>
<cylinder radius="0.135" length="0.015" />
</geometry>
</collision>
</link>
<separador_base id="1" />
<e_separador_base id="1" xsim="1" ysim="1" />
<separador_base id="2" />
<e_separador_base id="2" xsim="1" ysim="-1" />
<separador_base id="3" />
<e_separador_base id="3" xsim="-1" ysim="-1" />
<separador_base id="4" />
<e_separador_base id="4" xsim="-1" ysim="1" />
<joint name="base_2" type="fixed">
<parent link="e_base_1_link"/>
<child link="e_base_2_link"/>
<origin xyz="0 0 0.135" rpy="0 0 0" />
</joint>
<link name="e_base_2_link">
<inertial>
<mass value="0.05"/>
<origin rpy="0 0 0" xyz="0.135 0.135 ${0.02/2}"/>
<default_inertia_e />
</inertial>
<visual>
<origin rpy="0 0 0" xyz="0.135 0.135 ${0.02/2}"/>
<geometry>
<cylinder radius="0.135" length="0.02" />
</geometry>
<material name="wood">
<color rgba="${205/255} ${133/255} ${63/255} 1" />
</material>
</visual>
<collision>
<origin rpy="0 0 0" xyz="0.135 0.135 ${0.02/2}"/>
<geometry>
<cylinder radius="0.135" length="0.02" />
</geometry>
</collision>
</link>
<joint name="pilar" type="fixed">
<parent link="e_base_2_link"/>
<child link="e_pilar_link"/>
<origin xyz="0 0 0.02" rpy="0 0 0" />
</joint>
<link name="e_pilar_link">
<inertial>
<mass value="0.08"/>
<origin rpy="0 0 0" xyz="0 0 ${0.7/2}"/>
<default_inertia_e />
</inertial>
<visual>
<origin rpy="0 0 0" xyz="0 0 0"/>
<geometry>
<mesh filename="package://myrabot_fer_modelo/meshes/e_pilar.stl" scale="0.001 0.001 0.001"/>
</geometry>
<material name="wood" />
</visual>
<collision>
<origin rpy="0 0 0" xyz="0 0 0"/>
<geometry>
<mesh filename="package://myrabot_fer_modelo/meshes/e_pilar.stl" scale="0.001 0.001 0.001"/>
</geometry>
</collision>
</link>
<joint name="ultrasonidos" type="fixed">
<parent link="e_base_2_link"/>
<child link="e_ultrasonidos_link"/>
<origin xyz="0 0 0.02" rpy="0 0 0" />
</joint>
<link name="e_ultrasonidos_link">
<inertial>
<mass value="0.04"/>
<origin rpy="0 0 0" xyz="0.0 0.0 ${0.04/2}"/>
<default_inertia_e />
</inertial>
<visual>
<origin rpy="0 0 0" xyz="-0.160 -0.135 0"/>
<geometry>
<mesh filename="package://myrabot_robot_model/meshes/e_ultrasonidos.stl" scale="0.001 0.001 0.001"/>
</geometry>
<material name="wood" />
</visual>
<collision>
<origin rpy="0 0 0" xyz="-0.160 -0.135 0"/>
<geometry>
<mesh filename="package://myrabot_robot_model/meshes/e_ultrasonidos.stl" scale="0.001 0.001 0.001"/>
</geometry>
</collision>
</link>
<joint name="botonera" type="fixed">
<parent link="e_base_2_link"/>
<child link="e_botonera_link"/>
<origin xyz="0 0 0.02" rpy="0 0 0" />
</joint>
<link name="e_botonera_link">
<inertial>
<mass value="0.06"/>
<origin rpy="0 0 0" xyz="0.135 ${0.165-(0.09/2)} ${0.1/2}"/>
<default_inertia_e />
</inertial>
<visual>
<origin rpy="0 0 0" xyz="0.135 ${0.165-(0.09/2)} ${0.1/2}"/>
<geometry>
<box size="0.2 0.09 0.1"/>
</geometry>
<material name="wood" />
</visual>
<collision>
<origin rpy="0 0 0" xyz="0.135 ${0.165-(0.09/2)} ${0.1/2}"/>
<geometry>
<box size="0.2 0.09 0.1"/>
</geometry>
</collision>
</link>
<joint name="start_button_1" type="fixed">
<parent link="e_botonera_link"/>
<child link="e_start_button_1_link"/>
<origin xyz="-0.06 0 0.1" rpy="0 0 0" />
</joint>
<link name="e_start_button_1_link">
<inertial>
<mass value="0.001"/>
<origin rpy="0 0 0" xyz="0.135 ${0.165-(0.09/2)} ${0.002/2}"/>
<default_inertia_e />
</inertial>
<visual>
<origin rpy="0 0 0" xyz="0.135 ${0.165-(0.09/2)} ${0.002/2}"/>
<geometry>
<cylinder radius="0.009" length="0.002"/>
</geometry>
<material name="black">
<color rgba="0 0 0 1"/>
</material>
</visual>
<collision>
<origin rpy="0 0 0" xyz="0.135 ${0.165-(0.09/2)} ${0.002/2}"/>
<geometry>
<cylinder radius="0.009" length="0.002"/>
</geometry>
</collision>
</link>
<joint name="start_button_2" type="fixed">
<parent link="e_start_button_1_link"/>
<child link="e_start_button_2_link"/>
<origin xyz="0.0 0 0.002" rpy="0 0 0" />
</joint>
<link name="e_start_button_2_link">
<inertial>
<mass value="0.001"/>
<origin rpy="0 0 0" xyz="0.135 ${0.165-(0.09/2)} ${0.004/2}"/>
<default_inertia_e />
</inertial>
<visual>
<origin rpy="0 0 0" xyz="0.135 ${0.165-(0.09/2)} ${0.004/2}"/>
<geometry>
<cylinder radius="0.0075" length="0.004"/>
</geometry>
<material name="green">
<color rgba="0 1 0 1"/>
</material>
</visual>
<collision>
<origin rpy="0 0 0" xyz="0.135 ${0.165-(0.09/2)} ${0.004/2}"/>
<geometry>
<cylinder radius="0.0075" length="0.004"/>
</geometry>
</collision>
</link>
<joint name="emergency_button_1" type="fixed">
<parent link="e_botonera_link"/>
<child link="e_emergency_button_1_link"/>
<origin xyz="0.06 0 0.1" rpy="0 0 0" />
</joint>
<link name="e_emergency_button_1_link">
<inertial>
<mass value="0.001"/>
<origin rpy="0 0 0" xyz="0.135 ${0.165-(0.09/2)} ${0.015/2}"/>
<default_inertia_e />
</inertial>
<visual>
<origin rpy="0 0 0" xyz="0.135 ${0.165-(0.09/2)} ${0.015/2}"/>
<geometry>
<cylinder radius="0.0125" length="0.015"/>
</geometry>
<material name="metal" />
</visual>
<collision>
<origin rpy="0 0 0" xyz="0.135 ${0.165-(0.09/2)} ${0.015/2}"/>
<geometry>
<cylinder radius="0.0125" length="0.015"/>
</geometry>
</collision>
</link>
<joint name="emergency_button_2" type="fixed">
<parent link="e_emergency_button_1_link"/>
<child link="e_emergency_button_2_link"/>
<origin xyz="0.0 0 0.015" rpy="0 0 0" />
</joint>
<link name="e_emergency_button_2_link">
<inertial>
<mass value="0.001"/>
<origin rpy="0 0 0" xyz="0.135 ${0.165-(0.09/2)} ${0.003/2}"/>
<default_inertia_e />
</inertial>
<visual>
<origin rpy="0 0 0" xyz="0.135 ${0.165-(0.09/2)} ${0.003/2}"/>
<geometry>
<cylinder radius="0.018" length="0.003"/>
</geometry>
<material name="red">
<color rgba="1 0 0 1"/>
</material>
</visual>
<collision>
<origin rpy="0 0 0" xyz="0.135 ${0.165-(0.09/2)} ${0.003/2}"/>
<geometry>
<cylinder radius="0.018" length="0.003"/>
</geometry>
</collision>
</link>
<joint name="base_kinect" type="fixed">
<parent link="e_pilar_link"/>
<child link="e_base_kinect_link"/>
<origin xyz="0 0 ${0.395-0.155}" rpy="0 0 0" />
</joint>
<link name="e_base_kinect_link">
<inertial>
<mass value="0.02"/>
<origin rpy="0 0 0" xyz="0 0 ${0.005/2}"/>
<default_inertia_e />
</inertial>
<visual>
<origin rpy="0 0 0" xyz="0 0 0"/>
<geometry>
<mesh filename="package://myrabot_fer_modelo/meshes/e_base_kinect.stl" scale="0.001 0.001 0.001"/>
</geometry>
<material name="wood" />
</visual>
<collision>
<origin rpy="0 0 0" xyz="0 0 0"/>
<geometry>
<mesh filename="package://myrabot_fer_modelo/meshes/e_base_kinect.stl" scale="0.001 0.001 0.001"/>
</geometry>
</collision>
</link>
<joint name="base_brazo_1" type="fixed">
<parent link="e_pilar_link"/>
<child link="e_base_brazo_1_link"/>
<origin xyz="0 0 ${0.708-(0.395-0.155)}" rpy="0 0 0" />
</joint>
<link name="e_base_brazo_1_link">
<inertial>
<mass value="0.03"/>
<origin rpy="0 0 0" xyz="0 0 ${0.005/2}"/>
<default_inertia_e />
</inertial>
<visual>
<origin rpy="0 0 0" xyz="0 0 0"/>
<geometry>
<mesh filename="package://myrabot_fer_modelo/meshes/e_base_brazo_1.stl" scale="0.001 0.001 0.001"/>
</geometry>
<material name="wood" />
</visual>
<collision>
<origin rpy="0 0 0" xyz="0 0 0"/>
<geometry>
<mesh filename="package://myrabot_fer_modelo/meshes/e_base_brazo_1.stl" scale="0.001 0.001 0.001"/>
</geometry>
</collision>
</link>
<separador_base_brazo id="1" />
<e_separador_base_brazo id="1" xsim="1" ysim="1" />
<separador_base_brazo id="2" />
<e_separador_base_brazo id="2" xsim="1" ysim="-1" />
<separador_base_brazo id="3" />
<e_separador_base_brazo id="3" xsim="-1" ysim="-1" />
<separador_base_brazo id="4" />
<e_separador_base_brazo id="4" xsim="-1" ysim="1" />
<joint name="base_brazo_2" type="fixed">
<parent link="e_base_brazo_1_link"/>
<child link="e_base_brazo_2_link"/>
<origin xyz="0 0 0.074" rpy="0 0 0" />
</joint>
<link name="e_base_brazo_2_link">
<inertial>
<mass value="0.005"/>
<origin rpy="0 0 0" xyz="0 0 ${0.005/2}"/>
<default_inertia_e />
</inertial>
<visual>
<origin rpy="0 0 0" xyz="0 0 0"/>
<geometry>
<mesh filename="package://myrabot_fer_modelo/meshes/e_base_brazo_2.stl" scale="0.001 0.001 0.001"/>
</geometry>
<material name="wood" />
</visual>
<collision>
<origin rpy="0 0 0" xyz="0 0 0"/>
<geometry>
<mesh filename="package://myrabot_fer_modelo/meshes/e_base_brazo_2.stl" scale="0.001 0.001 0.001"/>
</geometry>
</collision>
</link>
<joint name="soporte_1" type="fixed">
<parent link="e_pilar_link"/>
<child link="e_soporte_1_link"/>
<origin xyz="0 0 ${0.995-(0.708-0.155)-(0.395-0.155)}" rpy="0 0 0" />
</joint>
<link name="e_soporte_1_link">
<inertial>
<mass value="0.05"/>
<origin rpy="0 0 0" xyz="0 0 ${0.64/2}"/>
<default_inertia_e />
</inertial>
<visual>
<origin rpy="0 0 0" xyz="0 0 0"/>
<geometry>
<mesh filename="package://myrabot_fer_modelo/meshes/e_soporte_1.stl" scale="0.001 0.001 0.001"/>
</geometry>
<material name="wood" />
</visual>
<collision>
<origin rpy="0 0 0" xyz="0 0 0"/>
<geometry>
<mesh filename="package://myrabot_fer_modelo/meshes/e_soporte_1.stl" scale="0.001 0.001 0.001"/>
</geometry>
</collision>
</link>
<joint name="soporte_2" type="fixed">
<parent link="e_soporte_1_link"/>
<child link="e_soporte_2_link"/>
<origin xyz="0 0.2 0.61" rpy="-0.12 0 0" />
</joint>
<link name="e_soporte_2_link">
<inertial>
<mass value="0.01"/>
<origin rpy="0 0 0" xyz="0 0 ${0.06/2}"/>
<default_inertia_e />
</inertial>
<visual>
<origin rpy="0 0 0" xyz="0 -0.2 -0.03"/>
<geometry>
<mesh filename="package://myrabot_fer_modelo/meshes/e_soporte_2.stl" scale="0.001 0.001 0.001"/>
</geometry>
<material name="wood" />
</visual>
<collision>
<origin rpy="0 0 0" xyz="0 -0.2 -0.03"/>
<geometry>
<mesh filename="package://myrabot_fer_modelo/meshes/e_soporte_2.stl" scale="0.001 0.001 0.001"/>
</geometry>
</collision>
</link>
<joint name="monitor" type="fixed">
<parent link="e_soporte_2_link"/>
<child link="e_monitor_link"/>
<origin xyz="0 -0.2 -0.09" rpy="0 0 0" />
</joint>
<link name="e_monitor_link">
<inertial>
<mass value="0.1"/>
<origin rpy="0 0 0" xyz="0 0 ${0.180/2}"/>
<default_inertia_e />
</inertial>
<visual>
<origin rpy="0 0 0" xyz="0 0 0"/>
<geometry>
<mesh filename="package://myrabot_fer_modelo/meshes/e_monitor.stl" scale="0.001 0.001 0.001"/>
</geometry>
<material name="wood" />
</visual>
<collision>
<origin rpy="0 0 0" xyz="0 0 0"/>
<geometry>
<mesh filename="package://myrabot_fer_modelo/meshes/e_monitor.stl" scale="0.001 0.001 0.001"/>
</geometry>
</collision>
</link>
<joint name="pantalla" type="fixed">
<parent link="e_monitor_link"/>
<child link="e_pantalla_link"/>
<origin xyz="0.135 ${0.135-0.005-0.03-0.0001} 0.086" rpy="0 0 0" />
</joint>
<link name="e_pantalla_link">
<inertial>
<mass value="0.0001"/>
<origin rpy="0 0 0" xyz="0 0 0"/>
<default_inertia_e />
</inertial>
<visual>
<origin rpy="0 0 0" xyz="0 0 0"/>
<geometry>
<box size="0.22 0.0001 0.130" />
</geometry>
<material name="black" />
</visual>
<collision>
<origin rpy="0 0 0" xyz="0 0 0"/>
<geometry>
<box size="0.22 0.0001 0.127" />
</geometry>
</collision>
</link>
<gazebo_propiedades nombre="e_base_1_link" material="LightWood" />
<gazebo_propiedades nombre="e_base_2_link" material="LightWood" />
<gazebo_propiedades nombre="e_separador_base_1_link" material="Grey" />
<gazebo_propiedades nombre="e_separador_base_2_link" material="Grey" />
<gazebo_propiedades nombre="e_separador_base_3_link" material="Grey" />
<gazebo_propiedades nombre="e_separador_base_4_link" material="Grey" />
<gazebo_propiedades nombre="e_separador_base_brazo_1_link" material="Grey" />
<gazebo_propiedades nombre="e_separador_base_brazo_2_link" material="Grey" />
<gazebo_propiedades nombre="e_separador_base_brazo_3_link" material="Grey" />
<gazebo_propiedades nombre="e_separador_base_brazo_4_link" material="Grey" />
<gazebo_propiedades nombre="e_pilar_link" material="LightWood" />
<gazebo_propiedades nombre="e_base_kinect_link" material="LightWood" />
<gazebo_propiedades nombre="e_base_brazo_1_link" material="LightWood" />
<gazebo_propiedades nombre="e_base_brazo_2_link" material="LightWood" />
<gazebo_propiedades nombre="e_botonera_link" material="LightWood" />
<gazebo_propiedades nombre="e_start_button_1_link" material="Black" />
<gazebo_propiedades nombre="e_start_button_2_link" material="Green" />
<gazebo_propiedades nombre="e_emergency_button_1_link" material="Grey" />
<gazebo_propiedades nombre="e_emergency_button_2_link" material="Red" />
<gazebo_propiedades nombre="e_soporte_1_link" material="LightWood" />
<gazebo_propiedades nombre="e_soporte_2_link" material="LightWood" />
<gazebo_propiedades nombre="e_monitor_link" material="LightWood" />
<gazebo_propiedades nombre="e_pantalla_link" material="Black" />
</macro>
</robot>
We will add the next files within the folder "meshes" of our package:
- e_pilar.stl
- e_base_kinect.stl
- e_base_brazo_1.stl
- e_base_brazo_2.stl
- e_soporte_1.stl
- e_soporte_2.stl
- e_monitor.stl
- e_ultrasonidos.stl
For the macros file, we will create a file named "estructura-myrabot-macros.xacro" within the folder "urdf" of our package with the content that is shown below:
<?xml version="1.0"?>
<robot>
<macro name="default_inertia_e">
<inertia ixx="0.01" ixy="0.0" ixz="0.0" iyy="0.01" iyz="0.0" izz="0.01"/>
</macro>
<macro name="separador_base" params="id">
<joint name="separador_base_${id}" type="fixed">
<parent link="e_base_1_link"/>
<child link="e_separador_base_${id}_link"/>
<origin xyz="0.135 0.135 0.015" rpy="0 0 0" />
</joint>
</macro>
<macro name="e_separador_base" params="id xsim ysim">
<link name="e_separador_base_${id}_link">
<inertial>
<mass value="0.02"/>
<origin rpy="0 0 0" xyz="${xsim*0.040} ${ysim*0.105} ${0.120/2}"/>
<default_inertia_e />
</inertial>
<visual>
<origin rpy="0 0 0" xyz="${xsim*0.040} ${ysim*0.105} ${0.120/2}"/>
<geometry>
<cylinder radius="0.0075" length="0.120" />
</geometry>
<material name="metal">
<color rgba="${211/255} ${211/255} ${211/255} 1" />
</material>
</visual>
<collision>
<origin rpy="0 0 0" xyz="${xsim*0.040} ${ysim*0.105} ${0.120/2}"/>
<geometry>
<cylinder radius="0.0075" length="0.120" />
</geometry>
</collision>
</link>
</macro>
<macro name="separador_base_brazo" params="id">
<joint name="separador_base_brazo_${id}" type="fixed">
<parent link="e_base_brazo_1_link"/>
<child link="e_separador_base_brazo_${id}_link"/>
<origin xyz="0.135 ${0.135-0.082} 0.075" rpy="0 0 0" />
</joint>
</macro>
<macro name="e_separador_base_brazo" params="id xsim ysim">
<link name="e_separador_base_brazo_${id}_link">
<inertial>
<mass value="0.002"/>
<origin rpy="0 0 0" xyz="${xsim*0.029} ${ysim*0.019} ${0.034/2}"/>
<default_inertia_e />
</inertial>
<visual>
<origin rpy="0 0 0" xyz="${xsim*0.029} ${ysim*0.019} ${0.034/2}"/>
<geometry>
<cylinder radius="0.002" length="0.034" />
</geometry>
<material name="metal" />
</visual>
<collision>
<origin rpy="0 0 0" xyz="${xsim*0.029} ${ysim*0.019} ${0.034/2}"/>
<geometry>
<cylinder radius="0.002" length="0.034" />
</geometry>
</collision>
</link>
</macro>
<macro name="gazebo_propiedades" params="nombre material">
<gazebo reference="${nombre}">
<material>Gazebo/${material}</material>
<mu1>0.5</mu1>
<mu2>0.5</mu2>
<selfCollide>true</selfCollide>
<turnGravityOff>false</turnGravityOff>
</gazebo>
</macro>
</robot>
URDF Roomba
We have used the model of the mobile base create of the robot turtlebot, because the vacuum Roomba has similar sensors and physics. We have to install the stacks turtlebot and turtlebot_simulator that contain the robot model and the plugins for gazebo. We have divided the model in two files, main file and plugins file. For the main file, we will create a file named "roomba.xacro" within the folder "urdf" of the created package with the content that is shown below:
<?xml version="1.0"?>
<robot xmlns:xacro="http://ros.org/wiki/xacro">
<include filename="$(find myrabot_fer_modelo)/urdf/roomba-gazebo.xacro"/>
<xacro:macro name="roomba">
<material name="Green">
<color rgba="0.0 0.8 0.0 1.0"/>
</material>
<link name="base_footprint">
<inertial>
<mass value="0.0001" />
<origin xyz="0 0 0" />
<inertia ixx="0.0001" ixy="0.0" ixz="0.0"
iyy="0.0001" iyz="0.0"
izz="0.0001" />
</inertial>
<visual>
<origin xyz="0 0 0" rpy="0 0 0" />
<geometry>
<box size="0.001 0.001 0.001" />
</geometry>
<material name="Green" />
</visual>
<collision>
<origin xyz="0 0 0.017" rpy="0 0 0" />
<geometry>
<box size="0.001 0.001 0.001" />
</geometry>
</collision>
</link>
<link name="base_link">
<inertial>
<mass value="3.6" />
<origin xyz="0 0 ${0.063/2}" />
<inertia ixx="0.01" ixy="0.0" ixz="0.0" iyy="0.01" iyz="0.0" izz="0.5" />
</inertial>
<visual>
<origin xyz=" 0 0 ${0.063/2}" rpy="0 0 0" />
<geometry>
<cylinder length="0.063" radius="0.17"/>
</geometry>
<material name="white">
<color rgba="1 1 1 1" />
</material>
</visual>
<collision>
<origin xyz="0.0 0.0 ${0.063/2}" rpy="0 0 0" />
<geometry>
<cylinder length="0.063" radius="0.17"/>
</geometry>
</collision>
</link>
<link name="wall_sensor_link">
<inertial>
<mass value="0.01" />
<origin xyz="0 0 0"/>
<inertia ixx="0.001" ixy="0.0" ixz="0.0"
iyy="0.001" iyz="0.0" izz="0.001" />
</inertial>
</link>
<link name="left_cliff_sensor_link">
<inertial>
<mass value="0.01" />
<origin xyz="0 0 0"/>
<inertia ixx="0.001" ixy="0.0" ixz="0.0"
iyy="0.001" iyz="0.0" izz="0.001" />
</inertial>
</link>
<link name="right_cliff_sensor_link">
<inertial>
<mass value="0.01" />
<origin xyz="0 0 0"/>
<inertia ixx="0.001" ixy="0.0" ixz="0.0"
iyy="0.001" iyz="0.0" izz="0.001" />
</inertial>
</link>
<link name="leftfront_cliff_sensor_link">
<inertial>
<mass value="0.01" />
<origin xyz="0 0 0"/>
<inertia ixx="1.0" ixy="0.0" ixz="0.0"
iyy="0.01" iyz="0.0" izz="0.01" />
</inertial>
</link>
<link name="rightfront_cliff_sensor_link">
<inertial>
<mass value="0.01" />
<origin xyz="0 0 0"/>
<inertia ixx="0.001" ixy="0.0" ixz="0.0"
iyy="0.001" iyz="0.0" izz="0.001" />
</inertial>
</link>
<joint name="base_footprint_joint" type="fixed">
<origin xyz="0 0 0.017" rpy="0 0 0" />
<parent link="base_footprint"/>
<child link="base_link" />
</joint>
<joint name="base_wall_sensor_joint" type="fixed">
<origin xyz="0.09 -0.120 0.042" rpy="0 0 -1.0" />
<parent link="base_link"/>
<child link="wall_sensor_link" />
</joint>
<joint name="base_left_cliff_sensor_joint" type="fixed">
<origin xyz="0.07 0.14 0.01" rpy="0 1.57079 0" />
<parent link="base_link"/>
<child link="left_cliff_sensor_link" />
</joint>
<joint name="base_right_cliff_sensor_joint" type="fixed">
<origin xyz="0.07 -0.14 0.01" rpy="0 1.57079 0" />
<parent link="base_link"/>
<child link="right_cliff_sensor_link" />
</joint>
<joint name="base_leftfront_cliff_sensor_joint" type="fixed">
<origin xyz="0.15 0.04 0.01" rpy="0 1.57079 0" />
<parent link="base_link"/>
<child link="leftfront_cliff_sensor_link" />
</joint>
<joint name="base_rightfront_cliff_sensor_joint" type="fixed">
<origin xyz="0.15 -0.04 0.01" rpy="0 1.57079 0" />
<parent link="base_link"/>
<child link="rightfront_cliff_sensor_link" />
</joint>
<link name="left_wheel_link">
<inertial>
<origin xyz="0 0 0"/>
<mass value="0.01" />
<inertia ixx="0.001" ixy="0.0" ixz="0.0"
iyy="0.001" iyz="0.0" izz="0.001" />
</inertial>
<visual>
<origin xyz="0 0 0" rpy="0 1.5707 1.5707" />
<geometry>
<cylinder radius="0.033" length = "0.023"/>
</geometry>
</visual>
<collision>
<origin xyz="0 0 0" rpy="0 1.5707 1.5707" />
<geometry>
<cylinder radius="0.033" length = "0.023"/>
</geometry>
</collision>
</link>
<joint name="left_wheel_joint" type="continuous">
<origin xyz="0 0.13 0.015" rpy="0 0 0"/>
<parent link="base_link"/>
<child link="left_wheel_link"/>
<axis xyz="0 1 0"/>
</joint>
<link name="right_wheel_link">
<inertial>
<origin xyz="0 0 0"/>
<mass value="0.01" />
<inertia ixx="0.001" ixy="0.0" ixz="0.0"
iyy="0.001" iyz="0.0" izz="0.001" />
</inertial>
<visual>
<origin xyz="0 0 0" rpy="0 1.5707 1.5707" />
<geometry>
<cylinder radius="0.033" length = "0.023"/>
</geometry>
</visual>
<collision>
<origin xyz="0 0 0" rpy="0 1.5707 1.5707" />
<geometry>
<cylinder radius="0.033" length = "0.023"/>
</geometry>
</collision>
</link>
<joint name="right_wheel_joint" type="continuous">
<origin xyz="0 -0.13 0.015" rpy="0 0 0"/>
<parent link="base_link"/>
<child link="right_wheel_link"/>
<axis xyz="0 1 0"/>
</joint>
<link name="rear_wheel_link">
<inertial>
<origin xyz="0 0 0"/>
<mass value="0.001" />
<inertia ixx="0.0001" ixy="0.0" ixz="0.0"
iyy="0.0001" iyz="0.0" izz="0.0001" />
</inertial>
<visual>
<origin xyz="0 0 0" rpy="0 1.5707 1.5707"/>
<geometry>
<sphere radius="0.015" />
</geometry>
</visual>
<collision>
<origin xyz="0 0 0" rpy="0 1.5707 1.5707" />
<geometry>
<sphere radius="0.015" />
</geometry>
</collision>
</link>
<joint name="rear_castor_joint" type="fixed">
<origin xyz="-0.13 0 0.0" rpy="0 0 0"/>
<parent link="base_link"/>
<child link="rear_wheel_link"/>
<axis xyz="0 1 0"/>
</joint>
<link name="front_wheel_link">
<inertial>
<origin xyz="0 0 0" />
<mass value="0.01" />
<inertia ixx="0.001" ixy="0.0" ixz="0.0"
iyy="0.001" iyz="0.0" izz="0.001" />
</inertial>
<visual>
<origin xyz="0 0 0" rpy="0 1.5707 1.5707"/>
<geometry>
<sphere radius="0.018" />
</geometry>
</visual>
<collision>
<origin xyz="0 0 0" rpy="0 1.5707 1.5707" />
<geometry>
<sphere radius="0.018" />
</geometry>
</collision>
</link>
<joint name="front_castor_joint" type="fixed">
<origin xyz="0.13 0 0.0" rpy="0 0 0"/>
<parent link="base_link"/>
<child link="front_wheel_link"/>
<axis xyz="0 1 0"/>
</joint>
<joint name="gyro_joint" type="fixed">
<axis xyz="0 1 0" />
<origin xyz="0 0 0.04" rpy="0 0 0" />
<parent link="base_link"/>
<child link="gyro_link"/>
</joint>
<link name="gyro_link">
<inertial>
<mass value="0.001" />
<origin xyz="0 0 0" rpy="0 0 0" />
<inertia ixx="0.0001" ixy="0" ixz="0" iyy="0.000001" iyz="0" izz="0.0001" />
</inertial>
</link>
<joint name="laser_joint" type="fixed">
<origin xyz="-0.065 0 0.57" rpy="0 0 0" />
<parent link="base_link" />
<child link="laser" />
</joint>
<link name="laser" />
<gaezebo>
<material>Gazebo/White</material>
</gaezebo>
<myrabot_sim_imu/>
<myrabot_sim_laser/>
<myrabot_sim_roomba/>
<myrabot_sim_wall_sensors/>
</xacro:macro>
</robot>
For the plugins file, we will create a file named "roomba-gazebo.xacro" within the folder "urdf" of our package with the content that is shown below:
<?xml version="1.0"?>
<robot xmlns:controller="http://playerstage.sourceforge.net/gazebo/xmlschema/#controller" xmlns:interface="http://playerstage.sourceforge.net/gazebo/xmlschema/#interface" xmlns:sensor="http://playerstage.sourceforge.net/gazebo/xmlschema/#sensor" xmlns:xacro="http://ros.org/wiki/xacro">
<xacro:macro name="myrabot_sim_imu">
<gazebo>
<controller:gazebo_ros_imu name="imu_controller" plugin="libgazebo_ros_imu.so">
<robotNamespace>/</robotNamespace>
<alwaysOn>true</alwaysOn>
<updateRate>30</updateRate>
<bodyName>gyro_link</bodyName>
<topicName>imu/data</topicName>
<gaussianNoise>${0.0017*0.0017}</gaussianNoise>
<xyzOffsets>0 0 0</xyzOffsets>
<rpyOffsets>0 0 0</rpyOffsets>
<interface:position name="imu_position"/>
</controller:gazebo_ros_imu>
</gazebo>
</xacro:macro>
<xacro:macro name="myrabot_sim_laser">
<gazebo reference="laser">
<sensor:ray name="laser">
<rayCount>180</rayCount>
<rangeCount>180</rangeCount>
<laserCount>1</laserCount>
<origin>0.0 0.0 0.0</origin>
<displayRays>false</displayRays>
<minAngle>-${60/2}</minAngle>
<maxAngle>${60/2}</maxAngle>
<minRange>0.08</minRange>
<maxRange>5.0</maxRange>
<resRange>0.01</resRange>
<updateRate>20</updateRate>
<controller:gazebo_ros_laser name="gazebo_ros_laser_controller" plugin="libgazebo_ros_laser.so">
<robotNamespace>/</robotNamespace>
<gaussianNoise>0.005</gaussianNoise>
<alwaysOn>true</alwaysOn>
<updateRate>20</updateRate>
<topicName>scan</topicName>
<frameName>laser</frameName>
<interface:laser name="gazebo_ros_laser_iface" />
</controller:gazebo_ros_laser>
</sensor:ray>
</gazebo>
</xacro:macro>
<xacro:macro name="myrabot_sim_roomba">
<gazebo>
<controller:gazebo_ros_roomba name="roomba_controller" plugin="libgazebo_ros_roomba.so">
<alwaysOn>true</alwaysOn>
<node_namespace>turtlebot_node</node_namespace>
<left_wheel_joint>left_wheel_joint</left_wheel_joint>
<right_wheel_joint>right_wheel_joint</right_wheel_joint>
<front_castor_joint>front_castor_joint</front_castor_joint>
<rear_castor_joint>rear_castor_joint</rear_castor_joint>
<wheel_separation>.260</wheel_separation>
<wheel_diameter>0.066</wheel_diameter>
<base_geom>base_link_geom_base_link</base_geom>
<updateRate>40</updateRate>
<torque>1.0</torque>
</controller:gazebo_ros_roomba>
</gazebo>
</xacro:macro>
<xacro:macro name="myrabot_sim_wall_sensors">
<gazebo reference="wall_sensor_link">
<sensor:ray name="wall_sensor">
<alwaysActive>true</alwaysActive>
<rayCount>1</rayCount>
<rangeCount>1</rangeCount>
<resRange>0.1</resRange>
<minAngle>0</minAngle>
<maxAngle>0</maxAngle>
<minRange>0.0160</minRange>
<maxRange>0.04</maxRange>
<displayRays>false</displayRays>
</sensor:ray>
</gazebo>
<gazebo reference="left_cliff_sensor_link">
<sensor:ray name="left_cliff_sensor">
<alwaysActive>true</alwaysActive>
<rayCount>1</rayCount>
<rangeCount>1</rangeCount>
<resRange>0.1</resRange>
<minAngle>0</minAngle>
<maxAngle>0</maxAngle>
<minRange>0.01</minRange>
<maxRange>0.04</maxRange>
<displayRays>false</displayRays>
</sensor:ray>
</gazebo>
<gazebo reference="right_cliff_sensor_link">
<sensor:ray name="right_cliff_sensor">
<alwaysActive>true</alwaysActive>
<rayCount>1</rayCount>
<rangeCount>1</rangeCount>
<resRange>0.1</resRange>
<minAngle>0</minAngle>
<maxAngle>0</maxAngle>
<minRange>0.01</minRange>
<maxRange>0.04</maxRange>
<displayRays>false</displayRays>
</sensor:ray>
</gazebo>
<gazebo reference="leftfront_cliff_sensor_link">
<sensor:ray name="leftfront_cliff_sensor">
<alwaysActive>true</alwaysActive>
<rayCount>1</rayCount>
<rangeCount>1</rangeCount>
<resRange>0.1</resRange>
<minAngle>0</minAngle>
<maxAngle>0</maxAngle>
<minRange>0.01</minRange>
<maxRange>0.04</maxRange>
<displayRays>false</displayRays>
</sensor:ray>
</gazebo>
<gazebo reference="rightfront_cliff_sensor_link">
<sensor:ray name="rightfront_cliff_sensor">
<alwaysActive>true</alwaysActive>
<rayCount>1</rayCount>
<rangeCount>1</rangeCount>
<resRange>0.1</resRange>
<minAngle>0</minAngle>
<maxAngle>0</maxAngle>
<minRange>0.01</minRange>
<maxRange>0.04</maxRange>
<displayRays>fan</displayRays>
</sensor:ray>
</gazebo>
<gazebo reference="left_wheel_link">
<mu1 value="10"/>
<mu2 value="10"/>
<kp value="100000000.0"/>
<kd value="10000.0"/>
<fdir value="1 0 0"/>
</gazebo>
<gazebo reference="right_wheel_link">
<mu1 value="10"/>
<mu2 value="10"/>
<kp value="100000000.0"/>
<kd value="10000.0"/>
<fdir value="1 0 0"/>
</gazebo>
<gazebo reference="rear_wheel_link">
<mu1 value="0"/>
<mu2 value="0"/>
<kp value="100000000.0"/>
<kd value="10000.0"/>
</gazebo>
<gazebo reference="front_wheel_link">
<mu1 value="0"/>
<mu2 value="0"/>
<kp value="100000000.0"/>
<kd value="10000.0"/>
</gazebo>
</xacro:macro>
</robot>
URDF kinect
We will create a file named "kinect.xacro" within the folder "urdf" of our package with the content that is shown below:
<?xml version="1.0"?>
<robot xmlns:controller="http://playerstage.sourceforge.net/gazebo/xmlschema/#controller" xmlns:interface="http://playerstage.sourceforge.net/gazebo/xmlschema/#interface" xmlns:sensor="http://playerstage.sourceforge.net/gazebo/xmlschema/#sensor" xmlns:xacro="http://ros.org/wiki/xacro">
<property name="M_PI" value="3.14159"/>
<xacro:macro name="kinect" params="parent *origin">
<joint name="base_camera_joint" type="fixed">
<insert_block name="origin" />
<parent link="${parent}" />
<child link="camera_link" />
</joint>
<link name="camera_link">
<inertial>
<mass value="0.01" />
<origin xyz="0 0 0" />
<inertia ixx="0.001" ixy="0.0" ixz="0.0"
iyy="0.001" iyz="0.0"
izz="0.001" />
</inertial>
<visual>
<origin xyz=" 0 0 0 " rpy="0 0 0" />
<geometry>
<mesh filename="package://myrabot_fer_modelo/meshes/kinect.dae"/>
</geometry>
</visual>
<collision>
<origin xyz="0.0 0.0 0.0" rpy="0 0 0" />
<geometry>
<mesh filename="package://myrabot_fer_modelo/meshes/kinect.dae"/>
</geometry>
</collision>
</link>
<joint name="camera_depth_joint" type="fixed">
<origin xyz="0 0.018 0" rpy="0 0 0" />
<parent link="camera_link" />
<child link="camera_depth_frame" />
</joint>
<link name="camera_depth_frame">
<inertial>
<mass value="0.01" />
<origin xyz="0 0 0" />
<inertia ixx="0.001" ixy="0.0" ixz="0.0"
iyy="0.001" iyz="0.0"
izz="0.001" />
</inertial>
</link>
<joint name="camera_depth_optical_joint" type="fixed">
<origin xyz="0 0 0" rpy="${-M_PI/2} 0 ${-M_PI/2}" />
<parent link="camera_depth_frame" />
<child link="camera_depth_optical_frame" />
</joint>
<link name="camera_depth_optical_frame">
<inertial>
<mass value="0.001" />
<origin xyz="0 0 0" />
<inertia ixx="0.0001" ixy="0.0" ixz="0.0"
iyy="0.0001" iyz="0.0"
izz="0.0001" />
</inertial>
</link>
<joint name="camera_rgb_joint" type="fixed">
<origin xyz="0 -0.005 0" rpy="0 0 0" />
<parent link="camera_link" />
<child link="camera_rgb_frame" />
</joint>
<link name="camera_rgb_frame">
<inertial>
<mass value="0.001" />
<origin xyz="0 0 0" />
<inertia ixx="0.0001" ixy="0.0" ixz="0.0"
iyy="0.0001" iyz="0.0"
izz="0.0001" />
</inertial>
</link>
<joint name="camera_rgb_optical_joint" type="fixed">
<origin xyz="0 0 0" rpy="${-M_PI/2} 0 ${-M_PI/2}" />
<parent link="camera_rgb_frame" />
<child link="camera_rgb_optical_frame" />
</joint>
<link name="camera_rgb_optical_frame">
<inertial>
<mass value="0.001" />
<origin xyz="0 0 0" />
<inertia ixx="0.0001" ixy="0.0" ixz="0.0"
iyy="0.0001" iyz="0.0"
izz="0.0001" />
</inertial>
</link>
<gazebo reference="camera_link">
<sensor:camera name="camera">
<imageFormat>R8G8B8</imageFormat>
<imageSize>640 480</imageSize>
<hfov>60</hfov>
<nearClip>0.05</nearClip>
<farClip>5</farClip>
<updateRate>20</updateRate>
<baseline>0.1</baseline>
<controller:gazebo_ros_openni_kinect name="kinect_camera_controller" plugin="libgazebo_ros_openni_kinect.so">
<alwaysOn>true</alwaysOn>
<updateRate>20</updateRate>
<robotNamespace>/</robotNamespace>
<imageTopicName>/camera/image_raw</imageTopicName>
<pointCloudTopicName>/camera/depth/points</pointCloudTopicName>
<cameraInfoTopicName>/camera/camera_info</cameraInfoTopicName>
<frameName>camera_depth_optical_frame</frameName>
<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>
</controller:gazebo_ros_openni_kinect>
</sensor:camera>
</gazebo>
</xacro:macro>
</robot>
URDF webcam
We will create a file named "webcam.xacro" within the folder "urdf" of our package with the content that is shown below:
<?xml version="1.0"?>
<robot xmlns:controller="http://playerstage.sourceforge.net/gazebo/xmlschema/#controller" xmlns:interface="http://playerstage.sourceforge.net/gazebo/xmlschema/#interface" xmlns:sensor="http://playerstage.sourceforge.net/gazebo/xmlschema/#sensor" xmlns:xacro="http://ros.org/wiki/xacro">
<xacro:macro name="webcam" params="parent *origin">
<joint name="webcam_1" type="fixed">
<insert_block name="origin" />
<parent link="${parent}" />
<child link="e_webcam_1_link" />
</joint>
<link name="e_webcam_1_link">
<inertial>
<mass value="0.01" />
<origin xyz="0 0 0" />
<inertia ixx="0.001" ixy="0.0" ixz="0.0" iyy="0.001" iyz="0.0" izz="0.001" />
</inertial>
<visual>
<origin xyz=" 0 0 0 " rpy="0 0 0" />
<geometry>
<mesh filename="package://myrabot_robot_model/meshes/webcam_1.stl" scale="0.001 0.001 0.001"/>
</geometry>
<material name="black">
<color rgba="0 0 0 1" />
</material>
</visual>
<collision>
<origin xyz="0.0 0.0 0.0" rpy="0 0 0" />
<geometry>
<mesh filename="package://myrabot_robot_model/meshes/webcam_1.stl" scale="0.001 0.001 0.001"/>
</geometry>
</collision>
</link>
<joint name="webcam_2" type="fixed">
<origin xyz="0 ${0.135-0.04-(0.02-0.009)} ${(0.185/2)+0.0045}" rpy="0.82 0 0" />
<parent link="e_webcam_1_link" />
<child link="e_webcam_2_link" />
</joint>
<link name="e_webcam_2_link">
<inertial>
<mass value="0.01" />
<origin xyz="0 -${0.135-0.04-(0.02-0.009)} -${(0.185/2)+0.0045}" rpy="0 0 0" />
<inertia ixx="0.001" ixy="0.0" ixz="0.0" iyy="0.001" iyz="0.0" izz="0.001" />
</inertial>
<visual>
<origin xyz="0 -${0.135-0.04-(0.02-0.009)} -${(0.185/2)+0.0045}" rpy="0 0 0" />
<geometry>
<mesh filename="package://myrabot_robot_model/meshes/webcam_2.stl" scale="0.001 0.001 0.001"/>
</geometry>
<material name="black" />
</visual>
<collision>
<origin xyz="0 -${0.135-0.04-(0.02-0.009)} -${(0.185/2)+0.0045}" rpy="0 0 0" />
<geometry>
<mesh filename="package://myrabot_robot_model/meshes/webcam_2.stl" scale="0.001 0.001 0.001"/>
</geometry>
</collision>
</link>
<joint name="webcam_optica" type="fixed">
<origin xyz="0.135 -0.0285 0" rpy="0 0 -1.57" />
<parent link="e_webcam_2_link" />
<child link="e_webcam_optica_link" />
</joint>
<link name="e_webcam_optica_link">
<inertial>
<mass value="0.001" />
<origin xyz="0 0 0" rpy="0 0 0" />
<inertia ixx="0.0001" ixy="0.0" ixz="0.0" iyy="0.0001" iyz="0.0" izz="0.0001" />
</inertial>
<visual>
<origin xyz="0 0 0" rpy="0 1.57 0" />
<geometry>
<cylinder radius="0.017" length="0.004" />
</geometry>
<material name="white">
<color rgba="1 1 1 1"/>
</material>
</visual>
<collision>
<origin xyz="0 0 0" rpy="0 1.57 0" />
<geometry>
<cylinder radius="0.017" length="0.004" />
</geometry>
</collision>
</link>
<gazebo reference="e_webcam_1_link">
<material>myrabot_fer/Black</material>
<mu1>0.5</mu1>
<mu2>0.5</mu2>
<selfCollide>true</selfCollide>
<turnGravityOff>false</turnGravityOff>
</gazebo>
<gazebo reference="e_webcam_2_link">
<material>myrabot_fer/Black</material>
<mu1>0.5</mu1>
<mu2>0.5</mu2>
<selfCollide>true</selfCollide>
<turnGravityOff>false</turnGravityOff>
</gazebo>
<gazebo reference="e_webcam_optica_link">
<material>myrabot_fer/White</material>
<mu1>0.5</mu1>
<mu2>0.5</mu2>
<selfCollide>true</selfCollide>
<turnGravityOff>false</turnGravityOff>
</gazebo>
<gazebo reference="e_webcam_optica_link">
<sensor:camera name="webcam">
<imageFormat>R8G8B8</imageFormat>
<imageSize>640 480</imageSize>
<hfov>63.09</hfov>
<nearClip>0.02</nearClip>
<farClip>3</farClip>
<updateRate>20</updateRate>
<baseline>0.1</baseline>
<controller:gazebo_ros_openni_kinect name="webcam_camera_controller" filename="libgazebo_ros_openni_kinect.so">
<alwaysOn>true</alwaysOn>
<updateRate>20</updateRate>
<robotNamespace>/</robotNamespace>
<imageTopicName>/webcam/image_raw</imageTopicName>
<pointCloudTopicName>/webcam/depth/points</pointCloudTopicName>
<cameraInfoTopicName>/webcam/camera_info</cameraInfoTopicName>
<frameName>e_webcam_optica_link</frameName>
<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>
</controller:gazebo_ros_openni_kinect>
</sensor:camera>
</gazebo>
</xacro:macro>
</robot>
We will add the next files within the folder "meshes" of our package:
URDF ultrasound sensor
Creation of a gazebo plugin
we will create a new package with the necessary dependences for our plugins (gazebo sensor_msgs roscpp). We will execute the next commands in a terminal:
cd ~/ros_workspace
roscreate-pkg myrabot_gazebo_plugins gazebo sensor_msgs roscpp
We will create a file named "gazebo_ros_sonar.cpp" within the folder "src" of the created package with the content that is shown below:
/*
* Software License Agreement (Modified BSD License)
*
* Copyright (c) 2012, PAL Robotics, S.L.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of PAL Robotics, S.L. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <gazebo/Sensor.hh>
#include <gazebo/Global.hh>
#include <gazebo/XMLConfig.hh>
#include <gazebo/Simulator.hh>
#include <gazebo/gazebo.h>
#include <gazebo/GazeboError.hh>
#include <gazebo/ControllerFactory.hh>
#include <limits>
#include <myrabot_gazebo_plugin/gazebo_ros_sonar.h>
using namespace gazebo;
GZ_REGISTER_DYNAMIC_CONTROLLER("gazebo_ros_sonar", GazeboRosSonar)
GazeboRosSonar::GazeboRosSonar(Entity *parent) : Controller(parent)
{
sensor_ = dynamic_cast<RaySensor*>(parent);
if (!sensor_) gzthrow("GazeboRosSonar controller requires a RaySensor as its parent");
Param::Begin(¶meters);
topic_param_ = new ParamT<std::string>("topicName", "sonar", false);
frame_id_param_ = new ParamT<std::string>("frameId", "", false);
radiation_param_ = new ParamT<std::string>("radiation","ultrasound",false);
fov_param_ = new ParamT<double>("fov", 0.05, false);
gaussian_noise_ = new ParamT<double>("gaussianNoise", 0.0, 0);
Param::End();
}
////////////////////////////////////////////////////////////////////////////////
// Destructor
GazeboRosSonar::~GazeboRosSonar()
{
delete topic_param_;
delete frame_id_param_;
delete radiation_param_;
delete fov_param_;
}
////////////////////////////////////////////////////////////////////////////////
// Load the controller
void GazeboRosSonar::LoadChild(XMLConfigNode *node)
{
ROS_INFO("INFO: gazebo_ros_ir plugin loading" );
topic_param_->Load(node);
frame_id_param_->Load(node);
radiation_param_->Load(node);
fov_param_->Load(node);
gaussian_noise_->Load(node);
}
///////////////////////////////////////////////////////
// Initialize the controller
void GazeboRosSonar::InitChild()
{
Range.header.frame_id = **frame_id_param_;
if (**radiation_param_==std::string("ultrasound"))
Range.radiation_type = sensor_msgs::Range::ULTRASOUND;
else
Range.radiation_type = sensor_msgs::Range::INFRARED;
Range.field_of_view = **fov_param_;
Range.max_range = sensor_->GetMaxRange();
Range.min_range = sensor_->GetMinRange();
sensor_->SetActive(false);
node_handle_ = new ros::NodeHandle("");
publisher_ = node_handle_->advertise<sensor_msgs::Range>(**topic_param_, 10);
}
////////////////////////////////////////////////////////////////////////////////
// Utility for adding noise
double GazeboRosSonar::GaussianKernel(double mu,double sigma)
{
// using Box-Muller transform to generate two independent standard normally disbributed normal variables
// see wikipedia
double U = (double)rand()/(double)RAND_MAX; // normalized uniform random variable
double V = (double)rand()/(double)RAND_MAX; // normalized uniform random variable
double X = sqrt(-2.0 * ::log(U)) * cos( 2.0*M_PI * V);
//double Y = sqrt(-2.0 * ::log(U)) * sin( 2.0*M_PI * V); // the other indep. normal variable
// we'll just use X
// scale to our mu and sigma
X = sigma * X + mu;
return X;
}
////////////////////////////////////////////////////////////////////////////////
// Update the controller
void GazeboRosSonar::UpdateChild()
{
if (!sensor_->IsActive()) sensor_->SetActive(true);
Range.header.stamp.sec = (Simulator::Instance()->GetSimTime()).sec;
Range.header.stamp.nsec = (Simulator::Instance()->GetSimTime()).nsec;
Range.range = std::numeric_limits<sensor_msgs::Range::_range_type>::max();
for(int i = 0; i < sensor_->GetRangeCount(); ++i) {
double ray = sensor_->GetRange(i);
if (ray < Range.range) Range.range = ray;
}
Range.range = std::min(Range.range + this->GaussianKernel(0,**gaussian_noise_), sensor_->GetMaxRange());
publisher_.publish(Range);
}
////////////////////////////////////////////////////////////////////////////////
// Finalize the controller
void GazeboRosSonar::FiniChild()
{
sensor_->SetActive(false);
node_handle_->shutdown();
delete node_handle_;
}
We will create a file named "gazebo_ros_sonar.h" within the path "include/myrabot_gazebo_plugins/" of the created package with the content that is shown below:
/*
* Software License Agreement (Modified BSD License)
*
* Copyright (c) 2012, PAL Robotics, S.L.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of PAL Robotics, S.L. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <ros/ros.h>
#include <gazebo.hh>
#include <gazebo/common/Plugin.hh>
#include <gazebo/sensors/RaySensor.hh>
#include <ros/callback_queue.h>
#include <sensor_msgs/Range.h>
namespace gazebo
{
class GazeboRosSonar : public gazebo::SensorPlugin
{
public:
GazeboRosSonar();
virtual ~GazeboRosSonar();
protected:
virtual void Load(sensors::SensorPtr _parent, sdf::ElementPtr _sdf);
virtual void Update();
/// \brief Gaussian noise generator
private:
double GaussianKernel(double mu,double sigma);
private:
gazebo::sensors::RaySensorPtr sensor_;
ros::NodeHandle* node_handle_;
ros::Publisher publisher_;
sensor_msgs::Range range_;
std::string namespace_;
std::string topic_name_;
std::string frame_id_;
std::string radiation_;
double fov_;
double gaussian_noise_;
gazebo::physics::WorldPtr parent_;
common::Time last_time;
gazebo::event::ConnectionPtr updateConnection;
};
} // namespace gazebo
We have to add the next lines at the end within the file CMakeLists.txt of the plugins package:
rosbuild_add_library(gazebo_ros_sonar src/gazebo_ros_sonar.cpp)
Also, we have to add the next lines before the tag </package> within the file "manifest.xml" of the plugins package:
<export>
<cpp cflags="-I${prefix}/include" lflags="-Wl,-rpath,${prefix}/lib -L${prefix}/lib" />
<gazebo plugin_path="${prefix}/lib" />
</export>
We will execute the next commands in a terminal in order to compile the plugin:
roscd myrabot_gazebo_plugins
make
URDF
We will create a file named "ultrasonidos.xacro" within the folder "urdf" of our robot model package with the content that is shown below:
<?xml version="1.0"?>
<robot xmlns:controller="http://playerstage.sourceforge.net/gazebo/xmlschema/#controller" xmlns:interface="http://playerstage.sourceforge.net/gazebo/xmlschema/#interface" xmlns:sensor="http://playerstage.sourceforge.net/gazebo/xmlschema/#sensor" xmlns:xacro="http://ros.org/wiki/xacro">
<xacro:macro name="ultrasonidos" params="id parent d_centro *origin">
<joint name="ultrasonidos_${id}_joint_fisico" type="fixed">
<parent link="${parent}"/>
<child link="ultrasonidos_${id}_link_fisico"/>
<insert_block name="origin" />
</joint>
<link name="ultrasonidos_${id}_link_fisico">
<inertial>
<mass value="0.001"/>
<origin rpy="1.57 0 0" xyz="0 -${d_centro} ${0.015/2}"/>
<inertia ixx="0.0001" ixy="0.0" ixz="0.0" iyy="0.0001" iyz="0.0" izz="0.0001"/>
</inertial>
<visual>
<origin rpy="1.57 0 0" xyz="0 -${d_centro} ${0.015/2}"/>
<geometry>
<cylinder radius="${0.015/2}" length="0.015" />
</geometry>
<material name="black">
<color rgba="0 0 0 1" />
</material>
</visual>
<collision>
<origin rpy="1.57 0 0" xyz="0 -${d_centro} ${0.015/2}"/>
<geometry>
<cylinder radius="${0.015/2}" length="0.015" />
</geometry>
</collision>
</link>
<joint name="ultrasonidos_${id}_joint" type="fixed">
<parent link="ultrasonidos_${id}_link_fisico"/>
<child link="ultrasonidos_${id}_link"/>
<origin rpy="0 0 -1.57" xyz="0 -${d_centro+(0.015/2)} ${0.015/2}"/>
</joint>
<link name="ultrasonidos_${id}_link">
</link>
<gazebo reference="ultrasonidos_${id}_link_fisico">
<material>myrabot_fer/Black</material>
<mu1>0.5</mu1>
<mu2>0.5</mu2>
<selfCollide>true</selfCollide>
<turnGravityOff>false</turnGravityOff>
</gazebo>
<gazebo reference="ultrasonidos_${id}_link">
<sensor:ray name="ultrasonidos_${id}">
<displayRays>false</displayRays>
<rayCount>5</rayCount>
<rangeCount>5</rangeCount>
<verticalRayCount>1</verticalRayCount>
<verticalRangeCount>1</verticalRangeCount>
<minAngle>-16</minAngle>
<verticalMinAngle>-16</verticalMinAngle>
<maxAngle>16</maxAngle>
<verticalMaxAngle>16</verticalMaxAngle>
<minRange>0</minRange>
<maxRange>7</maxRange>
<resRange>0.01</resRange>
<updateRate>20</updateRate>
<controller:gazebo_ros_sonar name="gazebo_ros_ultrasonidos_${id}_controller" plugin="libgazebo_ros_sonar.so">
<robotNamespace>/</robotNamespace>
<gaussianNoise>0.005</gaussianNoise>
<alwaysOn>true</alwaysOn>
<updateRate>20</updateRate>
<topicName>ultrasonidos_${id}</topicName>
<frameId>ultrasonidos_${id}_link</frameId>
<radiation>ultrasound</radiation>
<fov>32</fov>
</controller:gazebo_ros_sonar>
</sensor:ray>
</gazebo>
</xacro:macro>
</robot>
Assembled of MYRAbot model
We have to join all the parts that form the MYRAbot. We have to set the parent link and origin of each part. We will create a file named "myrabot.urdf.xacro" within the folder "urdf" of our package with the content that is shown below:
<?xml version="1.0"?>
<robot name="MYRAbot"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:gazebo="http://playerstage.sourceforge.net/gazebo/xmlschema/#gz"
xmlns:model="http://playerstage.sourceforge.net/gazebo/xmlschema/#model"
xmlns:sensor="http://playerstage.sourceforge.net/gazebo/xmlschema/#sensor"
xmlns:body="http://playerstage.sourceforge.net/gazebo/xmlschema/#body"
xmlns:geom="http://playerstage.sourceforge.net/gazebo/xmlschema/#geom"
xmlns:joint="http://playerstage.sourceforge.net/gazebo/xmlschema/#joint"
xmlns:interface="http://playerstage.sourceforge.net/gazebo/xmlschema/#interface"
xmlns:rendering="http://playerstage.sourceforge.net/gazebo/xmlschema/#rendering"
xmlns:renderable="http://playerstage.sourceforge.net/gazebo/xmlschema/#renderable"
xmlns:controller="http://playerstage.sourceforge.net/gazebo/xmlschema/#controller"
xmlns:physics="http://playerstage.sourceforge.net/gazebo/xmlschema/#physics">
<include filename="$(find myrabot_fer_modelo)/urdf/roomba.xacro" />
<include filename="$(find myrabot_fer_modelo)/urdf/estructura-myrabot.xacro" />
<include filename="$(find myrabot_fer_modelo)/urdf/kinect.xacro" />
<include filename="$(find brazo_fer_modelo)/urdf/brazo.xacro" />
<include filename="$(find myrabot_fer_modelo)/urdf/webcam.xacro" />
<roomba />
<estructura_myrabot parent="base_link">
<origin rpy="0 0 1.57" xyz="0.135 -0.135 0.063"/>
</estructura_myrabot>
<kinect parent="e_base_kinect_link">
<origin rpy="0 0 -1.57" xyz="0.135 0.090 0.112"/>
</kinect>
<brazo parent="e_base_brazo_1_link">
<origin rpy="0 0 3.1416" xyz="0.135 0.0335 0.075"/>
</brazo>
<webcam parent="e_monitor_link">
<origin rpy="0 0 0" xyz="0 0 ${0.185/2}"/>
</webcam>
<ultrasonidos id="1" parent="e_base_2_link" d_centro="0.150">
<origin rpy="0 0 1.57" xyz="0.135 0.135 0.02"/>
</ultrasonidos>
<ultrasonidos id="2" parent="e_base_2_link" d_centro="0.150">
<origin rpy="0 0 2.36" xyz="0.135 0.135 0.02"/>
</ultrasonidos>
<ultrasonidos id="3" parent="e_base_2_link" d_centro="0.150">
<origin rpy="0 0 3.14" xyz="0.135 0.135 0.02"/>
</ultrasonidos>
<ultrasonidos id="4" parent="e_base_2_link" d_centro="0.150">
<origin rpy="0 0 3.93" xyz="0.135 0.135 0.02"/>
</ultrasonidos>
<ultrasonidos id="5" parent="e_base_2_link" d_centro="0.150">
<origin rpy="0 0 4.71" xyz="0.135 0.135 0.02"/>
</ultrasonidos>
</robot>