Gazebo使用筆記(6) —— 摩擦力特性與碰撞位掩碼

1. 平移摩擦

Gazebo的物理引擎(如ODE,Bullet,Simbody,DART)都有不同的摩擦模型,摩擦力參數列表可參見傳送門

假設使用的默認物理引擎ODE

摩擦力的工作原理

ODE中由兩部分組成,mumu2,ODE將自動計算第一、第二摩擦方向:

  • mu是第一摩擦方向的庫倫摩擦係數
  • mu2是垂直於第一摩擦方向的第二摩擦方向摩擦係數

兩個對象發生碰撞,Gazebo將從兩個對象中選擇最小的mumu2

mumu2的範圍爲任何非負數,where,0表示無摩擦接觸,較大值表示具有無限摩擦的表面。

各種材料的摩擦特性可從工程工具箱獲取

SDF中指定摩擦

栗子1:

<model name="box">
  <pose>0 0 0.5 0 0 0</pose>
  <link name="link">
    <collision name="collision">
      <geometry>
        <box>
          <size>1 1 1</size>
        </box>
      </geometry>
      <surface>
 <!--###########################-->
        <friction>
          <ode>
            <mu>0.01</mu>
            <mu2>0.01</mu2>
          </ode>
        </friction>
<!--###########################-->
      </surface>
    </collision>
    <visual name="visual">
      <geometry>
        <box>
          <size>1 1 1</size>
        </box>
      </geometry>
    </visual>
  </link>
</model>

栗子2:

