目次

実機パラメータ調整

 ハードウエアをすべて完成させ、テストが終了したので
 実機パラメータを調整します。

 カメラのパラメータを調整するために、ストレート板を
 敷いて、朝、昼、夕方、真夜中と画像を取得します。



 LED光照射器に与えるDUTY比を10%〜90%まで変化させました。

 LED光照射器に与えるDUTY比は、60%以上にするとカメラで
 コントラストがハッキリすることがわかりました。

 後輪に与えるDUTY比が、どの程度なら移動できるのかを
 調べるために、30Rのコースにマシンを載せ、ノートPC
 からパラメータを送信して調べます。



 後輪に与えるDUTY比は、30%でスムーズにスタートできる
 ことがわかりました。CUIでテストしたDUTY比と、ほぼ同じ
 ですが、30%+αにしていけばよいと判断します。

 前輪は、PWM波形を与えないと中央になっています。
 右、左に振るには、PWM波形を与えて、DUTY比により
 角度を制御できます。

 角度とDUTY比の関係を、調べるために、30Rのコースにマシン
 をのせて、左右のDUTY比と後輪に与えるDUTY比の組合せを変えて
 みました。



 ワィンディングの場合、少し右、右、かなり右のように大雑把に
 変化させるには、DUTY比は5%、10%、15%でよいことがわかりました。
 このとき、後輪に与えるDUTY比は、30%です。

 レーンチェンジのためのコースをおいて、センター
 ラインが途切れてから、どの程度のDUTY比で舵を切るか
 を調べます。



 後輪をDUTY比30%で動かしている場合は、右か左にDUTY比20%で
 進行方向を変えてから、ステアリングを戻し直進します。

 画面の左か右にラインを見つけたならば、前とは逆にステアリング
 を切って進行方向を変えます。

 進行方向を変えたならば、直進してNORMALモードの走行に切替えます。
 これで、センターラインを見ながら、移動するようになります。

 窓から光が入る状態で、カメラでどのような
 画像が得られるかを調べました。



 昼間の太陽光が入る状態では、人工網膜チップを利用した
 カメラでは、ハレーションが起きて、画面一面が白になり
 センターラインを認識できません。

 夜間蛍光灯の下で撮影した画像と、昼間太陽光が入る場合の
 画像を左右に並べると次のようになります。



 夜間の画像は、20Wの蛍光管を2つ利用した室内で
 LED光照射器のDUTY比を90%にして撮影しています。

 この結果から、大阪電気通信大学の自由工房にある
 コース横で、ある程度チップのパラメータを、操作
 しなければならないとわかります。

 コース上をマシンを動かしていると、前進だけでなく
 後退させたい場面も出てきました。そこで、Javaで
 つくるテストアプリーケーションに、後退指定できる
 機能を加えました。



 ソースコードは、以下です。
import java.awt.*;
import java.awt.event.*;

import javax.swing.*;
import javax.swing.event.*;

import gnu.io.*;
import java.io.*;

// internal Device Test Board class
class DtbC
{
  SerialPort         port;
  CommPortIdentifier comID;

  String comName;
  int    baudRate;

  InputStream  in;
  OutputStream out;
  // open method
  boolean rs_open(String Com_Name,int Baud_Rate)
  {
    comName = Com_Name;
    baudRate = Baud_Rate;
    // get port ID
    try {
      comID = CommPortIdentifier.getPortIdentifier(comName);
    } catch(Exception e) {
      JOptionPane.showMessageDialog(null,"Do not nortify !","DtbC.open()",JOptionPane.INFORMATION_MESSAGE);
      return false;
    }
    // already opened
    if ( comID.isCurrentlyOwned() == false ) {
      try { 
        // generate instance
        port = (SerialPort)comID.open("DTB",2000);
        // baud rate , data length , stop bit , parity 
        port.setSerialPortParams(baudRate,SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE );
        // no flow control
        port.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
        // input and output stream
        in = port.getInputStream();
        out = port.getOutputStream();
      } catch(Exception e) {
        JOptionPane.showMessageDialog(null,"Do not open !","DtbC.rs_open()",JOptionPane.INFORMATION_MESSAGE);
        return false;
      }
    } else {
      JOptionPane.showMessageDialog(null,"Already opened !","DtbC.rs_open()",JOptionPane.INFORMATION_MESSAGE);
      return false;
    }
    return true;
  }
  // close method 
  boolean rs_close()
  {
    if ( comID.isCurrentlyOwned() ) {
      try {
        port.close();
        in.close();
        out.close();
      } catch(IOException e) {
        JOptionPane.showMessageDialog(null,"Do not close !","DtbC.rs_close()",JOptionPane.INFORMATION_MESSAGE);
        return false;
      }
    } else {
      JOptionPane.showMessageDialog(null,"Already closed !","DtbC.rs_close()",JOptionPane.INFORMATION_MESSAGE);
      return false; 
    }
    return true;
  }
  // send string
  void Serial_puts(String str)
  {
    byte[] data = str.getBytes();
    try {
      out.write(data);
      out.flush();
    } catch(Exception e) {
    }
  }
}

