问:
My robot keeps getting saved as one cylinder leaving out the bottom cube
I created a robot in the model editor that is made up of a cube and a cylinder with a revolute joint between them but after saving it and inserting another instance into the world, I only get the cylinder and no cube at the bottom. There is a revolute joint between the two so I don't get how the two don't move together or get bundled up. What is happening with gazebo?

Using:

Ubuntu 18.06

gazebo9

EDIT:

Here's myrobot.sdf

<?xml version='1.0'?>
<sdf version='1.6'>
  <model name='myrobot'>
    <link name='link_0'>
      <inertial>
        <mass>1</mass>
        <inertia>
          <ixx>0.166667</ixx>
          <ixy>0</ixy>
          <ixz>0</ixz>
          <iyy>0.166667</iyy>
          <iyz>0</iyz>
          <izz>0.166667</izz>
        </inertia>
        <pose frame=''>0 0 0 0 -0 0</pose>
      </inertial>
      <pose frame=''>0 0 -0.5 0 -0 0</pose>
      <gravity>1</gravity>
      <self_collide>0</self_collide>
      <kinematic>0</kinematic>
      <enable_wind>0</enable_wind>
      <visual name='visual'>
        <pose frame=''>0 0 0 0 -0 0</pose>
        <geometry>
          <box>
            <size>1 1 1</size>
          </box>
        </geometry>
        <material>
          <lighting>1</lighting>

          <shader type='vertex'>
            <normal_map>__default__</normal_map>
          </shader>
          <ambient>0.3 0.3 0.3 1</ambient>
          <diffuse>0.7 0.7 0.7 1</diffuse>
          <specular>0.01 0.01 0.01 1</specular>
          <emissive>0 0 0 1</emissive>
        </material>
        <transparency>0</transparency>
        <cast_shadows>1</cast_shadows>
      </visual>
      <collision name='collision'>
        <laser_retro>0</laser_retro>
        <max_contacts>10</max_contacts>
        <pose frame=''>0 0 0 0 -0 0</pose>
        <geometry>
          <box>
            <size>1 1 1</size>
          </box>
        </geometry>
        <surface>
          <friction>
            <ode>
              <mu>1</mu>
              <mu2>1</mu2>
              <fdir1>0 0 0</fdir1>
              <slip1>0</slip1>
              <slip2>0</slip2>
            </ode>
            <torsional>
              <coefficient>1</coefficient>
              <patch_radius>0</patch_radius>
              <surface_radius>0</surface_radius>
              <use_patch_radius>1</use_patch_radius>
              <ode>
                <slip>0</slip>
              </ode>
            </torsional>
          </friction>
          <bounce>
            <restitution_coefficient>0</restitution_coefficient>
            <threshold>1e+06</threshold>
          </bounce>
          <contact>
            <collide_without_contact>0</collide_without_contact>
            <collide_without_contact_bitmask>1</collide_without_contact_bitmask>
            <collide_bitmask>1</collide_bitmask>
            <ode>
              <soft_cfm>0</soft_cfm>
              <soft_erp>0.2</soft_erp>
              <kp>1e+13</kp>
              <kd>1</kd>
              <max_vel>0.01</max_vel>
              <min_depth>0</min_depth>
            </ode>
            <bullet>
              <split_impulse>1</split_impulse>
              <split_impulse_penetration_threshold>-0.01</split_impulse_penetration_threshold>
              <soft_cfm>0</soft_cfm>
              <soft_erp>0.2</soft_erp>
              <kp>1e+13</kp>
              <kd>1</kd>
            </bullet>
          </contact>
        </surface>
      </collision>
    </link>
    <link name='link_1'>
      <inertial>
        <mass>1</mass>
        <inertia>
          <ixx>0.145833</ixx>
          <ixy>0</ixy>
          <ixz>0</ixz>
          <iyy>0.145833</iyy>
          <iyz>0</iyz>
          <izz>0.125</izz>
        </inertia>
        <pose frame=''>0 0 0 0 -0 0</pose>
      </inertial>
      <pose frame=''>0 0 0.5 0 -0 0</pose>
      <gravity>1</gravity>
      <self_collide>0</self_collide>
      <kinematic>0</kinematic>
      <enable_wind>0</enable_wind>
      <visual name='visual'>
        <pose frame=''>0 0 0 0 -0 0</pose>
        <geometry>
          <cylinder>
            <radius>0.2</radius>
            <length>1</length>
          </cylinder>
        </geometry>
        <material>
          <lighting>1</lighting>

          <shader type='vertex'>
            <normal_map>__default__</normal_map>
          </shader>
          <ambient>0.3 0.3 0.3 1</ambient>
          <diffuse>0.7 0.7 0.7 1</diffuse>
          <specular>0.01 0.01 0.01 1</specular>
          <emissive>0 0 0 1</emissive>
        </material>
        <transparency>0</transparency>
        <cast_shadows>1</cast_shadows>
      </visual>
      <collision name='collision'>
        <laser_retro>0</laser_retro>
        <max_contacts>10</max_contacts>
        <pose frame=''>0 0 0 0 -0 0</pose>
        <geometry>
          <cylinder>
            <radius>0.2</radius>
            <length>1</length>
          </cylinder>
        </geometry>
        <surface>
          <friction>
            <ode>
              <mu>1</mu>
              <mu2>1</mu2>
              <fdir1>0 0 0</fdir1>
              <slip1>0</slip1>
              <slip2>0</slip2>
            </ode>
            <torsional>
              <coefficient>1</coefficient>
              <patch_radius>0</patch_radius>
              <surface_radius>0</surface_radius>
              <use_patch_radius>1</use_patch_radius>
              <ode>
                <slip>0</slip>
              </ode>
            </torsional>
          </friction>
          <bounce>
            <restitution_coefficient>0</restitution_coefficient>
            <threshold>1e+06</threshold>
          </bounce>
          <contact>
            <collide_without_contact>0</collide_without_contact>
            <collide_without_contact_bitmask>1</collide_without_contact_bitmask>
            <collide_bitmask>1</collide_bitmask>
            <ode>
              <soft_cfm>0</soft_cfm>
              <soft_erp>0.2</soft_erp>
              <kp>1e+13</kp>
              <kd>1</kd>
              <max_vel>0.01</max_vel>
              <min_depth>0</min_depth>
            </ode>
            <bullet>
              <split_impulse>1</split_impulse>
              <split_impulse_penetration_threshold>-0.01</split_impulse_penetration_threshold>
              <soft_cfm>0</soft_cfm>
              <soft_erp>0.2</soft_erp>
              <kp>1e+13</kp>
              <kd>1</kd>
            </bullet>
          </contact>
        </surface>
      </collision>
    </link>
    <joint name='link_0_JOINT_0' type='revolute'>
      <parent>link_0</parent>
      <child>link_1</child>
      <pose frame=''>0 0 0 0 -0 0</pose>
      <axis>
        <xyz>0 0 1</xyz>
        <use_parent_model_frame>0</use_parent_model_frame>
        <limit>
          <lower>-1.79769e+308</lower>
          <upper>1.79769e+308</upper>
          <effort>-1</effort>
          <velocity>-1</velocity>
        </limit>
        <dynamics>
          <spring_reference>0</spring_reference>
          <spring_stiffness>0</spring_stiffness>
          <damping>0</damping>
        </dynamics>
      </axis>
      <physics>
        <ode>
          <limit>
            <cfm>0</cfm>
            <erp>0.2</erp>
          </limit>
          <suspension>
            <cfm>0</cfm>
            <erp>0.2</erp>
          </suspension>
        </ode>
      </physics>
    </joint>
    <static>0</static>
    <allow_auto_disable>1</allow_auto_disable>
  </model>
</sdf>
```

<hr>

<p><strong>EDIT:</strong></p>

<p>Updated <code>myrobot.sdf</code> that shows up upside-down. </p>

<pre class="lang-xml prettyprint-override"><code><?xml version='1.0'?>
<sdf version='1.6'>
  <model name='robot'>
    <link name='link_0'>
      <inertial>
        <mass>1</mass>
        <inertia>
          <ixx>0.166667</ixx>
          <ixy>0</ixy>
          <ixz>0</ixz>
          <iyy>0.166667</iyy>
          <iyz>0</iyz>
          <izz>0.166667</izz>
        </inertia>
        <pose frame=''>0 0 0 0 -0 0</pose>
      </inertial>
      <pose frame=''>0 0 1.0 0 0 0</pose>
      <gravity>1</gravity>
      <self_collide>0</self_collide>
      <kinematic>0</kinematic>
      <enable_wind>0</enable_wind>
      <visual name='visual'>
        <pose frame=''>0 0 0 0 -0 0</pose>
        <geometry>
          <box>
            <size>1 1 1</size>
          </box>
        </geometry>
        <material>
          <lighting>1</lighting>
          <script>
            <uri>file://media/materials/scripts/gazebo.material</uri>
            <name>Gazebo/Grey</name>
          </script>
          <shader type='vertex'>
            <normal_map>__default__</normal_map>
          </shader>
          <ambient>0.3 0.3 0.3 1</ambient>
          <diffuse>0.7 0.7 0.7 1</diffuse>
          <specular>0.01 0.01 0.01 1</specular>
          <emissive>0 0 0 1</emissive>
        </material>
        <transparency>0</transparency>
        <cast_shadows>1</cast_shadows>
      </visual>
      <collision name='collision'>
        <laser_retro>0</laser_retro>
        <max_contacts>10</max_contacts>
        <pose frame=''>0 0 0 0 -0 0</pose>
        <geometry>
          <box>
            <size>1 1 1</size>
          </box>
        </geometry>
        <surface>
          <friction>
            <ode>
              <mu>1</mu>
              <mu2>1</mu2>
              <fdir1>0 0 0</fdir1>
              <slip1>0</slip1>
              <slip2>0</slip2>
            </ode>
            <torsional>
              <coefficient>1</coefficient>
              <patch_radius>0</patch_radius>
              <surface_radius>0</surface_radius>
              <use_patch_radius>1</use_patch_radius>
              <ode>
                <slip>0</slip>
              </ode>
            </torsional>
          </friction>
          <bounce>
            <restitution_coefficient>0</restitution_coefficient>
            <threshold>1e+06</threshold>
          </bounce>
          <contact>
            <collide_without_contact>0</collide_without_contact>
            <collide_without_contact_bitmask>1</collide_without_contact_bitmask>
            <collide_bitmask>1</collide_bitmask>
            <ode>
              <soft_cfm>0</soft_cfm>
              <soft_erp>0.2</soft_erp>
              <kp>1e+13</kp>
              <kd>1</kd>
              <max_vel>0.01</max_vel>
              <min_depth>0</min_depth>
            </ode>
            <bullet>
              <split_impulse>1</split_impulse>
              <split_impulse_penetration_threshold>-0.01</split_impulse_penetration_threshold>
              <soft_cfm>0</soft_cfm>
              <soft_erp>0.2</soft_erp>
              <kp>1e+13</kp>
              <kd>1</kd>
            </bullet>
          </contact>
        </surface>
      </collision>
    </link>
    <link name='link_1'>
      <inertial>
        <mass>1</mass>
        <inertia>
          <ixx>0.145833</ixx>
          <ixy>0</ixy>
          <ixz>0</ixz>
          <iyy>0.145833</iyy>
          <iyz>0</iyz>
          <izz>0.125</izz>
        </inertia>
        <pose frame=''>0 0 0 0 -0 0</pose>
      </inertial>
      <pose frame=''>-1e-06 0 0.5 0 -0 0</pose>
      <gravity>1</gravity>
      <self_collide>0</self_collide>
      <kinematic>0</kinematic>
      <enable_wind>0</enable_wind>
      <visual name='visual'>
        <pose frame=''>0 0 0 0 -0 0</pose>
        <geometry>
          <cylinder>
            <radius>0.2</radius>
            <length>1</length>
          </cylinder>
        </geometry>
        <material>
          <lighting>1</lighting>
          <script>
            <uri>file://media/materials/scripts/gazebo.material</uri>
            <name>Gazebo/Grey</name>
          </script>
          <shader type='vertex'>
            <normal_map>__default__</normal_map>
          </shader>
          <ambient>0.3 0.3 0.3 1</ambient>
          <diffuse>0.7 0.7 0.7 1</diffuse>
          <specular>0.01 0.01 0.01 1</specular>
          <emissive>0 0 0 1</emissive>
        </material>
        <transparency>0</transparency>
        <cast_shadows>1</cast_shadows>
      </visual>
      <collision name='collision'>
        <laser_retro>0</laser_retro>
        <max_contacts>10</max_contacts>
        <pose frame=''>0 0 0 0 -0 0</pose>
        <geometry>
          <cylinder>
            <radius>0.2</radius>
            <length>1</length>
          </cylinder>
        </geometry>
        <surface>
          <friction>
            <ode>
              <mu>1</mu>
              <mu2>1</mu2>
              <fdir1>0 0 0</fdir1>
              <slip1>0</slip1>
              <slip2>0</slip2>
            </ode>
            <torsional>
              <coefficient>1</coefficient>
              <patch_radius>0</patch_radius>
              <surface_radius>0</surface_radius>
              <use_patch_radius>1</use_patch_radius>
              <ode>
                <slip>0</slip>
              </ode>
            </torsional>
          </friction>
          <bounce>
            <restitution_coefficient>0</restitution_coefficient>
            <threshold>1e+06</threshold>
          </bounce>
          <contact>
            <collide_without_contact>0</collide_without_contact>
            <collide_without_contact_bitmask>1</collide_without_contact_bitmask>
            <collide_bitmask>1</collide_bitmask>
            <ode>
              <soft_cfm>0</soft_cfm>
              <soft_erp>0.2</soft_erp>
              <kp>1e+13</kp>
              <kd>1</kd>
              <max_vel>0.01</max_vel>
              <min_depth>0</min_depth>
            </ode>
            <bullet>
              <split_impulse>1</split_impulse>
              <split_impulse_penetration_threshold>-0.01</split_impulse_penetration_threshold>
              <soft_cfm>0</soft_cfm>
              <soft_erp>0.2</soft_erp>
              <kp>1e+13</kp>
              <kd>1</kd>
            </bullet>
          </contact>
        </surface>
      </collision>
    </link>
    <joint name='link_0_JOINT_1' type='revolute'>
      <parent>link_0</parent>
      <child>link_1</child>
      <pose frame=''>0 0 0 -0.04 0 0</pose>
      <axis>
        <xyz>0 0 1</xyz>
        <use_parent_model_frame>0</use_parent_model_frame>
        <limit>
          <lower>-1.79769e+308</lower>
          <upper>1.79769e+308</upper>
          <effort>-1</effort>
          <velocity>-1</velocity>
        </limit>
        <dynamics>
          <spring_reference>0</spring_reference>
          <spring_stiffness>0</spring_stiffness>
          <damping>0</damping>
        </dynamics>
      </axis>
      <physics>
        <ode>
          <limit>
            <cfm>0</cfm>
            <erp>0.2</erp>
          </limit>
          <suspension>
            <cfm>0</cfm>
            <erp>0.2</erp>
          </suspension>
        </ode>
      </physics>
    </joint>
    <static>0</static>
    <allow_auto_disable>1</allow_auto_disable>
  </model>
</sdf>
</code>```

