こんにちは、junjunです!

本日のテーマは「ロボット制御の舞台裏!? シリアルモニタで各車輪の動きを調整してみた」です。
今回は、台車ロボットに限らず全てのロボット制御にも通ずるようなテーマになります。

↓NEXUS ROBOTの製品情報はこちら
http://www.vstone.co.jp/products/nexusrobot/index.html

以前私が投稿した記事では、理論的に3WDロボットを動かす方法についてご紹介していました。
技術的小話【その6】3輪台車ロボットの制御方法を簡単に解いてみた

しかし、決められた方向にただモータを回すだけでは思い通りに動けないのが
ロボット制御の楽しくも難しいところです。

同じ型のモータであっても、個体差によってその挙動が変わることが良くあります。
さらにはバッテリーの残量、組み立ての精度、路面の状態、ホイールの傷み具合などなど……
言い出してしまえばキリがないものです;

そんな中でも比較的プログラムで調整のしやすい「各車輪の動き」について、説明をします。

Nexus robot 3WD(10014)の車輪は、サーボモータを使って回転しています。

このサーボモータは送られてきた信号に対し、一般的な「指定した角度に合わせて動く」ものとは異なり
「角度値によって、正転・逆転・停止を行う」という少し変わった制御方法となっています。
(無限回転サーボと呼ばれることもあります)

Arduinoで行う制御としては割とシンプルで、通常のサーボ制御と同じように
角度値を送信すると、当てはまる動作(正転・逆転・停止)をします。
【例】(分かりやすくするために、正確ではない仮の値を設定しています)
0~89°まで:正転 / 90°:停止 / 91~180°まで:逆転

この動作をする角度値の幅がモータによって微妙に違うため、
今回はシリアルモニタを使って、停止させるために丁度良い角度値を探す様子を動画にしてみました!

当たり前のようにキレイに動いているロボットも、こういった地道な調整があってこそのものですからね…
私はこういった調整は好きなタイプです(笑)

使用したスケッチはコチラ
——————————————-
#include 
#include 

#define MOTOR1 9
#define MOTOR2 10
#define MOTOR3 11

#define FOWORD1 0
#define REVERSE1 164
#define STOP1 83

#define FOWORD2 7
#define REVERSE2 171
#define STOP2 89

#define FOWORD3 6
#define REVERSE3 170
#define STOP3 88

char input[1];
int pos = 0; // サーボのポジション(変数)
int target = 0; // サーボのポジション(変数)
String inString = “”; // 受信文字列用のバッファ

Servo wheels[3];

void setup(){
wheels[0].attach(MOTOR1);
wheels[1].attach(MOTOR2);
wheels[2].attach(MOTOR3);

wheels[0].write(STOP1);
wheels[1].write(STOP2);
wheels[2].write(STOP3);

Serial.begin(9600);

}

// シリアル通信で受信したデータを数値に変換
void serialNumVal(){
while (Serial.available() > 0) { // 受信データがあったら…
int inChar = Serial.read(); // 1バイト読み込む
if (isDigit(inChar)) { // 数値だったら…
inString += (char)inChar; // 文字列を連結する
}
else if(inChar != ‘\n’){
if(inChar == 97){ //a
target = 0;
Serial.println(“Target Change wheel0”);
}
else if(inChar == 98){ //b
target = 1;
Serial.println(“Target Change wheel1”);
}
else if(inChar == 99){ //c
target = 2;
Serial.println(“Target Change wheel2”);
}
}
if (inChar == ‘\n’) { // 改行コードLFが来たら…
pos = inString.toInt(); // 文字列を数値に変換する
Serial.println(pos);
wheels[target].write(pos);
//wheels[0].writeMicroseconds(pos);
inString = “”; // バッファクリア
}
}
}

void loop(){
serialNumVal();
/*
wheels[0].write(FOWORD1);
delay(2000);
wheels[0].write(STOP1);
delay(2000);
wheels[0].write(REVERSE1);
delay(2000);
wheels[0].write(STOP1);
delay(2000);

wheels[1].write(FOWORD2);
delay(2000);
wheels[1].write(STOP2);
delay(2000);
wheels[1].write(REVERSE2);
delay(2000);
wheels[1].write(STOP2);
delay(2000);

wheels[2].write(FOWORD3);
delay(2000);
wheels[2].write(STOP3);
delay(2000);
wheels[2].write(REVERSE3);
delay(2000);
wheels[2].write(STOP3);
delay(2000);
*/
}

——————————————
ご質問等は受け付けておりませんのであしからず!