3.ライトセンサの使用 TOPへ 5.超音波センサの使用

4.ロータリーエンコーダの使用


ここでは回転量を知ることができるロータリーエンコーダのプログラムを学びます。 NXTではモーターにロータリーエンコーダが組み込まれており、正確な角度制御が出来るようになりました。 さらに、複数のモーターを同調させるなどの実際に使う上で便利な機能もあります。


1.モーターを任意の角度回転させる

ロータリーエンコーダはモーターに組み込まれているので、ロボットの改造はしません。
ここではモーターを360度回転させるプログラムを作成します。
次のプログラムを作成してください。ここでは、rotary1.c とします。
rotary1.c
#define ANGLE 360

task main(){
	nMotorEncoder[motorB] = 0;
	nMotorEncoder[motorC] = 0;
	nMotorEncoderTarget[motorB] = ANGLE;
	nMotorEncoderTarget[motorC] = ANGLE;

	motor[motorB] = 50;
	motor[motorC] = 50;
	while(nMotorEncoder[motorB] < ANGLE && nMotorEncoder[motorC] < ANGLE){
		wait1Msec(1);
	}
}

このプログラムの解説をします。

nMotorEncoder[motorB] = 0 (nMotorEncoder[motorC] = 0)
出力ポートB(C)のエンコーダの値に0を代入しリセットします。これにより現在の角度を基準に回転角を指定することができます。 ただし、エンコーダの値の代入は0のみで、それ以外の値を代入しても0が代入されます。
また、代入をしないことで出力ポートB(C)のロータリーエンコーダの値を読み込むことができます。

nMotorEncoderTarget[motorB] = ANGLE (nMotorEncoderTarget[motorC] = ANGLE)
出力ポートB(C)のロータリーエンコーダの値が代入した値以上になったとき、そのポートのモーターを停止させます。 ただし、この命令では代入した値まで待つ動作は行わないので、プログラム中のwhile()文とセットで使います。

ロータリーエンコーダから得られる値はdegree単位であり、精度は1度です。
このプログラムでは両方のポートのtargetを360度に設定したため、両方が1回転するまで回転し続け、 そして1回転すると両方のモーターを止めるプログラムになっています。


2.複数のモーターを同調させる

次に、それぞれのモーターに内蔵されたロータリーエンコーダを用いて、複数のモーターを同調させて動かすプログラムを作成します。 例えば、今回使用しているロボットにおいて左右のモーターを同調させることにより、正確な直進やターンが可能になります。 このとき、1.モータの制御で行ったように、左右のスピード調整を行う必要がなくなります。

それでは次のプログラムを作成してください。ここでは、rotary2.c とします。
rotary2.c
task main(){
	nSyncedMotors = synchBC;
	nSyncedTurnRatio = 100;

	nMotorEncoder[motorB] = 0;
	motor[motorB] = 100;
	wait1Msec(3000);

	motor[motorB] = 0;

	nSyncedTurnRatio = -100;
	nMotorEncoder[motorB] = 0;
	motor[motorB] = 70;
	wait1Msec(1000);

	motor[motorB] = 0;
	nSyncedMotors = synchNone;
}

このプログラムの解説をします。

nSyncedMotors = synchBC
出力ポートBのモータとポートCのモータを同調させます。 今回はポートBのモータを基準としたので、ポートCのモータはそれに追従するように動作します。 これを逆にしたい場合は、『synchCB』とします。つまり、synch○△とした場合は○に追従するように△を動作させます。
また、『synchNone』とした場合は、各々のモーターを同調させずに、独立させて動作させるようにします。 一度同調させた後に同調を止めたい場合は、この指定をする必要があります。

nSyncedTurnRatio = 100 (-100)
基準のエンコーダに対して、どの割合で追従させるかをパーセントで指定します。 100とした場合は100%となり回転量が同じになるように、-100とした場合は-100%となり逆の方向に同じ量だけ回転させます。

このプログラムは3秒間前進した後、1秒間その場でターンします。この時、これまでのように直進が曲がることがなく、 またターンもずれずに行われると思います。
このモータの同調プログラムを用いれば、簡単かつ正確に直進動作を行います。 さらにモータの同調と角度指定を組み合わせることができ、正確なロボットの制御を行うことが可能です。


3.課題

角度指定と同調を組み合わせて「1m前進→その場で180度ターン」を繰り返すプログラムを作成せよ。

【ヒント】
直進やターンに必要な回転量は以下の式から導くことができる。
hint1.png(3439 byte)
参考として、例で作成したロボットの場合、 r=27[mm], D=116[mm] です。 ただし、この値はロボットにより微妙に異なるため、実際に走行させたときの直進や回転角度に応じて調整する必要があります。

また、直進動作を行う場合には上式のθがラジアン単位であるため、ラジアンから度へ単位換算を行う必要があります (回転動作の場合ではどちらも単位が同じであるため単位換算は不要)。 この際、RobotCでは円周率πは『PI』と定義されているのでこれを用いて単位換算を行うと良いでしょう。


【プログラム上の注意】
RobotCの仕様上、ロータリーエンコーダによる指定の角度の回転と2つのモータの同調を行う場合には、以下の記述に従わなければならない。
nMotorEncoder[motorB] = 0; // Encoder Reset
nMotorEncoder[motorC] = 0; // Encoder Reset
nSyncedMotors = synchBC;
nSyncedTurnRatio = 100;

 (直進動作などの同調処理)
nSyncedMotors = synchNone;

nMotorEncoder[motorB] = 0; // Encoder Reset
nMotorEncoder[motorC] = 0; // Encoder Reset
nSyncedMotors = synchBC;
nSyncedTurnRatio = -100;

 (その場ターン動作などの同調処理)
nSyncedMotors = synchNone;
  • モータ同調設定の前にエンコーダのリセットや停止点(EncoderTarget)を指定する
  • 追従する割合を変える場合には、赤字で記述したように同調を一旦リセットした後に再び同調と割合の設定を行う。
    これは追従するポートが変化しない場合でも必要であり、エンコーダのリセット前に行う必要がある
このように記述しない場合では、RobotCが途中でエラーとなり、NXTのディスプレイには『 Err Type: 69 』と表示されます。
これ以外の場合で同様のメッセージが表示されるときは、エンコーダ等の宣言の順序を入れ替える、同調の設定を変更するなどを行ってみてください。



3.ライトセンサの使用 TOPへ 5.超音波センサの使用