答:
I suppose that what you're seeing when you add your robot model to the world is something like this:

That is, only the top part of the robot is visible. The problem is not that the bottom part isn't there, it's just that the robot's origin is the joint between the two parts, therefore the lower part is below the floor. If you rotate the world (hold <Shift> + <Left Mouse Click> then move the mouse around) so you can see it from under the floor, you'll probably see something like this:

You have two ways to fix this. Either you keep the model as it is, and manually add a vertical offset to its pose when adding it to a world:

Or you add a vertical offset to the model.sdf file:

<?xml version='1.0'?>
<sdf version='1.6'>
  <model name='myrobot'>

    <pose frame=''>0 0 1.0 0 0 0</pose>

    <link name='link_0'>
      <inertial>
        <mass>1</mass>
        <inertia>
          <ixx>0.166667</ixx>
          <ixy>0</ixy>
          <ixz>0</ixz>
          <iyy>0.166667</iyy>
          <iyz>0</iyz>
          <izz>0.166667</izz>
        </inertia>
        <pose frame=''>0 0 0 0 -0 0</pose>
      </inertial>
      <pose frame=''>0 0 -0.5 0 -0 0</pose>
      <gravity>1</gravity>
      <self_collide>0</self_collide>
      <kinematic>0</kinematic>
      <enable_wind>0</enable_wind>
      <visual name='visual'>
        <pose frame=''>0 0 0 0 -0 0</pose>
        <geometry>
          <box>
            <size>1 1 1</size>
          </box>
        </geometry>
        <material>
          <lighting>1</lighting>

          <shader type='vertex'>
            <normal_map>__default__</normal_map>
          </shader>
          <ambient>0.3 0.3 0.3 1</ambient>
          <diffuse>0.7 0.7 0.7 1</diffuse>
          <specular>0.01 0.01 0.01 1</specular>
          <emissive>0 0 0 1</emissive>
        </material>
        <transparency>0</transparency>
        <cast_shadows>1</cast_shadows>
      </visual>
      <collision name='collision'>
        <laser_retro>0</laser_retro>
        <max_contacts>10</max_contacts>
        <pose frame=''>0 0 0 0 -0 0</pose>
        <geometry>
          <box>
            <size>1 1 1</size>
          </box>
        </geometry>
        <surface>
          <friction>
            <ode>
              <mu>1</mu>
              <mu2>1</mu2>
              <fdir1>0 0 0</fdir1>
              <slip1>0</slip1>
              <slip2>0</slip2>
            </ode>
            <torsional>
              <coefficient>1</coefficient>
              <patch_radius>0</patch_radius>
              <surface_radius>0</surface_radius>
              <use_patch_radius>1</use_patch_radius>
              <ode>
                <slip>0</slip>
              </ode>
            </torsional>
          </friction>
          <bounce>
            <restitution_coefficient>0</restitution_coefficient>
            <threshold>1e+06</threshold>
          </bounce>
          <contact>
            <collide_without_contact>0</collide_without_contact>
            <collide_without_contact_bitmask>1</collide_without_contact_bitmask>
            <collide_bitmask>1</collide_bitmask>
            <ode>
              <soft_cfm>0</soft_cfm>
              <soft_erp>0.2</soft_erp>
              <kp>1e+13</kp>
              <kd>1</kd>
              <max_vel>0.01</max_vel>
              <min_depth>0</min_depth>
            </ode>
            <bullet>
              <split_impulse>1</split_impulse>
              <split_impulse_penetration_threshold>-0.01</split_impulse_penetration_threshold>
              <soft_cfm>0</soft_cfm>
              <soft_erp>0.2</soft_erp>
              <kp>1e+13</kp>
              <kd>1</kd>
            </bullet>
          </contact>
        </surface>
      </collision>
    </link>
    <link name='link_1'>
      <inertial>
        <mass>1</mass>
        <inertia>
          <ixx>0.145833</ixx>
          <ixy>0</ixy>
          <ixz>0</ixz>
          <iyy>0.145833</iyy>
          <iyz>0</iyz>
          <izz>0.125</izz>
        </inertia>
        <pose frame=''>0 0 0 0 -0 0</pose>
      </inertial>
      <pose frame=''>0 0 0.5 0 -0 0</pose>
      <gravity>1</gravity>
      <self_collide>0</self_collide>
      <kinematic>0</kinematic>
      <enable_wind>0</enable_wind>
      <visual name='visual'>
        <pose frame=''>0 0 0 0 -0 0</pose>
        <geometry>
          <cylinder>
            <radius>0.2</radius>
            <length>1</length>
          </cylinder>
        </geometry>
        <material>
          <lighting>1</lighting>

          <shader type='vertex'>
            <normal_map>__default__</normal_map>
          </shader>
          <ambient>0.3 0.3 0.3 1</ambient>
          <diffuse>0.7 0.7 0.7 1</diffuse>
          <specular>0.01 0.01 0.01 1</specular>
          <emissive>0 0 0 1</emissive>
        </material>
        <transparency>0</transparency>
        <cast_shadows>1</cast_shadows>
      </visual>
      <collision name='collision'>
        <laser_retro>0</laser_retro>
        <max_contacts>10</max_contacts>
        <pose frame=''>0 0 0 0 -0 0</pose>
        <geometry>
          <cylinder>
            <radius>0.2</radius>
            <length>1</length>
          </cylinder>
        </geometry>
        <surface>
          <friction>
            <ode>
              <mu>1</mu>
              <mu2>1</mu2>
              <fdir1>0 0 0</fdir1>
              <slip1>0</slip1>
              <slip2>0</slip2>
            </ode>
            <torsional>
              <coefficient>1</coefficient>
              <patch_radius>0</patch_radius>
              <surface_radius>0</surface_radius>
              <use_patch_radius>1</use_patch_radius>
              <ode>
                <slip>0</slip>
              </ode>
            </torsional>
          </friction>
          <bounce>
            <restitution_coefficient>0</restitution_coefficient>
            <threshold>1e+06</threshold>
          </bounce>
          <contact>
            <collide_without_contact>0</collide_without_contact>
            <collide_without_contact_bitmask>1</collide_without_contact_bitmask>
            <collide_bitmask>1</collide_bitmask>
            <ode>
              <soft_cfm>0</soft_cfm>
              <soft_erp>0.2</soft_erp>
              <kp>1e+13</kp>
              <kd>1</kd>
              <max_vel>0.01</max_vel>
              <min_depth>0</min_depth>
            </ode>
            <bullet>
              <split_impulse>1</split_impulse>
              <split_impulse_penetration_threshold>-0.01</split_impulse_penetration_threshold>
              <soft_cfm>0</soft_cfm>
              <soft_erp>0.2</soft_erp>
              <kp>1e+13</kp>
              <kd>1</kd>
            </bullet>
          </contact>
        </surface>
      </collision>
    </link>
    <joint name='link_0_JOINT_0' type='revolute'>
      <parent>link_0</parent>
      <child>link_1</child>
      <pose frame=''>0 0 0 0 -0 0</pose>
      <axis>
        <xyz>0 0 1</xyz>
        <use_parent_model_frame>0</use_parent_model_frame>
        <limit>
          <lower>-1.79769e+308</lower>
          <upper>1.79769e+308</upper>
          <effort>-1</effort>
          <velocity>-1</velocity>
        </limit>
        <dynamics>
          <spring_reference>0</spring_reference>
          <spring_stiffness>0</spring_stiffness>
          <damping>0</damping>
        </dynamics>
      </axis>
      <physics>
        <ode>
          <limit>
            <cfm>0</cfm>
            <erp>0.2</erp>
          </limit>
          <suspension>
            <cfm>0</cfm>
            <erp>0.2</erp>
          </suspension>
        </ode>
      </physics>
    </joint>
    <static>0</static>
    <allow_auto_disable>1</allow_auto_disable>
  </model>
