コンテンツにスキップ

02. 加速して停止する移動

止まっている台車を 10 m 先へ運び、そこでぴったり止めます。台車の加速度は ±2 m/s² までしか出せません。 いちばん早く着くには、いつアクセルを踏み、いつブレーキをかければよいでしょうか。

項目内容
状態位置 xx、速度 vv
制御加速度 aa
目的到着時刻 tft_f を最小にする
区間2区間(加速・減速)、各12ノード、区間の境目の時刻と終了時刻は自由
新しく学ぶこと状態が2つある運動方程式、制御の上下限、時間を2つの区間に分けること

例題01 では速度を直接選べました。現実の乗り物では、選べるのはアクセルやブレーキ、 つまり加速度です。速度は加速度を積み重ねた結果として決まり、急には変えられません。 そのため、この例では位置 xx と速度 vv の2つを状態とし、加速度 aa を制御にします。

着いたときに止まっていなければならないので、ただ全力で加速し続けるわけにはいきません。 どこかでブレーキに切り替える必要があります。切り替えが早すぎると途中で遅くなって時間を損し、 遅すぎると止まりきれずに行き過ぎます。

x˙=vv˙=a\begin{aligned} \dot{x} &= v \\[2pt] \dot{v} &= a \end{aligned}

1行目は「位置は速度で変わる」、2行目は「速度は加速度で変わる」という意味です。 台車に摩擦や空気抵抗はないものとします。加速度 aa を選ぶと、まず速度が変わり、その速度によって位置が変わります。 制御が状態に2段階を経て効くのが、例題01との違いです。

x(0)=0,v(0)=0x(tf)=10,v(tf)=0\begin{aligned} x(0) &= 0, & v(0) &= 0 \\[2pt] x(t_f) &= 10, & v(t_f) &= 0 \end{aligned}

原点に止まっている状態から出発し、10 m 先で止まっている状態で終わります。終了時刻 tft_f は未知で、答えとして決まります。

−2≤a≤2-2 \le a \le 2

加速度の大きさは 2 m/s² 以下です。正の値はアクセル、負の値はブレーキにあたります。 この制約は両方の区間で同じです。

時間を「区間1」と「区間2」の2つに分けて解きます。区間の境目の時刻 t1t_1 も終了時刻 tft_f と同じく未知数です。 境目では位置と速度がつながる条件が自動で課されますが、加速度は境目で不連続に変わってもかまいません。 後で見るように、最適な加速度は途中で一度だけ不連続に切り替わるので、その切り替え時刻を区間の境目にあてるための分割です。

J=tfJ = t_f

到着時刻そのものを最小にします。積分コストはありません。

記号意味値
dd移動距離 PARAMETERS["distance"]10 m
amax⁡a_{\max}加速度の上限 PARAMETERS["max_acceleration"]2 m/s²

答えを知らない前提で、大まかな初期推定から始めます。

  • 区間の時刻は 0→3→60 \to 3 \to 6 s と置きます。
  • 6 s かけて一定の速さ d/6d/6 で進むとし、位置は 0 から dd へ直線的に増やし、速度は d/6d/6 で一定にします。
  • 加速度は 0 にします。

この推定は出発時と到着時に止まっていないので、境界条件を満たしていません。 境界条件を満たし、所要時間が短くなるように、区間の時刻・状態・加速度をソルバーが動かします。

位置・速度・加速度の時間履歴。青は区間1(加速)、オレンジは区間2(減速)で、点は各区間12個のノードでの値、線はそれらを通る多項式です。黒の破線は解析解、縦の灰色の破線は区間の境目、赤の点線は加速度の上下限 ±2 です。
位置・速度・加速度の時間履歴。青は区間1(加速)、オレンジは区間2(減速)で、点は各区間12個のノードでの値、線はそれらを通る多項式です。黒の破線は解析解、縦の灰色の破線は区間の境目、赤の点線は加速度の上下限 ±2 です。
台車が動く様子。左は直線上の台車の位置で、通った部分を区間ごとの色で示します。右は速度と加速度の時間履歴で、縦線が現在の時刻です。
  • 到着時刻は 4.472 s です。解析解 25=2\sqrt{5} = 4.472 s と一致します。
  • 区間の境目は 2.236 s、そのときの位置は 5.00 m(ちょうど中間)、速度は最大の 4.472 m/s です。
  • 加速度は区間1でずっと上限 +2+2、区間2でずっと下限 −2-2 です。速度のグラフは三角形になります。

なぜ「全力で加速して全力で止まる」のか

Section titled “なぜ「全力で加速して全力で止まる」のか”

速度を縦軸、時刻を横軸にとったグラフでは、グラフの下の面積が進んだ距離になります。 距離は 10 m と決まっているので、面積 10 の図形を、できるだけ横幅(時間)を短くして作ればよいことになります。

出発時と到着時は速度 0 なので、図形は左端と右端で高さ 0 です。そして加速度の上限のため、 グラフの傾きは ±2\pm 2 を超えられません。この条件で横幅を最小にするには、 できるだけ急な傾きで上がり、できるだけ急な傾きで下がる三角形にするしかありません。 台形や丸い形では、同じ面積を作るのに横幅が余分に必要になります。

このように、制御が常に上限か下限のどちらかに張り付き、その間を切り替えるだけの制御をバンバン制御といいます。 最短時間問題でよく現れる形です(間接法による導出)。

三角形は左右対称で、頂点は中間点 x=d/2x = d/2 です。加速度 amax⁡a_{\max} で d/2d/2 進む時間 t1t_1 は

12amax⁡t12=d2⇒t1=damax⁡\frac{1}{2} a_{\max} t_1^2 = \frac{d}{2} \quad\Rightarrow\quad t_1 = \sqrt{\frac{d}{a_{\max}}}

なので、到着時刻は

tf=2t1=2damax⁡=25t_f = 2 t_1 = 2\sqrt{\frac{d}{a_{\max}}} = 2\sqrt{5}

です。最大速度は amax⁡t1=d amax⁡=20a_{\max} t_1 = \sqrt{d\,a_{\max}} = \sqrt{20} m/s です。

擬スペクトル法は、各区間の状態と制御をなめらかな多項式で表します。多項式は、加速度が +2+2 から −2-2 へ 跳ぶような不連続な関数を表すのが苦手です。無理に1本で表すと、跳びの前後で値が波打ちます (区間に分ける)。

そこで、切り替えの時刻を区間の境目に置けば、各区間の中では加速度は一定になり、多項式でぴったり表せます。 加速度は境目で跳んでもよく、位置と速度だけがつながっていればよいのです。

  • PARAMETERS["distance"] を 40 にすると、到着時刻が 240/2≈8.942\sqrt{40/2} \approx 8.94 s と2倍になることを確かめる。距離を4倍にすると時間は2倍です。
  • make_problem の Problem([0, 3, 6], ...) を Problem([0, 1, 6], ...) に変え、区間の境目の初期推定を偏らせる。 最適化は成功を報告しますが、境目の時刻は約 1.32 s で止まり、加速度の切り替えは区間2の途中で数ノードかけて起こります。 到着時刻は約 4.50 s で、解析解よりわずかに長くなります。区間の境目と制御の切り替えが合っていることの大切さがわかります。
  • main() の solve() を solve(nodes=4) に変えて各区間のノード数を 12 から 4 に減らしても、各区間の解が1次式・2次式なので答えが変わらないことを確かめる。
ターミナルウィンドウ
uv run python examples/02_move_stop.py

examples/02_move_stop.py を GitHub で見る