目次
前
次
難コースエミュレータ
MCR_VCでは、カメラやバーコードスキャナを利用した
センサーを利用しています。カメラやハレーションに
弱く、過去のレースでは途中でラインを見失うことで
コースアウトしていました。
ハレーションによるコースアウトが発生しないように
ファームウエアを作成していけば、実コースの走行時
に適用できます。
ランダムに光量が変化する難コースエミュレータを作成
することにします。
次のようなカラクリを用意します。
- 灯台のように周期的にコース面に光をあてる
- マシンが近づくと、通常よりも強い光をコースにあてる
- コース面を左右を緩やかな周期で上下させる
3つカラクリを実現する方法を考えていきます。
周期的にコース面に光をあてる
周期的にコース面に光をあてるには、LFO(Low Frequency Oscillator)
で、LEDを点滅させます。
LED照光器に、LFOを接続して実現します。
LED照光器は、MCR_VCの過去マシンに搭載していた
基板を再利用します。
回路は単純で以下。
LFOは、ブザーを鳴らす回路を使います。
このジャンク基板では、「HIGH」ワイヤーに'0'を与えると
ブザーが鳴動します。ワイヤーに'0'を与える回路は、次の
OPアンプを使った発振回路を使います。
また、赤色回転灯を使い、ピンポイントでコース面に
光をあてます。
赤色回転灯の回転周期は固定ですが、マシンの走行速度は
任意なので、ランダムで光が変化することになります。
マシン接近で強い光をコースにあてる
マシンの接近は、光センサーを利用して判定します。
昼夜判定回路を利用し、マシンがつくる陰を利用します。
上の回路は、左に接続する電源電圧は3V以上あれば
確実に動作します。出力には、LED照光器を接続します。
コース面を左右を緩やかな周期で上下させる
コース面に貼られているシートは、光の入射角が変化すると
反射する光の量と角度が変わります。
コース面の左右に、モータのシャフトを入れ、ドライブ回路に
与えるDUTY比を左右のモータで変えておきます。
コース面は微妙に上下するので、光の反射量が変化して
センサーが受取るコース面の情報が変化します。
偶発的な事象を扱うには、乱数を利用します。手持ちのArduino互換
IchigoJam互換のマイコン基板で、乱数を発生させるコードを作成
しておきます。
Arduinoスケッチ
Arduinoの日本語リファレンスを参照して、次のスケッチを
作成しました。
#include <MsTimer2.h>
#define OFF 0
#define ON OFF+1
#define TMAX 1500
#define LED_BIT 5
word randNumber;
byte eflag ;
byte uflag ;
byte sindex ;
byte sbuf[4] ;
byte mode ;
byte cmd ;
/* function prototype */
void rs_putchar(char x);
void rs_puts(char *x);
void crlf(void);
void show_help(void);
void send_led(byte x);
void setup()
{
/* enable serial */
Serial.begin(9600);
/* command interpreter buffer */
sindex = 0 ;
/* initialize PORT values */
PORTB = 0x00 ;
PORTD = 0x01 ;
/* initialize PORT direction */
DDRB = 0xff ;
DDRD = 0xfe ;
/* get seed from no connection pin */
randomSeed( analogRead(0) );
/* clear flags */
eflag = OFF ;
uflag = OFF ;
/* initialize */
mode = OFF ;
/* 3000ms period */
MsTimer2::set(3000,update_trigger);
/* enable */
MsTimer2::start();
}
void loop()
{
/* timer interrupt */
if ( eflag == ON ) {
/* clear flag */
eflag = OFF ;
/* judge */
if ( mode == ON ) {
/* get random number */
randNumber = random(TMAX);
/* monitor */
Serial.println(randNumber);
/* send High */
send_led(ON);
/* delay */
delay( randNumber );
}
/* send LOW */
send_led(OFF);
}
/* serial handling */
if ( uflag == ON ) {
/* clear flag */
uflag = OFF ;
/* new line */
crlf();
/* get command */
cmd = *(sbuf+0) ;
/* judge */
if ( cmd == '?' ) { show_help(); }
/* execute */
if ( cmd == 'E' ) {
mode = ON ;
rs_puts("Execute !");
crlf();
}
/* idle */
if ( cmd == 'e' ) {
mode = OFF ;
rs_puts("Idle !");
crlf();
}
}
}
void rs_putchar(char x)
{
Serial.write(x);
}
void rs_puts(char *x)
{
while ( *x ) {
rs_putchar(*x);
x++ ;
}
}
void crlf(void)
{
rs_putchar('\r');
rs_putchar('\n');
}
void show_help(void)
{
rs_puts("? help"); crlf();
rs_puts("E enable random Flashing"); crlf();
rs_puts("e disable random Flashing"); crlf();
}
void send_led(byte x)
{
if ( x ) { PORTB |= (1 << LED_BIT); }
else { PORTB &= ~(1 << LED_BIT); }
}
void update_trigger(void)
{
eflag = ON ;
}
/* receive interrupt */
void serialEvent()
{
char ch ;
if ( Serial.available() > 0 ) {
/* get 1 character */
ch = Serial.read();
/* store */
*(sbuf+sindex) = ch ;
/* increment */
sindex++ ;
/* judge */
if ( ch == '\r' ) {
sindex = 0 ;
uflag = ON ;
}
}
}
IchigoJamのBasicコード
Basicでは、RNDを利用して乱数を発生させます。
10 ' random flashing
20 LET A,1 : GOSUB 100
30 LET A,A+1 : GOSUB 100
40 IF BTN() THEN GOTO 60
50 GOTO 30
60 ? "EXIT" : END
100 ' ? 0 or 1
110 LET B,A & #01
120 LED B ' impress
130 W = RND(100) ' generate random number
135 ? W,B,A
140 WAIT W+60 ' delay
150 RETURN
Arduino基板は、複数枚あるので次の場所に配置。
- 右クランク
- 左クランク
- 右レーンチェンジ
- 左レーンチェンジ
IchigoJam基板は、1枚だけなので、ワインディングに
赤色回転灯とともに置いて、LED照光器を制御します。
LED照光器には、100円ショップで入手した自転車用
ランプを利用。
電源をつけるとLED点灯、はなすとLED消灯なので
マイコンの出力ピンに、'1'か'0'を印加。
ランプは、2つあるので、1つのIchigoJam基板を
使い、2つのランプの照光を制御します。
2つのLED照光器が、離れていることを考えて
先に書いたプログラムを、少しだけ変更。
10 ' random flashing
20 LET A,1 : GOSUB 100
30 LET A,A+1 : GOSUB 100
40 IF BTN() THEN GOTO 60
50 GOTO 30
60 ? "EXIT" : END
100 ' ? 0 or 1
110 LET B,A & #01 : LET C,(A+1) & #01
120 OUT 1,B : OUT 2,C : ' impress
130 W = RND(100) : ' generate random number
135 ' ? W,B,A,C
140 WAIT W+60 : ' delay
150 RETURN
出力ビット1、2に反転した値を印加。
距離が離れているので、位相をもった点灯で
照射面をずらすことと同じになります。
目次
前
次