</sdf>
```

In the latter case the robot model's bottom will be automatically aligned with the floor when you add it.

Body:
I suppose that what you're seeing when you add your robot model to the world is something like this:

That is, only the top part of the robot is visible. The problem is not that the bottom part isn't there, it's just that the robot's origin is the joint between the two parts, therefore the lower part is below the floor. If you rotate the world (hold <Shift> + <Left Mouse Click> then move the mouse around) so you can see it from under the floor, you'll probably see something like this:

You have two ways to fix this. Either you keep the model as it is, and manually add a vertical offset to its pose when adding it to a world:

Or you add a vertical offset to the model.sdf file:

<?xml version='1.0'?>
<sdf version='1.6'>
  <model name='myrobot'>
    <!-- This shifts the entire model 1.0 m up. -->
    <pose frame=''>0 0 1.0 0 0 0</pose>

    <link name='link_0'>
      <inertial>
        <mass>1</mass>
        <inertia>
          <ixx>0.166667</ixx>
          <ixy>0</ixy>
          <ixz>0</ixz>
          <iyy>0.166667</iyy>
          <iyz>0</iyz>
          <izz>0.166667</izz>
        </inertia>
        <pose frame=''>0 0 0 0 -0 0</pose>
      </inertial>
      <pose frame=''>0 0 -0.5 0 -0 0</pose>
      <gravity>1</gravity>
      <self_collide>0</self_collide>
      <kinematic>0</kinematic>
      <enable_wind>0</enable_wind>
      <visual name='visual'>
        <pose frame=''>0 0 0 0 -0 0</pose>
        <geometry>
          <box>
            <size>1 1 1</size>
          </box>
        </geometry>
        <material>
          <lighting>1</lighting>
          <script>
            <uri>file://media/materials/scripts/gazebo.material</uri>
            <name>Gazebo/Grey</name>
          </script>
          <shader type='vertex'>
            <normal_map>__default__</normal_map>
          </shader>
          <ambient>0.3 0.3 0.3 1</ambient>
          <diffuse>0.7 0.7 0.7 1</diffuse>
          <specular>0.01 0.01 0.01 1</specular>
          <emissive>0 0 0 1</emissive>
        </material>
        <transparency>0</transparency>
        <cast_shadows>1</cast_shadows>
      </visual>
      <collision name='collision'>
        <laser_retro>0</laser_retro>
        <max_contacts>10</max_contacts>
        <pose frame=''>0 0 0 0 -0 0</pose>
        <geometry>
          <box>
            <size>1 1 1</size>
          </box>
        </geometry>
        <surface>
          <friction>
            <ode>
              <mu>1</mu>
              <mu2>1</mu2>
              <fdir1>0 0 0</fdir1>
              <slip1>0</slip1>
              <slip2>0</slip2>
            </ode>
            <torsional>
              <coefficient>1</coefficient>
              <patch_radius>0</patch_radius>
              <surface_radius>0</surface_radius>
              <use_patch_radius>1</use_patch_radius>
              <ode>
                <slip>0</slip>
              </ode>
            </torsional>
          </friction>
          <bounce>
            <restitution_coefficient>0</restitution_coefficient>
            <threshold>1e+06</threshold>
          </bounce>
          <contact>
            <collide_without_contact>0</collide_without_contact>
            <collide_without_contact_bitmask>1</collide_without_contact_bitmask>
            <collide_bitmask>1</collide_bitmask>
            <ode>
              <soft_cfm>0</soft_cfm>
              <soft_erp>0.2</soft_erp>
              <kp>1e+13</kp>
              <kd>1</kd>
              <max_vel>0.01</max_vel>
              <min_depth>0</min_depth>
            </ode>
            <bullet>
              <split_impulse>1</split_impulse>
              <split_impulse_penetration_threshold>-0.01</split_impulse_penetration_threshold>
              <soft_cfm>0</soft_cfm>
              <soft_erp>0.2</soft_erp>
              <kp>1e+13</kp>
              <kd>1</kd>
            </bullet>
          </contact>
        </surface>
      </collision>
    </link>
    <link name='link_1'>
      <inertial>
        <mass>1</mass>
        <inertia>
          <ixx>0.145833</ixx>
          <ixy>0</ixy>
          <ixz>0</ixz>
          <iyy>0.145833</iyy>
          <iyz>0</iyz>
          <izz>0.125</izz>
        </inertia>
        <pose frame=''>0 0 0 0 -0 0</pose>
      </inertial>
      <pose frame=''>0 0 0.5 0 -0 0</pose>
      <gravity>1</gravity>
      <self_collide>0</self_collide>
      <kinematic>0</kinematic>
      <enable_wind>0</enable_wind>
      <visual name='visual'>
        <pose frame=''>0 0 0 0 -0 0</pose>
        <geometry>
          <cylinder>
            <radius>0.2</radius>
            <length>1</length>
          </cylinder>
        </geometry>
        <material>
          <lighting>1</lighting>
          <script>
            <uri>file://media/materials/scripts/gazebo.material</uri>
            <name>Gazebo/Grey</name>
          </script>
          <shader type='vertex'>
            <normal_map>__default__</normal_map>
          </shader>
          <ambient>0.3 0.3 0.3 1</ambient>
          <diffuse>0.7 0.7 0.7 1</diffuse>
          <specular>0.01 0.01 0.01 1</specular>
          <emissive>0 0 0 1</emissive>
        </material>
        <transparency>0</transparency>
        <cast_shadows>1</cast_shadows>
      </visual>
      <collision name='collision'>
        <laser_retro>0</laser_retro>
        <max_contacts>10</max_contacts>
        <pose frame=''>0 0 0 0 -0 0</pose>
        <geometry>
          <cylinder>
            <radius>0.2</radius>
            <length>1</length>
          </cylinder>
        </geometry>
        <surface>
          <friction>
            <ode>
              <mu>1</mu>
              <mu2>1</mu2>
              <fdir1>0 0 0</fdir1>
              <slip1>0</slip1>
              <slip2>0</slip2>
            </ode>
            <torsional>
              <coefficient>1</coefficient>
              <patch_radius>0</patch_radius>
              <surface_radius>0</surface_radius>
              <use_patch_radius>1</use_patch_radius>
              <ode>
                <slip>0</slip>
              </ode>
            </torsional>
          </friction>
          <bounce>
            <restitution_coefficient>0</restitution_coefficient>
            <threshold>1e+06</threshold>
          </bounce>
          <contact>
            <collide_without_contact>0</collide_without_contact>
            <collide_without_contact_bitmask>1</collide_without_contact_bitmask>
            <collide_bitmask>1</collide_bitmask>
            <ode>
              <soft_cfm>0</soft_cfm>
              <soft_erp>0.2</soft_erp>
              <kp>1e+13</kp>
              <kd>1</kd>
              <max_vel>0.01</max_vel>
              <min_depth>0</min_depth>
            </ode>
            <bullet>
              <split_impulse>1</split_impulse>
              <split_impulse_penetration_threshold>-0.01</split_impulse_penetration_threshold>
              <soft_cfm>0</soft_cfm>
              <soft_erp>0.2</soft_erp>
              <kp>1e+13</kp>
              <kd>1</kd>
            </bullet>
          </contact>
        </surface>
      </collision>
    </link>
    <joint name='link_0_JOINT_0' type='revolute'>
      <parent>link_0</parent>
      <child>link_1</child>
      <pose frame=''>0 0 0 0 -0 0</pose>
      <axis>
        <xyz>0 0 1</xyz>
        <use_parent_model_frame>0</use_parent_model_frame>
        <limit>
          <lower>-1.79769e+308</lower>
          <upper>1.79769e+308</upper>
          <effort>-1</effort>
          <velocity>-1</velocity>
        </limit>
        <dynamics>
          <spring_reference>0</spring_reference>
          <spring_stiffness>0</spring_stiffness>
          <damping>0</damping>
        </dynamics>
      </axis>
      <physics>
        <ode>
          <limit>
            <cfm>0</cfm>
            <erp>0.2</erp>
          </limit>
          <suspension>
            <cfm>0</cfm>
            <erp>0.2</erp>
          </suspension>
        </ode>
      </physics>
    </joint>
    <static>0</static>
    <allow_auto_disable>1</allow_auto_disable>
  </model>
</sdf>

In the latter case the robot model's bottom will be automatically aligned with the floor when you add it.


问:
Is a gazebo world unmodifiable after you hit save?
I created a world in gazebo with 2 levels and realized that I wouldn't see my robot moving in it. So I tried to delete the 2nd level but couldn't find a means to do so. Is the GUI not capable of doing this? Do I have to go through the thousand-line sdf file to remove the level?

答:
You can call gazebo passing the world file as argument, modify it and use File -> Save As... overwriting the original file.

But a more robust approach is bypassing the GUI editor entirely and creating world and model files directly in your text editor of choice.

The reason GUI editing features don't seem very robust is probably because advanced users seldom use them: instead we use e.g. xacro to enable the creation of part libraries that can be reused in much more flexible ways than any GUI would ever allow.

ContentLicense: CC BY-SA 4.0


问:
Odd L293D behavior: Pin 16 seems to act as enable
I have a chip that is labeled L293D with a small 'ST' logo, which does not behave like I believe a L239D should:

I have the chip on a breadboard with pins 4,5,12 and 13 connected to the ground rail. The positive rail gets 6V from a battery pack.
A motor is connected to pins 3 and 6.
Pin 2 is connected to the positive rail.

Now, when I connect pin 1 (enable 1) to the positive rail, the motor spins, which is expected.

The weird thing is that if I connect pin 16 instead of pin 1 to positive, the motor spins, as well.

Also, with the motor connected to 11 and 14, and 15 connected to positive, the motor spins if I connect pin 1 or pin 16 to positive, but not if I connect pin 9 (which should be the enable pin for that side).

Does any of that make sense? Am I missing something here?

Thanks!

答:
The behaviour you're describing seems to be correct (as described in the Texas Instruments L293 datasheet - which should be the same as ST's variant). Here's an example of how to wire 3 different motors (please note the indicated diodes are internal to the L293).

The idea is that Vcc1 (pin 16) should be associated with your logic inputs: pins 1, 2, 7, 9, 10 and 15 (in other words, if your micro is powered from 3V3, Vcc1 should be 3V3). On the other hand, if you run your motors from 6V, Vcc2 (pin 8) should be 6V (or whichever voltage you use to drive the motors).

For reference, here's the pinout of the TI L293.

Update:

The TI variant does indeed seem to be the same as ST's L293D (see powerdip package).

ContentLicense: CC BY-SA 3.0


问:
motion model for forward movement
I thought this is a simple and well known problem and therefore there is a lot of literature. But I'm not able to find the correct keywords to google the answer. Maybe instead of answering the whole question you can already help me by telling me the correct keywords.

My problem is the following:

For a given parametrisation of a robot, for example the simple two dimensional $(\varphi,p_1,p_2)$, where $\varphi$ describes the orientation and $p$ the 2D position, I want to find a trajectory

$c:[0,1]\rightarrow S^1\times R^2$

from one given pose $(\varphi_0,(p_1)_0,(p_2)_0)$ to another given pose $(\varphi_1,(p_1)_1,(p_2)_1)$. This trajectory should also be optimal with respect to an energy functional for example

$\int_0^1 \varphi^2+p^2_1+p^2_2 \;dt$

and I want two constraints to be fulfilled in order to make sure that the robot moves only forward. These constraints are:

$\dot{p_1}=\cos(\varphi)$

$\dot{p_2}=\sin(\varphi)$

With Euler-Langrange I get the ODE system:

$\ddot{\varphi}=\varphi^2$

$\ddot{p_1}=-sin(\varphi)\dot{p_1}$

$\ddot{p_2}=cos(\varphi)\dot{p_2}$

Now I'm wondering if this equation system is solvable with my boundary conditions.

My questions are
1) Are there any theorems that I can use to make statements about the existence of solutions? Whenever I tried to solve this ODE in Matlab the second boundary condition was not reached.

2) Would it be easier to proof the existence if I would use another model for example with an orientation independent stearing wheel?

3) How can I solve this equation system?

4) In literature I only found very complicated models with a lot more parameters or the paper was not about reaching a specific goal pose can you advise me more basic literature with approches similar to what I derived here?

One step back to the onedimensional model

My parameters are $(p,v)\in R^2$, where $p$ indicates the onedimensional position and $v$ the velocity.

I used the energyfuctional $\int v^2 dt$ and the constraint $\dot{p}=v$.
The resulting ODE system is

$\ddot{x}_1=\dot{v}$

$\ddot{x}_2=0$

I didn't find a solution for the boundary values $(0,1)$ and $(1,1)$.

And a new question araised. Maybe I should not assume that I get a continuous solustion for all my model parameters?

答:
with the key words chuck gave me I found an article of David Anisi about "Optimal motion control of a ground vehicle".

There he describes an algorithm using the Hamilton to solve these kind of optimal control problems. Chuck was right that I had to add parameters for linear as well as angular velocity. Therefore my constraints are

$\dot{p_1}=v cos(\phi)$

$\dot{p_2}=v sin(\phi)$

$\dot{p_3}=w$

The linear velocity $v$ and the angular velocity $w$ are not part of the parametrisation but control variables.
The function $L$ simplifies to $L=v^2+w^2$. The right hand sides of the constraints are abreviated with $f$.

The Algorithm is:

1) define $H(x,v,w,\lambda):=-L+\lambda f$

2) find the maximal argument $\bar{v}$ $\bar{w}$ s.t. H is maximal.

3) the derivations of $H(x,\bar{v},\bar{w},\lambda)$ with respect to $\lambda$ define the derivatives of $x$ and the negative derivations of $H(x,\bar{v},\bar{w},\lambda)$ with respect to $x$ define the derivatives of $\lambda$.

4) this ode system can be solved with the shooting method

Title: motion model for forward movement


问:
Controller Design using Webots!
I am trying to work on a Digital Twin of a Physical Robot which is used at my uni. I made a rough model of the robot using Webots (Open source). I need to design certain controllers aiming at the Tilt, Heading, Velocity control of the robot. Can anyone explain to me the implementation & the initial steps for designing the control part using Webots? </p>

答:
Since you already have controller code written for the physical robot, I recommend creating a set of adapters so you can run the same code in Webots, instead of rewriting everything from scratch.

The Webots User Guide provides extensive guidance on how to setup and interface with the platform. In particular I recommend taking a look into the chapters on how to setup MATLAB language support and the Webots MATLAB API. You'll probably also want to go through the tutorials, especially the one about controllers. Notice that MATLAB code snippets are provided, but you may have to click the corresponding button in the code window to visualize it:

Title: Controller Design using Webots!


问:
Transform timestamped messages recorded in a bag file using tf messages
I have a .bag which contains recorded messages on topics /topic1 and /topic2. The messages have /world as frame_id, so both of the messages associated with these topics are stamped, i.e. they have a header.

The same .bag file also contains recorded messages on the topic /tf (of type tf2_msgs/TFMessage). These transform messages have the frame_id set to /world and the child_frame_id set to the local frames associated with the IMUs from which the messages are being sent over respectively topic /topic1 and /topic2.

Now, I need the messages sent over the /topic1 and /topic2 to be converted to their corresponding local frame (i.e. the child frame or child_frame_id ) from the (fixed) frame /world. Since both the /tf messages and the messages of the topics /topic1 and /topic2 are stamped, I thought we could do this without much trouble, but I'm not sure since I'm very new to ROS.

I've looked around for various solutions, but I didn't find an exact solution for my problem, maybe because I didn't recognize it as such, given my limited knowledge of ROS, as I said.

I would appreciate a step by step description of the approach and, if you don't want to write a full solution with code (preferably in Python), at least point me to the similar examples. Please, do not suggest me to read the tutorials of /tf, I've partially done it, and it didn't help much.

答:
In general terms, transforms between coordinate frames in ROS are achieved through the tf API. Strictly speaking we should actually use tf2, but since its documentation still has some catch up to do you might want to stick to tf for the time being.

The Python tf API makes it easy to convert geometric messages between coordinate frames. Following the scenario you outlined, converting IMU data from global to local coordinate frames could be done as below:

```<code>import rospy
import tf