// internal Serial Class (super class => DtbC)
class Serial_Class extends DtbC
{
  JComboBox   cbxCom;
  JComboBox   cbxBaud;
  JTextArea   edtText;
  JScrollPane scrPane;
  // constructor
  Serial_Class()
  {
    // generate text area
    edtText = new JTextArea();
    // generate scroll pane
    scrPane = new JScrollPane(edtText);
    scrPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
    scrPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
    // COM port ComboBox
    cbxCom = new JComboBox();
    cbxCom.addItem("COM1"); cbxCom.addItem("COM2");
    cbxCom.addItem("COM3"); cbxCom.addItem("COM4");
    cbxCom.addItem("COM5"); cbxCom.addItem("COM6");
    cbxCom.addItem("COM7"); cbxCom.addItem("COM8");
    cbxCom.addItem("COM9");
    // default port
    cbxCom.setSelectedItem("COM6");
    // Buad rate ComboBox
    cbxBaud = new JComboBox();
    cbxBaud.addItem("4800") ; cbxBaud.addItem("9600");
    cbxBaud.addItem("19200"); cbxBaud.addItem("38400");
    cbxBaud.addItem("57600");
    // default baud rate
    cbxBaud.setSelectedItem("38400");
  }
  // open method
  void open()
  {
    boolean flag;
    // convert COM name to string
    String COM_Name = (cbxCom.getSelectedItem()).toString();
    // get baud rate from ComboBox
    int Baud_Rate = Integer.parseInt((cbxBaud.getSelectedItem()).toString());
    // open 
    flag = rs_open(COM_Name,Baud_Rate);
    // success
    if ( flag ) {
      try {
        // register receive event handler
        port.addEventListener(new SerialPortListener());
        // add event monitor
        port.notifyOnDataAvailable(true);
      } catch(Exception e) {
      }
      edtText.append("Connected\n");
    }
  }
  // close method
  void close()
  {
    boolean flag;
    // close 
    flag = rs_close();
    // success
    if ( flag ) { edtText.append("Disconnected\n"); }
  }
  // event listener
  class SerialPortListener implements SerialPortEventListener
  {
    // event handler
    public void serialEvent(SerialPortEvent Serial_event)
    {
      StringBuffer buffer = new StringBuffer();
      int received_data = 0 ;
      // receive completed 
      if ( Serial_event.getEventType() == SerialPortEvent.DATA_AVAILABLE ) {
        // loop until get 'break'
        while (true) {
          try {
            // get data from input stream
            received_data = in.read();
            // no charactor
            if ( received_data == -1 ) break;
            // store
            if ( (char)received_data != '\r' ) {
              buffer.append((char)received_data);
            } else {
            // get delimiter
              // convert 
              edtText.append(buffer.toString());
              // clear buffer
              buffer.delete(0,buffer.length()); 
              // post handling
              edtText.setCaretPosition(edtText.getText().length());
              //break;
            }
          } catch(IOException ex){
          }
        }
      }
    }
  }
}