<sdf version="1.4">
  <world name="default">
    <scene>
      <ambient>1.000000 1.000000 1.000000 1.000000</ambient>
      <background>0.700000 0.700000 0.700000 1.000000</background>
      <shadows>1</shadows>
    </scene>
    <physics type="ode">
      <gravity>0.000000 -1.000000 -1.000000</gravity>
      <ode>
        <solver>
          <type>quick</type>
          <iters>50</iters>
          <precon_iters>0</precon_iters>
          <sor>1.300000</sor>
        </solver>
        <constraints>
          <cfm>0.000000</cfm>
          <erp>0.200000</erp>
          <contact_max_correcting_vel>100.000000</contact_max_correcting_vel>
          <contact_surface_layer>0.001000</contact_surface_layer>
        </constraints>
      </ode>
      <real_time_update_rate>0.000000</real_time_update_rate>
      <max_step_size>0.001000</max_step_size>
    </physics>
    <model name="gplane">
      <pose>0.000000 0.000000 0.000000 0.000000 -0.000000 0.000000</pose>
      <link name="plane">
        <pose>0.000000 0.000000 0.000000 0.000000 -0.000000 0.000000</pose>
        <collision name="plane">
          <pose>0.000000 0.000000 0.000000 0.000000 -0.000000 0.000000</pose>
          <geometry>
            <plane>
              <normal>0.000000 0.000000 1.000000</normal>
            </plane>
          </geometry>
          <surface>
            <friction>
              <ode>
                <mu>50.000000</mu>
                <mu2>50.000000</mu2>
                <fdir1>0.000000 0.000000 0.000000</fdir1>
                <slip1>0.000000</slip1>
                <slip2>0.000000</slip2>
              </ode>
            </friction>
            <bounce>
              <restitution_coefficient>0.000000</restitution_coefficient>
              <threshold>100000.000000</threshold>
            </bounce>
            <contact>
              <ode>
                <soft_cfm>0.000000</soft_cfm>
                <soft_erp>0.200000</soft_erp>
                <kp>1000000000.000000</kp>
                <kd>1.000000</kd>
                <max_vel>100.000000</max_vel>
                <min_depth>0.001000</min_depth>
              </ode>
            </contact>
          </surface>
          <laser_retro>0.000000</laser_retro>
        </collision>
        <gravity>1</gravity>
        <self_collide>0</self_collide>
        <kinematic>0</kinematic>
      </link>
      <static>1</static>
    </model>
    <model name="box_01_model">
      <allow_auto_disable>0</allow_auto_disable>
      <pose>2.000000 8.000000 0.500000 0.000000 -0.000000 0.000000</pose>
      <link name="box_01_body">
        <pose>0.000000 0.000000 0.000000 0.000000 -0.000000 0.000000</pose>
        <inertial>
          <pose>0.000000 0.000000 -0.500000 0.000000 -0.000000 0.000000</pose>
          <inertia>
            <ixx>10.000000</ixx>
            <ixy>0.000000</ixy>
            <ixz>0.000000</ixz>
            <iyy>10.000000</iyy>
            <iyz>0.000000</iyz>
            <izz>10.000000</izz>
          </inertia>
          <mass>1.000000</mass>
        </inertial>
        <collision name="box_01_geom">
          <pose>0.000000 0.000000 0.000000 0.000000 -0.000000 0.000000</pose>
          <geometry>
            <box>
              <size>1.000000 1.000000 1.000000</size>
            </box>
          </geometry>
          <surface>
            <friction>
              <ode>
                <mu>0.998000</mu>
                <mu2>0.998000</mu2>
                <fdir1>0.000000 0.000000 0.000000</fdir1>
                <slip1>0.000000</slip1>
                <slip2>0.000000</slip2>
              </ode>
            </friction>
            <bounce>
              <restitution_coefficient>0.000000</restitution_coefficient>
              <threshold>100000.000000</threshold>
            </bounce>
            <contact>
              <ode>
                <soft_cfm>0.000000</soft_cfm>
                <soft_erp>0.200000</soft_erp>
                <kp>100000.000000</kp>
                <kd>1.000000</kd>
                <max_vel>100.000000</max_vel>
                <min_depth>0.001000</min_depth>
              </ode>
            </contact>
          </surface>
          <laser_retro>0.000000</laser_retro>
        </collision>
        <visual name="box_01_geom_visual">
          <pose>0.000000 0.000000 0.000000 0.000000 -0.000000 0.000000</pose>
          <geometry>
            <box>
              <size>1.000000 1.000000 1.000000</size>
            </box>
          </geometry>
          <material>
            <script>Gazebo/Rocky</script>
          </material>
          <cast_shadows>1</cast_shadows>
          <laser_retro>0.000000</laser_retro>
          <transparency>0.000000</transparency>
        </visual>
        <gravity>1</gravity>
        <self_collide>0</self_collide>
        <kinematic>0</kinematic>
      </link>
      <static>0</static>
    </model>
    <model name="box_02_model">
      <allow_auto_disable>0</allow_auto_disable>
      <pose>4.000000 8.000000 0.500000 0.000000 -0.000000 0.000000</pose>
      <link name="box_02_body">
        <pose>0.000000 0.000000 0.000000 0.000000 -0.000000 0.000000</pose>
        <inertial>
          <pose>0.000000 0.000000 -0.500000 0.000000 -0.000000 0.000000</pose>
          <inertia>
            <ixx>10.000000</ixx>
            <ixy>0.000000</ixy>
            <ixz>0.000000</ixz>
            <iyy>10.000000</iyy>
            <iyz>0.000000</iyz>
            <izz>10.000000</izz>
          </inertia>
          <mass>1.000000</mass>
        </inertial>
        <collision name="box_02_geom">
          <pose>0.000000 0.000000 0.000000 0.000000 -0.000000 0.000000</pose>
          <geometry>
            <box>
              <size>1.000000 1.000000 1.000000</size>
            </box>
          </geometry>
          <surface>
            <friction>
              <ode>
                <mu>0.998500</mu>
                <mu2>0.998500</mu2>
                <fdir1>0.000000 0.000000 0.000000</fdir1>
                <slip1>0.000000</slip1>
                <slip2>0.000000</slip2>
              </ode>
            </friction>
            <bounce>
              <restitution_coefficient>0.000000</restitution_coefficient>
              <threshold>100000.000000</threshold>
            </bounce>
            <contact>
              <ode>
                <soft_cfm>0.000000</soft_cfm>
                <soft_erp>0.200000</soft_erp>
                <kp>100000.000000</kp>
                <kd>1.000000</kd>
                <max_vel>100.000000</max_vel>
                <min_depth>0.001000</min_depth>
              </ode>
            </contact>
          </surface>
          <laser_retro>0.000000</laser_retro>
        </collision>
        <visual name="box_02_geom_visual">
          <pose>0.000000 0.000000 0.000000 0.000000 -0.000000 0.000000</pose>
          <geometry>
            <box>
              <size>1.000000 1.000000 1.000000</size>
            </box>
          </geometry>
          <material>
            <script>Gazebo/Rocky</script>
          </material>
          <cast_shadows>1</cast_shadows>
          <laser_retro>0.000000</laser_retro>
          <transparency>0.000000</transparency>
        </visual>
        <gravity>1</gravity>
        <self_collide>0</self_collide>
        <kinematic>0</kinematic>
      </link>
      <static>0</static>
    </model>
    <model name="box_03_model">
      <allow_auto_disable>0</allow_auto_disable>
      <pose>6.000000 8.000000 0.500000 0.000000 -0.000000 0.000000</pose>
      <link name="box_03_body">
        <pose>0.000000 0.000000 0.000000 0.000000 -0.000000 0.000000</pose>
        <inertial>
          <pose>0.000000 0.000000 -0.500000 0.000000 -0.000000 0.000000</pose>
          <inertia>
            <ixx>10.000000</ixx>
            <ixy>0.000000</ixy>
            <ixz>0.000000</ixz>
            <iyy>10.000000</iyy>
            <iyz>0.000000</iyz>
            <izz>10.000000</izz>
          </inertia>
          <mass>1.000000</mass>
        </inertial>
        <collision name="box_03_geom">
          <pose>0.000000 0.000000 0.000000 0.000000 -0.000000 0.000000</pose>
          <geometry>
            <box>
              <size>1.000000 1.000000 1.000000</size>
            </box>
          </geometry>
          <surface>
            <friction>
              <ode>
                <mu>0.999000</mu>
                <mu2>0.999000</mu2>
                <fdir1>0.000000 0.000000 0.000000</fdir1>
                <slip1>0.000000</slip1>
                <slip2>0.000000</slip2>
              </ode>
            </friction>
            <bounce>
              <restitution_coefficient>0.000000</restitution_coefficient>
              <threshold>100000.000000</threshold>
            </bounce>
            <contact>
              <ode>
                <soft_cfm>0.000000</soft_cfm>
                <soft_erp>0.200000</soft_erp>
                <kp>100000.000000</kp>
                <kd>1.000000</kd>
                <max_vel>100.000000</max_vel>
                <min_depth>0.001000</min_depth>
              </ode>
            </contact>
          </surface>
          <laser_retro>0.000000</laser_retro>
        </collision>
        <visual name="box_03_geom_visual">
          <pose>0.000000 0.000000 0.000000 0.000000 -0.000000 0.000000</pose>
          <geometry>
            <box>
              <size>1.000000 1.000000 1.000000</size>
            </box>
          </geometry>
          <material>
            <script>Gazebo/Rocky</script>
          </material>
          <cast_shadows>1</cast_shadows>
          <laser_retro>0.000000</laser_retro>
          <transparency>0.000000</transparency>
        </visual>
        <gravity>1</gravity>
        <self_collide>0</self_collide>
        <kinematic>0</kinematic>
      </link>
      <static>0</static>
    </model>
    <model name="box_04_model">
      <allow_auto_disable>0</allow_auto_disable>
      <pose>8.000000 8.000000 0.500000 0.000000 -0.000000 0.000000</pose>
      <link name="box_04_body">
        <pose>0.000000 0.000000 0.000000 0.000000 -0.000000 0.000000</pose>
        <inertial>
          <pose>0.000000 0.000000 -0.500000 0.000000 -0.000000 0.000000</pose>
          <inertia>
            <ixx>10.000000</ixx>
            <ixy>0.000000</ixy>
            <ixz>0.000000</ixz>
            <iyy>10.000000</iyy>
            <iyz>0.000000</iyz>
            <izz>10.000000</izz>
          </inertia>
          <mass>1.000000</mass>
        </inertial>
        <collision name="box_04_geom">
          <pose>0.000000 0.000000 0.000000 0.000000 -0.000000 0.000000</pose>
          <geometry>
            <box>
              <size>1.000000 1.000000 1.000000</size>
            </box>
          </geometry>
          <surface>
            <friction>
              <ode>
                <mu>0.999500</mu>
                <mu2>0.999500</mu2>
                <fdir1>0.000000 0.000000 0.000000</fdir1>
                <slip1>0.000000</slip1>
                <slip2>0.000000</slip2>
              </ode>
            </friction>
            <bounce>
              <restitution_coefficient>0.000000</restitution_coefficient>
              <threshold>100000.000000</threshold>
            </bounce>
            <contact>
              <ode>
                <soft_cfm>0.000000</soft_cfm>
                <soft_erp>0.200000</soft_erp>
                <kp>100000.000000</kp>
                <kd>1.000000</kd>
                <max_vel>100.000000</max_vel>
                <min_depth>0.001000</min_depth>
              </ode>
            </contact>
          </surface>
          <laser_retro>0.000000</laser_retro>
        </collision>
        <visual name="box_04_geom_visual">
          <pose>0.000000 0.000000 0.000000 0.000000 -0.000000 0.000000</pose>
          <geometry>
            <box>
              <size>1.000000 1.000000 1.000000</size>
            </box>
          </geometry>
          <material>
            <script>Gazebo/Rocky</script>
          </material>
          <cast_shadows>1</cast_shadows>
          <laser_retro>0.000000</laser_retro>
          <transparency>0.000000</transparency>
        </visual>
        <gravity>1</gravity>
        <self_collide>0</self_collide>
        <kinematic>0</kinematic>
      </link>
      <static>0</static>
    </model>
    <model name="box_05_model">
      <allow_auto_disable>0</allow_auto_disable>
      <pose>10.000000 8.000000 0.500000 0.000000 -0.000000 0.000000</pose>
      <link name="box_05_body">
        <pose>0.000000 0.000000 0.000000 0.000000 -0.000000 0.000000</pose>
        <inertial>
          <pose>0.000000 0.000000 -0.500000 0.000000 -0.000000 0.000000</pose>
          <inertia>
            <ixx>10.000000</ixx>
            <ixy>0.000000</ixy>
            <ixz>0.000000</ixz>
            <iyy>10.000000</iyy>
            <iyz>0.000000</iyz>
            <izz>10.000000</izz>
          </inertia>
          <mass>1.000000</mass>
        </inertial>
        <collision name="box_05_geom">
          <pose>0.000000 0.000000 0.000000 0.000000 -0.000000 0.000000</pose>
          <geometry>
            <box>
              <size>1.000000 1.000000 1.000000</size>
            </box>
          </geometry>
          <surface>
            <friction>
              <ode>
                <mu>1.000000</mu>
                <mu2>1.000000</mu2>
                <fdir1>0.000000 0.000000 0.000000</fdir1>
                <slip1>0.000000</slip1>
                <slip2>0.000000</slip2>
              </ode>
            </friction>
            <bounce>
              <restitution_coefficient>0.000000</restitution_coefficient>
              <threshold>100000.000000</threshold>
            </bounce>
            <contact>
              <ode>
                <soft_cfm>0.000000</soft_cfm>
                <soft_erp>0.200000</soft_erp>
                <kp>100000.000000</kp>
                <kd>1.000000</kd>
                <max_vel>100.000000</max_vel>
                <min_depth>0.001000</min_depth>
              </ode>
            </contact>
          </surface>
          <laser_retro>0.000000</laser_retro>
        </collision>
        <visual name="box_05_geom_visual">
          <pose>0.000000 0.000000 0.000000 0.000000 -0.000000 0.000000</pose>
          <geometry>
            <box>
              <size>1.000000 1.000000 1.000000</size>
            </box>
          </geometry>
          <material>
            <script>Gazebo/Rocky</script>
          </material>
          <cast_shadows>1</cast_shadows>
          <laser_retro>0.000000</laser_retro>
          <transparency>0.000000</transparency>
        </visual>
        <gravity>1</gravity>
        <self_collide>0</self_collide>
        <kinematic>0</kinematic>
      </link>
      <static>0</static>
    </model>
    <model name="box_06_model">
      <allow_auto_disable>0</allow_auto_disable>
      <pose>12.000000 8.000000 0.500000 0.000000 -0.000000 0.000000</pose>
      <link name="box_06_body">
        <pose>0.000000 0.000000 0.000000 0.000000 -0.000000 0.000000</pose>
        <inertial>
          <pose>0.000000 0.000000 -0.500000 0.000000 -0.000000 0.000000</pose>
          <inertia>
            <ixx>10.000000</ixx>
            <ixy>0.000000</ixy>
            <ixz>0.000000</ixz>
            <iyy>10.000000</iyy>
            <iyz>0.000000</iyz>
            <izz>10.000000</izz>
          </inertia>
          <mass>1.000000</mass>
        </inertial>
        <collision name="box_06_geom">
          <pose>0.000000 0.000000 0.000000 0.000000 -0.000000 0.000000</pose>
          <geometry>
            <box>
              <size>1.000000 1.000000 1.000000</size>
            </box>
          </geometry>
          <surface>
            <friction>
              <ode>
                <mu>1.010000</mu>
                <mu2>1.010000</mu2>
                <fdir1>0.000000 0.000000 0.000000</fdir1>
                <slip1>0.000000</slip1>
                <slip2>0.000000</slip2>
              </ode>
            </friction>
            <bounce>
              <restitution_coefficient>0.000000</restitution_coefficient>
              <threshold>100000.000000</threshold>
            </bounce>
            <contact>
              <ode>
                <soft_cfm>0.000000</soft_cfm>
                <soft_erp>0.200000</soft_erp>
                <kp>100000.000000</kp>
                <kd>1.000000</kd>
                <max_vel>100.000000</max_vel>
                <min_depth>0.001000</min_depth>
              </ode>
            </contact>
          </surface>
          <laser_retro>0.000000</laser_retro>
        </collision>
        <visual name="box_06_geom_visual">
          <pose>0.000000 0.000000 0.000000 0.000000 -0.000000 0.000000</pose>
          <geometry>
            <box>
              <size>1.000000 1.000000 1.000000</size>
            </box>
          </geometry>
          <material>
            <script>Gazebo/Rocky</script>
          </material>
          <cast_shadows>1</cast_shadows>
          <laser_retro>0.000000</laser_retro>
          <transparency>0.000000</transparency>
        </visual>
        <gravity>1</gravity>
        <self_collide>0</self_collide>
        <kinematic>0</kinematic>
      </link>
      <static>0</static>
    </model>
  </world>
