中野島ロボット

小さなロボットの自作記事を書いています。

週刊中ロボ31 「よつあし」調整用スケッチ公開

はじめに

「よつあし」のモーションはまだ微調整中なのですが、直ぐに作って遊べるように調整用に使ったスケッチを公開しておきます。

 

「よつあし調整用スケッチ」ダウンロードサイト

 

// Arduiroid Humanoid Robot 0.1 nakarobo 2018.11.4
// File yotuasiTest.ino

// Servo
#include <Servo.h>

#define MAX_SERVO_NUM 8
Servo servo[MAX_SERVO_NUM+1];

//Arduroid4 (Top View)
//FLONT
//  -----               -----
// |  2  |             |  6  |
// | P03 |             | P07 |
//  ----- -----   ----- -----
//       |  1  | |  5  |
//       | P02 | | P06 |
//        -----   -----
//       |  3  | |  7  |
//       | P04 | | P08 |
//  ----- -----   ----- -----
// |  4  |             |  8  |
// | P05 |             | P09 |
//  -----               -----  
//BACK


// Setup First Power On at Once
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  while (!Serial);

  // Servo Test
  attachServo();
  detachServo(); 

}

// MainLoop
void loop() {
  // if there's any serial available, read it:
  while (Serial.available() > 0) {

    // servo ON
    attachServo();

    char command = Serial.read();
    switch (command){
      case '0': // ToDo
        set8Pos(90,90,90,90,90,90,90,90);    delay(300);
        break;
      case '1': // ToDo
        set8Pos(90,90,90,90,90,90,90,90);    delay(300);
        break;
      case '2': // ToDo
        set8Pos(90,90,90,90,90,90,90,90);    delay(300);
        break;
      case '3': // ToDo
        set8Pos(90,90,90,90,90,90,90,90);    delay(300);
        break;
      case '4': // ToDo
        set8Pos(90,90,90,90,90,90,90,90);    delay(300);
        break;
      case '5': // ToDo
        set8Pos(90,90,90,90,90,90,90,90);    delay(300);
        break;
      case '6': // ToDo
        set8Pos(90,90,90,90,90,90,90,90);    delay(300);
        break;
      case '7': // ToDo
        set8Pos(90,90,90,90,90,90,90,90);    delay(300);
        break;
      case '8': // ex Back
        set8Pos( 90, 90, 90, 90, 90, 90, 90, 90);  delay(250);
        set8Pos( 90, 90, 70, 20, 90, 90,110,160);  delay(250);
        set8Pos( 90,160, 90, 90, 90, 20, 90, 90);  delay(250);
        set8Pos( 90, 90, 90, 90, 90, 20, 90, 90);  delay(250);
        set8Pos( 90, 90, 90, 90, 90, 90, 90, 90);  delay(300);
        break;
      case '9': // ToDo        
        set8Pos(90,90,90,90,90,90,90,90);    delay(300);
        break;
      case 'D': // Wait
      case 'd':
        delay(300);
        break;
     } // switch

    // SERVO Set command
    if ( command == 'S' || command == 's' )  // 'S' is Servo Command "S,Servo_no,Angle"
    {
      Serial.print(command);
      Serial.print(',');
      int servoNo = Serial.parseInt();
      Serial.print(servoNo);
      Serial.print(',');
      int servoAngle = Serial.parseInt();
      Serial.print(servoAngle);
      Serial.println();

      if ( 0 <= servoNo &&  servoNo < MAX_SERVO_NUM+1 )
      {
        // Single Servo Move
        servo[servoNo].write(servoAngle);

        // Wait Servo Move
        delay(300); // 180/60(°/100msec)=300(msec)
      }
    }  // SERVO Set END

    // SERVO All command
    if ( command == 'A' || command == 'a' )  // 'A' is Servo All Command "A,Angle0, Angle1...Angle7"
    {
      Serial.print(command);

      // read Angle from Serial
      int angle[MAX_SERVO_NUM];
      for (int i = 0; i < MAX_SERVO_NUM; i++)
      {
        angle[i] = Serial.parseInt();
        Serial.print(',');
        Serial.print(angle[i]);
      }
      Serial.println();

      // servo Move
      set8Pos( angle[0], angle[1], angle[2], angle[3], angle[4], angle[5], angle[6], angle[7] );
      
      // Wait Servo Move
      delay(300);

    }   // SERVO All End
    
    // Servo OFF
    detachServo(); 

  } // End while 

}// End loop

// attach ServoMotors
void attachServo()
{
  // attach Pin to ServoMotor
  servo[1].attach(6);
  servo[2].attach(7);
  servo[3].attach(8);
  servo[4].attach(9);
  servo[5].attach(2);
  servo[6].attach(3);
  servo[7].attach(4);
  servo[8].attach(5);
}

// dettach ServoMotors
void detachServo()
{
  servo[1].detach();
  servo[2].detach();
  servo[3].detach();
  servo[4].detach();
  servo[5].detach();
  servo[6].detach();
  servo[7].detach();
  servo[8].detach();
}

// Set 8 ServoMotor angles
void set8Pos(int a, int b, int c, int d, int e, int f, int g, int h){
  servo[1].write(a);
  servo[2].write(b);
  servo[3].write(c);
  servo[4].write(d);
  servo[5].write(e);
  servo[6].write(f);
  servo[7].write(g);
  servo[8].write(h);
}
// End
//---------------------

  解説

