開発記事公開日
Three.jsで移動式クレーンの荷振れを表現する方法

振り子運動と減衰を使った荷振れ表現の設計方針を、運動モデルとフレーム更新の観点から解説します
移動式クレーンの操作で特に注意が必要なのが、吊り荷の「荷振れ」です。移動式クレーン安全シミュレーターの開発では、この荷振れをThree.js上でどう表現するかが中心的な課題でした。揺れをそれらしく描くには、物理エンジンが要るのではないか。最初はそう見えますが、荷振れに限れば答えは違います。この記事では、振り子運動と減衰にもとづく荷振れ表現の一般的な設計方針を解説します。
荷振れを振り子としてモデル化する
物理エンジンに頼らずに済むのは、荷振れの成り立ちが単純だからです。クレーンの吊り荷は、ブーム先端を支点、ワイヤーを腕とする振り子と見なせます。ブームが動いたり止まったりすると支点が加速度を持ち、その反動で荷が鉛直方向からずれて往復運動を始めます。これが荷振れです。
振り子の運動方程式
鉛直方向からの振れ角をθ、ワイヤー長をL、重力加速度をgとすると、単振り子の運動は一般に次の形で表せます。
θ'' = -(g / L) * sin(θ)
振れ角が小さい範囲では sin(θ) ≒ θ と近似でき、周期がワイヤー長で決まる単純な振動になります。クレーンを操作する人が持つ「ワイヤーが長いほどゆっくり大きく振れる」という実感に対応する性質が、この一つの式から自然に得られます。
減衰項を加える
ただし、この式のままでは荷はいつまでも同じ調子で揺れ続けます。現実の荷振れは空気抵抗などにより時間とともに小さくなります。これを表現するため、角速度に比例する減衰項を加えます。
θ'' = -(g / L) * sin(θ) - c * θ'
残る問題は、減衰係数cの決め方です。ここでは物理的な厳密さを追わず、cは「体験として自然に収まって見えるか」を基準に調整するパラメータとして扱います。教育用途のシミュレーターでは、厳密な物理再現より、操作と荷振れの因果関係が伝わることを優先しているからです。
フレーム更新への組み込み
Three.jsのレンダリングループの各フレームで、経過時間を使って角度と角速度を数値積分し、その結果を吊り荷の位置に反映します。擬似コードでは次のような流れになります。
毎フレーム:
dt = 前フレームからの経過時間
θ'' = -(g / L) * sin(θ) - c * θ'
θ' = θ' + θ'' * dt
θ = θ + θ' * dt
荷の位置 = 支点位置 + L * (sin(θ), -cos(θ)) 方向
設計上の注意点は次の通りです。
- フレームレートに依存しないよう、必ず経過時間dtベースで積分する
- 支点(ブーム先端)の移動を荷振れの入力として扱い、操作が振れを生む因果を再現する
- 実際の荷振れは前後と左右の2方向に起きるため、振れ角を2軸で持つ
二つめの項目は、最初に見た「支点が加速度を持つと荷が振れる」という荷振れの成り立ちを、そのまま実装に写したものです。
物理エンジンなしでどこまで表現できるか
冒頭の問いに戻ると、荷振れ表現の骨格は、「振り子の運動方程式に減衰項を加え、フレームごとに経過時間で数値積分する」というシンプルな構成で成立します。厳密な物理エンジンを導入しなくても、荷振れの「操作すると揺れる、待つと収まる」という因果関係は十分に表現できます。
このシミュレーターを安全教育にどう活かせるか、また何を代替できないかは、ガイド記事「クレーン安全教育に3Dシミュレーターを使う利点と限界」で整理しています。




