目次

路面情報生成

 センサーから得られる素の情報では、扱いにくいので
 4ビットの情報に縮退させます。

 センサーが出力する8ビットの情報を、中央にラインがあるとし
 テンプレートのビットパターンと排他的論理和をとって、新しい
 4ビット路面情報を生成します。

 テンプレートのビットパターンを「00011000」とします。

 中央にセンターラインあり
    00011000
    00011000
    --------
    00000000 0x00(排他的論理和)

 中央から右にセンターラインあり
    00011000
    00001100
    --------
    00010100 0x14(排他的論理和)

 中央から右にセンターラインあり
    00011000
    00000110
    --------
    00011110 0x1E(排他的論理和)

 中央から右にセンターラインあり
    00011000
    00000011
    --------
    00011011 0x1B(排他的論理和)

 中央から左にセンターラインあり
    00011000
    00110000
    --------
    00101000 0x28(排他的論理和)

 中央から左にセンターラインあり
    00011000
    01100000
    --------
    01111000 0x78(排他的論理和)

 中央から左にセンターラインあり
    00011000
    11000000
    --------
    11011000 0xD8(排他的論理和)

 右に偏った白あり
    00011000
    00000111
    --------
    00011111 0x1F(排他的論理和)

    00011000
    00001111
    --------
    00010111 0x17(排他的論理和)

    00011000
    00011111
    --------
    00000111 0x07(排他的論理和)

    00011000
    00111111
    --------
    00100111 0x27(排他的論理和)

 左に偏った白あり
    00011000
    11100000
    --------
    11111000 0xF8(排他的論理和)

    00011000
    11110000
    --------
    11101000 0xE8(排他的論理和)

    00011000
    11111000
    --------
    11100000 0xE0(排他的論理和)

    00011000
    11111100
    --------
    11100100 0xE4(排他的論理和)

 すべて白
    00011000
    11111111
    --------
    11100111 0xE7(排他的論理和)

 すべて黒
    00011000
    00000000
    --------
    00011000 0x18(排他的論理和)

 センサー情報から4ビット情報を生成する関数を定義します。

#define ALL_BLACK   0
#define ALL_WHITE   1
#define LEFT_WHITE  2
#define RIGHT_WHITE 3
#define CENTER      4
#define TINY_RIGHT  5
#define RIGHT       6
#define BIG_RIGHT   7
#define TINY_LEFT   8
#define LEFT        9
#define BIG_LEFT    10
#define BOTH_WHITE  11
#define ILLEAGAL    12

UBYTE get_code(UBYTE x)
{
  UBYTE result ;
  UBYTE xcode ;
  /* generate code */
  xcode = x ^ 0x18 ;
  /* default */
  result = ILLEAGAL ;
  /* judge */
  if ( xcode == 0x00 ) { result = CENTER ; }
  if ( xcode == 0x14 ) { result = TINY_RIGHT ; }
  if ( xcode == 0x1E ) { result = RIGHT ; }
  if ( xcode == 0x1B ) { result = BIG_RIGHT ; }
  if ( xcode == 0x28 ) { result = TINY_LEFT ; }
  if ( xcode == 0x78 ) { result = LEFT ; }
  if ( xcode == 0xD8 ) { result = BIG_LEFT ; }
  if ( xcode == 0x1F ) { result = RIGHT_WHITE ; }
  if ( xcode == 0x17 ) { result = RIGHT_WHITE ; }
  if ( xcode == 0x07 ) { result = RIGHT_WHITE ; }
  if ( xcode == 0x27 ) { result = RIGHT_WHITE ; }
  if ( xcode == 0xF8 ) { result = LEFT_WHITE ; }
  if ( xcode == 0xE8 ) { result = LEFT_WHITE ; }
  if ( xcode == 0xE0 ) { result = LEFT_WHITE ; }
  if ( xcode == 0xE4 ) { result = LEFT_WHITE ; }
  if ( xcode == 0xE7 ) { result = ALL_WHITE ; }
  if ( xcode == 0x18 ) { result = ALL_BLACK ; }

  return result ;
}

 マイコンの場合、タイマー割込みで周期的にセンサーデータを
 入力してモータに与えるDUTY比を計算します。



 マイコンで扱うとは限らないので、VHDLでデコードする
 処理も定義しておきます。

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity xdecode is
  port (
    -- sensor input
    SX     : in  std_logic_vector(7 downto 0) ;
    -- decode output
    SOUT   : out std_logic_vector(3 downto 0) -- ;
  );
