ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

I tested your solution. The simulation is stable, but a portion of the wheels penetrates the ground. I don't know whether this can influence the behavior of the platform (increasing friction for example). Anyway, I post the urdf of the platform and the world file with the updates suggested by you. Just a note: I changed the kp and kd of the ground plane model in the world file, and the cfm and erp of the wheel joint (is this correct?).

Platform (it is based on the PR2 base):

<?xml version="1.0"?>
<robot xmlns:sensor="http://playerstage.sourceforge.net/gazebo/xmlschema/#sensor"
   xmlns:controller="http://playerstage.sourceforge.net/gazebo/xmlschema/#controller"
   xmlns:interface="http://playerstage.sourceforge.net/gazebo/xmlschema/#interface"
   xmlns:xacro="http://ros.org/wiki/xacro">

<include filename="$(find prototype_description)/urdf/base.gazebo.xacro" />
<include filename="$(find prototype_description)/urdf/base.transmission.xacro" />


<property name="M_PI" value="3.1415926535897931" />

<property name="caster_offset_x" value="1.5" />
<property name="caster_offset_y" value="0.5" />
<property name="caster_offset_z" value="0.0282" />

<property name="caster_wheel_offset_y" value="0.049" />
<property name="wheel_length" value="0.085" /> 
<property name="wheel_radius" value="0.205" /> 
<property name="base_mass" value="5000.0" /> 

<!-- simplified box collision geometry for base -->
<property name="base_size_x" value="4.0" />
<property name="base_size_y" value="2.0" />
<property name="base_size_z" value="0.2" />
<property name="base_collision_size_z" value="0.04" />

<!--                                                      -->
<!--           wheel                                      -->
<!--                                                      -->
<xacro:macro name="experimental_wheel_v0" params="suffix parent reflect"> <!-- The idea is to remove reflect from here -->

<joint name="${parent}_${suffix}_wheel_joint" type="continuous">
  <axis xyz="0 1 0" />
  <limit effort="500" velocity="100"/>
  <safety_controller  k_velocity="10" />
  <dynamics damping="0.0" friction="0.0" />
  <origin xyz="0 0 0" rpy="0 0 0" /> 
  <parent link="${parent}_rotation_link"/>
  <child link="${parent}_${suffix}_wheel_link"/>
  <cfm>0.00000017</cfm> 
  <erp>0.17</erp>    
</joint>
<link name="${parent}_${suffix}_wheel_link">
  <inertial>
    <mass value="10.44036" /> <!-- original value = 0.44036 -->
    <origin xyz="0 0 0" />
    <inertia  ixx="0.012411765597" ixy="-0.000711733678" ixz="0.00050272983"
              iyy="0.015218160428" iyz="-0.000004273467" izz="0.011763977943" />
  </inertial>
  <visual>
    <origin xyz="0 0 0" rpy="${M_PI/2} 0 0" /> <!-- original rpy="0 0 0"-->
    <geometry>
  <cylinder radius="${wheel_radius}" length="${wheel_length}" /> 
    </geometry>

    <material name="Wheel_${suffix}" />
  </visual>
  <collision>
    <origin xyz="0 0 0" rpy="${M_PI/2} 0 0" /> <!-- rotation because cyl. geom primitive has symmetry axis in +x direction -->
    <geometry>
      <cylinder radius="${wheel_radius}" length="${wheel_length}" />
    </geometry>
  </collision>
</link>

<!-- extensions -->
<xacro:experimental_wheel_gazebo_v0 parent="${parent}" suffix="${suffix}" />
<xacro:prototype_wheel_transmission_v0 parent="${parent}" suffix="${suffix}" reflect="${reflect}" /> 

</xacro:macro>

