DCモーター特性について考える

#概要
ＤＣモーターを制御する事はロボット工学・制御工学で良く例になるうえに、良く使用する対象であると思います。しかし、実際にやってみると、どうやってパラメータを同定すれば良いかわからない・同定したパラメータが信用できるのかと不安になります。私も今やってて信用できません・・・

#モーター特性

```tex
トルク　　＝　電流　*　トルク係数
入力電圧　＝ R*I +　逆起電圧
逆起電圧　＝ 回転速度　* 逆起電圧係数
```
というのが一般に、言われるDCモーターの特性です。
実際にはどこまで、この式は信用できるのでしょうか？

使用するモーターはRE-260,電流電圧をINA226で計測しながら、エンコーダーで回転角度を計測します。ドライバはL298Nを使用します。と思って装置を組んでいたところ、INA226のVBASの端子が読み出す電圧はV-基準でなくGND基準であるため、Hプリッジ型ドライバには使えませんでした。電圧が上限を一瞬大きく超えますが、ArduinoのAnalogReadピンに繫いで計測することにしました。I2C通信だからか、通信が途絶して、さらに以後の通信ができなくなることがありました。難しい。制御は5ms置きに行うこととする。INAのデータは逐次更新する。

#データーシートより
データーシートには定常応答しかないため、回転速度が一定となった場合しか使えないですが
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405484/081004b8-a05a-7685-8666-4691ac43352e.png)

```
I=(T+To)/Kt                     //T:トルク   To:損失トルク　Kt:トルク係数[N*m/A]
w = (V- Ra*I)/Ke                //w:角速度rpm   V:印加電圧　　R:モーター抵抗（直列）
                                        //Ke:逆起電圧係数[V/rpm]
```
とモデルを立て、仕様書のデータと一致するように数値を割り当てると

```
To損失トルク = 2.50*10^-4[N*m]
Ktトルク係数 = 2.00*10^-3[N*m/A]
Ke逆起電圧係数 = 2.53*10^-4[V/rpm] = 2.42*10^-3[V/(rad/s)]
Raモーター抵抗 = 0.633[Ω]
```
となった。実際にモーター間抵抗を計測すると3Ω程であった、静止状態の抵抗測定は接触の仕方、コイルの通過状態でちょっと変わるのかもしれない。

#実験ー参考までに
まず、ステップ応答にを見る
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405484/35a46c35-87b6-0330-be8f-897bc00bde79.png)


* 印加電圧がステップ状に印加できていない:ドライバ、電源で電圧降下している。抵抗と近似して見たが誤差が大きくてあまり抵抗近似は無理な気がする。
* 計測電圧にパルス上のノイズが乗っている：ＰＷＭ　で　電圧を指定しているためだと思われる。もしくは、整流子の影響？
* 電流が指数関数的に上がり、一定になるところはかなり線形方程式由来だと感じさせる。
(追記)

* MCP4922を使ってＰＷＭをAnalog入力にに変えたところ、ノイズが入らなくなりました！PWMは音も鳴るし、DACって大事ですね。
* しかし、L298NのVrefはアナログ入力ではなくEnableのことだったようで、PWM以外の選択肢はなかった（笑）
* Vrefはハイインピーダンスにするかどうかの選択肢なので、ノイズはハイインピーダンス状態に変化させられたため計測電圧がMAXに行っていたと予想します。よって、PWMする端子をIN端子のほうでVrefはHIGHで固定すればよい気がします。PWMの速度が遅すぎて、制御周期10msに合わないという結果になりました。モーター間電圧はなかなかいいデータは取れないですね

```math
入力電圧　＝ R*I +　逆起電圧\\
逆起電圧　＝ 回転速度　* 逆起電圧係数
```
と考えることで、Ｒ，逆起電圧係数を定める。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405484/ff612877-2445-8134-967f-8aca82d15c9f.png)

次に、電圧を印加後、モーターの角速度、電流が一定になるまで待つことでパラメータを推定する。