import sensor_msgs.msg
import geometry_msgs.msg

class IMUListener(object):
    def __init__(self):
        self.tf_listener = tf.TransformListener()
        self.global_frame = rospy.get_param('~global_frame', 'world')
        self.subscriber = rospy.Subscriber('imu', sensor_msgs.msg.Imu, self.callback, queue_size=1)

    def callback(self, imu):
        global_frame = self.global_frame
        local_frame = imu.header.frame_id

        if not (self.tf.frameExists(global_frame) and self.tf.frameExists(local_frame)):
            rospy.logerr('Could not transform between frames "%s" and "%s"' % (global_frame, local_frame))
            return

        # Build a stamped quaternion message containing the IMU orientation readings,
        # timestamp and source reference frame (presumed to be the global reference frame).
        reading = geometry_msgs.msg.QuaternionStamped()
        reading.header.seq = imu.header.seq
        reading.header.stamp = imu.header.stamp
        reading.header.frame_id = global_frame
        reading.quaternion = imu.orientation

        # Convert the input quaternion from its source frame (taken from header.frame_id)
        # to the given target frame, using the transform available at time header.stamp.
        transformed = self.tf_listener.transformQuaternion(local_frame, reading)

        print transformed
</code>```

This code assumes that your problem is that even though IMU messages are assigned the sensor's frame id, the actual readings are relative to the global frame, and therefore you need a way to convert them to the right reference. It uses a tf.TransformListener object to listen to messages in the /tf topic and extract time-stamped transforms between coordinate frames. The method transformQuaternion() transforms the input QuaternionStamped message from its assigned header.frame_id reference frame to the target frame, using the transform between source and target frames that was in effect at time header.stamp.

Body:
In general terms, transforms between coordinate frames in ROS are achieved through the tf API. Strictly speaking we should actually use tf2, but since its documentation still has some catch up to do you might want to stick to tf for the time being.

The Python tf API makes it easy to convert geometric messages between coordinate frames. Following the scenario you outlined, converting IMU data from global to local coordinate frames could be done as below:

import rospy
import tf

import sensor_msgs.msg
import geometry_msgs.msg

class IMUListener(object):
    def __init__(self):
        self.tf_listener = tf.TransformListener()
        self.global_frame = rospy.get_param('~global_frame', 'world')
        self.subscriber = rospy.Subscriber('imu', sensor_msgs.msg.Imu, self.callback, queue_size=1)

    def callback(self, imu):
        global_frame = self.global_frame
        local_frame = imu.header.frame_id

        if not (self.tf.frameExists(global_frame) and self.tf.frameExists(local_frame)):
            rospy.logerr('Could not transform between frames "%s" and "%s"' % (global_frame, local_frame))
            return

        # Build a stamped quaternion message containing the IMU orientation readings,
        # timestamp and source reference frame (presumed to be the global reference frame).
        reading = geometry_msgs.msg.QuaternionStamped()
        reading.header.seq = imu.header.seq
        reading.header.stamp = imu.header.stamp
        reading.header.frame_id = global_frame
        reading.quaternion = imu.orientation

        # Convert the input quaternion from its source frame (taken from header.frame_id)
        # to the given target frame, using the transform available at time header.stamp.
        transformed = self.tf_listener.transformQuaternion(local_frame, reading)

        print transformed

This code assumes that your problem is that even though IMU messages are assigned the sensor's frame id, the actual readings are relative to the global frame, and therefore you need a way to convert them to the right reference. It uses a tf.TransformListener object to listen to messages in the /tf topic and extract time-stamped transforms between coordinate frames. The method transformQuaternion() transforms the input QuaternionStamped message from its assigned header.frame_id reference frame to the target frame, using the transform between source and target frames that was in effect at time header.stamp.


问:
Open source implementations for GPS+IMU sensor fusion?
Are there any Open source implementations of GPS+IMU sensor fusion (loosely coupled; i.e. using GPS module output and 9 degree of freedom IMU sensors)? -- kalman filtering based or otherwise.

I did find some open source implementations of IMU sensor fusion that merge accel/gyro/magneto to provide the raw-pitch-yaw, but haven't found anything that includes GPS data to provide filtered location and speed info.

答:
A followup on holmeski's reply.

It seems those pages have been taken down.
I found the old webpages on the 'Way Back Machine'.

Pixhawk Attitude Estimator (EKF)

Pixhawk ekf_att_pos_estimator (Application)


问:
What are the notable limitations on using Java with Mindstorms NXT 2.0?
I'm a long time Java developer who is starting to learn on the Lego Mindstorms NXT 2.0. Are there any limitations to using the Java API? Which language is the most robust on the platform?

I found a post, Which programming language should I use with the NXT? which mentions many of the alternatives. The answer is helpful, but doesn't mention the different languages' limitations.

答:
A lot of the different options with regards to language are listed on the NXT wiki page http://en.wikipedia.org/wiki/Lego_Mindstorms_NXT_2.0.

NXT-G NXT-G is the programming software included in the
standard base kit. It is based on LabVIEW graphical programming. It
features an interactive drag-and-drop environment. LabVIEW
Toolkit[edit] NXT-G is powered by LabVIEW, an industry standard in
programming. Created by National Instruments, LabVIEW uses data flow
programming to create a virtual instrument. To allow for more
advanced programming, in the graphical sense, National Instruments
released a Toolkit for the NXT. Version 1.0 came out in December
2006 Since its release, several bugs have been found and new sensors have been created. While the toolkit does allow for the creation of new sensors, National Instruments has yet to formally release an update

Lego::NXT Lego::NXT provides an API between Perl and
NXT.

Ada A port of GNAT is available for the NXT. It requires
nxtOSEK to run. The port includes Ada bindings to the NXT hardware
and nxtOSEK.

Next Byte Codes & Not eXactly C Next Byte Codes
(NBC) is a simple open-source language with an assembly language
syntax that can be used to program the NXT brick. Not eXactly C (NXC)
is a high level open-source language, similar to C, built on top
of the NBC compiler. It can also be used to program the NXT brick.
NXC is basically NQC for the NXT. It is the most widely used
third-party programming language.

ROBOTC ROBOTC is an
Integrated development environment targeted towards students that is
used to program and control LEGO NXT, VEX, RCX, and Arduino robots
using a programming language based on the C programming language.

RoboMind RoboMind is an educational programming environment
that offers a concise scripting language for programming a simulated
robot. These internationalized scripts can, however, also directly be
exported to Lego Mindstorms robots. It does not require custom
firmware in order to run.

NXTGCC NXTGCC is a GCC toolchain for
programming the NXT firmware in C. URBI[edit] URBI is a parallel and
event-driven language, with interfaces to C++/Java and Matlab. It
also has a component architecture (UObject) for distributed
computation. Urbi is compatible with many robots, including Nao (cf
Robocup), Bioloid or Aibo.

leJOS NXT leJOS NXT is a high
level open source language based on Java that uses custom firmware
developed by the leJOS team.

nxtOSEK To be able to write in
C (programming language)/C++, nxtOSEK can be used, but that requires
custom firmware too.

MATLAB and Simulink MATLAB is a
high-level programming language for numerical computing, data
acquisition and analysis. It can be used to control LEGO NXT robots
over a Bluetooth serial port (serial port communication is part of
the base functionality of MATLAB) or via a USB connection; for
example using the RWTH - Mindstorms NXT Toolbox (free & open-source).
Simulink is a MATLAB-based environment for modeling and simulating
dynamic systems. Using Simulink, a user can design control
algorithms, automatically generate C code for those algorithms, and
download the compiled code onto the LEGO NXT. MATLAB and Simulink
code for NXT programming is freely available.

Lua pbLua is an
implementation of the Lua programming language, a general purpose
scripting language, for Lego Mindstorms. FLL

NXT Navigation FLL
Nxt Navigation An open source program to help navigation on the FLL
competition table. Uses NXT-G and .txt files to write programs.

ruby-nxt ruby-nxt is a library to program the NXT for the Ruby
programming language. Unlike the other languages for the NXT the code
isn't compiled to a binary file. Instead the code is directly
transmitted to the NXT via a bluetooth connection. This method of
execution is significantly slower than executing compiled code
directly. Robotics.

NXT Robotics.NXT is a Haskell interface to
NXT over Bluetooth. It supports direct commands, messages and many
sensors (also unofficial). It has also support for a simple
message-based control of a NXT brick via remotely executed program
(basic NXC code included).

As previously mentioned the chart in  http://teamhassenplug.org/NXT/NXTSoftware.html is a good comparison.

Which language is the most robust on the platform?

Although I agree that the question is far too ambiguous, after using NXT-G, Matlab, Labview and a number of the other interfaces, I have found that the BricxCC IDE and the NXC is very easy to use with great contextual help and a lot of examples. It allows a lot more programming freedom that the visual based solutions do not offer. I have not attempted to use the higher level programming languages such as Java and C++ because most of the applications that I have been using would not have benefited from the advanced functions. If you are wanting these advanced functions is NXT the right hardware?

One might also like to know (1) which (if any) of these alternatives supports hard real-time systems

This post for the LeJOS discuses this with regards to Java: http://www.lejos.org/forum/viewtopic.php?f=18&t=4619 :- "The NXT firmware switches thread contexts every 1ms. Also, the scheduler of the NXT firmware is much more predictable. For example, a thread with high priority would be preferred by the scheduler over any thread with lower priority. So high priority threads could be pretty sure to be scheduled as soon as possible. The motor regulation was typically running as a high priority thread. But as you already guessed, the NXT firmware was no realtime system either. Threads with the same priority are served round-robin. Oh and once in a while, the garbage collector will halt the whole JVM. This is always true for the NXT. But the Oracle JVM used on the EV3 uses concurrent garbage collectors. However, in the worst case, even those fall back to halting the whole JVM. The trick to avoid that is to reuse object, arrays, and such stuff as far as possible in performance critical code paths."

how much memory on the NXT is left over for my "user-level" programs and data after the language-support infrastructure libraries are loaded

This post for the LeJOS discuses this with regards to Java: http://www.lejos.org/nxt/nxj/tutorial/AdvancedTopics/UnderstandingFilesLCPMemTools.htm

"The NXT has 256kb of flash memory. A fixed section at the start of the flash memory is allocated to the system. It is used to hold the firmware, followed by the startup menu. The rest of this system area is unused. The size of the system area varies between releases.

The firmware is written in C, with some ARM assembly language. The startup menu is written in Java (in the startup project in SVN).

Flash memory is read and written in 256-byte pages. The first page after the system area is used for persistent system settings administered by the startup menu.

The rest of the flash memory is used for the user file system. The first two pages hold the file table (directory), and the rest of the pages hold user files. Files are held as a contiguous set of bytes – i.e they use a single range of page numbers with no gaps. This allows a file to be addressed as a region of memory."

do any of these alternatives support interrupt handlers

One way of programming interrupt handlers on the NXT is to program at a lower level: http://www.tau.ac.il/~stoledo/lego/nxt-native/

"It's pretty easy to get started. You need two tools: the GNU development tools for ARM processors, and some way to download the resulting programs to the NXT. I use nexttool to download programs to the NXT, but I suppose that you could use NXT-G as well. There are several distributions of the GNU tools for ARM around. I usually use a distribution called WinARM, which is for windows; GNUARM and YAGARTO are two other options (I have used GNUARM on Linux)."


问:
Difference between SLAM and Localization
What are the differences between SLAM and Localization if you have a known map? How does the position probability update differ between the two?

In particular I'm curious on if localization is a fundamentally easier problem give you have map.

I have a virtual environment with a simulated LIDAR sensor and a known map. I want to try implementing localization but I'm not completely sure how to do it - you can do IPCM over the whole space but this is a very poor idea if you have a strong prior on where the robot started a sequence of sensor values/actions up until your current location.

答:
There's one point to add:

When you localize a vehicle in a pre-built map you assume that the map is static or at least the majority of the map hasn't changed which means that the changes will minimally affect your pose estimate


问:
Unable to find my robot with an error
This question and the docs pointed me to $GAZEBO_MODEL_PATH as being the environment variable to change to include models in a gazebo world. However, I am getting an error.

This is my current tree structure:

```<code>.
├── CMakeLists.txt
├── model
│   └── robot
│       ├── model.config
│       └── model.sdf
├── script
│   └── hello.cpp
└── worlds
    ├── empty.world
    └── myworld
