70366
## バックグラウンド

私は今、LEGO
EV3というプログラミング練習のオモチャで遊んでいます。数日前から倒立振子の作成に取り掛かりました。私は制御工学初心者ですので、現代制御はまだ難しく感じ、コーディングが簡単そうな古典制御のPID制御で作ることにしました。

制御もプログラミングも初心者なので、とりあえず必要と思う情報を書きます。不足があれば教えてください。

Python3.8,VScodeで書いてます。VScodeの拡張機能で、予めEv3に入っているクラス、モジュール、メソッドを呼び出してコードし、遠隔で操作しています。使うのは、ジャイロセンサーと、モーターです。

## やろうとしたこと

めちゃクチャ単純なのですが、本体が倒れかけて、くっつけたジャイロセンサーが`0`以外の角度を持てば、それに比例した速度で車体が倒れかけた方向に進みます。

```

    left_motor = Motor(Port.D)  # モーターと本体を繋ぐためにオブジェクト生成
    right_motor = Motor(Port.A) # モーターと本体を繋ぐためにオブジェクト生成
    robot = DriveBase(left_motor,right_motor,60,123) # 二つのモーターを同期させるためにオブジェクト生成
    gyro = GyroSensor(Port.S3)  # ジャイロセンサーと本体を繋ぐためにオブジェクト生成
    
    while True:
        robot.drive(-23*gyro.angle(),0)　
    
```

### 引数二つの説明

`drive`メソッドは、二つの数を要求します。（車体の速度mm/s,左右のモーターが出力するときの差）
注意していただきたいのは、角速度を要求しているのではないことと、二番目の引数は今回は必ず`0`ということです。

一つ目の引数の説明。`gyro.angle()`は呼び出されたときの角度を計って返します。

## 疑問点

これがP制御なのか怪しいところです。`-23`は適当にチューニングして手に入れたので比例ゲインぽいですが、やってることは実際のところ、偏差の実数倍を適当に出力してはオーバーシュートしての繰り返しです。時々、子鹿のようにプルプル震えながら一秒くらいたつのですが、基本的にはずっこけます。P制御とは、偏差を感じとって、例え残留偏差があろうとも、確実に目標値に近ずく制御方法です。しかし僕のコードではhileループを回しているだけで、目標値に向かっての”改善”が行われません。どうコーディングすればよいでしょうか？  
EV3のクラス、モジュール、メソッドをご存知ない方もいらしゃると思うので、あくまでコード例を提示していただくのは求めていません。指針だけでもお教えください。よろしくお願いします。
CC BY-SA 4.0
2020-09-11T12:55:14.177
70321
2020-09-14T01:45:39.123
2020-09-11T21:13:58.063
41334
41334
question
python python3 numpy sympy scipy
倒立振子（台車型）のPID制御について
シミュレーションでなく実物を制御するなら時間が大事です。

  * モーターやジャイロに指示を送る通信にも一定の時間が必要で
  * 指示に対してアクチュエータが反応するまでにも一定の時間が必要で
  * アクチュエータ上の「もの」が反応するまでにも一定の時間が必要で
  * 「もの」の動きを読み取る装置が反応するにも一定の時間が必要で

「機械」の実動作は CPU からみると超絶遅いので、その動作時間を無視して CPU
的にできる最速ループを回しても早すぎて破綻するだけです。提示コードの待ち時間は「通信」分だけですよね。ではどれだけ待てばよいかは系の反応速度であるとか消費してよい電力量とかの案件で異なります。

結論を言うと「式は P 制御に見える」「制御が早すぎて破綻している」でしょう。
CC BY-SA 4.0
2020-09-14T01:45:39.123
70366
2020-09-14T01:45:39.123
8589
70321
answer