end xdecode ;

architecture behavioral of xdecode is
  --
  CONSTANT ALL_BLACK   : integer :=  0 ;
  CONSTANT ALL_WHITE   : integer :=  1 ;
  CONSTANT LEFT_WHITE  : integer :=  2 ;
  CONSTANT RIGHT_WHITE : integer :=  3 ;
  CONSTANT CENTER      : integer :=  4 ;
  CONSTANT BIG_RIGHT   : integer :=  5 ;
  CONSTANT RIGHTX      : integer :=  6 ;
  CONSTANT TINY_RIGHT  : integer :=  7 ;
  CONSTANT TINY_LEFT   : integer :=  8 ;
  CONSTANT LEFTX       : integer :=  9 ;
  CONSTANT BIG_LEFT    : integer := 10 ;
  CONSTANT BOTH_WHITE  : integer := 11 ;
  CONSTANT ILLEAGAL    : integer := 12 ;
  -- handling
  signal iSENSOR : std_logic_vector(7 downto 0) ;
  -- decoder output
  signal iSOUT : std_logic_vector(3 downto 0) ;
  signal iDECX : integer range 0 to 15 ;
begin
  -- input
  iSENSOR <= SX xor X"18";

  -- output
  SOUT  <= iSOUT ;

  -- convert
  iSOUT <= conv_std_logic_vector(iDECX,4) ;

  -- decoder 
  iDECX <= ALL_BLACK   when ( iSENSOR = X"18" ) else
           ALL_WHITE   when ( iSENSOR = X"E7" ) else
           LEFT_WHITE  when ( iSENSOR = X"F8" ) else
           LEFT_WHITE  when ( iSENSOR = X"E8" ) else
           LEFT_WHITE  when ( iSENSOR = X"E0" ) else
           LEFT_WHITE  when ( iSENSOR = X"E4" ) else
           RIGHT_WHITE when ( iSENSOR = X"1F" ) else
           RIGHT_WHITE when ( iSENSOR = X"17" ) else
           RIGHT_WHITE when ( iSENSOR = X"07" ) else
           RIGHT_WHITE when ( iSENSOR = X"27" ) else
           CENTER      when ( iSENSOR = X"00" ) else
           TINY_LEFT   when ( iSENSOR = X"28" ) else
           LEFTX       when ( iSENSOR = X"78" ) else
           BIG_LEFT    when ( iSENSOR = X"D8" ) else
           TINY_RIGHT  when ( iSENSOR = X"14" ) else
           RIGHTX      when ( iSENSOR = X"1E" ) else
           BIG_RIGHT   when ( iSENSOR = X"1B" ) else
           ILLEAGAL ;

end behavioral;

 FPGAではセンサーデータを100Hz程度のクロックでラッチ(記憶)し
 ラッチしたデータをデコーダに与え、そこからモータに与えるDUTY比
 を算出します



 100Hz程度のクロックでラッチするのは、センサーとして
 カメラを利用すると、シャッターを押してから10ms程度の
 ディレイがあるので、それにあわせるため。

 ブロック図で「???」の部分は、マイコンやシーケンサの
 担当になります。

 マイコンやシーケンサが担当するブロックは、実際に
 走行させて、動作を確定します。


目次

inserted by FC2 system