</code>```

My GAZEBO_MODEL_PATH is:

```<code>$ $ echo $GAZEBO_MODEL_PATH
:/home/self/workspace/build_my_world/model/robot:
</code>```

But when I run gazebo I get an error.

```<code>$ gazebo worlds/myworld
Error [parser.cc:652] Could not find model.config or manifest.xml for the model
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
</code>```

This is what I have in myworld file:

```<code>   1 <sdf version='1.6'>
   2   <world name='default'>
   3
   4     <include>
   5       <pose frame=''>0 0 30 0 0 0</pose>
   6       <uri>model://model</uri>
   7     </include>
   8
</code>```

The final problem is that even if I remove the model in the world file, entering gazebo doesn't launch the application. There's NO output either.

答:
First, you should add to $GAZEBO_MODEL_PATH the base directory of your model collection, /home/self/workspace/build_my_world/model.

Second, you should refer to your model by the name of its subdirectory, robot in this case.

Third, you should close the <world> and <sdf> tags at the end of the file.

It's also advisable to add the sun and ground_plane models to your world.

So in summary, what you should have is the following:

```<code><span class="math-container">$ echo $</span>GAZEBO_MODEL_PATH
:/home/self/workspace/build_my_world/model
</code>```

<?xml version="1.0" encoding="utf-8"?>
<sdf version='1.6'>
  <world name='default'>
    <include>
      <uri>model://sun</uri>
    </include>
    <include>
      <uri>model://ground_plane</uri>
    </include>
    <include>
      <pose frame=''>0 0 0 0 0 0</pose>
      <uri>model://robot</uri>
    </include>
  </world>
</sdf>
```

Title: Unable to find my robot with an error

Body:
First, you should add to $GAZEBO_MODEL_PATH the base directory of your model collection, /home/self/workspace/build_my_world/model.

Second, you should refer to your model by the name of its subdirectory, robot in this case.

Third, you should close the <world> and <sdf> tags at the end of the file.

It's also advisable to add the sun and ground_plane models to your world.

So in summary, what you should have is the following:

$ echo $GAZEBO_MODEL_PATH
:/home/self/workspace/build_my_world/model

<?xml version="1.0" encoding="utf-8"?>
<sdf version='1.6'>
  <world name='default'>
    <include>
      <uri>model://sun</uri>
    </include>
    <include>
      <uri>model://ground_plane</uri>
    </include>
    <include>
      <pose frame=''>0 0 0 0 0 0</pose>
      <uri>model://robot</uri>
    </include>
  </world>
</sdf>


问:
Sensors to detect targets in low visibility environment
I want to know what type of sensor hardware I need to allow detection of moving targets (20mm - 200mm size range) in heavily murky water, where visibility range of typical camera can be limited to 0.5 meter and less.The operational range of the sensor can be not more than 10-20 meters. The goal is to detect organic bodies,estimate their size and count them using computer vision software like OpenCV. I am software guy and looking for an advice for the hardware part of this task.</p>

答:
As you're probably aware, the sensor solution you're looking for is pretty much a research subject in itself. There have been experiments using infrared time-of-flight cameras in murky water, and there are a few devices commercially available, but they're most certainly expensive and will require some engineering work to be adapted for a robotics application.

A relatively simpler option is to buy a set of underwater infrared cameras and implement range estimation in software, e.g. using OpenCV as you mentioned. Another alternative approach is to use sonar: there are 2D and 3D sonars commercially available, or you could try to build your own.


问:
what is ultrasonic based slam
i am confused about SLAM implementation, and i need your advise to organize my mind.
Fist let me say that i have to generate 2D map, what is in this case the SLAM input? is it like (x1,y1),(x2,y2)...(xn,yn)?
Second, if we have to generate 3D map, what is the real input of slam, Does it is (x1,y1,z1)..?

Many SLAM implementations use LIDAR, and i have to know the data form that it provides, but really i have no LIDAR, i have to use ultrasonic sensors to map environment, how much does this speak seem logical ?
If  we generate a 3d surrounding points from specific ultrasonic sensors configuration, does these 3d points enough to build 3D map?

答:
usually ultrasonic sensors are not precise

Using an ultrasonic sensor will not very good for large environments. It is very imprecise and SLAM algorithms accumulate error intrinsically it my be enough for simple indoor environments but you'd better use a lidar or a camera (cameras are cheap)

Title: what is ultrasonic based slam


问:
Do self-driving robots use object-level SLAM?
How do self-driving bots usually deal with transient objects, e.g., parked cars on the side of roads when they can come and go? These aren't moving objects at the time of capture, but they do move at a later time. Is it common to run a CNN to detect static/dynamic objects prior to feature extraction? It's certainly much more computationally expensive, but otherwise how are dynamic objects dealt with or filtered out?</p>

答:
The answer of @C.O Park is pretty good.
I will just add that when you SLAM, either you are doing it to localize the vehicle and thus the map is a consequence, in this case using transient objects which are stationary at the moment is good because they will help with the scan matching.

If you are SLAMing to localize the vehicle currently and then use the map later on, the transient objects are useful for the current run, however they may not be there for the following runs. In this case they might affect the results of the scan matching for subsequent runs. In this case it might be interesting to filter such objects to improve the quality of the generated map as we suppose that the map generated contains static objects useful for localization.


问:
Is it possible to implement VSLAM on Arduino?
If not, then which microcontroller will be suitable? </p>

答:
If it is a real-time SLAM for some real application I would say yes, it is impossible. You won't be able to process 30 fps on your arduino
go for the latest Raspberry or Odroid or a similar SBC</p>


问:
How do I evaluate the minimum requirements of the processor and camera for a visual SLAM robot?
I would like to build a visual SLAM robot (just for self-learning purpose) but I get frustrated how I know which processor and camera should be used for visual SLAM.

First, for the processor, I have seen three articles, which shows different systems are used for implementing their SLAM algorithm:

Implementing SLAM algorithm (however it uses ultrasonic sensor rather than visual sensor) in Raspberry Pi (processing power is only 700 MHz) in Implementing Odometry and SLAM Algorithms on a Raspberry Pi to Drive a Rover

I have also seen that Boston Dynamics use Pentium CPU, PC104 stack and QNX OS for their Big Dog project, BigDog Overview
November 22, 2008