「よつあし」は関節の向きを変えることで、違った動物に見えるようにする事ができます。そのため、モデルを変えサーボの取付方向が変わると、軸の回転方向が異なることになり、同じ足の運び方でもモデル毎に角度指定を変える必要があります。つまり、「カニ風味」のモーションは、「たこ風味」では回転方向が逆になったりしてそのままでは使えないのです。 

なので、軸の回転方向を初期値で変更できるようにしておいたり、原点をサーボの中心角度に設定したり、サーボ間のオフセットを調整したりする機能を持たせていたのですが、ソフトの初心者には逆に難しく思えるそうです。

 その辺のおせっかい機能はバッサリそぎ落として、

  ”指定した角度にサーボは回る 以上”

としたのがこのスケッチで、パソコンからUSBケーブルを通じて「よつあし」のモーションを直感的に作成できるようにしています。

 

スケッチの使い方

Arduino IDE からArduino Nanoにスケッチを書き込みます。

なお、Arduino IDE 1.8.X以降では、プロセッサでATmega328P (Old Bootloader)を選択しないと書き込めません。

スケッチが書き込めたら、Arduino IDEのシリアルコンソールを開いて、サーボモーターの位置を指定できるようになります。

 

s コマンド

  続くサーボ番号と指示角度を読み込んで、サーボを指定位置に向けます。

  例  s,1,120

最初に重要なのはサーボの駆動範囲の確認です。サーボがどこまで回したらボディや他のサーボに当たるかをsコマンドで確認して行きます。軸がどっち回りに回ると、足がどう動くかを確認してメモを取っておきます。

 

a コマンド
 続く八個の角度を読み込んで、順番にサーボモータを指定した角度に回します。サーボモータの角度は0から180の間で指定して下さい。

 例 a,90,90,90,90,90,90,90,90

だいたいこの設定の時に、「よつあし」の原点調整を行い、ロボットの原点を決めておきます。大きくずれている場合は、サーボホーンを一旦外して付け直します。

f:id:nakarobo:20181112134656j:plain

つぎにロック位置の確認です。ロック位置とは、サーボの電源をオフにしても、ロボットが転倒せずに安定して保持していられるサーボ位置です。先に探した駆動範囲の端で、安全に止められるようならそこをロック位置にします。

 

dコマンド

 300msecディレイします。

300msecのあいだはサーボモータの電源が入り、先に指定していた角度に向かって動くので、軸の動きが遅いときや時間調整が必要な時に使います。

SG90サーボモータのスペックは、60°/0.1sec (軽負荷時)なので、最大0°から180°まで動かすには、180÷60*0.1sec =0.3sec=300msec の時間が必要になります。

 

ユーザコマンド

0から9までのユーザコマンドを登録可能です。メモリが許せばさらに追加も可能です。作成したモーションを好きな番号の case と break; の間に登録して行きます。
姿勢一回分を設定する関数が、 set8pos() 関数で、8つの引数はそれぞれ8つのサーボモータの角度を指定します。サーボモータが動くまでの時間は、delay() 関数で待ちます。最初は100~300msecくらいから始めると良いでしょう。

f:id:nakarobo:20181112132515p:plain

 

モーションの作り方

モーションエディタでモーションを編集して、シリアルコンソールから入力すると、そのモーションを再生します。モーションとは aコマンドで希望とする姿勢になるように、調整したサーボモーターの位置を繋ぎ合わせて一連の動きとしたものです。

モーションエディタは Windows10標準のメモ帳を使用します。 

f:id:nakarobo:20181112125413p:plain

 

 

モーションの作成

あとはaコマンドで、自分が思い描いた位置に足が来るように入力して行きます。最初はなんとなくで構いません。もう少し前とか、足りなければ5°足すとかして姿勢を作成して行きます。
aコマンドで一度に送れるのは、3行までなので、3行ごとに分けて書いておきます。3行ごとにシリアルコンソールにコピーして貼り付けて送信を押すと、三行分の動作を行います。

f:id:nakarobo:20181112125340p:plain

姿勢を組み合わせてモーションが出来上がったら、適当な数字の所にコード記述して行きます。そうすると、シリアルコンソールから一文字入力するだけでそのモーションが再生できるようになります。

また、色んなモーションが出来上がると、続けて入力して連続したモーションとして再生することができます。たとえば、前進を2、左回転を4に登録したとして、

 前進、前進、左回転、左回転、左回転、前進、前進

だったら

 2244422

とすれば指示されたとおりにロボットが動きます。

 

おわりに

これで「よつあし」が自由に動かせるようになりました。
あとは、センサや赤外線リモコンを追加して、オリジナルの四足歩行ロボットの制作を楽しんで下さい。

もし良いモーションが出来たら、Thingversかブログのコメント欄に乗せてみて下さい。case 8 は僕のお気に入り「たこ風味」の後進モーションです。

 

購入品情報

コントローラはやはり、ArduinoNanoが使いやすいですね。

これが純正品です。 

Arduino Nano

Arduino Nano

 

 以下の二つは国内発送なので到着が早いです。ヘッダピンがはんだ付けされていません。

こちらも国内発送です。ヘッダピンがはんだ付けされていますが、曲がっていることが多いようです。