4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

MuJoCo対応 箱庭ドローンシミュレータ入門ガイド:PID制御・MJCFモデルを自由にカスタマイズ

4
Last updated at Posted at 2025-09-21

無償版 箱庭ドローンシミュレータ が、ついにMuJoCo対応しました。

これまで箱庭ドローンPRO版のみで利用できたMuJoCo(Multi-Joint dynamics with Contact) を手軽に試せるようになっています。

今回公開された機能を使うと、MuJoCoの高精度な剛体計算を活かしつつ、

  • ⚙️ PID制御パラメータの調整
  • 🛠️ MJCFモデル(機体構造ファイル)のカスタマイズ
  • 🎮 キーボード操作+OpenGL描画+WSL2環境での操縦体験

といったことが可能です。
研究から趣味まで、様々な機体の設計やPIDチューニングを自由に楽しめます。

本記事では 「環境構築 → 基本操作 → カスタマイズ」 の流れで、入門ガイドとして分かりやすく紹介します。

目次

必要なもの

  • Windows 11
  • WSL2 (Ubuntu 24.04 LTS)
  • Docker Desktop for Windows
  • キーボード
  • (目安)CPU: Core i5相当以上 / メモリ: 8GB+(16GB推奨)/ GPU不要

GPUは不要で、ゲームエンジンも使いません。
そのため、比較的軽量に普通のPCで動作させることができます。

Windows 11 の WSL2 は WSLg により GUI/OpenGL をそのまま表示できます(X サーバ不要)。

セットアップ

まずは、WSL2を起動して、ホームディレクトリ直下で、hakoniwaというディレクトリを作成しましょう。

mkdir ~/hakoniwa

hakoniwaディレクトリに移動します。

cd ~/hakoniwa

箱庭ドローンシミュレータをクローンして、ディレクトリ移動します。

git clone --recursive https://github.com/toppers/hakoniwa-drone-core.git
cd hakoniwa-drone-core

起動方法

ディレクトリを hakoniwa-drone-core に移動しましょう。

cd ~/hakoniwa/hakoniwa-drone-core

以下のコマンドでdocker コンテナを起動します。

bash docker/run.bash

箱庭ドローンシミュレータを起動します。

linux-drone_service_rc_mujoco  1 config/drone/mujoco/
  • 第1引数: シミュレーションの時間刻み(1 = 1ms)
  • 第2引数: MuJoCo/箱庭の設定ディレクトリ

ドローンの物理側のコンフィグファイルは以下のものです。

config/drone/mujoco/
├── drone.xml    ... MJCFファイルです
└── drone_config_0.json ... 箱庭ドローンシミュレータの設定ファイルです

ドローンの制御側のコンフィグファイルは以下のものです。

config/controller/param-api-mixer-mujoco.txt

成功すると、こんな感じで、OpenGLのビューワーが現れます。そして、シンプルなドローンが登場です。

スクリーンショット 2025-09-21 8.34.51.png

操作方法

ドローンの操作は、キーボードで行います。以下がその操作マニュアル。めちゃシンプル!

 ----- USAGE -----
 ----- STICK -----
|  LEFT  | RIGHT  |
|   w    |   i    |
| a   d  | j   l  |
|   s    |   k    |
 ---- BUTTON ----
 x : radio control button
 p : get position
 r : get attitude
 t : get simtime usec
 b : get battery status

具体的には:

  • x : ラジコンのアームON/OFF(起動直後に1回押してアームONにしてください)
  • w / s : 上昇 / 下降
  • a / d : 左右移動
  • i / k : 前進 / 後退
  • j / l : 左右旋回
  • p, r, t, b : それぞれ位置・姿勢・シミュレーション時間・バッテリ情報を取得

必ず、起動が終わったら、x を1回だけ押してください。

x

その後、w を押すと、ゆっくりドローンが浮上して、ホバリング状態になります。