Then, I also found a project uses a modern XILINX Zynq-7020 System-on-Chip (a device that combines FPGA resources with a dual ARM Cortex-A9 on
a single chip), for a Synchronized Visual-Inertial Sensor System, in A synchronized visual-inertial sensor system with FPGA pre-processing for accurate real-time SLAM

But after reading those, I have no clue how they end up with those decisions to use those kinds of processors, stacks or even OSes for their project. Is there a mathematical way, or a general practice, to evaluate the minimum requirement of the system (as cheap and as power efficient as possible) for an algorithm to run?

If not, how could I know what processor or system I have to prepare for a visual SLAM robot? If there is no simple answer, it is also cool if you can recommend something I could read to have a good start.

Secondly, I also cannot find clear information which camera I should use for a visual SLAM robot. I also have no idea how they evaluate the minimum requirement of the camera. I found a lot of papers saying they use RGB-D camera but when I Google to find one, there are very few commercially available. The one I found is Xtion Pro Live from ASUS Global (for $170). Are there any practice I can choose a suitable camera system for visual SLAM too?

答:
Depending on the camera you are using, your SLAM algorithm has to be adapted.
You can simply use a RGB camera (webcam-like camera), it is not necessary that the camera is an RGB-D camera. Nevertheless, using only an RGB cam you'll be doing a bearing only SLAM.

I recommed you stay away from ultrasonic sensors for SLAM, they are not precise. They were used in the past but with LIDARs getting cheaper and more accessible it is a much better choice.

