元高専生のロボット作り

元高専生のロボット作り

主にプログラミング, 電子系について書きます。たまに機械系もやります。メモ代わりの記事ばっか書きます

Arduinoでサーボモーターの角速度制御をする

サーボモーターって角度制御は簡単なんですけど、角速度制御しようと思うと面倒だったり、動きがカクカクしてしまうことあると思います。

しかし、ArduinoにはVarSpeedServo.hという素晴らしいライブラリがあります。

これは、タイマーを利用して、角速度から角度を計算し、自動で角速度制御をしてくれるものです。

自分でやるよりこのライブラリを使用した方がサーボモーターの動きは滑らかになります。

とりあえずこんなコードを書いてみました。

#include <VarSpeedServo.h> 

VarSpeedServo servo;

void setup() {
  servo.attach(11);
} 

void loop() {
  servo.write(140, 1, true);
  servo.write(50, 30, true);
}

詳しくはここ読んでください。
github.com

servo.write(value, speed, wait)
で角速度speedで角度valueへ向かうといった感じでしょうか。waitはbool値で、trueなら目標角度に到達するまで他の処理を受け付けない、falseなら制御途中で角度の変更ができます。

ただ、このspeedというのが1から255の値で定めるので、正確な単位が分からないんですよね。
なので、すこし計測してみました。
使用したサーボモーターはロボット用サーボのDSR3801です。(現在入手方法が分からないです)

角度を50度変化させるのと、90度変化させるのとで引数speedの値を変化させて目標角度への到達時間を計測してみました。
計測結果です。

speed [deg] [sec] ω1[deg/sec] speed [deg] [sec] ω2[deg/sec] speed ω1とω2の平均
1 50 20.48 2.44140625 1 90 37.31 2.412221924 1 2.426814087
2 50 10.35 4.830917874 2 90 18.81 4.784688995 2 4.807803435
3 50 6.91 7.235890014 3 90 12.61 7.137192704 3 7.186541359
4 50 5.22 9.578544061 4 90 9.41 9.564293305 4 9.571418683
5 50 4.2 11.9047619 5 90 7.61 11.82654402 5 11.86565296
6 50 3.6 13.88888889 6 90 6.5 13.84615385 6 13.86752137
7 50 2.95 16.94915254 7 90 5.5 16.36363636 7 16.65639445
8 50 2.7 18.51851852 8 90 4.77 18.86792453 8 18.69322152
9 50 2.44 20.49180328 9 90 4.29 20.97902098 9 20.73541213
10 50 2.11 23.69668246 10 90 3.99 22.55639098 10 23.12653672
11 50 1.95 25.64102564 11 90 3.45 26.08695652 11 25.86399108
12 50 1.82 27.47252747 12 90 3.24 27.77777778 12 27.62515263
13 50 1.61 31.05590062 13 90 2.91 30.92783505 13 30.99186784
14 50 1.55 32.25806452 14 90 2.75 32.72727273 14 32.49266862
15 50 1.45 34.48275862 15 90 2.6 34.61538462 15 34.54907162
16 50 1.4 35.71428571 16 90 2.5 36 16 35.85714286

speedと角速度ωの関係をグラフにあらわすとこうなります。
f:id:sgrsn1711:20180315233713p:plain
speed=10あたりから秒数が小さくなるので計測誤差が目立ちますが、まあまあ線形性がでてますね。

線形近似による式から
ω = 2.2809speed + 0.3824
の関係が分かりますので、この式を用いて単位のはっきりしている角速度制御ができそうです。