本物のセンサーの癖まで、
設定で。
GPS は遅れて届き、気圧計にはノイズが乗り、ジャイロはゆっくりずれる。モーターは指令にすぐには追いつかない。箱庭ドローンPROは、こうした癖を1つの機体設定として持ち、PX4・ArduPilot・Control Link それぞれの仕組みに合わせて反映します。再現できない違いも、はっきり書きます。
それぞれの仕組みに合わせて反映し、
再現できない違いも明らかにする。
- できること:センサーの遅れ・ノイズ・ずれ・精度・更新周期と、モーターの特性を、機体ごとの設定で決められる。
- つなぎ方に合わせる:PX4 SITL には箱庭ドローンPROがそのまま効かせ、ArduPilot SITL には設定を変換して渡し、Control Link では箱庭ドローンPROが再現する。
- 確かめた:この設定で、Control Link と PX4 SITL・ArduPilot SITL を統計で照合し、どちらも外れた項目なし。
SITL との照合の結果 照合済み x500、Control Link 10回 対 SITL 10回、事前に決めた許容差で判定
「完全に同じ」ではなく、事前に決めた許容差の内側で一致した、という結果です。何が違いの原因だったかは、下の「SITL との照合で、どう効いたか」にまとめました。
実機のセンサーは「そのままの値」をくれない 再現例
実機の計測ではなく、箱庭ドローンPRO(Control Link)でこれらの癖を設定して飛ばしたシミュレーションの記録です。GPS の遅れ 100 ms、気圧計のノイズ 0.115 m。
フライトコントローラは、癖を前提に推定している
- GPSは、位置の計算に時間がかかり、約0.1秒前の位置を報告する。精度の見込みも報告する。
- 気圧計は、フィルタで少し遅れ、ノイズが乗る。
- ジャイロは、ゆっくりずれていく。
- 地磁気は、場所ごとに真北からずれている(偏角)。
- モーターは、指令してから回転が追いつくまでに時間がかかる。
PX4 や ArduPilot の状態推定(EKF)は、「GPS は何 ms 遅れて来る」といった見込みを持ち、それで補正しています。シミュレーションでセンサーが理想的すぎると、本物とは違う動きになります。
前提:フライトコントローラと箱庭ドローンPROのつなぎ方 センサーの値を、どこで作るか
箱庭ドローンPROは機体の物理を計算し、フライトコントローラとつないで飛ばします。つなぎ方は3通りあり、センサーの値をどこで作るかが違います。
PX4 SITL PX4 をまるごと動かす。センサーは箱庭ドローンPROが作る
箱庭ドローンPROが作ったセンサーの値を、PX4 はそのまま受け取ります。センサーの設定は、そのまま効きます。
周期:箱庭ドローンPROが送る間隔で決まる。センサーごとの更新周期(updatePeriodMsec)のとおりに、新しい値を渡す。
ArduPilot SITL ArduPilot をまるごと動かす。GPS・気圧計・地磁気は ArduPilot が作る
ArduPilot SITL は、受け取った真の位置・速度から GPS・気圧計・地磁気の値を自分の中で作ります(ノイズや遅れも ArduPilot の設定で)。そこで、箱庭ドローンPROの機体設定を ArduPilot の設定(SIM_* など)に変換して渡し、箱庭ドローンPROの側からは外します。
周期:IMU は物理の刻みごとに送る。GPS・気圧計・地磁気は ArduPilot SITL が自分の間隔で作る。GPS の更新周期は SIM_GPS_HZ に変換して渡し、気圧計(10 ms)・地磁気は ArduPilot の中で決まる。
Control Link フライトコントローラの部品を、箱庭ドローンPROの中で動かす
フライトコントローラの推定と制御の部品を、1つのプロセスの中で直接呼び出します。本物のソフトが生む処理の遅れ(ソフトの遅れ)や、出力から Duty への変換は、ここでは箱庭ドローンPROが再現します。
周期:「送る」経路がないので、推定に新しい値が届く間隔を、センサーごとの更新周期のとおりに再現する。SITL と比べるときは SITL の周期に、実機に合わせるときは実機の周期にそろえる。
センサーの更新周期:どこで決まるか
センサーは、決まった間隔で新しい値を出します。フライトコントローラの推定は、毎回の計算(予測)とは別に、新しい値が届いたときだけその値で補正します。更新周期も、遅れと同じく推定の動きを変える「癖」の一つです。
| センサー | 実機(目安) | PX4 SITL | ArduPilot SITL | Control Link |
|---|---|---|---|---|
| IMU(加速度・ジャイロ) | 250 Hz〜1 kHz 以上 | 更新周期のとおりに送る(x500 は 4 ms) | 物理の刻みごと(1 ms) | 更新周期のとおりに、推定に新しい値を渡す |
| 気圧計・地磁気 | 10〜100 Hz | 同じメッセージで送り、更新周期の回だけ「新しい値」の印を立てる(設定がなければ IMU と同じ) | ArduPilot SITL が作る(気圧計 10 ms。変えられない) | |
| GPS | 5〜10 Hz(100〜200 ms) | 更新周期のとおりに送る(設定がなければ 30 ms) | 更新周期を SIM_GPS_HZ に変換(設定がなければ 5 Hz) |
照合では、Control Link の周期を SITL にそろえました(PX4 の GPS は 30 ms、ArduPilot の地磁気は ArduCopter が読む 100 ms)。
箱庭ドローンPROの考え方
遅れは2種類に分けています。ハードの遅れは、センサーの値そのものが古い(フライトコントローラにも古い値が届く)。ソフトの遅れは、値は新しいが、制御ソフトが使うまでに時間がかかる。SITL では本物のソフトが自分でソフトの遅れを生むので、箱庭ドローンPROが入れるのは Control Link のときだけです。
設定できること:センサー 機体設定 components.sensors
| 設定 | 意味 | なぜ必要か | Control Link | PX4 SITL | ArduPilot SITL |
|---|---|---|---|---|---|
ノイズ(加速度・ジャイロ) noise | 正規分布のノイズの大きさ(標準偏差) | 推定やフィルタが、揺れる値の中で正しく働くかを確かめるため。乱数の種を変えれば、別の「個体」として何回でも試せる | ● | ● | ● |
ノイズ(気圧計・地磁気) noise | 同上 | 気圧計のノイズは高さの推定の揺れに、地磁気のノイズは機首の向きの推定の揺れに効く | ● | ● | 変換 |
ノイズ(GPS) noise | 位置・速度に加えるノイズ。注:現在は緯度・経度(度)・高度(m)・速度(m/s)に同じ値を加えるため、メートルにそろった位置の誤差ではありません(下の「限界」) | GPS の値のばらつきを再現するため | ● | ● | ― |
平均するサンプル数 sampleCount | 直近の何回分を平均して出すか | センサーの内部の平均化を再現するため。平均すると揺れは減るが、そのぶん遅れる | ● | ● | 加速度・ジャイロ |
ハードの遅れ(加速度・ジャイロ) delayMsec | センサーの値そのものが遅れる | フライトコントローラは遅れの見込みで補正する。遅れがないと、見込みとずれて推定が狂う | ● | ● | ● |
ハードの遅れ(GPS・気圧計・地磁気) delayMsec | GPS の解の計算、気圧計のフィルタなどによる遅れ | GPS は約0.1秒遅れて届くのが普通。フライトコントローラの見込み(GPS1_DELAY_MS など)と同じ値にそろえる | ● | ● | 変換 |
更新周期 updatePeriodMsec | 新しい測定値をフライトコントローラに渡す間隔(センサーごと)。上の「センサーの更新周期」 | 推定は新しい値が届いたときだけ補正する。周期が違うと推定の動きが変わる。GPS は実機では 100〜200 ms ごと | ● | ● | GPS だけ変換 |
ソフトの遅れ softDelayMsec | 制御ソフトが、受け取った値を使うまでの遅れ | 実機の処理の遅れは推定では補正されず、制御の安定の余裕を削る。SITL では本物のソフトが自分で生むので設定しない | ● | ― | ― |
ジャイロのずれ drift | ゆっくり増える角速度の誤差(三角波、またはランダムウォーク) | 機首の向きの推定がずれていく現象を再現するため。速度や位置の制御で打ち消せるかも確かめられる | ● | ● | 変換 |
GPS の精度(水平・垂直) accuracy.horizontalM・verticalM | GPS 自身が申告する位置の誤差の見込み(m)。下の解説 | フライトコントローラは、この値で GPS を使うか、どれだけ信用するかを決める | ● | ● | ― |
GPS の精度(速度) accuracy.speedMps | GPS 自身が申告する速度の誤差の見込み(m/s) | 速度の推定で GPS をどれだけ信用するかに効く。PX4 SITL は内部で固定値を使う | ● | ― | ― |
衛星の数 satellitesVisible | 見えている衛星の数 | フライトコントローラは、衛星が少ない GPS を使わない。受け入れの条件を試すため | ● | ● | ― |
CL=Control Link。● 箱庭ドローンPROがそのまま効かせる 変換 フライトコントローラの設定に変換して渡す ― 使わない(フライトコントローラが自分で生む、またはその経路がない)
解説:GPS の精度とは
GPS は、位置と一緒に「この位置はどのくらい当てにできるか」も報告します。一般には eph・epv と呼ばれる値です。
- 水平の精度(eph:Estimated Position error, Horizontal):水平の位置の誤差の見込み(m)。例:0.5 なら「水平はおよそ 50 cm の誤差」。
- 垂直の精度(epv:Estimated Position error, Vertical):高さの誤差の見込み(m)。一般に水平より大きい。
- 速度の精度(sacc:Speed Accuracy):速度の誤差の見込み(m/s)。
空が開けた場所では小さく、ビルの谷間や衛星が少ないときには大きくなります。
フライトコントローラは、この値を2つの目的に使います。
- 使うかどうか:誤差の見込みが大きい間は、GPS を位置の推定に使いません(PX4 では
EKF2_REQ_EPH・EKF2_REQ_EPV・EKF2_REQ_SACCなどで条件を決め、EKF2_GPS_CHECKでどの条件を使うかを選ぶ)。 - どれだけ信用するか:使うときも、誤差の見込みが大きいほど GPS の値を軽く扱い、加速度などからの予測を重く扱います。
精度の見込みと、実際の誤差は別のもの:精度は GPS の「申告」で、位置のばらつきそのものではありません。箱庭ドローンPROでも、精度(accuracy)と実際の誤差(noise)は別々に設定します。GPS の劣化を表すときは、両方を合わせて設定します。
設定できること:アクチュエータ
| 設定 | 意味 | なぜ必要か | Control Link | PX4 SITL | ArduPilot SITL |
|---|---|---|---|---|---|
ロータの特性 rotor.dynamics_constants | 抵抗・逆起電力定数・推力係数・トルク係数・慣性。回転が指令に追いつく速さ(時定数)もここから決まる | モーターはすぐには回らない。この遅れが、姿勢の制御の速さの限界を決める | ● | ● | ● |
最大回転数 max_rad_per_sec | 回転数の上限。指令と回転数の対応の基準にもなる | 全力で回したときの推力の余裕(推力と重さの比)を本物に合わせるため | ● | ● | ● |
電池 battery | 電圧の変化(電池のモデル)。モーターは Duty × 電池の電圧で回る | 電池が減ると同じ指令でも推力が落ちる。長い飛行での変化を見るため | ● | ● | ● |
| ローターの故障 | ローターごとの出力の倍率(1.0 正常、0.0 完全故障、その間は出力低下)。シナリオLinkから時刻に合わせて与える | 故障したときに機体がどうなるか、制御が持ちこたえるかを試すため | ● | ● | ● |
モーターまでの遅れ rotor.softDelayMsec | 制御の出力がモーターに届くまでの遅れ | ESC や通信の遅れを再現するため。SITL ではフライトコントローラの出力をそのまま使う | ● | ― | ― |
推力カーブ px4ThrustModelFactor | PX4 の推力カーブ(THR_MDL_FAC)と同じ形で、指令を Duty に直す | 指令と推力の関係(ループのゲイン)を、フライトコントローラの想定と同じにするため。SITL ではフライトコントローラ自身が行う | ● | ― | ― |
| 最新の指令だけを使う(UDP) | 溜まって届いた古い指令を捨て、最新だけでモーターを回す(常にON) | 古い指令が溜まると、その分だけ常に遅れて効く。ArduPilot SITL で 9 ms の遅れの原因だった | ― | ― | ● |
設定できること:環境と周期
| 設定 | 意味 | なぜ必要か | Control Link | PX4 SITL | ArduPilot SITL |
|---|---|---|---|---|---|
場所 location | 緯度・経度・高度 | GPS と気圧計の値の基準。地磁気も場所で決まる | ● | ● | ● |
地磁気 magneticField | 強さ・偏角・伏角。地磁気センサーはこの磁場を機体の向きで回して出す | 機首の向きの推定は地磁気が頼り。偏角がフライトコントローラの想定と違うと、機首の推定がずれる | ● | ● | 合わせる |
乱数の種 randomSeed | センサーごとのノイズの乱数を決める | 同じ種なら毎回同じ結果。違いの原因を切り分けられ、種を変えれば統計もとれる | ● | ● | 加速度・ジャイロ |
推定への周期の上書き ekf.*IntervalUsec | Control Link の推定に新しい値が届く間隔を、更新周期とは別に直接決める | Control Link だけで、推定側の周期を個別に試したいときのため(ふだんは更新周期から決まる) | ● | ― | ― |
ArduPilot の地磁気は ArduPilot が自分の磁気モデルで作り、置き換えられません。そこで、機体設定の地磁気を ArduPilot の値に合わせ、偏角は COMPASS_DEC で最初から渡します。
SITL との照合で、どう効いたか PX4編・ArduPilot編で見つけ、設定で直したもの
| 見えた違い | 原因 | 設定したこと | |
|---|---|---|---|
| PX4 | ホバー中に SITL だけ 11〜13 Hz で揺れる | PX4 SITL は IMU を1回遅れて使い、出力がモーターに届くのも約2 ms遅い。推力カーブの傾きも違う | Control Link に、ジャイロ・加速度のソフトの遅れ 4 ms、モーターまでの遅れ 2 ms、推力カーブ |
| PX4 | GPS・気圧計の遅れの見込みとずれる | 実機の GPS(約0.1秒)・気圧計の遅れ | GPS 100 ms・気圧計 60 ms のハードの遅れ。PX4 の見込み(SENS_GPS0_DELAY・EKF2_BARO_DELAY)も同じ値に |
| PX4 | 東への移動で推定が波打つ | PX4 SITL の GPS の更新周期は 30 ms。Control Link は既定の 100 ms だった | Control Link で、GPS の更新周期(新しい値が推定に届く間隔)を PX4 SITL と同じ 30 ms に |
| PX4 | 機首の推定が約0.3°ずれる | PX4 は自分の世界磁気モデルの偏角を使う | 機体設定の偏角を PX4 の値(15.011°)に |
| PX4 | 静止中に機首の推定が 0.3〜0.6° ずれる | PX4 SITL は IMU を 16 ビットの整数で受け取り、目盛りより遅い回転が見えない | Control Link で同じ整数化を再現 |
| ArduPilot | GPS・気圧計の遅れが二重 | ArduPilot SITL は GPS・気圧計を自分で作って遅らせる。機体サービスでも遅らせていた | 機体サービス側の遅れを外し、ArduPilot の SIM_* に変換 |
| ArduPilot | 指令が常に 9 ms 遅れて効く | SITL の起動時に送り直された指令が UDP の受信に溜まっていた | 受信で最新の指令だけを使う |
| ArduPilot | 機首の推定が 0.7° ずれる | 起動時は偏角0で機首を推定。SITL だけにジャイロのずれがあった | COMPASS_DEC を最初から設定。Control Link にもジャイロのずれを追加 |
| ArduPilot | 加速度のフィルタが効きすぎる | ArduPilot は IMU を 1 kHz と見込んでフィルタを決める | INS_ACCEL_FILTER を実際の周期に合わせて換算 |
結果:PX4 は68項目、ArduPilot は72項目を事前に決めた許容差で判定し、どちらも外れた項目なし。ArduPilot は直す前の OK 51 / 要確認 19 / NG 2 から、OK 66 / 要確認 6 / NG 0 になりました。
フライトコントローラの側で合わせる値 x500 の例
| 目的 | PX4 | ArduPilot | 決め方 |
|---|---|---|---|
| GPS の遅れの見込み | SENS_GPS0_DELAY 100 | GPS1_DELAY_MS 100 | 実際の遅れと同じ値 |
| 気圧計の遅れの見込み | EKF2_BARO_DELAY 60 | EK3_HGT_DELAY 60 | 同上 |
| 偏角 | 設定しない(PX4 の磁気モデル)→ 機体設定を合わせる | COMPASS_DEC 0.2645 rad(15.155°) | 起動時の機首の推定のため |
| GPS の遅れ(SITL が作る) | — | SIM_GPS_LAG_MS 100 | 機体設定から変換 |
| 気圧計(SITL が作る) | — | SIM_BARO_DELAY 60、SIM_BARO_RND(ノイズ × √3) | 正規分布の標準偏差を一様分布にそろえる |
| 地磁気(SITL が作る) | — | SIM_MAG_RND(ノイズ × √3 ÷ 100)、SIM_MAG_DELAY | nT → mGauss |
| ジャイロのずれ(SITL が作る) | — | SIM_DRIFT_SPEED・SIM_DRIFT_TIME | ずれなしなら 0(既定の 0.05 を使わない) |
| GPS の更新周期(SITL が作る) | — | SIM_GPS_HZ(更新周期から換算) | 設定がなければ 5 Hz |
| 推力カーブ | THR_MDL_FAC、MPC_THR_HOVER | MOT_THST_EXPO、MOT_THST_HOVER、MOT_SPIN_MIN/MAX | 機体のロータのモデルから |
| フィルタ | — | INS_GYRO_FILTER 42、INS_ACCEL_FILTER(周期で換算) | プロペラの大きさからの推奨値 |
| GPS の受け入れ条件 | EKF2_REQ_EPH・EPV・SACC・NSATS、EKF2_GPS_CHECK | — | GPS の精度の設定と合わせる |
ArduPilot の SITL 用の値(SIM_*、COMPASS_DEC)と EKF の見込みは、ツールが機体設定から自動で作ります。PX4 の EKF の見込みは、機体設定の遅れと同じ値をパラメータファイルに書きます。
箱庭ドローンPROでできること
- センサーの癖を、機体ごとの設定として持てる。遅れ・ノイズ・ずれ・精度・周期を、センサーごとに。
- 1つの設定を、PX4 にも ArduPilot にも。フライトコントローラが自分でセンサーを作る場合も、同じ意味になるよう変換します。
- 「理想のモデルでは飛んだのに、なぜ本物では違うのか」を切り分けられる。癖を一つずつ入れたり外したりして、原因を再現し、確かめられます。
- 乱数の種を変えて、何通りでも。同じ種なら同じ結果になるので、違いの原因を切り分けられます。
- 遅れを、共通の時刻で測れる。指令から機体が動くまでの各段の遅れを ms 単位で比べられます。SITL 側の 9 ms の遅れも、これで見つけました。
再現できない違い・限界
- ノイズの分布の形:箱庭は正規分布、ArduPilot は一様分布。標準偏差だけをそろえます。
- ArduPilot SITL は気圧計が2個。静止中の高さの推定のばらつきは、SITL のほうが大きく残ります。
- 地磁気は ArduPilot・PX4 の磁気モデルが基準。機体設定をそれに合わせます。
- GPS のノイズは、位置と速度で単位を分けるかを検討中です。
- SITL の実行ごとの揺らぎ(OS のタイミング)は再現しません。そのため、乱数の種を変えた10回と SITL の10回を統計で比べます。
ここに示した設定と値は、x500 の照合(PX4:2026年10月11日、ArduPilot:10月12日)で使ったものです。実機に合わせるときは、実機のセンサーの仕様や測定値に置き換えてください。
機体作成(Vehicle Builder) PID自動チューニング(Auto Tuning) シナリオLink Control Link:PX4編 Control Link:ArduPilot編 PROライセンスに戻る