Concerning the CPU, if you're doing a VSLAM and you're just grabbing some opensource code try to use a CPU with similar processing power. Otherwise you can try your algorithm (if you're writing your own code) on a pre-registered dataset offline on any PC and at the end if you cannot manage to run it in real-time then you should opt for a faster CPU.
If you were comfortable with GPU programming try to accelerate your code in VSLAM you will end up doing a lot of image processing.

Finally, it is true that the performance depends on the algorithm developed, however, keep in mind that a major factor is the quantity of data you are throwing at it per unit of time. Example with LIDAR-based SLAM processing data coming from a velodyne-16 layers was a lot easier than processing data coming from velodyne-64 layers or 128 layers. The number of points it will generate per second is much higher. One approach would be to down-sample the data acquired.

In case of the camera, you should take into account the size of the processed frame, and the how many frames you're getting per second.

I recommend you start testing offline on any available PC and then estimate your needs based on your algorithms & sensor combination.


问:
Matlab Simulation using Webots!

I am trying to run this youbot ( sample world) from webots, where the controller is implemented in MATLAB, on running the code it pops out the following error seen in the picture attached. I have also however installed the Support for MinGW-w64 C/C++ Compiler, though it still shows the same error. Could someone help a bit? The error is as follows:

```<code>Warning: Name is nonexistent or not a directory: C:\Program Files\Webots\lib\matlab
> In path (line 109)
  In addpath (line 86)
  In launcher (line 23)
The MATLAB "MinGW-w64 C/C++ Compiler" addon is not installed, please install it from: https://fr.mathworks.com/matlabcentral/fileexchange/52848-matlab-support-for-mingw-w64-c-c-compiler
Waiting up to 5 seconds for C:\Users\asus\AppData\Local\Temp\webots_matlab_lock to be deleted by another MATLAB instance.
Deleting C:\Users\asus\AppData\Local\Temp\webots_matlab_lock...
Creating: C:\Users\asus\AppData\Local\Temp\protofile_matlab_2018b_webots_R2020a_revision_1.m
Load Library failed.
Error using loadlibrary
Could not find file allincludes.h.

Error in loadlibrary

Error in launcher (line 74)
      loadlibrary( ...
<span class="math-container">```
```

答:
You've got two serious problems clearly stated in your error message:

Warning: Name is nonexistent or not a directory: C:\Program Files\Webots\lib\matlab

And

The MATLAB "MinGW-w64 C/C++ Compiler" addon is not installed, please install it

Have you fixed these problems? It looks like you don't have the Webots library installed and you also don't have a compiler installed. Nothing is going to work and we can't provide any other assistance until you get these resolved (and resolving them may fix everything).

Title: Matlab Simulation using Webots!


问:
Which math books would help in learning SLAM systems?
Recently I started studying papers on SLAM systems by Durrant-Whyte for my research and I'm finding some difficulties in the math (matrices and probability) that is tackled in these papers.

Which math books/topics would you recommend me to go over before continuing with other papers?

答: The Probabilistic Robotics written by Thuran and his colleagues was completely helpful for me. Also, you can follow one of their colleague videos on youtube for SLAM. </p>


问:
Problems fixing frames to a 6 degrees freedom robot
Hello Robotics Stack Exchange. I am trying to put frames to this robot so I can make forward and inverse kinematics. However, when I use the DH parameters I do not get the same results as roboDK (a robot visualisation program).

Here is said robot.

Here are my reasoning for putting the frames there, showing my reasoning I believe will show my mistakes to those more knowledgable than me hopefully.

-1: First i identify the joint axis. The second joint axis is displaced 25 mm to the side according to the data sheet so that's why its moved in the illustration.

0: Then I put a base frame. The base frame I chose to be exactly as the first frame since i want zeros in my data sheet to give me fewer variables when I need to make inverse kinematics later on.

1: Then I put frame one in. I put the z direction around the axis of rotation. Then I put the frame one next to axis 2 because i want the common normal. For that they have to next to each other so it can be a line with 90 degrees. When they are next to each other x_1 is pointing to the common perpendicular.

2: Frame 2 is there because the next link is parallel with it. Now z_2 is pointing into the page and x_2 is pointing towards the common perpendicular.

3: Same logic as in 2.

4: Frame four physically is at joint 4 but the origin is at frame 5. That is because frame 4 intersects frame 5 at the z axis. X_5 points toward the common normal.

5: Now z_5 and z_6 do intersect but we chose that it has to be where frame 4 is because they already intersect. So the origin is at the same place as 5.

6: Z follows the axis of rotation. The x_6 axis looks down because that's what the roboDK said it looks like. We want our calculations to match with that program and the last frame is also arbitrary because it does not have any link after to compare after it.

This was my reasoning. I hope someone can spot my mistake in my reasoning because I am sure I can do the DH-parameters from the frame description so the problems must be with the frames themselves. Thank you.

The data is here if it is needed: https://www.kuka.com/-/media/kuka-downloads/imported/6b77eecacfe542d3b736af377562ecaa/0000210361_en.pdf

答: I have studied manipulators kinematic by Craig book "Intro to robotics". Based on this book you must consider frame 0 and 1 co-incident. Look at this much similar example in this book:


答:
Probability and statistics.  Stochastic signal processing.  Estimation and Detection theory (I highly recommend that you find a class that uses Harry VanTrees's book and that offers office hours, that you enroll, and study, and that you reserve lots of time in your schedule to take it -- if you can learn that stuff by reading the book you're somewhere in the 99.9th percentile).

"Optimal State Estimation" by Dan Simon is a really good Kalman filter book, but if you find yourself just reading the words and not getting the math, then you need to put it down and go study multivariate probability for a while.

Matrix math has been mentioned -- but you can know the matrix math up the wazoo, and all it does is make it quicker to formulate the problems.  Without the knowledge of probability & statistics part, the matrix math will just help you screw up quicker, and with more elan.

Title: Which math books would help in learning SLAM systems?

Body:
Recently I started studying papers on SLAM systems by Durrant-Whyte for my research and I'm finding some difficulties in the math (matrices and probability) that is tackled in these papers.

Which math books/topics would you recommend me to go over before continuing with other papers?


答:
The correct way to wire the pins out on a L293D is as follows:

Pin 1 & 9 are enable pins should be tied to +5 if pulled low the outputs will be turned off regardless of the input states.

Pins 4,5, 13, 12 are ground pins and ideally connected to the micro-controller ground connection.

Pin2, Pin7, Pin10 and Pin15 are logic input pins. These are control pins and should be connected to micro-controller pins.

Pins 2 & 7 control the left motor and 10 & 15 control the right motor.
Pin3, Pin6, Pin11, and Pin14 are output pins. Tie Pin3 and Pin6 to the first motor, Pin11 and Pin14 to second motor.

Pin 16 enables the IC should be connected to a +5v Regulated Supply
Pin 8 powers the motors

More details:
http://www.robotplatform.com/howto/L293/motor_driver_1.html

Title: Odd L293D behavior: Pin 16 seems to act as enable

Body:
I have a chip that is labeled L293D with a small 'ST' logo, which does not behave like I believe a L239D should:

I have the chip on a breadboard with pins 4,5,12 and 13 connected to the ground rail. The positive rail gets 6V from a battery pack.
A motor is connected to pins 3 and 6.
Pin 2 is connected to the positive rail.

Now, when I connect pin 1 (enable 1) to the positive rail, the motor spins, which is expected.

The weird thing is that if I connect pin 16 instead of pin 1 to positive, the motor spins, as well.

Also, with the motor connected to 11 and 14, and 15 connected to positive, the motor spins if I connect pin 1 or pin 16 to positive, but not if I connect pin 9 (which should be the enable pin for that side).

Does any of that make sense? Am I missing something here?

Thanks!


问:
Control a servo (two position 180-degree swing) with an On/Off switch without microcontrollers
For my application, I need to be able to control a servo with a simple on/off switch. When it's off (pulled LOW), I need to servo to go at -90 degrees and stay there - possibly for a prolonged time. When it's on (pulled HIGH), I need the servo to go to +90 degree and stay there - possibly for a prolonged time.

I'd like to minimize the control logic footprint and complexity, and also to minimize standby power consumption in servo jitter in both positions. So ideally I'd want to get by without Arduino at all - with some kind of a simple analog / IC comparator logic based on servo's internal potentiometer, and direct control of motor wires.

Rotation precision is not important, so +90 can be "anything above +85 degrees", and -90 can be "anything below -85 degrees".

I won't be able to fit external end-switches to the mechanical application and want to rely on servo's internals only. I have a bunch of no-name SG90 lying around (which are a perfect fit size-wise and torque-wise) - but I would not be against buying a different kind of a "servo-like" actuator that would facilitate a simpler conversion.

Can someone suggest where to look for the solution schematics - and whether it might exist as a pre-made IC?

I found a Servo Trigger board: https://www.sparkfun.com/products/13118?_ga=2.160099069.1169016740.1587923297-1103320110.1587923297 which at a first glance does what I need ad is easy to use. But it is still an over-complicated (internally) solution with a constantly running microcontroller to produce PWM pulses that are to be decoded on the servo side. I guess a much simpler (and less idle power draw) solution would be possible based on a direct hook-up to servo's potentiometer and analog comparator logic, but I can't find anything.

Will appreciate any advice.

Thanks!

答:
Make a 555 servo exerciser, and replace the position pot with your switch (or use a pair of position pots and switch between them).

Here's your starting point: http://www.seattlerobotics.org/encoder/200210/servoex/ServoExcerciser.htm


问:
Kinematic isotropy equal 0
I am developing a robot arm and after calculating the jacobian matrix and then the kinematic isotropy through:

I get a kinematic isotropy of zero, due to four zero eigenvalues in my jacobian. What does this mean for the smoothnes of my workspace? I have read that the closer the kinematic isotropy is to 1, the more isotropic the manipulability ellipsoid. Does a kinematic isotropy of zero imply no manipulability?

答:
If you look at the formula, the only way for it to equal zero is if the determinant of the Jacobian equals zero.  This tells you that the device is in a singular configuration.

With four eigenvalues zero, are you sure the robot is able to span the workspace in any pose?

Title: Kinematic isotropy equal 0


问:
PID controller issue
Recently I've successfully implemented PID controller for my robot's moving motors. Now the system can automatically adjust it's speed depending on different situations: increase it if something blocks robot's movement, decrease it if robot moves to fast and so on and so on. But with it system gained specific feature: after stop of the movement (sending zero speed from the joystick) integral error doesn't go to zero, it stays active resulting some signal on the output of pid controller. Check the diagrams:

On the upper diagram you can see 4 variables changing with time:

'LeftWheel.target_ticks_speed' - speed which is sent from joystick

'actual_speed' - measured on the run

'speed_error' - difference between joystick speed and actual

'calc_pwm_value.summary' - output of pid controller which goes directly on motor

On the below diagram there are 3 components of the pid controller: proportional, integral and derivative.

As you can see at the time stamp 48.600 'speed_error' goes to zero but integral error and summary of pid controller save some value.

Does anybody encountered issues like that in their pid controller implementations? I'm just not sure is math model should be improved somehow? Or speed setting mechanism should be reworked? Any comments or thougths would be appreciated.

Posting here C code of pid controller math model:

#include "pid.h"

#define K_P 1.0f
#define K_I 0.2f
#define K_D 0.5f

/* Used for testing in STM studio*/
/*float sum_prop = 0;
float sum_int = 0;
float sum_diff = 0;*/

static inline float prop_compute(float error)
{
    return error * K_P;
}

static inline float int_compute(float error, float* int_error)
{
    float sum = 0;
    sum = *int_error + (K_I * error);
    *int_error = sum;
    return sum;
}

static inline float diff_compute(float error, float* der_error)
{
    float sum = 0;
    sum = K_D * (error - *der_error);
    *der_error = error;
    return sum;
}

void pid_calculate(int16_t error, pid_entity* process)
{
    /* Used for testing in STM studio*/
    /*sum_prop = prop_compute(error);
    sum_int = int_compute(error);
    sum_diff = diff_compute(error);
    result = sum_prop + sum_int + sum_diff;*/

    process->prop_calc = prop_compute(error);
    process->integral_calc = int_compute(error, &(process->integral_error));
    process->derivative_calc = diff_compute(error, &(process->derivative_error));

    process->summary = process->prop_calc + process->integral_calc + process->derivative_calc;
```

答:
You should only enable the integral term when the system is “close” to the desired state.  This is because all physical systems will lag the control input, and the integral term will continue to build due to this lag.   This leads to overshoot before finally settling at the final state.

Controllers I’ve developed turn on the $I$ gain when within $x$ counts of the final state, or after they are 90% to that state.  This decreases overshoot but still allows the $I$ term to eliminate steady-state offsets.  Some motor controllers will have a “settling” signal that you can use to turn on the $I$ gain.

Title: PID controller issue


问:
Bluetooth module HC-05 giving ERROR :(0)
I am working right now with Arduino UNO and HC-05 bluetooth module.I followed the instruction given on this link for wiring. So there are 2 mode of working with this HC-05 module

Simple serial communication

Working in AT command mode so as to change the parameters of HC-05 module

As long as I work in simple serial communication mode, everything works fine but when I tried to change the parameters of module, it didn't work out. For working in At command mode, PIN NO 34 of HC-05 module needs to be high which I had taken care of. Lately I found that in mu module they had knowingly not connected the Berg strip to PIN 34, so I connected the PIN directly, even though I am not able to change the parameters of module and when I write any command on COM port of arduino IDE, I get this response

```<code>Enter AT commands:
ERROR:(0)
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõÿýì¢^
ERROR:(0)
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõÿýì¢^
ERROR:(0)
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõÿýì¢^
ERROR:(0)
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõÿýì¢^
ERROR:(0)
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõÿýì¢^
ERROR:(0)
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõÿýì¢^
</code>```

I think that garbage is due to my code

Here is my code:

```<code>#include <SoftwareSerial.h>

SoftwareSerial BTSerial(10, 11); // RX | TX

void setup()
{
  pinMode(9, OUTPUT);
  digitalWrite(9, HIGH);
  Serial.begin(9600);
  Serial.println("Enter AT commands:");
  BTSerial.begin(38400);
}

void loop()
{
  uint8_t x;
  char CommandFromSerial[50]=" ";
  char ResponseFromBluetooth[50]= " ";

  if ((Serial.available())){
    if(Serial.available()>0){
      for(x=0;x<50;x++)
        CommandFromSerial[x]=Serial.read();
      BTSerial.println(CommandFromSerial);
    }
  }

  if ((BTSerial.available())){
    if(BTSerial.available()>0)
      for(x=0;x<50;x++)
        ResponseFromBluetooth[x]=BTSerial.read();
    Serial.println(ResponseFromBluetooth);
  }
}
</code>```

I am not able to figure out what I am doing wrong. I used this command on COM port
AT\r\n and many other commands but every time I get the same response.

Did I mess up with my bluetooth module unknowingly?

答:
Wouldn't have thought you have messed up your bluetooth module or it's a problem with your code; it could be the firmware loaded on the module.

I too have encountered problems getting those HC-05 "linvor" modules to respond to AT command set. If the only AT commands that module responds to is AT  and setting the name; then you have a slave module. These have been loaded with limited firmware which doesn't respond to other AT commands given.

You need the ones which are master's as they will respond to the other AT commands and have better firmware installed on them.

Found this out by trial and error as I have 2 modules which I was trying to configure so they paired up without user intervention and failing. I bought my modules on eBay from a seller with a ID for emailforyou which gave good information within the description; which informed me that in order to get each module to pair up you need a master & slave. I bought 2 surface mount masters but also opted to get a 6 pin (assembled) HC-06 Master/Slave module as well from the above seller.

Updated

```<code>#include <SoftwareSerial.h>

SoftwareSerial BTSerial(16, 17); // RX | TX

void setup()
{
  pinMode(11, OUTPUT);  // this pin will pull the HC-05 pin 34 (key pin) HIGH to switch module to AT mode
  digitalWrite(11, HIGH);
  Serial.begin(9600);
  Serial.println("Enter AT commands:");
  BTSerial.begin(9600);  // HC-05 default speed in AT command more
                         // was 38400 but changed it to 9600
}

void loop()
{

  // Keep reading from HC-05 and send to Arduino Serial Monitor
  if (BTSerial.available())
    Serial.write(BTSerial.read());

  // Keep reading from Arduino Serial Monitor and send to HC-05
  if (Serial.available())
    BTSerial.write(Serial.read());
}
</code>```

Body:
Wouldn't have thought you have messed up your bluetooth module or it's a problem with your code; it could be the firmware loaded on the module.

I too have encountered problems getting those HC-05 "linvor" modules to respond to AT command set. If the only AT commands that module responds to is AT  and setting the name; then you have a slave module. These have been loaded with limited firmware which doesn't respond to other AT commands given.

You need the ones which are master's as they will respond to the other AT commands and have better firmware installed on them.

Found this out by trial and error as I have 2 modules which I was trying to configure so they paired up without user intervention and failing. I bought my modules on eBay from a seller with a ID for emailforyou which gave good information within the description; which informed me that in order to get each module to pair up you need a master & slave. I bought 2 surface mount masters but also opted to get a 6 pin (assembled) HC-06 Master/Slave module as well from the above seller.

Updated

#include <SoftwareSerial.h>

SoftwareSerial BTSerial(16, 17); // RX | TX

void setup()
{
  pinMode(11, OUTPUT);  // this pin will pull the HC-05 pin 34 (key pin) HIGH to switch module to AT mode
  digitalWrite(11, HIGH);
  Serial.begin(9600);
  Serial.println("Enter AT commands:");
  BTSerial.begin(9600);  // HC-05 default speed in AT command more
                         // was 38400 but changed it to 9600
}

void loop()
{

  // Keep reading from HC-05 and send to Arduino Serial Monitor
  if (BTSerial.available())
    Serial.write(BTSerial.read());

  // Keep reading from Arduino Serial Monitor and send to HC-05
  if (Serial.available())
    BTSerial.write(Serial.read());
}


问:
What is the concepts of submaps in LIDAR based graph slam algorithms?
I have been reading some slam papers recently and many of the papers mention building and performing scan matching on submaps instead of individual poses. Does it mean that a submap is just a single vertex (pose) with its associated uncertainty or is it a combination of several poses. How do we maintain such sub maps with respect to g2o gtsam etc ? As far as I know we can build a pose graph with vertices and edges describing robot pose and perform incremental scan matching. Would be highly thankful for any explanation.

https://www.mathworks.com/help/nav/ug/perform-lidar-slam-using-3d-lidar-point-clouds.html

答:
The word is exactly as it sounds. It is a submap of a larger map. Essentially a large map is broken up into smaller submaps in order to improve the computational complexity.

In the reference you give the map is the accumulated pointcloud. This giant pointcloud is then broken up into smaller pointclouds(the submaps*).  These submaps are then used to facilitate loop closure. So rather than checking the current scan against the whole map, it will only check against the submaps.

At least in this case it looks like the submaps have nothing to do with the pose graph optimization. It is only used to identify loop closure candidates. However, in other papers like this it uses pose graph submaps. Again it is a larger pose graph broken up into smaller submap graphs in order to make the problem easier to solve.

So just to be clear:

Does it mean that a submap is just a single vertex (pose) with its associated uncertainty or is it a combination of several poses.

No. In this case a submap is just a smaller pointcloud.

How do we maintain such sub maps with respect to g2o gtsam etc

In this case the submap is solely there for identifying loop closure. This information is stored separate from your Pose graph.


问:
Finding the PID values for a vehicle control system
I'm trying to design a PID system for the longitudinal control of an autonomous vehicle. I figured out about most of it but I'm trying to figure out the Kp, Ki and Kd values. This is an illustration of what I'm working with:

So the PID controller outputs u, which is the acceleration value. However, I don't know how to find the Kp, Ki and Kd.

答:
Kp, Kd, Ki are called gains of the controller and can be found using manual tuning or via some techniques for example the Ziegler-Nichols method which is more precise.
And you can use different software for example MATLAB to achive the desired controller response and can calculate PID gains.
For more information on PID gains tuning, I would like to refer a previous answer, which will elaborate in detail:

What are good strategies for tuning PID loops?


答: In addition to the manual Ziegler-Nichols method on manual tuning, I wanted to point out that the dynamics of the throttle/brake might not be symmetric. In that case, the set of Kp, Ki, Kd working for throttle (acceleration), might not work for braking (deceleration). </p>

Title: Finding the PID values for a vehicle control system

Body:
I'm trying to design a PID system for the longitudinal control of an autonomous vehicle. I figured out about most of it but I'm trying to figure out the Kp, Ki and Kd values. This is an illustration of what I'm working with:

So the PID controller outputs u, which is the acceleration value. However, I don't know how to find the Kp, Ki and Kd.


问:
Controlling bot using video and image processing
I am going to start a project on controlling robots using hand gestures.
Though I have used MATLAB for this purpose earlier, I realized it is extremely slow for any practical real-time system.
I am currently planning to use OpenCV for this purpose.
I want suggestions on, if OpenCV is the best alternative, are there any other alternatives and if I use OpenCV, which language should I go for, C, C++ or Python?</p>

答:
If starting out with programming use C/C++ as most of the examples using OpenCV on the internet use that language but there are interfaces for many other languages. I.E. Java, Python, C++, C

More details: http://opencv.org/


问:
What and where is "the log file" for errors in ROS?
I ran the following and got an error with something that previously ran well (I was just missing the entire world though and not the robot). Something I did in the middle could be the problem.

```<code>$ roslaunch my_robot world.launch
RLException: [world.launch] is neither a launch file in package [my_robot] nor is [my_robot] a launch file name
The traceback for the exception was written to the log file
</code>```

However, the main question for now is what is this special log file? The error mentions it like there's only one and it is evident where it is. This question has a similar error but no answer. My question for now though, is where can I find this log file? And what what does RL stand for in RLException?

答:
tl;dr -

If you are using roslaunch, you can use the roslaunch-logs command to tell you the location of the log directory.

From the ROS wiki:

Output

There are four potential places a log message may end up, depending on the verbosity level:

stdout

DEBUG and INFO messages arrive on stdout if they are enabled. Note that this may not be sent to the screen depending on the value of the roslaunch/XML/node output parameter.

stderr

WARN, ERROR and FATAL messages arrive on stderr if they are enabled.

Node log file

Everything enabled goes into the log file. Your node's log file will be in ~/.ros/log unless you override it with the ROS_HOME or ROS_LOG_DIR environment variables. If you are using roslaunch, you can use the roslaunch-logs command to tell you the location of the log directory.

/rosout topic

Everything enabled is sent to the /rosout topic. Note that until the node is fully started, messages will not be sent, so you may not see initial messages.

Here is a table summarizing the above:

$$\begin{matrix}
\text{ }        & \text{Debug} & \text{Info} & \text{Warn} & \text{Error} & \text{Fatal} \\
\text{stdout}   & \text{X}     & \text{X}    & \text{ }    & \text{ }     & \text{ }     \\
\text{stderr}   & \text{ }     & \text{ }    & \text{X}    & \text{X}     & \text{X}     \\
\text{log file} & \text{X}     & \text{X}    & \text{X}    & \text{X}     & \text{X}     \\
\text{/rosout}  & \text{X}     & \text{X}    & \text{X}    & \text{X}     & \text{X}     \end{matrix}$$
  Also note that this table is different for rospy.

(emphasis added)


问:
EKF-SLAM what should the observation model be?
I am implementing an EKF algorithm for a drone localization, and while I was defining the observation model I got a bit confused.

This is my situation:
I have a drone which is able to give me the landmarks' pose in the drone's reference frame (it is a PoseStamped message).
In my implementation I have a state vector which contains not only the drone's pose, but also the landmarks' pose, all of them in the fixed reference frame (the world).

Now my question: what should observation model be in this case? I have this question because the landmarks' pose are given, so should the observation model project the estimated landmark pose to the drone's reference frame and in the innovation compute the error between the observed and the estimated poses?

To be a bit more clear:

My state vector is
$
\hat\mu = \begin{bmatrix} x_r & y_r & z_r & \phi_r & \theta_r & \psi_r & x_{m_i} & y_{m_i} & z_{m_i} & \phi_{m_i} & \theta_{m_i} & \psi_{m_i} \end{bmatrix}
$ where elements with $r$ represent the pose of the drone and $m_i$ the pose for landmark $i$, everything expressed in the fixed reference frame.

The observation at time $t$ is $z_t = \begin{bmatrix}x_{m_i}^L & y_{m_i}^L & z_{m_i}^L & \phi_{m_i}^L & \theta_{m_i}^L & \psi_{m_i}^L \end{bmatrix}$ in the drone's reference frame.

So, should the observation model produce the following $h(\hat\mu) = \begin{bmatrix}\hat{x}_{m_i}^L & \hat{y}_{m_i}^L & \hat{z}_{m_i}^L & \hat\phi_{m_i}^L & \hat\theta_{m_i}^L & \hat\psi_{m_i}^L \end{bmatrix}$ ?

Is my reasoning correct? Am I missing something?

Thanks in advance!

答: Since your state includes the position and orientation of the robot and the landmarks in the global frame, but your measurements are in the robot frame, like you said, the observation model will basically transform the pose estimate from the prediction step into the robot frame followed by addition of noise. Then you compute the innovation by finding the error between the actual measurement and that obtained from the measurement model (both of which are in the robot frame).</p>


问:
rostopic list not showing topic
When I use the rostopic list commands, the output is only returning /rosout & /rosout_agg. Although when I rosrun both the subscriber and the publisher python files, that contain my new topic, they can communicate no problem. A few questions here:

Does the rostopic list command list all the topics that are part of the catkin workspace?
At what point is this rostopic 'created'. In other words what command is responsible for rostopic list to generate the new topic that is created in the publisher?
Thanks!

答: you need to check rostopic list while the talker node is running</p>

Title: rostopic list not showing topic


问:
Invoking "cmake" failed
I am unable to solve this problem. I tried to run catkin_make command in catkin_ws directory</p>

```<code>yograj@yograj-Inspiron-5537:~/catkin_ws$ catkin_make
Base path: /home/yograj/catkin_ws
Source space: /home/yograj/catkin_ws/src
Build space: /home/yograj/catkin_ws/build
Devel space: /home/yograj/catkin_ws/devel
Install space: /home/yograj/catkin_ws/install
####
#### Running command: "cmake /home/yograj/catkin_ws/src -DCATKIN_DEVEL_PREFIX=/home/yograj/catkin_ws/devel -DCMAKE_INSTALL_PREFIX=/home/yograj/catkin_ws/install -G Unix Makefiles" in "/home/yograj/catkin_ws/build"
####
-- Using CATKIN_DEVEL_PREFIX: /home/yograj/catkin_ws/devel
-- Using CMAKE_PREFIX_PATH: /opt/ros/kinetic
-- This workspace overlays: /opt/ros/kinetic
-- Using PYTHON_EXECUTABLE: /home/yograj/anaconda2/bin/python
-- Using Debian Python package layout
-- Using empy: /usr/bin/empy
-- Using CATKIN_ENABLE_TESTING: ON
-- Call enable_testing()
-- Using CATKIN_TEST_RESULTS_DIR: /home/yograj/catkin_ws/build/test_results
-- Found gtest sources under '/usr/src/gtest': gtests will be built
-- Using Python nosetests: /usr/bin/nosetests-2.7
ImportError: "from catkin_pkg.package import parse_package" failed: No module named catkin_pkg.package
Make sure that you have installed "catkin_pkg", it is up to date and on the PYTHONPATH.
CMake Error at /opt/ros/kinetic/share/catkin/cmake/safe_execute_process.cmake:11 (message):
  execute_process(/home/yograj/anaconda2/bin/python
  "/opt/ros/kinetic/share/catkin/cmake/parse_package_xml.py"
  "/opt/ros/kinetic/share/catkin/cmake/../package.xml"
  "/home/yograj/catkin_ws/build/catkin/catkin_generated/version/package.cmake")
  returned error code 1
Call Stack (most recent call first):
  /opt/ros/kinetic/share/catkin/cmake/catkin_package_xml.cmake:74 (safe_execute_process)
  /opt/ros/kinetic/share/catkin/cmake/all.cmake:151 (_catkin_package_xml)
  /opt/ros/kinetic/share/catkin/cmake/catkinConfig.cmake:20 (include)
  CMakeLists.txt:52 (find_package)

-- Configuring incomplete, errors occurred!
See also "/home/yograj/catkin_ws/build/CMakeFiles/CMakeOutput.log".
See also "/home/yograj/catkin_ws/build/CMakeFiles/CMakeError.log".
Invoking "cmake" failed
</code>```

答:
catkin_create_pkg  [depend1] [depend2] [depend3]
- Just change the name of the package.There are some keywords that should not be used since it confuse the compiler. I first use  and I had an error after compiling(catkin_make). I changed it to  and it worked. Hope it helps.</p>

Title: Invoking "cmake" failed


问:
Creating a fast, uniform, linear actuator
Most of the linear actuators I've seen are nonuniform and/or slow. Those using a cam or crankshaft-like mechanism (and nearly anything hydraulic/pneumatic) cannot be moved at a constant speed without some programming. Those using a screw-like mechanism are uniform, but slow.

Aside from a rack and pinion/rope wound around a stick, what other fast, uniform linear actuators exist? By uniform, I mean that the speed is uniform (Or the distance moved is linearly dependant on the angle rotated by the motor)

答:
I don't know if this qualifies as a rack & pinion, or rope wound round a stick, but a simple belt drive actuator is very fast and smooth. I'm using one for a SMD pick and place machine where I need very good speed and smoothness of movement.

Linear actuators based on screws don't need to be slow at all, it just depends on the pitch of the screw you use. Use a long pitch screw, and you get a lot more travel per revolution of the motor.


问:
Are time-of-flight cameras like the swissranger affected by outdoor fog?
I'm looking to build an outdoor robot and I need to know if time-of-flight cameras like the SwissRanger™ SR4500 work in fog, does anybody have some experiences on that?</p>

答:
The swissranger is a RF-modulated light sources with phase detectors which is one type of time of flight camera. The other type is Range Gated Imager. The Wiki Page for time-of-flight cameras http://en.wikipedia.org/wiki/Time-of-flight_camera  states this for the Range Gated imagers:

"Range gated imagers can also be used in 2D imaging to suppress anything outside a specified distance range, such as to see through fog. A pulsed laser provides illumination, and an optical gate allows light to reach the imager only during the desired time period."

It also states that:

"The ZCam by 3DV Systems is a range-gated system."


问:
Using DH parameters to visualize a robot
Suppose I receive a table containing the DH parameters of a 5 DOF robot. Am I able to reconstruct the geometry of this robot and actually visualize it (i.e. all the mechanical joints and links), using MATLAB or another tool?

I was thinking that I could link all the origins of the frames with a line to get this raw visualization, but apparently, it's more complicated than that.

From what I have been studying, the origin of the DH frame assignment is not always exactly linked to the mechanical construction of the robot, but it needs to respect some specific rules and can even be located "outside" the robot, or two frames may have the same origin in space.

答:
Yes you can visualive it in matlab, using robot toolbox for Matlab here.

Visualization would look like this

And code example for MDH table for my 6 DOF Serial manipulator :

```<code>a = 40/1000;
b = 81/1000;
c = 130/1000;
d = 18/1000;
e = 166/1000;
f = 31/1000;
g = 95/1000;

p = SerialLink([...
Revolute('d',b,'a',0,'alpha',0,'modified');...
Revolute('d',0,'a',a,'alpha',deg2rad(90),'offset',pi/4,'modified');...
Revolute('d',0,'a',c,'alpha',0,'modified');...
Revolute('d',e+f,'a',d,'alpha',deg2rad(90),'modified');...
Revolute('d',0,'a',0,'alpha',deg2rad(-90),'modified');...
Revolute('d',g,'a',0,'alpha',deg2rad(90),'modified');],...
'name','6 DOF')
p.teach([0 0 0 0 0 0])
</code>```

Body:
Yes you can visualive it in matlab, using robot toolbox for Matlab here.

Visualization would look like this

And code example for MDH table for my 6 DOF Serial manipulator :

a = 40/1000;
b = 81/1000;
c = 130/1000;
d = 18/1000;
e = 166/1000;
f = 31/1000;
g = 95/1000;

p = SerialLink([...
Revolute('d',b,'a',0,'alpha',0,'modified');...
Revolute('d',0,'a',a,'alpha',deg2rad(90),'offset',pi/4,'modified');...
Revolute('d',0,'a',c,'alpha',0,'modified');...
Revolute('d',e+f,'a',d,'alpha',deg2rad(90),'modified');...
Revolute('d',0,'a',0,'alpha',deg2rad(-90),'modified');...
Revolute('d',g,'a',0,'alpha',deg2rad(90),'modified');],...
'name','6 DOF')
p.teach([0 0 0 0 0 0])