// internal Frame (window) class
class MFrame extends JFrame
{
  Serial_Class serial;
  static JTextArea edtFront ;
  static JTextArea edtRear ;
  static JTextArea edtLed ;
  static JComboBox cbxDir;
  static JComboBox cbxRear;
  static JComboBox cbxMode ;
  // constructor
  MFrame()
  {
    // call super class method
    super("MCR machine test");

    serial = new Serial_Class();
    // generate pane
    JPanel cp = new JPanel();
    // set layout moe
    cp.setLayout(null);
    // add pane to frame
    setContentPane(cp);
    // generate scroll pane
    JScrollPane sp = new JScrollPane(serial.edtText);
    // enable vertical scroll bar
    sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
    sp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
    // set scroll pane dimension
    sp.setBounds(50,50,400,300);
    // add scroll pane
    cp.add(sp);
    // show COM port
    JLabel com_label = new JLabel("COM port:");
    cp.add(com_label);
    com_label.setBounds(50,20,100,20);
    cp.add(serial.cbxCom);
    serial.cbxCom.setBounds(120,20,80,20);
    // show selected baud rate
    JLabel baud_label = new JLabel("Baud rate : ");
    cp.add(baud_label);
    baud_label.setBounds(250,20,100,20);
    cp.add(serial.cbxBaud);
    serial.cbxBaud.setBounds(350,20,80,20);
    // generate Font
    Font font = new Font("SansSerif",Font.PLAIN,16);
    // add Font information to textarea。
    serial.edtText.setFont(font);
    serial.edtText.setLineWrap(true);
    serial.edtText.addKeyListener(new KeyInput());
    serial.scrPane.setBounds(50,50,400,300);
    cp.add(serial.scrPane);
    // define button
    JButton btnConnect = new JButton(new open_action());
    btnConnect.setBounds(10,360,90,30);
    cp.add(btnConnect);
    JButton btnDisconnect = new JButton(new close_action());
    btnDisconnect.setBounds(110,360,100,30);
    cp.add(btnDisconnect);
    JButton btnSend = new JButton(new send_action());
    btnSend.setBounds(400,350,80,20);
    cp.add(btnSend);
    JButton btnClear = new JButton(new clear_action());
    btnClear.setBounds(100,400,80,30);
    cp.add(btnClear);
    // Front label
    JLabel lblFront = new JLabel("Front");
    lblFront.setBounds(240,340,100,40);
    cp.add(lblFront);
    // Rear label
    JLabel lblRear = new JLabel("Rear");
    lblRear.setBounds(240,360,100,40);
    cp.add(lblRear);
    // LED label
    JLabel lblLed = new JLabel("Led");
    lblLed.setBounds(240,380,100,40);
    cp.add(lblLed);
    // Front value
    edtFront = new JTextArea("00");
    edtFront.setBounds(280,350,40,20);
    cp.add(edtFront);
    // Rear value
    edtRear = new JTextArea("00");
    edtRear.setBounds(280,370,40,20);
    cp.add(edtRear);
    // LED value
    edtLed = new JTextArea("90");
    edtLed.setBounds(280,390,40,20);
    cp.add(edtLed);
    // Front direction
    cbxDir = new JComboBox() ;
    cbxDir.setBounds(320,350,60,20);
    cbxDir.addItem("NONE");
    cbxDir.addItem("RIGHT");
    cbxDir.addItem("LEFT");
    cp.add(cbxDir);
    // Rear direction
    cbxRear = new JComboBox() ;
    cbxRear.setBounds(320,380,100,20);
    cbxRear.addItem("FORWARD");
    cbxRear.addItem("REVERSE");
    cp.add(cbxRear);
    // Mode selector (Label)
    JLabel lblMode = new JLabel("mode");
    lblMode.setBounds(240,420,40,20);
    cp.add(lblMode);
    // Mode selector (ComboBox)
    cbxMode = new JComboBox();
    cbxMode.setBounds(240,440,80,20);
    cbxMode.addItem("NONE");
    cbxMode.addItem("NORMAL");
    cbxMode.addItem("CRANK");
    cbxMode.addItem("LANE");
    cp.add(cbxMode);
    // Mode set (Button)
    JButton btnMSet = new JButton(new mset_action());
    btnMSet.setBounds(400,440,80,20);
    cp.add(btnMSet);
    // Stop (Button)
    JButton btnStop = new JButton(new stop_action());
    btnStop.setBounds(400,410,80,20);
    cp.add(btnStop);
    // register KeyInput class to KeyListener
    serial.edtText.addKeyListener(new KeyInput());
  }
  // internal class (bntConnect)
  class open_action extends AbstractAction
  {
    // constructor
    open_action()
    {
      putValue(Action.NAME,"Connect\n");
    }
    // event method
    public void actionPerformed(ActionEvent btnConnect_act)
    {
      serial.open();
    }
  }
  // internal class (bntDisconnect)
  class close_action extends AbstractAction
  {
    // constructor
    close_action()
    {
      putValue(Action.NAME,"Disconnect\n");
    }
    // event method
    public void actionPerformed(ActionEvent btnDisconnect_act)
    {
      serial.close();
    }
  }
  // internal class (bntSend)
  class send_action extends AbstractAction
  {
    // constructor
    send_action()
    {
      putValue(Action.NAME,"Send");
    }
    // event method
    public void actionPerformed(ActionEvent btnSend_act)
    {
      String stmp = new String("");
      // generate code
      if ( (MFrame.cbxDir.getSelectedItem()).toString() == "LEFT" ) {
        stmp += "P1" ;
      } else {
        if ( (MFrame.cbxDir.getSelectedItem()).toString() == "RIGHT" ) {
          stmp += "P2" ;
        } else {
          stmp += "P0" ;
        }
      }
      stmp += MFrame.edtFront.getText() ;
      stmp += "0\r" ;
      if ( (MFrame.cbxRear.getSelectedItem()).toString() == "FORWARD") {
        stmp += "P2" ;
      } else {
        stmp += "P1" ;
      }
      stmp += MFrame.edtRear.getText() ;
      stmp += "1\r" ;
      stmp += "P1" ;
      stmp += MFrame.edtLed.getText() ;
      stmp += "2\r" ;
      // show
      serial.edtText.append(stmp);
      // send 
      serial.Serial_puts(stmp);
    }
  }
  // internal class (bntClear)
  class clear_action extends AbstractAction
  {
    // constructor
    clear_action()
    {
      putValue(Action.NAME,"Clear\n");
    }
    // event method
    public void actionPerformed(ActionEvent btnClear_act)
    {
      serial.edtText.setText("");
    }
  }
  // internal class (bntMSet)
  class mset_action extends AbstractAction
  {
    // constructor
    mset_action()
    {
      putValue(Action.NAME,"SET\n");
    }
    // event method
    public void actionPerformed(ActionEvent btnMSet_act)
    {
      String stmp = new String("");
      // generate code
      stmp += "L" ;
      if ( (MFrame.cbxMode.getSelectedItem()).toString() == "NONE" ) {
        stmp += "00" ;
      }
      if ( (MFrame.cbxMode.getSelectedItem()).toString() == "NORMAL" ) {
        stmp += "01" ;
      }
      if ( (MFrame.cbxMode.getSelectedItem()).toString() == "CRANK" ) {
        stmp += "10" ;
      }
      if ( (MFrame.cbxMode.getSelectedItem()).toString() == "LANE" ) {
        stmp += "11" ;
      }
      stmp += "\r" ;
      // show
      serial.edtText.append(stmp);
      // send 
      serial.Serial_puts(stmp);
    }
  }
  // internal class (bntStop)
  class stop_action extends AbstractAction
  {
    // constructor
    stop_action()
    {
      putValue(Action.NAME,"Stop");
    }
    // event method
    public void actionPerformed(ActionEvent btnStop_act)
    {
      String stmp = new String("");
      stmp += "P0000\r" ;
      stmp += "P2001\r" ;
      // show
      serial.edtText.append(stmp);
      // send 
      serial.Serial_puts(stmp);
    }
  }
  // key event
  class KeyInput extends KeyAdapter
  {
    String   stmp;
    String[] stmp_array;
    int lineNum;

    public void keyPressed(KeyEvent e)
    {
      // get key then echo to textArea
      if ( e.getKeyCode() == KeyEvent.VK_ENTER )
      {
        //serial.edtText.append("\n");
        stmp = serial.edtText.getText();
        stmp_array = stmp.split("\n",0);
        lineNum = stmp_array.length - 1;
        // send serial port
        serial.Serial_puts(stmp_array[lineNum]+"\r");
      }
    }
  }
}

public class McrTst
{
  private final static int my_frm_width  = 500 ;
  private final static int my_frm_height = 500 ;

  public static void main(String args[])
  {
    MFrame frame = new MFrame();
    // 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    // set dimension
    frame.setSize(my_frm_width,my_frm_height);
    // show
    frame.setVisible(true);
  }
}


目次

inserted by FC2 system