目次

tutebot実現

 tutebot(チュートボット)は、MITのロボット工学を
 専攻する学生が実習で作成する自走式ロボット。




 tutebotは、壁づたいに移動して部屋のドアから
 外にでることを、試行錯誤しながら実現します。

 tutebotは、ブレッドボードに実装した回路で動作。
 その回路は、以下。



 半田付けした基板は、次の写真で示すようになっています。



 左の2ピンをマイクロスイッチに、右の2ピンをモータに接続。

 用意したメカで、マイクロスイッチを接続すると、以下。
 (プラ板にマイクロスイッチをつけてます)



 プラスチックケースに基板を入れ、メカの上に取り付け。
 (このプラスチックケースは、電子回路専用)




 剥き出しの基板では、衝突時に破損することもあります。
 電子部品の破損、配線ワイヤー切断等が考えられます。

 移動中に、アクシデントが発生しても、ボックス内に
 回路があれば、様々な不具合発生を回避できると判断
 しています。

 マイクロスイッチを使い、障害物に衝突すると後退。
 このとき、左右のモータの回転時間に差があるので
 前進を再開したときには、衝突の前とは少し異なる
 角度で移動。

 前進→衝突→後退を何度か繰り返すと、衝突しない
 経路を見つけ出します。これが、知的動作に見える
 ので、知能を考えるキッカケを与えられます。

 tutebotは、アナログ回路でモータの回転を制御すると
 ともに、知的動作をRC積分回路で実現。

 tutebotを、ライントレーサのメカを使い
 エミュレートしてみます。

 tutebotでは、モータの回転数を細かく制御できないので
 カクカクした動きになります。タイムチャートでみると
 以下。



 後退は、キャパシタに蓄えた電荷を放電するまで続きます。
 放電時間は、左右で異なるので、右あるいは左に曲げながら
 後退します。

 カクカクした動きは、ラインを探しているように見えるので
 考えているようには、思えますが、時間を無駄にしていると
 も言えるので、滑らかに動けるようにします。

 センサーは6個利用して、床面の状況を表現する
 情報量を増やしておきます。

 使うセンサーは、以下。




 本来は、黒白を判定しますが、物体が近づいていると
 白黒は、無関係に何かあるという信号を出力。

 このセンサーを、床面ではなく、壁に向かうように
 シャーシの前面に配置して対応。

 10ピンケーブルに、次のように信号が配置されています。

 1 Vcc
 2 sensor_7(MSB)
 3 sensor_6
 4 sensor_5
 5 sensor_4
 6 sensor_3
 7 sensor_2
 8 sensor_1
 9 sensor_0(LSB)
10 GND

 MSBとLSBを、ポートCに接続。

 1 Vcc           : Vcc
 2 
 3 
 4 
 5 
 6 
 7 
 8 sensor_7(MSB) : PORTC.B1
 9 sensor_0(LSB) : PORTC.B0
10 GND           : GND

 モータには、PWM波形を送ればよいので
 ポートBにドライバ基板を接続。
 ピンアサインは、以下。

 1 Vcc             : Vcc
 2 LED(red)        : PORTB.B4
 3 LED(green)      : PORTB.B3
 4 mode_switch
 5 start switch    : PORTB.B0
 6 
 7 motor_driver    : PORTB.B2
 8 
 9 motor_driver    : PORTB.B1
