前章までのライントレースは、常にロボットが旋回しているため、ジグザグに走行してしまい、あまり速くは走れませんでした。
今回はそれを改良し、速く、安定した走りを実現しましょう。
ロボットは基本的にこれまでのものを引き続き使います。
1.比例制御
これまでのプログラムでは、色の閾値より暗いとき、明るいとき、で旋回方向を指定していました。
しかし、光センサが色の目標付近(この場合は白黒中間値)を読み取っているとき、ロボットを大きく旋回する必要はありません。
そこで、左右のモータの駆動力の差(旋回値)を、光センサ値の目標値(この場合は白黒の中間値)からのずれに比例して大きくなるようにして走行させます(図)。

このような制御を比例制御(P制御)といいます。
次のプログラムをコンパイルして、NXTにダウンロードしてください。
しかし、光センサが色の目標付近(この場合は白黒中間値)を読み取っているとき、ロボットを大きく旋回する必要はありません。
そこで、左右のモータの駆動力の差(旋回値)を、光センサ値の目標値(この場合は白黒の中間値)からのずれに比例して大きくなるようにして走行させます(図)。

このような制御を比例制御(P制御)といいます。
次のプログラムをコンパイルして、NXTにダウンロードしてください。
trace_p.c
#include "kernel.h"
#include "kernel_id.h"
#include "ecrobot_interface.h"
#define PORT_LIGHT NXT_PORT_S3 /* 入出力ポートの定義 */
#define PORT_TOUCH NXT_PORT_S2
#define L_MOTOR NXT_PORT_B
#define R_MOTOR NXT_PORT_C
#define BLACK 700
#define WHITE 500
DeclareTask(Task1); /* Task1を宣言 */
void ecrobot_device_initialize(){ /* OSEK起動時の処理 */
nxt_motor_set_speed(L_MOTOR,0,1);
nxt_motor_set_speed(R_MOTOR,0,1);
ecrobot_set_light_sensor_active(PORT_LIGHT);
}
void ecrobot_device_terminate(){ /* OSEK終了時の処理 */
nxt_motor_set_speed(L_MOTOR,0,1);
nxt_motor_set_speed(R_MOTOR,0,1);
ecrobot_set_light_sensor_inactive(PORT_LIGHT);
}
void user_1ms_isr_type2(void){}
void sound_beep(){ /* ビープ音を鳴らすユーザ関数 */
ecrobot_sound_tone(600, 2, 80);
systick_wait_ms(20);
ecrobot_sound_tone(500, 5, 80);
systick_wait_ms(50);
}
TASK(Task1)
{
int speed = 70; // SPEED値
float Kp = 0.4; // Pゲイン変数
int black,white,gray; // 色変数
float turn;
float turn_prev;
black = BLACK;
white = WHITE;
gray = (black + white) / 2;
while(1){
while(ecrobot_get_touch_sensor(PORT_TOUCH) == 0){ /* TSが押されるまでループする*/
display_goto_xy(0, 1);
display_string("PUSH START");
display_update();
}
display_clear(1);
systick_wait_ms(500); /* wait 500msec */
turn_prev = 0.0;
while(ecrobot_get_touch_sensor(PORT_TOUCH) == 0){ //TSが押されるまでループする
// P制御による旋回
turn = Kp * (ecrobot_get_light_sensor(PORT_LIGHT) - gray);
nxt_motor_set_speed( L_MOTOR, speed - turn, 1);
nxt_motor_set_speed( R_MOTOR, speed + turn, 1);
turn_prev = turn;
systick_wait_ms(10); /* wait 10msec*/
}
//停止
nxt_motor_set_speed(L_MOTOR,0,1);
nxt_motor_set_speed(R_MOTOR,0,1);
systick_wait_ms(1000); /* 1秒待つ */
}
TerminateTask(); /* 処理終了 */
}
|
このプログラムを実行しても、ロボットはジグザグに走ってしまうかもしれません。しかし、前の閾値で制御していたものよりも、ロボットの振れは緩やかになっているはずです。
速度と比例ゲインを適切に設定すれば、かなり安定して走れるようになります。
比例ゲインを大きくしすぎると、ロボットが曲がりすぎるので不安定になります。
逆に小さくしすぎると、振れは小さくなりますが、カーブなどが曲がりきれなくなります。
適切な比例ゲインと速度は、コースやロボットによって異なるので、試験走行をして適切な値を探りましょう。