w
[STATE] Idle -> Ascending
[STATE] Ascending -> Hovering
Set hovering altitude to: 0.3 m
Takeoff completed. Switching to HOVERING mode.

上記ログが出たらホバリング状態です。

この状態になったら、ドローンを移動させることができます。

以下、デモです。

ちなみに、ビューワー側は、マウス操作でカメラビューを変更できます。

ドローンの機体設定方法

ドローンの機体設定は、MJCFファイルで行います。

config/drone/mujoco/drone.xml


    <!-- 本体(ベース) -->
    <body name="drone_base" pos="0 0 0.0" childclass="gray">
      <freejoint/>
      <geom name="base" type="box" size="0.07 0.07 0.015" density="810"/>

      <body name="arm1" pos="0.13 -0.13 0" childclass="black">
        <geom name="arm_geom1" type="cylinder" size="0.008 0.077" euler="90 45 0" density="500"/>
        <body name="p1" pos="0.05 -0.05 0.02" childclass="blue">
          <geom name="prop1_geom" type="cylinder" size="0.076 0.0025" density="200"/>
        </body>
      </body>
      <body name="prop1" pos="0.18 -0.18 0.02" childclass="black">
        <geom name="p1_geom" type="box" size="0.007 0.007 0.007" density="500"/>
      </body>
      <body name="arm2" pos="-0.13 0.13 0" childclass="black">
        <geom name="arm_geom2" type="cylinder" size="0.008 0.077" euler="90 45 0" density="500"/>
        <body name="p2" pos="-0.05 0.05 0.02" childclass="green" gravcomp="0.0">
          <geom name="prop2_geom" type="cylinder" size="0.076 0.0025" density="200"/>
        </body>
      </body>
      <body name="prop2" pos="-0.18 0.18 0.02" childclass="black">
        <geom name="p2_geom" type="box" size="0.007 0.007 0.007" density="500"/>
      </body>

      <body name="arm3" pos="0.13 0.13 0" childclass="black">
        <geom name="arm_geom3" type="cylinder" size="0.008 0.077" euler="90 -45 0" density="500"/>
        <body name="p3" pos="0.05 0.05 0.02" childclass="pink">
          <geom name="prop3_geom" type="cylinder" size="0.076 0.0025" density="200"/>
        </body>
      </body>
      <body name="prop3" pos="0.18 0.18 0.02" childclass="black">
        <geom name="p3_geom" type="box" size="0.007 0.007 0.007" density="500"/>
      </body>

      <body name="arm4" pos="-0.13 -0.13 0" childclass="black">
        <geom name="arm_geom4" type="cylinder" size="0.008 0.077" euler="90 -45 0" density="500"/>
        <body name="p4" pos="-0.05 -0.05 0.02" childclass="orange">
          <geom name="prop4_geom" type="cylinder" size="0.076 0.0025" density="200"/>
        </body>
      </body>
      <body name="prop4" pos="-0.18 -0.18 0.02" childclass="black">
        <geom name="p4_geom" type="box" size="0.007 0.007 0.007" density="500"/>
      </body>

      <body name="reg1" pos="-0.1 0.1 -0.10" childclass="black">
        <geom name="reg_geom1" type="cylinder" size="0.008 0.077" euler="20 0 0" density="500"/>
      </body>
      <body name="reg2" pos="0.1 0.1 -0.10" childclass="black">
        <geom name="reg_geom2" type="cylinder" size="0.008 0.077" euler="20 0 0" density="500"/>
      </body>
      <body name="reg3" pos="-0.1 -0.1 -0.10" childclass="black">
        <geom name="reg_geom3" type="cylinder" size="0.008 0.077" euler="-20 0 0" density="500"/>
      </body>
      <body name="reg4" pos="0.1 -0.1 -0.10" childclass="black">
        <geom name="reg_geom4" type="cylinder" size="0.008 0.077" euler="-20 0 0" density="500"/>
      </body>
      <body name="reg_bottom1" pos="0.0 -0.13 -0.18" childclass="pink">
        <geom name="reg_bottom1" type="cylinder" size="0.008 0.13" euler="0 90 0" density="500"/>
      </body>
      <body name="reg_bottom2" pos="0.0 0.13 -0.18" childclass="pink">
        <geom name="reg_bottom2" type="cylinder" size="0.008 0.13" euler="0 90 0" density="500"/>
      </body>

    </body>