<!-- Macro for caster hub only -->
<xacro:macro name="experimental_caster_hub_v0" params="suffix parent *origin ref_position" >
  <joint name="${suffix}_rotation_joint" type="continuous">
    <axis xyz="0 0 1" />
    <limit effort="1000" velocity="1000"/>
    <safety_controller  k_velocity="10" />
    <calibration rising="${ref_position}" />
    <dynamics damping="0.0" friction="0.0" />
    <insert_block name="origin" />
    <parent link="${parent}"/>
    <child link="${suffix}_rotation_link" />
  </joint>
  <link name="${suffix}_rotation_link">

  <inertial>
    <mass value="53.473082"/>
    <origin xyz="0 0 0.07" />
    <inertia  ixx="0.012411765597" ixy="-0.000711733678" ixz="0.00050272983"
              iyy="0.015218160428" iyz="-0.000004273467" izz="0.011763977943" />
  </inertial>

  <visual>
    <origin xyz="0 0 0.130208" rpy="0 0 0" />
    <geometry>
      <mesh filename="package://pr2_description/meshes/base_v0/caster.stl" />
    </geometry>

    <material name="Caster" />
  </visual>

  <collision>
    <origin xyz="0 0 0.130208" rpy="0 0 0" />
    <geometry>
      <mesh filename="package://pr2_description/meshes/base_v0/caster_L.stl" />
    </geometry>
  </collision>
</link>

<!-- extensions -->
<xacro:prototype_caster_transmission_v0 suffix="${suffix}" />
</xacro:macro>

<xacro:macro name="experimental_caster_v0" params="suffix parent *origin ref_position">

<xacro:experimental_caster_hub_v0 parent="${parent}" suffix="${suffix}_caster"
                         ref_position="${ref_position}" >
  <insert_block name="origin" />
</xacro:experimental_caster_hub_v0>

<!-- wheel macros -->
<xacro:experimental_wheel_v0 parent="${suffix}_caster" suffix="l" reflect="1"/>

<!-- extensions -->
<xacro:experimental_caster_gazebo_v0 suffix="${suffix}" />
</xacro:macro>  

<!-- Overload link, to simulate high loads for the platform -->
<xacro:macro name="overload" params="name parent pos_x pos_y pos_z overload_mass">
  <link name="${name}_overload_link">

    <inertial>
      <mass value="${overload_mass}" />
  <origin xyz="0 0 ${base_size_z/2}" />
      <inertia ixx="5.652232699207" ixy="-0.009719934438" ixz="1.293988226423"
             iyy="5.669473158652" iyz="-0.007379583694" izz="3.683196351726" />
    </inertial>

    <visual>
      <origin xyz="0 0 0" rpy="0 0 0" /> 
      <geometry>
        <box size="${base_size_x/2} ${base_size_y/2} ${base_size_z}" />
      </geometry>        
    </visual>

    <collision>
      <origin xyz="0 0 0" rpy="0 0 0" /> 
      <geometry>
    <box size="${base_size_x/2} ${base_size_y/2} ${base_size_z}" />
      </geometry>
    </collision>
  </link>
  <joint name="${name}_overload_joint" type="fixed">
    <origin xyz="${pos_x} ${pos_y} ${pos_z}" rpy="0 0 0" />
    <child link="${name}_overload_link" />
    <parent link="${parent}"/>
  </joint>
</xacro:macro>

