0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Gazeboのタワークレーンに「トロリ横行」と「フック巻上げ・巻き下げ」を追加してみた

0
Posted at

1. はじめに

前回の記事では、OpenRoboticsの tower_crane.dae を base(土台)と upper(ジブ)に分割し、ジブが Z 軸まわりに旋回するモデルを作りました。今回はより実際の動きに近づけるため、前回記事の旋回モデルに **トロリ(横行)とフック(巻上げ・巻き下げ)**の機能 を追加して、(θ, r, h) の3軸で動かせるようにしてみました。

タワークレーンの動作は、円筒座標 (θ, r, h) に分けられます。

  • θ(旋回) … ジブが Z 軸まわりに回る ← 前回
  • r(横行) … トロリがジブに沿って前後する ← 今回
  • h(巻上げ) … フックが上下する ← 今回

完成すると、こんな動きになります:

最終的には以下のリンクの論文「Automating the Tower Crane: Integrating the Development and Simulation of Path Planning and Trajectory Tracking of Tower Crane in ROS Framework」(ISARC 2024) に倣って、ROS で自動搬送を再現したいと考えています。

2. 実行環境

項目 内容
OS Ubuntu 22.04 LTS
シミュレータ Gazebo Classic 11.10.2 / SDF 1.6
  • メッシュは .dae(COLLADA) ではなく .obj を使います(後述:DAE が重いと gzclient が固まることがあるため)。

3. 関節の構成

3つの関節を、親子関係で繋ぎます。**トロリもフックもジブの「子」**なので、旋回(θ)させると一緒に連れ回り、その上で横行(r)・巻上げ(h)が独立して動きます。

world
 └─(fixed)─ base_link        … マスト(土台)
      └─(yaw_joint / revolute Z)─ upper_link     … ジブ(旋回 θ)
            └─(trolley_joint / prismatic)─ trolley_link  … トロリ(横行 r)
                  └─(hoist_joint / prismatic Z)─ hook_link  … フック(巻上げ h)

4. トロリ・フックは元データに入っていた

「トロリとフックは自分でモデリングするか…」と思っていたのですが、tower_crane.dae を確認すると、ジブの下にトロリ+滑車ブロック+フックがちゃんと存在していました。

そこで、前回 base/upper を分割したのと同じ要領で、Blender でルーズパーツから該当部品だけを抽出し、軽量な OBJ として書き出して使います。

  • trolley.obj … トロリ
  • hook.obj … フック(ワイヤ+シーブ+鉤)

抽出したトロリ/フックはマテリアルを外して書き出します。こうするとタワー本体と同じ Gazebo 標準グレーで描画され、色が浮きません。また、ジブ側(upper)に残っている元のフック形状は削除**しておきます(残すと可動フックと二重に見えるため)。

5. model.sdf にトロリ・フックを追加する

yaw_joint の後ろに、以下を追記します。

<!-- ===== トロリ(ジブ下弦に沿って横行 r)===== -->
<link name="trolley_link">
  <pose>0.06 -10 28.3 0 0 0</pose>      <!-- ジブ下弦の直下に配置 -->
  <gravity>false</gravity>
  <inertial>
    <mass>50</mass>
    <inertia><ixx>10</ixx><iyy>10</iyy><izz>10</izz>
             <ixy>0</ixy><ixz>0</ixz><iyz>0</iyz></inertia>
  </inertial>
  <visual name="trolley_vis">
    <geometry>
      <mesh><uri>model://tower_crane_rot/meshes/trolley.obj</uri></mesh>
    </geometry>
  </visual>
</link>

<joint name="trolley_joint" type="prismatic">
  <parent>upper_link</parent>            <!-- ジブの子。だから旋回に追従する -->
  <child>trolley_link</child>
  <axis>
    <xyz>0 -1 0</xyz>                    <!-- ジブ長手(-Y)方向 -->
    <limit>
      <lower>-8</lower>                  <!-- スポーン(y=-10)基準で根元寄り -->
      <upper>12</upper>                  <!-- 先端寄り -->
      <effort>5000</effort>
      <velocity>2.0</velocity>
    </limit>
    <dynamics><damping>50.0</damping></dynamics>
  </axis>
</joint>

<!-- ===== フック(巻上げ h:トロリ直下を昇降)===== -->
<link name="hook_link">
  <pose>0.06 -10 27.9 0 0 0</pose>       <!-- トロリ直下 -->
  <gravity>false</gravity>
  <inertial>
    <pose>0 0 -1.4 0 0 0</pose>          <!-- CoG をフック実体中央へ -->
    <mass>10</mass>
    <inertia><ixx>2</ixx><iyy>2</iyy><izz>2</izz>
             <ixy>0</ixy><ixz>0</ixz><iyz>0</iyz></inertia>
  </inertial>
  <visual name="hook_vis">
    <geometry>
      <mesh><uri>model://tower_crane_rot/meshes/hook.obj</uri></mesh>
    </geometry>
  </visual>