現状、足つきのドローンです。
基本的に、自由に変更できますが、プロペラ名は変更しないでください。
(プログラム側でハードコードされております。)

MJCFファイルのマニュアル:
https://mujoco.readthedocs.io/en/latest/XMLreference.html

箱庭ドローンシミュレータの設定

箱庭ドローンシミュレータの物理側の設定は config/drone/mujoco/drone_config_0.jsonで行われています。

剛体シミュレーションはMuJoCoで行われていますが、ローターシミュレーションは、箱庭側で行われています。
(ローターの回転で発生する推力とトルクがMuJoCoに伝わるイメージです)

config/drone/mujoco/drone_config_0.json:

{
  "name": "Drone",
  "simulation": {
      "lockstep": true,
      "timeStep": 0.001,
      "logOutputDirectory": ".",
      "logOutput": {
          "sensors": {
              "acc": true,
              "gyro": true,
              "mag": true,
              "baro": true,
              "gps": true
          },
          "mavlink": {
              "hil_sensor": true,
              "hil_gps": true,
              "hil_actuator_controls": true
          }
      },
      "mavlink_tx_period_msec": {
          "hil_sensor": 3,
          "hil_gps": 3
      },
      "location": {
          "latitude": 47.641468,
          "longitude": -122.140165,
          "altitude": 121.321,
          "magneticField": {
              "intensity_nT": 53045.1,
              "declination_deg": 15.306,
              "inclination_deg": 68.984
          }
      }
  },
  "components": {
      "droneDynamics": {
          "physicsEquation": "MuJoCo",
          "mujoco": {
            "modelName": "drone_base",
            "propNames": [ "prop1", "prop2", "prop3", "prop4" ],
            "modelPath": "config/drone/mujoco/drone.xml"
          },
          "useQuaternion": false,
          "collision_detection": true,
          "enable_disturbance": false,
          "manual_control": false,
          "airFrictionCoefficient": [
              0.5,
              0.0
          ],
          "inertia": [
              0.0061,
              0.00653,
              0.0116
          ],
          "mass_kg": 0.61079,
          "body_size": [
              0.1,
              0.1,
              0.01
          ],
          "position_meter": [
              0.0,
              0.0,
              -0.1
          ],
          "angle_degree": [
              0,
              0,
              0
          ],
          "body_boundary_disturbance_power": 1.0
      },
      "battery": {
        "vendor": "None",
        "model": "constant",
        "BatteryModelCsvFilePath": "./tmp_battery_model.csv",
        "VoltageLevelGreen": 12.1, 
        "VoltageLevelYellow": 11.1,
        "CapacityLevelYellow": 3, 
        "NominalVoltage": 14.8,
        "NominalCapacity": 4.0,
        "EODVoltage": 3.0
      },
      "rotor": {
        "vendor": "BatteryModel",
        "dynamics_constants": {
            "R": 0.115,
            "Ct": 1.12E-04,
            "Cq": 2.64E-06,
            "K": 0.0103796702,
            "D": 0.0,
            "J": 4.00E-04
        },
        "radius": 0.03 
      },
      "thruster": {
          "vendor": "MuJoCo",
          "rotorPositions": [
              {
                  "position": [
                        0.18,
                        0.18,
                      0
                  ],
                  "rotationDirection": 1.0
              },
              {
                  "position": [
                      -0.18,
                      -0.18,
                      0
                  ],
                  "rotationDirection": 1.0
              },
              {
                  "position": [
                      0.18,
                      -0.18,
                      0
                  ],
                  "rotationDirection": -1.0
              },
              {
                  "position": [
                      -0.18,
                      0.18,
                      0
                  ],
                  "rotationDirection": -1.0
              }
          ],
          "Ct": 1.12E-04
      },
      "sensors": {
          "acc": {
              "sampleCount": 1,
              "noise": 0.03
          },
          "gyro": {
              "sampleCount": 1,
              "noise": 0.0
          },
          "mag": {
              "sampleCount": 1,
              "noise": 0.03
          },
          "baro": {
              "sampleCount": 1,
              "noise": 0.01
          },
          "gps": {
              "sampleCount": 1,
              "noise": 0
          }
      }
  },
  "controller": {
    "moduleDirectory": "../drone_control/cmake-build/workspace/RadioController",
    "paramText": "",
    "paramFilePath": "config/controller/param-api-mixer-mujoco.txt",
    "moduleName": "RadioController",
      "direct_rotor_control": false,
      "mixer": {
          "vendor": "None",
          "enableDebugLog": false,
          "enableErrorLog": false
      }
  }
}