<!-- The xacro macro xacro:experimental_base contains: base, casters and wheels -->
<xacro:macro name="experimental_base" params="name">
  <link name="${name}_link">

    <inertial>
      <mass value="1000" />
      <origin xyz="0 0 0.45" />
      <inertia ixx="5.652232699207" ixy="-0.009719934438" ixz="1.293988226423"
             iyy="5.669473158652" iyz="-0.007379583694" izz="3.683196351726" />
    </inertial>

    <visual>
      <origin xyz="0 0 0.430208" rpy="0 0 0" /> <!-- T!! -->
      <geometry>
        <box size="${base_size_x} ${base_size_y} ${base_size_z/2}" />
      </geometry>

      <material name="White" />
    </visual>

    <collision>
      <origin xyz="0 0 0.430208" rpy="0 0 0" /> 
      <geometry>
    <box size="${base_size_x} ${base_size_y} ${base_size_z}" />
      </geometry>
    </collision>
  </link>

  <!-- Put the four blocks for 5000 kg base -->

  <xacro:overload name="fl_base" parent="${name}_link" pos_x="${base_size_x/4}" pos_y="${base_size_y/4}" pos_z="${base_size_z/2 + 0.430208}" overload_mass="${base_mass/4 - 1000/4}"/>
  <xacro:overload name="bl_base" parent="${name}_link" pos_x="${-base_size_x/4}" pos_y="${base_size_y/4}" pos_z="${base_size_z/2 + 0.430208}" overload_mass="${base_mass/4 - 1000/4}"/>
  <xacro:overload name="br_base" parent="${name}_link" pos_x="${-base_size_x/4}" pos_y="${-base_size_y/4}" pos_z="${base_size_z/2 + 0.430208}" overload_mass="${base_mass/4 - 1000/4}"/>
  <xacro:overload name="fr_base" parent="${name}_link" pos_x="${base_size_x/4}" pos_y="${-base_size_y/4}" pos_z="${base_size_z/2 + 0.430208}" overload_mass="${base_mass/4 - 1000/4}"/>

  <!-- base_footprint is a fictitious link(frame) that is on the ground right below base_link origin, navigation stack dedpends on this frame -->
  <link name="${name}_footprint">
    <inertial>
      <mass value="1.0" />
      <origin xyz="0 0 0.45" />
      <inertia ixx="0.01" ixy="0.0" ixz="0.0"
             iyy="0.01" iyz="0.0" izz="0.01" />
    </inertial>
    <visual>
      <origin xyz="0 0 0.430208" rpy="0 0 0" />
      <geometry>
        <box size="0.01 0.01 0.01" />
      </geometry>

      <material name="White" />
    </visual>
    <collision>    
      <origin xyz="0 0 0.481208" rpy="0 0 0" />
      <geometry>
        <box size="0.001 0.001 0.001" />
      </geometry>
    </collision>
  </link>

  <joint name="${name}_footprint_joint" type="fixed">
    <origin xyz="0 0 0.430208" rpy="0 0 0" />
    <child link="${name}_link" />
    <parent link="${name}_footprint"/>
  </joint>  

<!-- all four caster macros -->
<xacro:experimental_caster_v0 suffix="fl" parent="${name}_link" ref_position="${cal_caster_fl - M_PI/4}" >
  <origin xyz="${caster_offset_x} ${caster_offset_y} ${caster_offset_z}" rpy="0 0 0" />
</xacro:experimental_caster_v0>
<xacro:experimental_caster_v0 suffix="fr" parent="${name}_link" ref_position="${cal_caster_fr - M_PI/4}" >
  <origin xyz="${caster_offset_x} ${-caster_offset_y} ${caster_offset_z}" rpy="0 0 0" />
</xacro:experimental_caster_v0>
<xacro:experimental_caster_v0 suffix="bl" parent="${name}_link" ref_position="${cal_caster_bl - M_PI / 4 + M_PI}" >
  <origin xyz="${-caster_offset_x} ${caster_offset_y} ${caster_offset_z}" rpy="0 0 0" />
</xacro:experimental_caster_v0>
<xacro:experimental_caster_v0 suffix="br" parent="${name}_link" ref_position="${cal_caster_br - M_PI / 4 + M_PI}" >
  <origin xyz="${-caster_offset_x} ${-caster_offset_y} ${caster_offset_z}" rpy="0 0 0" />
</xacro:experimental_caster_v0>

<!-- Add overload -->