</link>

<joint name="hoist_joint" type="prismatic">
  <parent>trolley_link</parent>          <!-- トロリの子。θ・r に h を追加 -->
  <child>hook_link</child>
  <axis>
    <xyz>0 0 -1</xyz>                    <!-- 下向き正=巻き下げ -->
    <limit>
      <lower>0</lower>                   <!-- h=0:巻き上げ最上 -->
      <upper>24</upper>                  <!-- 最大 ~24m 巻き下げ -->
      <effort>5000</effort>
      <velocity>2.0</velocity>
    </limit>
    <dynamics><damping>20.0</damping></dynamics>
  </axis>
</joint>

このSDFでやること

  • trolley_joint(prismatic)でトロリをジブ長手方向 (0 -1 0) にスライドさせる
  • hoist_joint(prismatic)でフックを鉛直 (0 0 -1) に昇降させる(--pos-t の値が吊り下げ量[m])
  • どちらも親が upper_link / trolley_link なので、旋回(θ)に自動で追従する

6. 動かしてみる

ターミナルを 2つ 使います。

ステップ1:ターミナルA で Gazebo を起動

cd ~/tower_crane_ws
gazebo --verbose tower_crane_rot.world

クレーンが表示されます。このターミナルは開いたままにします。

ステップ2:ターミナルB を開いて、最初に1回だけ

source /usr/share/gazebo-11/setup.sh

これで gz コマンドが使えるようになります。

ステップ3:トロリを横行させる(r)

# ジブ先端へ
gz joint -m tower_crane_rot -j trolley_joint --pos-t 10 --pos-p 1e3 --pos-i 50 --pos-d 5e3
# 根元へ戻す
gz joint -m tower_crane_rot -j trolley_joint --pos-t -6 --pos-p 1e3 --pos-i 50 --pos-d 5e3

トロリ(とフック)がジブに沿って動きます。--pos-t の値は -8(根元)〜 +12(先端)。

ステップ4:フックを巻き下げ/巻き上げする(h)

# 巻き下げ(12m 下ろす)
gz joint -m tower_crane_rot -j hoist_joint --pos-t 12 --pos-p 5e2 --pos-i 20 --pos-d 2e3
# 巻き上げ(最上へ戻す)
gz joint -m tower_crane_rot -j hoist_joint --pos-t 0  --pos-p 5e2 --pos-i 20 --pos-d 2e3

ステップ5:ジブを旋回させる(θ)

# 右旋回
gz joint -m tower_crane_rot -j yaw_joint --pos-t 0.6  --pos-p 2e5 --pos-d 1.2e6
# 左旋回
gz joint -m tower_crane_rot -j yaw_joint --pos-t -0.6 --pos-p 2e5 --pos-d 1.2e6

--pos-t はラジアン。ここで見るべきポイント:旋回させた状態で横行させると、トロリは「グローバルなY軸」ではなく「回転後のジブ方向」に動きます。トロリ・フックがジブの子になっているおかげです。

7. ハマりどころ

実際に動かすまでに、いくつかエラーがでまして以下のような対応をとりました。

  • スポーン位置を可動範囲(limit)の内側にする
    prismatic 関節は、リンクの初期位置が <limit> の外側だと、起動直後に限界補正の大きな力がかかってシミュレーションが発散します。hoist_joint の <lower> を 0(=初期位置)にするなどして、初期姿勢を必ず範囲内に収めます。

  • PID ゲインは控えめに
    gz joint --pos-t は力ベースの PID です。ゲインを上げすぎると(特に旋回)振動して上部が吹っ飛びます。上記の値あたりから始めるのが安全です。

  • 慣性をきちんと与える
    ジブにトロリがぶら下がるので、upper_link に十分な <inertial> を与えないと旋回時に倒れます。重心(CoG)はジブの高さ・旋回軸上に置くのがコツです。

  • DAE が重いと gzclient が固まる
    Blender から書き出した COLLADA(.dae) が数十 MB に肥大化し、gzclient が読み込みでフリーズしました。OBJ で書き出すと数百 KB に収まり、安定して表示できました。

8. まとめ

前回の 旋回(θ) に加えて、今回 横行(r) と 巻上げ(h) を追加し、タワークレーンの基本動作 (θ, r, h) をひと通り動かせるようになりました。トロリ・フックは元の tower_crane.dae に入っていた部品をそのまま使えたので、見た目も自然にできているかなと思います。

今後は ISARC 2024 の論文を参考に、ROS / ROS2 から軌道計画 → 関節指令を送り、荷物を A 地点から B 地点へ自動搬送するところまで取り組みたいと思っています。

ライセンス / クレジット

本記事で使用した3Dモデル「tower_crane」は、Open Robotics による
Gazebo モデルデータベース(osrf/gazebo_models)に含まれるもので、
Creative Commons Attribution 3.0 Unported (CC BY 3.0) で提供されています。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?