</sdf>

2. 轉動摩擦

注意:轉動摩擦當前僅適用於ODE物理引擎

轉動摩擦方程:

轉動摩擦的扭矩是根據接觸深度和表面半徑計算的,具體參考傳送門

T = 3*PI/16 * a * coefficient * N
a = sqrt(R * d)

where,

  • 3*PI/16:常數≈0.589
  • T:由於轉動摩擦產生的扭矩
  • N:接觸時的法向力
  • 係數:轉動摩擦係數,通常與平移摩擦係數mu和mu2相同
  • a:接觸面半徑(patch_radius in SDF),這是表面之間的接觸區域的半徑。平面頂部的球體會生成一個圓形的補丁區域,該區域取決於球體半徑和接觸深度
  • R:接觸點表面半徑(patch_radius in SDF)
  • d:接觸深度

由上可知,與平移摩擦不同,扭轉摩擦不僅取決於法向力和摩擦係數。它還取決於表面之間的接觸面積。

SDF參數

SDF提供了兩種參數化接觸表面的方法。 用戶可以定義一個patch_radius(上面的a)(與接觸深度無關)總是相同的,也可以定義一個surface_radius(上面的R)(與接觸深度一起使用)。 請注意,在這兩種情況下,用戶都爲整個曲面指定了一個值,因此爲非球形曲面選取值可能需要微調。