10 GND             : GND

 ドライバ基板は、以下を利用。



 ドライバ回路では、PWMの波形を1回路につき1出力と
 なっているので、リレーのNC、NOの接続を次のように
 変えます。また、後退制御をマイコンで扱えるように
 しておきます。



 追加したデバイスを半田付けすると、以下。



 センサーからの信号で、壁がありと判定したなら
 次のシーケンスを動かせばよいでしょう。
  1. PWM波形出力停止
  2. reverse controlに論理値の'1'を与える
  3. PWM波形出力再開
  4. 時間待ち
  5. PWM波形出力停止
  6. reverse controlに論理値の'0'を与える
  7. PWM波形出力再開
 reverse controlには、利用していないポートCの  いずれかのピンに接続すればよいでしょう。  ピンアサインは、以下。 1 Vcc : Vcc 2 3 4 5 6 7 reverse control : PORTC.B2 8 sensor_7(MSB) : PORTC.B1 9 sensor_0(LSB) : PORTC.B0 10 GND : GND  接続ピンを決めたならば、Forthで使うワードを  定義していきます。  ポート初期化   ポートBは、LSBだけ入力で他は出力。   ポートCは、LSBとその上のビットが入力で他は出力。   この設定をひとつのワードで指定。 : init.tutebot ( -- ) $00 PORTB c! $fe DDRB c! $00 PORTC c! $fc DDRC c! ;  センサー入力   ポートCのLSBとその上のビットが入力になっているので   どちらかに論理値の'1'があれば、フラグに'1'を設定と   しておきます。 : cur.sensor ( -- x) PINC c@ 3 and 0 = if 0 else 1 then ;   結果を示す論理値は、スタックに入れておきましょう。  前進と後退の指定   ポートCの2ビットが、前進と後退の制御トランジスタに   接続されているので論理値を出力することで対応。 : set.fwd ( -- ) PORTC c@ $04 or PORTC c! ; : set.rev ( -- ) PORTC c@ $fb and PORTC c! ;  PWM波形生成   ポートBの2、1ビットが、タイマー1のアウトプット   コンペアマッチ出力なので、その使い方を指定。 : init.timer1 ( -- ) $06 DDRB c@ or DDRB c! 19999 ICR1 ! %10100010 TCCR1A c! \ both pin impress low on compare matched %10 3 lshift %11 or TCCR1B c! \ /64 = 250kHz ;   次にPWM波形のDUTY比を設定するワードを定義。 : set.duty ( x -- ) dup 400 * swap 400 * OCR1A ! OCR1B ! ;  動作シーケンス   後退動作をひとつのシーケンスとして定義。 : do.rev 0 set.duty \ stop set.rev \ set reverse direction 50 set.duty \ resume 3000 MS \ delay 0 set.duty \ stop set.fwd \ set forward direction 50 set.duty \ resume ;   動作をポートの入出力、DUTY比設定を含めて   もう一度考えてみます。
  1. ポート初期化
  2. DUTY比設定
  3. PWM波形出力開始
  4. 前進設定
  5. センサー値を入力し、判定フラグが1なら後退処理、0なら前進処理
  6. ステート5に戻る
  tutebotの動作としてまとめます。 : run_tutebot init.tutebot 50 set.duty init.timer1 set.fwd begin 1 while cur.sensor 0 = if set.fwd else set.rev then repeat ;  PWMを利用してのスピード制御が必要ないなら  移動は、次のワードで充分。 : move.rev set.rev \ set reverse direction 3000 MS \ delay ; : move.tutebot init.tutebot set.fwd begin 1 while cur.sensor 0 = if set.fwd else move.rev then repeat ;  値の入れ替え処理は、配列を使うと扱いやすくなります。  2進数でセンサー入力とモータ制御出力の  相関関係をリストすると、以下。 00(input) : 11(output) 01(input) : 10(output) 10(input) : 01(output) 11(input) : 00(output)  入力を10進数で書き直してみると  次のようになります。 0(input) : 11(output) 1(input) : 10(output) 2(input) : 01(output) 3(input) : 00(output)  モータ制御のピンアサインは、以下。 1 Vcc : Vcc 2 LED(red) : PORTB.B4 3 LED(green) : PORTB.B3 4 mode_switch 5 start switch : PORTB.B0 6 7 motor_driver : PORTB.B2 8 9 motor_driver : PORTB.B1 10 GND : GND  ポートBの2、1ビットに値を出力すれば  モータは回るので、配列には10進数で値を  格納しておいて、それを出力するとよいと  考えます。  配列のインデックスと格納値の10進数  で対応は、以下。 0(index) : 3 1(index) : 2 2(index) : 1 3(index) : 0  配列の値格納は、次のようにすれば充分。 create MOTV 4 allot 3 MOTV 0 + c! 2 MOTV 1 + c! 1 MOTV 2 + c! 0 MOTV 3 + c!  センサーから0から3の値を入力できたとき  モータを動かすワードを定義すればよいはず。 : SND.MOT MOTV + c@ 1 lshift PORTB c@ $06 and or PORTB c! ;  このワードを使って、センサーから  路面情報を取得し、移動を制御する  には、次のようにタイプ。 PINC c@ $03 and SND.MOT  動かすには、ループを構成します。 : MOVE.TUTEBOT begin PINB c@ 1 and while PINC c@ $03 and SND.MOT 1000 MS repeat ;

目次

inserted by FC2 system