<xacro:overload name="fl" parent="fl_base_overload_link" pos_x="0" pos_y="0" pos_z="${base_size_z}" overload_mass="10000"/>
<xacro:overload name="br" parent="br_base_overload_link" pos_x="0" pos_y="0" pos_z="${base_size_z}" overload_mass="10000"/>
<xacro:overload name="bl" parent="bl_base_overload_link" pos_x="0" pos_y="0" pos_z="${base_size_z}" overload_mass="10000"/>
<xacro:overload name="fr" parent="fr_base_overload_link" pos_x="0" pos_y="0" pos_z="${base_size_z}" overload_mass="10000"/>

<!-- gazebo extensions -->
<xacro:experimental_base_gazebo_v0 name="${name}" />

</xacro:macro>

</robot>

World file (it is the same as empty.world, but with some different parameters):

<?xml version="1.0"?>

<gazebo:world 
   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:window="http://playerstage.sourceforge.net/gazebo/xmlschema/#window" 
   xmlns:param="http://playerstage.sourceforge.net/gazebo/xmlschema/#param" 
   xmlns:body="http://playerstage.sourceforge.net/gazebo/xmlschema/#body" 
   xmlns:geo="http://willowgarage.com/xmlschema/#geo" 
   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:ui="http://playerstage.sourceforge.net/gazebo/xmlschema/#ui"
   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" >

<thread>4</thread>
<verbosity>5</verbosity>

<!-- here's the global contact cfm/erp -->
<physics:ode>
  <stepTime>0.001</stepTime>
  <gravity>0 0 -9.8</gravity>
  <cfm>0.0000000001</cfm>       
  <erp>0.2</erp>
  <quickStep>true</quickStep>
  <stepIters>500</stepIters> <!-- 10 -->
  <stepW>1.3</stepW>
  <contactMaxCorrectingVel>100.0</contactMaxCorrectingVel>
  <contactSurfaceLayer>0.001</contactSurfaceLayer>
</physics:ode>

<geo:origin>
  <lat>37.4270909558</lat><lon>-122.077919338</lon>
</geo:origin>

<rendering:gui>
  <type>fltk</type>
  <size>480 320</size>
  <pos>0 0</pos>
  <frames>
    <row height="100%">
      <camera width="100%">
        <xyz>0.3 0 3</xyz>
        <rpy>0 90 90</rpy>
      </camera>
    </row>
  </frames>
</rendering:gui>


<rendering:ogre>
  <ambient>0.5 0.5 0.5 0.5</ambient>
  <sky>
    <material>Gazebo/CloudySky</material>
  </sky>
  <grid>false</grid>
  <maxUpdateRate>10.</maxUpdateRate>
  <shadowTechnique>none</shadowTechnique>
  <shadows>false</shadows>
</rendering:ogre>

<!-- ground plane -->
<model:physical name="gplane">
  <xyz>0 0 0</xyz>  
  <rpy>0 0 0</rpy>
  <static>true</static>

  <body:plane name="plane">
    <geom:plane name="plane">
      <laserRetro>2000.0</laserRetro>
      <mu1>50.0</mu1> 
      <mu2>50.0</mu2> 
      <kp>1000000000.0</kp>
      <kd>5000000</kd> 
      <normal>0 0 1</normal>
      <size>100 100</size> <!-- original value 51.3 51.3 -->
      <segments>10 10</segments>
      <uvTile>100 100</uvTile>
      <material>Gazebo/GrayGrid</material>
      <contactSurfaceLayer>0.00000001</contactSurfaceLayer>
    </geom:plane>
  </body:plane>
</model:physical>

<!-- White Point light -->
<model:renderable name="point_white">
  <xyz>0.0 0.0 8</xyz>
  <enableGravity>false</enableGravity>
  <light>
    <type>point</type>
    <diffuseColor>0.5 0.5 0.5</diffuseColor>
    <specularColor>.1 .1 .1</specularColor>
    <attenuation>0.2 0.1 0</attenuation>
    <range>10</range>
  </light>
</model:renderable>

</gazebo:world>