要在方法之間進行選擇,可以將patch_radiususe_patch_radius標籤設置爲true,而將surface_radius設置爲false,或反之。

默認值
  • coefficient:和mu,mu2一樣,默認值爲1.0
  • use_patch_radius:默認值爲true,因此patch_radius使用。
  • patch_radius:默認值爲0,因此即使coefficient設置爲零,也不會出現扭轉摩擦。
  • surface_radius:默認值爲0,因此即使coefficient設置爲零,也不會存在扭轉摩擦。

SDF中的設置

<model ...>
 ...
  <link ...>
    <collision ...>
     ...
      <surface>
<!--##################################-->
        <friction>
          <torsional>
            <coefficient>1.0</coefficient>
            <surface_radius>0.5</surface_radius>
            <use_patch_radius>false</use_patch_radius>
          </torsional>
        </friction>
<!--##################################-->
       ...
      </surface>
    </collision>
  </link>
</model>

測試:

gazebo -u worlds/torsional_friction_demo.world

3. 碰撞位掩碼

介紹

位掩碼是與某個對象相關聯的數字,通常以十六進制指定。

假設對象是碰撞幾何。當比較兩個位掩碼時,通過按位與運算,結果將用於控制所應用的邏輯。

  • BoxA:01
  • BoxB:10
  • BoxC:11
 gazebo -u worlds/shapes_bitmask.world

C(最頂端)→B(中)→A(最底端),仿真結果:boxA和boxB將發生碰撞。但按位及其位掩碼將產生零值。這表明,以仿真引擎,碰撞也應該被忽略,其結果是盒B通過BOXA。此時,boxA和boxB都位於同一地點並擱在地面上。同時,boxC從其起始位置下降。BoxC最終會命中boxA和boxB。boxC的位掩碼的按位與和以及屬於boxA和boxB的位掩碼將導致一個大於零的值。這個非零的結果,也被編程語言視爲“ true”,它向模擬引擎指示應該生成衝突。結果是boxC將停留在boxA和boxB的頂部。

碰撞位掩碼設置

<model name="box">
  <link name="link">
    <collision name="collision">
      <geometry> ... </geometry>

      <surface>
        <contact>
          <collide_bitmask>0x01</collide_bitmask>
        </contact>
      </surface>

    </collision>
    <visual name="visual"> ... </visual>
  </link>
</model>

默認值

每個幾何體(包括接地平面)的碰撞位掩碼的默認值爲0xffff。您可以將高16位用於不想與接地層碰撞的對象以及其他默認對象。


參考文獻:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章