Arduinoでロボットを作ってみました!【10】動作試験Part1:首関節が痙攣してる!!
スコープユニット動作確認
最初にθαβステージを中心位置にするため下記のスケッチを実行しました。
#include <Servo.h> // ライブラリの読み込み<Servo.h>
Servo servo0,servo1,servo2; // Servo型の変数は「servo0」~「servo2」とする
void setup() // 初期設定
{
servo0.attach(4); // Servo型の変数は「servo0」をピン4(θ軸)に割り当てる
servo1.attach(5); // Servo型の変数は「servo1」をピン5(α軸)に割り当てる
servo2.attach(6); // Servo型の変数は「servo2」をピン6(β軸)に割り当てる
}
void loop() // メインの処理
{
servo0.write(90); // サーボ出力。Servo0角度は90°
delay(1000); // タイマ(1秒)
servo1.write(80); // サーボ出力。Servo1角度は80°
delay(1000); // タイマ(1秒)
servo2.write(82); // サーボ出力。Servo2角度は82°
delay(1000); // タイマ(1秒)
}
ところが、いきなり首関節がはげしく痙攣し始めました。
当初、電気的なノイズによる誤動作かと思い、RCサーボの配線経路変更など行いましたが、現象は収まりません。そこで、スコープユニットの関節部の固有振動数が振動源の周波数と一致する共振現象によるものと推定して、スコープユニットの上におもりを載せてみました。おもりは、呼び6x30x1.5のステンレス製平座金を8個計61.5gです。
対策の効果をより分かりやすくするために、αテーブルに積極的に加振力を与えるように90°→80°→90°→・・・のように動かしています。
:
void loop() // メインの処理
{
servo0.write(90); // サーボ出力。Servo0角度は90°
delay(1000); // タイマ(1秒)
servo1.write(90); // サーボ出力。Servo1角度は90°
delay(500); // タイマ(0.5秒)
servo1.write(80); // サーボ出力。Servo1角度は80°
delay(1000); // タイマ(1秒)
servo2.write(82); // サーボ出力。Servo2角度は82°
delay(1000); // タイマ(1秒)
}
おもりを載せることで、αテーブルの振動は収まりますので、共振が原因とも考えられます。
それでは、振動源はなんでしょうか。αテーブルに使用しているRCサーボSG90のPWM周期が20ms (50Hz)ですので、これが振動源の候補となります。そこで、αステージから上で、固有振動数が50Hz近傍になる箇所を探していきます。
先ず、テーブルの回転軸に対して剛体振り子と考えるとどうでしょうか。剛体振り子の固有振動数は、
この式を使ってαテーブル、βテーブルについて計算すると、
αテーブルの回転軸に対する固有振動数は2.09Hz、βテーブルの回転軸に対する固有振動数は1.77Hzです。振動源の50Hzから大分離れていますので、これが共振の要因とは考えずらいようです。
次にαステージテーブルの固有振動数を計算してみます。
αステージテーブルはこのような形をしていますが、このままでは固有振動数が計算しずらいので、両端固定はりの固有振動数計算に置き換えて検討します。
材質、幅b、高さhをαステージテーブルと同じにして、中央に同一の集中荷重<ここではβステージ+スコープユニットの合計質量=60.5gより0.593N>を負荷した際にたわみが同一となるように両端固定はりの長さLを決め、これをαステージテーブルの等価モデルとして固有振動数を計算します。
上記の式に
材質:板目表紙(縦目)
縦弾性係数:3.89 GPa
密度:749.1 kg/m^3
はりの長さ L:44.94mm = 0.04494m
はりの幅 b:24mm = 0.024m
はりの高さ h:0.7mm = 0.0007m
負荷質量 m:60.5g = 0.0605kg(βステージ+スコープユニット合計質量)
を入れて計算すると
αステージテーブルの固有振動数 fa = 48.5Hz
αステージテーブルが共振して首関節が痙攣!!しているようです。
βステージテーブルの固有振動数は負荷質量 mをスコープユニットのみの質量 45gとして fb = 56.2Hzとなります。
共振対策
αステージテーブルの固有振動数を振動源の周波数50Hzからずらすために、スコープユニット内におもりを追加します。
おもりは、呼び6x30x1.5(実測値:内径φ6.7 x 外径φ29.7 x 厚み1.5)のステンレス製平座金8個計61.5gです。
重心位置を計算すると、αステージに関しては、おもりがない場合よりも重量バランスも良くなります。
実際におもりを追加して、振動がどのようになるかを確認しました。おもりは左右に1枚ずつ増やしていき、<おもりなし><左右各1個計2個><左右各2個計4個><左右各3個計6個><左右各4個計8個>の5通りをαステージ、βステージの振動に着目して試験を行いました。
αステージの振動試験は下記のスケッチで動かします。
#include <Servo.h> // ライブラリの読み込み<Servo.h>
Servo servo0,servo1,servo2; // Servo型の変数は「servo0」~「servo2」とする
void setup() // 初期設定
{
servo0.attach(4); // 「servo0」→ピン4(θ軸)
servo1.attach(5); // 「servo1」→ピン5(α軸)
//servo2.attach(6); // 「servo2」→ピン6(β軸):無効
}
void loop() // メインの処理
{
servo0.write(90); // Servo0角度:90°
delay(1000); // タイマ(1秒)
servo1.write(80); // Servo1角度は80°
delay(1000); // タイマ(1秒)
}
βステージの振動試験は下記のスケッチで動かします。
#include <Servo.h> // ライブラリの読み込み<Servo.h>
Servo servo0,servo1,servo2; // Servo型の変数は「servo0」~「servo2」とする
void setup() // 初期設定
{
servo0.attach(4); // 「servo0」→ピン4(θ軸)
//servo1.attach(5); // 「servo1」→ピン5(α軸):無効
servo2.attach(6); // 「servo2」→ピン6(β軸)
}
void loop() // メインの処理
{
servo0.write(90); // Servo0角度:90°
delay(1000); // タイマ(1秒)
servo2.write(87); // Servo2角度:82°+5°
delay(1000); // タイマ(1秒)
servo2.write(77); // Servo2角度:82°-5°
delay(1000); // タイマ(1秒)
}
βステージ中心位置±5°首振り運動です。
試験結果をまとめると、
×:振動が収束しない △:振動するが収束する
このように、固有振動数を共振周波数から離しただけでは、振動を抑えることができません。この要因はRCサーボSG90の非力な発生トルクに対して、慣性モーメントが大き過ぎて制動しきれていないためではと考えられます。
αテーブル回転軸回りの慣性モーメントがβテーブルに比べて、大分大きくなっています。
βステージの振動試験の結果を見ると、おもりの個数が少なくて慣性モーメントが小さいところで振動が収束せず、おもりを増やしていくと揺れながらも振動が収束しています。この要因はおもり0個と2個では固有振動数が振動源の周波数に近いために共振が発生しおり、おもりを増やしていくと固有振動数が振動源の周波数から離れていくために、共振が発生しずらくなって、SG90がなんとか頑張って制動していると考えて良いかと思います。
αテーブルでは固有振動数を下げるためにおもりを追加すると、慣性モーメントが巨大になり、SG90が制動できなくなっているものと考えられます。
以上の検討から、首関節の痙攣を収めるためには、固有振動数を振動源の周波数50Hzから上または下に10~15Hz以上離す、また回転軸回りの慣性モーメントをできるだけ小さく5E-5 (kg・m^2)以下程度にする必要がありそうです。
首関節の構造を大幅に見直さなければならないようです。