パラメータのマニュアルはこちらです。

PIDパラメータ設定方法

制御側のPIDパラメータは、config/controller/param-api-mixer-mujoco.txt で定義されています。

現状、drone.xml に合わせたPIDパラメータ設定されていますので、機体側を変更した場合は、PIDパラメータもチューニングしないとうまく動かないかもしれませんのでご注意ください。

config/controller/param-api-mixer-mujoco.txt:

# 基本パラメータ
SIMULATION_DELTA_TIME   0.001
MASS                    0.61079
GRAVITY                 9.81

# 高度制御
PID_ALT_CONTROL_CYCLE   0.0
PID_ALT_MAX_POWER       9.81
PID_ALT_THROTTLE_GAIN   1.0
PID_ALT_MAX_SPD         10.0

## 高度制御のPIDパラメータ
PID_ALT_Kp              10.0
PID_ALT_Ki              0.0
PID_ALT_Kd              10.0
PID_ALT_SPD_Kp          15.0
PID_ALT_SPD_Ki          0.0
PID_ALT_SPD_Kd          10.0

# out.thrust = ((mass * gravity) / BASE_THRUST_DIVISOR) + (throttle_gain * throttle_power);
# BASE_THRUST_DIVISOR must be greater than 1.0.
# A special value of 0.0 disables the mass * gravity term,
# i.e., out.thrust = (throttle_gain * throttle_power);
BASE_THRUST_DIVISOR     1.0

# 水平制御
POS_CONTROL_CYCLE       0.0
SPD_CONTROL_CYCLE       0.0
PID_POS_MAX_SPD         20.0

## 水平位置制御のPIDパラメータ
PID_POS_X_Kp            6.0
PID_POS_X_Ki            0.0
PID_POS_X_Kd            3.0
PID_POS_Y_Kp            6.0
PID_POS_Y_Ki            0.0
PID_POS_Y_Kd            3.0

# 水平速度制御のPIDパラメータ
PID_POS_VX_Kp           10.0
PID_POS_VX_Ki           0.0
PID_POS_VX_Kd           0.10
PID_POS_VY_Kp           10.0
PID_POS_VY_Ki           0.0
PID_POS_VY_Kd           0.10

# 姿勢角制御
HEAD_CONTROL_CYCLE 0.0
ANGULAR_CONTROL_CYCLE 0.0
ANGULAR_RATE_CONTROL_CYCLE 0.0
PID_POS_MAX_ROLL 15.0
PID_POS_MAX_PITCH 15.0
PID_ROLL_RPM_MAX 1800.0
PID_PITCH_RPM_MAX 1800.0
# Ix = 0.0061
PID_ROLL_TORQUE_MAX 30.149822911
# Iy = 0.00653
PID_PITCH_TORQUE_MAX 30.230876002
PID_YAW_TORQUE_MAX 0.2186548487

