実機パラメータ調整
ハードウエアをすべて完成させ、テストが終了したので
実機パラメータを調整します。
カメラのパラメータを調整するために、ストレート板を
敷いて、朝、昼、夕方、真夜中と画像を取得します。
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);
}
}
目次
前
次