```math
J*(dw/dt)=Kt*i - c*w - τ損\\
一定速度では\\
i = (c/Kt)*w  + τ損/Kt\\
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405484/596c43b5-baed-38e2-4de5-2413acd6537d.png)
角速度の正負が逆になっているが、これで

```math
c/Kt　= 7.88*10^-5
τ損/Kt　= 0.08712
```
が得られた。ちなみに、τ損が存在するおかげで、電圧がある程度のところまではいくらかけても回転しない。

次に、ドライバの電流による電圧降下をドライバ出力前に抵抗が入っていると仮定して、そのドライバ抵抗を推定する。

```math
Vobs = Vin - R_{drive}*I
```
と仮定してエクセルのソルバーで近似すると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405484/1529fb03-9349-f8ba-9376-e1c9fef80072.png)
ドライバ抵抗 =  2.28Ω
Vin  =  3.90V
とわかる。

最後に、モーター慣性モーメント、粘性抵抗係数という機械要素を特定するため、モータに電圧を掛けて回した後モーター端子間を解放し電気系統が全く働かない状態をみる事で定める。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405484/bb6d5150-211c-d899-f8da-335b890a3ee9.png)
回転速度は指数関数的に落ちていく。

```math
J*(dw/dt) + c*w =- τ損\\
\therefore w = A*exp(-c/J * t) - τ損/c
```
となります。正し、τ損（摩擦由来）がc*w(粘性摩擦由来)を卓越して大きい場合

```math
J*(dw/dt)  =- τ損\\
\therefore w = - τ損/J * t
```
という、比例的な応答をします。今回の応答も比例的に見ようと思えば見えますが指数関数の方でフィッティングすると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405484/349a5794-eaed-d6ee-2a67-1c6636b2a67e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405484/5f47e8fd-0d02-48fa-636e-ea768cade50b.png)
Ａは初期値由来で意味はないです。この方法で得られるのはc/Jとc/τ損失　で単体c,Jを出すことはできません。
ちなみに、tsonは二つの導出ほうがあるが今回はどちらもほぼ同じ値になっている。

```math
Const_Currentで　　　τ損/Kt->τ損 =τ損/Kt * Kt=0.07045*0.00314 = 2.2*10^{-4}    \\
no_Power（指数）で　　c/τ損->τ損 =c/(c/τ損)=2.74*10^{-6}/0.0123 = 2.2*10^{-4}
```

#同定方法案まとめ

* Const_Current:定電流になるまで待ち、そのときの角速度と電流の関係よりc,tsonを推定

```math
J*(dw/dt)=Kt*i - c*w - τ損\\
一定速度では\\
i = (c/Kt)*w  + τ損/Kt\\
```
c/Kt と　τ損/Kt が求まる。

* no_Power:電圧を印加して回転させその後モーター間電圧を開放状態にし、その応答を見る事で機械的パラメータJを推定

```math
J*(dw/dt) + c*w =- τ損\\
\therefore w = A*exp(-c/J * t) - τ損/c
```
得られるのはc/Jとc/τ損失　で単体c,Jを出すことはできません。（Const_Currentでcがわかるのでtsonが二つ出てくる）
cよりτ損が卓越しているとき

```math
J*(dw/dt)  =- τ損\\
\therefore w = - τ損/J * t
```
 τ損/Jが求まる。

* step_Voltage:印加電圧を計測する。Re,Kを推定

```math
V=R*i+Ki*w
```
RとKiが求まる。

Ki=Ktと仮定すれば
R,Ki,c,τ損,Jが求まる。
一応、モデル化パラメータ全てが求まる事になる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405484/0443271e-48cb-97e3-6e62-167e0d5cf46f.png)

こんな感じになった。

#ギアボックスモーターの場合
タミヤのギアボックスを乗っけた場合も同じ方法でパラメータを推定した

* Const_Current

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405484/6e496478-4bdc-d382-886b-9e7c6d5f47c1.png)
900rad/sあたりでＡの増加がなくなっている。動きが慣れてきて摩擦が減って角速度が増加したのか？
900まででパラメータ同定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405484/4f045d7d-a9c5-b9ed-0614-6c4f9c18d854.png)
全てを使って
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405484/3d55fd81-ec74-170a-6663-122d6bd649ad.png)
電圧を測っていたのでそこからＲ，Ｋｉを出すと
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405484/c12a9da1-f811-9f2d-9449-fb0ea8459509.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405484/abb1d17d-fa1a-f7e7-401a-67007cfa0ff1.png)

* no_Power
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405484/a6252ecf-c974-1f4b-32ff-c6e2fd06c935.png)
指数近似だと悪くはないがなんとなくせっかくの直線が失われている感じを受ける。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405484/279e6ae9-a758-4d78-cb8a-8c9c7ec0458a.png)
こっちもこっちであまり一致していない感じを受けてしまう。

よそう１：粘性係数は一定としていたが、粘性係数も速度に比例していた？この場合、速度二乗になる。
詳しい方おしえてください。

とりあえず、結果としては指数関数の方を使うと
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405484/4c10f751-9934-c5e6-e1d5-5c09cea709fa.png)

こんな感じになった。数値のオーダーは悪くないと思う。
二つtsonがあるが、
Const_Currentで　　　τ損/Kt
no_Power（指数）で　　c/τ損
と二つの導出があるため、個人的にはConst_Currentのほうが信用できる気がする。no_Powerの指数近似は微妙なところがある。