## ロール角度とロール角速度制御のPIDパラメータ
PID_ROLL_Kp 2.5
PID_ROLL_Ki 0.0
PID_ROLL_Kd 0.00
PID_ROLL_RATE_Kp 1.5
PID_ROLL_RATE_Ki 0.0
PID_ROLL_RATE_Kd 0.02

## ピッチ角度とピッチ角速度制御のPIDパラメータ
PID_PITCH_Kp 2.5
PID_PITCH_Ki 0.0
PID_PITCH_Kd 0.00
PID_PITCH_RATE_Kp 1.5
PID_PITCH_RATE_Ki 0.0
PID_PITCH_RATE_Kd 0.02


## ヨー角度とヨー角速度制御のPIDパラメータ
PID_YAW_RPM_MAX 180.0
PID_YAW_Kp 0.1
PID_YAW_Ki 0.0
PID_YAW_Kd 0.0
PID_YAW_RATE_Kp 0.452
PID_YAW_RATE_Ki 0.0
PID_YAW_RATE_Kd 0.000

# ラジオコントロール
YAW_DELTA_VALUE_DEG     0.07
ALT_DELTA_VALUE_M       0.003
ANGLE_CONTROL_ENABLE        0
ANGLE_CONTROL_ENABLE 0.0
ANGLE_RATE_CONTROL_ENABLE 0.0
ALT_SPD_CONTROL_ENABLE 1.0

# フリップコントロール

FLIP_STICK_CHECK_TIME_SEC   0.1
FLIP_STICK_VALUE            0.9

# フリップ時間
FLIP_TARGET_TIME_SEC        0.45

# 一定目標角速度時間
FLIP_CONSTANT_TIME_SEC      0.001

# 離陸制御モード
CTRLMODE_TAKEOFF_IDLE_THROTTLE_RATE             0.2
CTRLMODE_TAKEOFF_TRIGGER_THROTTLE_VALUE         0.1
CTRLMODE_TAKEOFF_TRIGGER_HOLD_SEC               0.1
CTRLMODE_TAKEOFF_ACTION_TARGET_ALTITUDE_M       0.3
CTRLMODE_TAKEOFF_ACTION_MAX_SPEED_M_S           0.1
CTRLMODE_TAKEOFF_COMPLETION_ALTITUDE_ERROR_M    0.03
CTRLMODE_TAKEOFF_COMPLETION_STABLE_DURATION_SEC 1.0
CTRLMODE_TAKEOFF_COMPLETION_STABLE_ANGLE_DEG    1.0

# 着陸制御モード
CTRLMODE_LANDING_TRIGGER_ALTITUDE_M             0.2
CTRLMODE_LANDING_TRIGGER_THROTTLE_VALUE         0.3
CTRLMODE_LANDING_TRIGGER_HOLD_SEC               0.1
CTRLMODE_LANDING_ACTION_TARGET_SPEED_M_S        0.1
CTRLMODE_LANDING_COMPLETION_ALTITUDE_M          0.05
CTRLMODE_LANDING_COMPLETION_STABLE_ANGLE_DEG    1.0
CTRLMODE_LANDING_COMPLETION_STABLE_DURATION_SEC 1.0

パラメータのマニュアルはこちらです。

まとめ

本記事では、

  • 🛠️ WSL2環境でMuJoCo対応版をビルド・起動する方法
  • 🎮 キーボードで操作して飛ばす方法
  • ⚙️ MJCFで機体形状を編集する方法
  • ⚡ PIDパラメータを調整して挙動を変える方法

を紹介しました。

MuJoCo対応によって、よりリアルな物理挙動を反映したドローン開発・研究が可能になります。
ぜひ自分だけの機体を設計して、PIDチューニングを楽しんでみてください 🚀

4
2
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
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?