Revision 1606
Added diagnostic server stuff.
trunk/code/projects/diagnostic_station/server/server.c | ||
---|---|---|
1 |
#include "comp-hub.h" |
|
2 |
|
|
3 |
// ALSO DON'T FORGET TO CHECK OUT |
|
4 |
// ATTRIBUTES ON LINES 39 ish TO 50 ish |
|
5 |
#define PORT_DEFAULT "/dev/ttyUSB0" |
|
6 |
#define BAUD_RATE 115200 |
|
7 |
|
|
8 |
static char* com_port = PORT_DEFAULT; |
|
9 |
static int stream; |
|
10 |
|
|
11 |
int main(void) |
|
12 |
{ |
|
13 |
if(lib_init() < 0) |
|
14 |
printf("Exiting...\n"); |
|
15 |
|
|
16 |
//your code here |
|
17 |
listen(); |
|
18 |
put_char('r'); |
|
19 |
listen(); |
|
20 |
put_char('b'); |
|
21 |
listen(); |
|
22 |
put_char('m'); |
|
23 |
listen(); |
|
24 |
|
|
25 |
return 0; |
|
26 |
} |
|
27 |
|
|
28 |
int lib_init() |
|
29 |
{ |
|
30 |
stream = open(com_port, O_RDWR); |
|
31 |
if (stream == -1) |
|
32 |
{ |
|
33 |
printf("Failed to open connection on port "); |
|
34 |
printf("%i\n", *com_port); |
|
35 |
return -1; |
|
36 |
} else { |
|
37 |
printf("Successfully opened connection on port "); |
|
38 |
printf("%i\n", (int)(*com_port)); |
|
39 |
} |
|
40 |
// set baud rate, etc. correctly |
|
41 |
struct termios options; |
|
42 |
if(tcgetattr(stream, &options)) |
|
43 |
printf("Error getting attributes"); |
|
44 |
cfsetispeed(&options, BAUD_RATE); |
|
45 |
cfsetospeed(&options, BAUD_RATE); |
|
46 |
//options.c_iflag &= ~ICRNL; |
|
47 |
//options.c_oflag &= ~OCRNL; |
|
48 |
//options.c_cflag |= (CLOCAL | CREAD); |
|
49 |
options.c_cflag &= ~PARENB; //no parity |
|
50 |
options.c_cflag &= ~CSTOPB; //one stop bit |
|
51 |
options.c_cflag &= ~CSIZE; |
|
52 |
options.c_cflag |= CS8; //8 bits |
|
53 |
//options.c_lflag &= ~ICANON; |
|
54 |
//options.c_cc[VMIN] = 1; |
|
55 |
//options.c_cc[VTIME] = 50; |
|
56 |
|
|
57 |
if (tcsetattr(stream, TCSANOW, &options)) |
|
58 |
{ |
|
59 |
printf("Error setting attributes.\n"); |
|
60 |
return -1; |
|
61 |
} |
|
62 |
return 0; |
|
63 |
} |
|
64 |
|
|
65 |
/** |
|
66 |
* Listener function |
|
67 |
* At the moment, just prints out what it receives |
|
68 |
**/ |
|
69 |
static void* listen() |
|
70 |
{ |
|
71 |
char c; |
|
72 |
int count = 0; |
|
73 |
char buf[100]; |
|
74 |
while (1) |
|
75 |
{ |
|
76 |
if (read_char(&c) != 0) { |
|
77 |
printf("Listen failed.\n"); |
|
78 |
return NULL; |
|
79 |
} |
|
80 |
|
|
81 |
printf("%c", c); fflush(stdout); |
|
82 |
|
|
83 |
if(c == '\0') |
|
84 |
break; |
|
85 |
} |
|
86 |
|
|
87 |
return NULL; |
|
88 |
} |
|
89 |
|
|
90 |
static int read_char(char* buf) |
|
91 |
{ |
|
92 |
if (read(stream, buf, 1) == -1) { |
|
93 |
printf("Failed to read.\r\n"); |
|
94 |
return -1; |
|
95 |
} |
|
96 |
return 0; |
|
97 |
} |
|
98 |
|
|
99 |
/** |
|
100 |
* Put functions |
|
101 |
**/ |
|
102 |
static int put_string(char *str) |
|
103 |
{ |
|
104 |
if (write(stream, str, strlen(str)) == -1) { |
|
105 |
printf("Failed to write.\r\n"); |
|
106 |
return -1; |
|
107 |
} |
|
108 |
return 0; |
|
109 |
} |
|
110 |
|
|
111 |
static int put_char(char c) |
|
112 |
{ |
|
113 |
if (write(stream, &c, 1) == -1) { |
|
114 |
printf("Failed to write.\r\n"); |
|
115 |
return -1; |
|
116 |
} |
|
117 |
return 0; |
|
118 |
} |
trunk/code/projects/diagnostic_station/server/server.h | ||
---|---|---|
1 |
#include <termios.h> |
|
2 |
#include <fcntl.h> |
|
3 |
#include <stdio.h> |
|
4 |
#include <stdlib.h> |
|
5 |
#include <string.h> |
|
6 |
#include <unistd.h> |
|
7 |
|
|
8 |
int main(void); |
|
9 |
int lib_init(); |
|
10 |
static void* listen(); |
|
11 |
static int read_char(char* buf); |
|
12 |
static int put_string(char *str); |
|
13 |
static int put_char(char c); |
trunk/code/projects/diagnostic_station/server/Makefile | ||
---|---|---|
1 |
all: |
|
2 |
gcc server.c -o server |
|
3 |
|
|
4 |
clean: |
|
5 |
rm server |
trunk/code/projects/diagnostic_station/server/Main.java | ||
---|---|---|
1 |
|
|
2 |
public class Main { |
|
3 |
public static void main(String[] args){ |
|
4 |
new DiagnosticsServer(); |
|
5 |
} |
|
6 |
} |
trunk/code/projects/diagnostic_station/server/SerialComm.java | ||
---|---|---|
1 |
import gnu.io.CommPort; |
|
2 |
import gnu.io.CommPortIdentifier; |
|
3 |
import gnu.io.SerialPort; |
|
4 |
|
|
5 |
import java.io.IOException; |
|
6 |
import java.io.InputStream; |
|
7 |
import java.io.OutputStream; |
|
8 |
|
|
9 |
public class SerialComm |
|
10 |
{ |
|
11 |
/* |
|
12 |
* The following define the default settings for connections |
|
13 |
*/ |
|
14 |
public static final String PORT_DEFAULT = "COM15"; |
|
15 |
public static final int BAUDRATE_DEFAULT = 115200; |
|
16 |
public static final int PARITY_DEFAULT = SerialPort.PARITY_NONE; |
|
17 |
public static final int DATABITS_DEFAULT = SerialPort.DATABITS_8; |
|
18 |
// At this time, the station does use 2 stopbits |
|
19 |
public static final int STOPBITS_DEFAULT = SerialPort.STOPBITS_2; |
|
20 |
|
|
21 |
/* |
|
22 |
* Possible parities |
|
23 |
*/ |
|
24 |
public static final int PARITY_EVEN = SerialPort.PARITY_EVEN; |
|
25 |
public static final int PARITY_MARK = SerialPort.PARITY_MARK; |
|
26 |
public static final int PARITY_NONE = SerialPort.PARITY_NONE; |
|
27 |
public static final int PARITY_ODD = SerialPort.PARITY_ODD; |
|
28 |
public static final int PARITY_SPACE = SerialPort.PARITY_SPACE; |
|
29 |
|
|
30 |
/* |
|
31 |
* Possible numbers of databits |
|
32 |
*/ |
|
33 |
public static final int DATABITS_5 = SerialPort.DATABITS_5; |
|
34 |
public static final int DATABITS_6 = SerialPort.DATABITS_6; |
|
35 |
public static final int DATABITS_7 = SerialPort.DATABITS_7; |
|
36 |
public static final int DATABITS_8 = SerialPort.DATABITS_8; |
|
37 |
|
|
38 |
/* |
|
39 |
* Possible numbers of stopbits |
|
40 |
*/ |
|
41 |
public static final int STOPBITS_1 = SerialPort.STOPBITS_1; |
|
42 |
public static final int STOPBITS_2 = SerialPort.STOPBITS_2; |
|
43 |
// 1.5 stopbits |
|
44 |
public static final int STOPBITS_1_5 = SerialPort.STOPBITS_1_5; |
|
45 |
|
|
46 |
/* |
|
47 |
* The following global variables define the settings for connections |
|
48 |
* These may be changed using the different constructors |
|
49 |
*/ |
|
50 |
private String port = PORT_DEFAULT; |
|
51 |
private int baudRate = BAUDRATE_DEFAULT; |
|
52 |
private int parity = PARITY_DEFAULT; |
|
53 |
private int dataBits = DATABITS_DEFAULT; |
|
54 |
private int stopBits = STOPBITS_DEFAULT; |
|
55 |
private int timeout = 10000; |
|
56 |
|
|
57 |
/* |
|
58 |
* These input and output streams read from and write to serial |
|
59 |
* These are initialized by the connect method |
|
60 |
*/ |
|
61 |
private InputStream in; |
|
62 |
private OutputStream out; |
|
63 |
|
|
64 |
/* |
|
65 |
* We need to store the gui so that we can write to its console whenever |
|
66 |
* we read or write from serial |
|
67 |
*/ |
|
68 |
private ServerGUI gui; |
|
69 |
|
|
70 |
/* |
|
71 |
* All settings at defaults (see above for default settings) |
|
72 |
*/ |
|
73 |
public SerialComm(ServerGUI gui) throws IOException{ |
|
74 |
super(); |
|
75 |
this.gui = gui; |
|
76 |
connect(); |
|
77 |
} |
|
78 |
|
|
79 |
/* |
|
80 |
* For example, port could be "COM4" |
|
81 |
* All other settings at defaults (see above for default settings) |
|
82 |
*/ |
|
83 |
public SerialComm(ServerGUI gui, String port) throws IOException{ |
|
84 |
super(); |
|
85 |
this.gui = gui; |
|
86 |
this.port = port; |
|
87 |
connect(); |
|
88 |
} |
|
89 |
|
|
90 |
/* |
|
91 |
* All settings set as specified in the arguments |
|
92 |
*/ |
|
93 |
public SerialComm(ServerGUI gui, String port, int baudRate, int dataBits, |
|
94 |
int stopBits, int parity) throws IOException{ |
|
95 |
super(); |
|
96 |
this.gui = gui; |
|
97 |
this.port = port; |
|
98 |
this.baudRate = baudRate; |
|
99 |
this.parity = parity; |
|
100 |
this.dataBits = dataBits; |
|
101 |
this.stopBits = stopBits; |
|
102 |
connect(); |
|
103 |
} |
|
104 |
|
|
105 |
public void puts(String s) throws IOException{ |
|
106 |
System.out.print("> " + s); |
|
107 |
gui.addTextToConsole("> " + s); |
|
108 |
out.write((s).getBytes()); |
|
109 |
} |
|
110 |
|
|
111 |
/* |
|
112 |
* Reads until a newline is found |
|
113 |
* This operation is blocking |
|
114 |
*/ |
|
115 |
public String gets() throws IOException{ |
|
116 |
int c_read = 0; |
|
117 |
String read = ""; |
|
118 |
do{ |
|
119 |
c_read = in.read(); |
|
120 |
if(c_read != -1) |
|
121 |
read += (char)c_read; |
|
122 |
} |
|
123 |
while(c_read != (int)'\n' && c_read != (int)'\r'); |
|
124 |
System.out.print("< " + read); |
|
125 |
gui.addTextToConsole("< " + read); |
|
126 |
return read; |
|
127 |
} |
|
128 |
|
|
129 |
/* |
|
130 |
* If no data is available to be read, returns null |
|
131 |
* If data is available, reads until a newline is found |
|
132 |
* This operation is blocking until a newline is read |
|
133 |
*/ |
|
134 |
public String gets_nb() throws IOException{ |
|
135 |
int c_read = 0; |
|
136 |
String read = ""; |
|
137 |
if(in.available() < 0) |
|
138 |
return null; |
|
139 |
do{ |
|
140 |
c_read = in.read(); |
|
141 |
if(c_read != -1) |
|
142 |
read += (char)c_read; |
|
143 |
} |
|
144 |
while(c_read != (int)'\n' && c_read != (int)'\r'); |
|
145 |
System.out.print("< " + read); |
|
146 |
gui.addTextToConsole("< " + read); |
|
147 |
return read; |
|
148 |
} |
|
149 |
|
|
150 |
/* |
|
151 |
* Returns the next character, or the character '\0' if there is no |
|
152 |
* character to read |
|
153 |
* This operation is non-blocking |
|
154 |
*/ |
|
155 |
public char getc_nb() throws IOException{ |
|
156 |
int c_read = 0; |
|
157 |
char read = '\0'; |
|
158 |
if(in.available() <= 0) |
|
159 |
return read; |
|
160 |
c_read = in.read(); |
|
161 |
if(c_read != -1) |
|
162 |
read = (char)c_read; |
|
163 |
System.out.print("< " + read); |
|
164 |
gui.addTextToConsole("< " + read); |
|
165 |
return read; |
|
166 |
} |
|
167 |
|
|
168 |
/* |
|
169 |
* Connects to a serial port using the settings specified in the |
|
170 |
* global variables |
|
171 |
* Must be called before using any of the get or put methods |
|
172 |
* (called by the constructor) |
|
173 |
* See global variables port, baudRate, parity, dataBits, stopBits, timeout |
|
174 |
*/ |
|
175 |
private void connect() throws IOException{ |
|
176 |
try{ |
|
177 |
CommPortIdentifier portIdentifier = |
|
178 |
CommPortIdentifier.getPortIdentifier(port); |
|
179 |
if ( portIdentifier.isCurrentlyOwned()){ |
|
180 |
System.out.println("Error: Port is currently in use\n"); |
|
181 |
} |
|
182 |
else{ |
|
183 |
CommPort commPort = portIdentifier.open(this.getClass().getName(), |
|
184 |
timeout); |
|
185 |
|
|
186 |
if ( commPort instanceof SerialPort ){ |
|
187 |
SerialPort serialPort = (SerialPort) commPort; |
|
188 |
serialPort.setSerialPortParams(baudRate, dataBits, stopBits, |
|
189 |
parity); |
|
190 |
|
|
191 |
in = serialPort.getInputStream(); |
|
192 |
out = serialPort.getOutputStream(); |
|
193 |
} |
|
194 |
else{ |
|
195 |
System.out.println("Error: " + port + |
|
196 |
" is not a serial port\n"); |
|
197 |
} |
|
198 |
} |
|
199 |
} |
|
200 |
catch(Exception e){ |
|
201 |
throw new IOException(e.getMessage()); |
|
202 |
} |
|
203 |
} |
|
204 |
} |
trunk/code/projects/diagnostic_station/server/ServerGUI.java | ||
---|---|---|
1 |
import java.awt.BorderLayout; |
|
2 |
import java.awt.Color; |
|
3 |
import java.awt.Component; |
|
4 |
import java.awt.Dimension; |
|
5 |
import java.awt.GridLayout; |
|
6 |
import java.awt.LayoutManager; |
|
7 |
import java.awt.event.ActionEvent; |
|
8 |
import java.awt.event.ActionListener; |
|
9 |
import java.util.ArrayList; |
|
10 |
import java.util.Enumeration; |
|
11 |
|
|
12 |
import javax.swing.AbstractButton; |
|
13 |
import javax.swing.BorderFactory; |
|
14 |
import javax.swing.Box; |
|
15 |
import javax.swing.BoxLayout; |
|
16 |
import javax.swing.ButtonGroup; |
|
17 |
import javax.swing.JButton; |
|
18 |
import javax.swing.JFrame; |
|
19 |
import javax.swing.JLabel; |
|
20 |
import javax.swing.JPanel; |
|
21 |
import javax.swing.JRadioButton; |
|
22 |
import javax.swing.JScrollPane; |
|
23 |
import javax.swing.JTextArea; |
|
24 |
import javax.swing.SwingUtilities; |
|
25 |
import javax.swing.border.Border; |
|
26 |
|
|
27 |
import org.jfree.chart.ChartFactory; |
|
28 |
import org.jfree.chart.ChartPanel; |
|
29 |
import org.jfree.chart.JFreeChart; |
|
30 |
import org.jfree.chart.plot.PlotOrientation; |
|
31 |
import org.jfree.data.xy.XYSeries; |
|
32 |
import org.jfree.data.xy.XYSeriesCollection; |
|
33 |
|
|
34 |
public class ServerGUI implements ActionListener{ |
|
35 |
|
|
36 |
private static final long serialVersionUID = 1L; |
|
37 |
|
|
38 |
// whether or not to use the console |
|
39 |
private static final boolean USE_CONSOLE = true; |
|
40 |
|
|
41 |
private int currentTest = -1; |
|
42 |
private int testNum = -1; |
|
43 |
|
|
44 |
// the area that shows messages |
|
45 |
private JTextArea console; |
|
46 |
// the DiagnosticsServer that does all the processing |
|
47 |
private DiagnosticsServer server; |
|
48 |
|
|
49 |
// a list of buttons |
|
50 |
private JButton[] buttons = new JButton[DiagnosticsServer.NUM_TESTS]; |
|
51 |
// the stop button |
|
52 |
JButton stop; |
|
53 |
ButtonGroup numSelectGroup; |
|
54 |
private JRadioButton[] radios; |
|
55 |
private JFrame numSelectWindow, frame; |
|
56 |
private JPanel graphPanel, top; |
|
57 |
private LayoutManager layout; |
|
58 |
|
|
59 |
// Constructor - sets up the GUI |
|
60 |
public ServerGUI(DiagnosticsServer server){ |
|
61 |
frame = new JFrame("Diagnostic Station Control Panel"); |
|
62 |
this.server = server; |
|
63 |
|
|
64 |
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); |
|
65 |
|
|
66 |
frame.setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.Y_AXIS)); |
|
67 |
|
|
68 |
top = new JPanel(); |
|
69 |
layout = new BoxLayout(top, BoxLayout.X_AXIS); |
|
70 |
top.setLayout(layout); |
|
71 |
top.add(buttonPanel()); |
|
72 |
top.add(Box.createGlue()); |
|
73 |
graphPanel = graphPanel(); |
|
74 |
top.add(graphPanel); |
|
75 |
|
|
76 |
frame.add(top); |
|
77 |
if(USE_CONSOLE) |
|
78 |
frame.add(console()); |
|
79 |
|
|
80 |
frame.pack(); |
|
81 |
frame.setVisible(true); |
|
82 |
} |
|
83 |
|
|
84 |
// returns the Panel containing the graph |
|
85 |
private JPanel graphPanel(){ |
|
86 |
if(currentTest == -1 || currentTest == DiagnosticsServer.ALL_TESTS) |
|
87 |
return blankPanel(); |
|
88 |
|
|
89 |
String[] labels = server.getLabels(currentTest, testNum); |
|
90 |
ArrayList[] data = server.getData(currentTest, testNum); |
|
91 |
|
|
92 |
int numSeries = labels.length - 3; |
|
93 |
XYSeries series[] = new XYSeries[numSeries]; |
|
94 |
for(int i=0; i<numSeries; i++){ |
|
95 |
series[i] = new XYSeries(labels[i+3]); |
|
96 |
ArrayList x = data[2*i]; |
|
97 |
ArrayList y = data[2*i+1]; |
|
98 |
for(int j=0; j<x.size(); j++){ |
|
99 |
series[i].add((Integer)x.get(j), (Integer)y.get(j)); |
|
100 |
} |
|
101 |
} |
|
102 |
XYSeriesCollection xyDataset = new XYSeriesCollection(series[0]); |
|
103 |
for(int i=1; i<numSeries; i++) |
|
104 |
xyDataset.addSeries(series[i]); |
|
105 |
|
|
106 |
JFreeChart chart = ChartFactory.createXYLineChart(labels[0], |
|
107 |
labels[1], labels[2], xyDataset, PlotOrientation.VERTICAL, true, |
|
108 |
false, false); |
|
109 |
ChartPanel panel = new ChartPanel(chart); |
|
110 |
|
|
111 |
JPanel graphPanel = new JPanel(); |
|
112 |
graphPanel.add(panel); |
|
113 |
return graphPanel; |
|
114 |
} |
|
115 |
|
|
116 |
// returns a blank panel |
|
117 |
private JPanel blankPanel(){ |
|
118 |
JPanel blank = new JPanel(); |
|
119 |
blank.setBorder(BorderFactory.createMatteBorder(20, 20, 20, 20, new Color(238, 238, 238))); |
|
120 |
blank.setBackground(Color.WHITE); |
|
121 |
blank.add(Box.createRigidArea(new Dimension(680, 420))); |
|
122 |
return blank; |
|
123 |
} |
|
124 |
|
|
125 |
// returns the console |
|
126 |
private JScrollPane console(){ |
|
127 |
console = new JTextArea(10, 50); |
|
128 |
JScrollPane pane = new JScrollPane(console); |
|
129 |
console.setEditable(false); |
|
130 |
console.setLineWrap(false); |
|
131 |
Border inner = BorderFactory.createLineBorder(Color.BLACK); |
|
132 |
Border outer = BorderFactory.createEmptyBorder(5, 15, 5, 15); |
|
133 |
Border border = BorderFactory.createCompoundBorder(outer, inner); |
|
134 |
pane.setBorder(border); |
|
135 |
return pane; |
|
136 |
} |
|
137 |
|
|
138 |
// adds the given String to the console |
|
139 |
public void addTextToConsole(final String s){ |
|
140 |
SwingUtilities.invokeLater(new Runnable (){ |
|
141 |
public void run() { |
|
142 |
console.append(s); |
|
143 |
} |
|
144 |
}); |
|
145 |
} |
|
146 |
|
|
147 |
// the panel with the control buttons |
|
148 |
private JPanel buttonPanel(){ |
|
149 |
int maxButtonWidth = 200; |
|
150 |
int maxButtonHeight = 30; |
|
151 |
|
|
152 |
JPanel buttonPanel = new JPanel(); |
|
153 |
buttonPanel.setBorder(BorderFactory.createEmptyBorder(10, 15, 5, 15)); |
|
154 |
buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.Y_AXIS)); |
|
155 |
buttonPanel.setMinimumSize(new Dimension(maxButtonWidth, 25 + ((maxButtonHeight + 5) * DiagnosticsServer.NUM_TESTS))); |
|
156 |
buttonPanel.setAlignmentX(Component.LEFT_ALIGNMENT); |
|
157 |
buttonPanel.setAlignmentY(Component.BOTTOM_ALIGNMENT); |
|
158 |
|
|
159 |
buttons[DiagnosticsServer.ALL_TESTS] = new JButton("Run all tests"); |
|
160 |
buttons[DiagnosticsServer.RANGEFINDER] = new JButton("Run rangefinder test"); |
|
161 |
buttons[DiagnosticsServer.ENCODER] = new JButton("Run encoder test"); |
|
162 |
buttons[DiagnosticsServer.MOTOR] = new JButton("Run motor test"); |
|
163 |
buttons[DiagnosticsServer.BOM] = new JButton("Run bom test"); |
|
164 |
buttons[DiagnosticsServer.BOM_EMITTER] = new JButton("Run bom emitter test"); |
|
165 |
buttons[DiagnosticsServer.BOM_DETECTOR] = new JButton("Run bom detector test"); |
|
166 |
for(int i=0; i<DiagnosticsServer.NUM_TESTS; i++){ |
|
167 |
buttons[i].setVerticalTextPosition(AbstractButton.CENTER); |
|
168 |
buttons[i].setActionCommand("frame " + i); |
|
169 |
buttons[i].addActionListener(this); |
|
170 |
buttons[i].setAlignmentX(Component.LEFT_ALIGNMENT); |
|
171 |
buttons[i].setAlignmentY(Component.TOP_ALIGNMENT); |
|
172 |
buttons[i].setMaximumSize(new Dimension(maxButtonWidth, maxButtonHeight)); |
|
173 |
if(i != 0) |
|
174 |
buttonPanel.add(Box.createRigidArea(new Dimension(0, 5))); |
|
175 |
buttonPanel.add(buttons[i]); |
|
176 |
} |
|
177 |
stop = new JButton("Stop testing"); |
|
178 |
stop.setVerticalTextPosition(AbstractButton.CENTER); |
|
179 |
stop.setActionCommand("stop"); |
|
180 |
stop.addActionListener(this); |
|
181 |
stop.setAlignmentX(Component.LEFT_ALIGNMENT); |
|
182 |
stop.setAlignmentY(Component.TOP_ALIGNMENT); |
|
183 |
stop.setMaximumSize(new Dimension(maxButtonWidth, maxButtonHeight)); |
|
184 |
//stop.setBackground(Color.RED); |
|
185 |
stop.setEnabled(false); |
|
186 |
buttonPanel.add(Box.createRigidArea(new Dimension(0, 5))); |
|
187 |
buttonPanel.add(stop); |
|
188 |
|
|
189 |
buttonPanel.add(Box.createGlue()); |
|
190 |
|
|
191 |
return buttonPanel; |
|
192 |
} |
|
193 |
|
|
194 |
// shows the dialog asking the user which specific parts to test |
|
195 |
private void getNumDialog(int testNum){ |
|
196 |
String instr = "Choose which test to run"; |
|
197 |
if(testNum == DiagnosticsServer.BOM){ |
|
198 |
instr = "Choose which bom to test"; |
|
199 |
} |
|
200 |
else if(testNum == DiagnosticsServer.BOM_DETECTOR){ |
|
201 |
instr = "Choose which detector to test"; |
|
202 |
} |
|
203 |
else if(testNum == DiagnosticsServer.BOM_EMITTER){ |
|
204 |
instr = "Choose which emitter to test"; |
|
205 |
} |
|
206 |
else if(testNum == DiagnosticsServer.RANGEFINDER){ |
|
207 |
instr = "Choose which rangefinder to test"; |
|
208 |
} |
|
209 |
else if(testNum == DiagnosticsServer.MOTOR){ |
|
210 |
instr = "Choose which motor to test"; |
|
211 |
} |
|
212 |
else if(testNum == DiagnosticsServer.ENCODER){ |
|
213 |
instr = "Choose which encoder to test"; |
|
214 |
} |
|
215 |
|
|
216 |
JLabel label = new JLabel(instr); |
|
217 |
radios = radios(testNum); |
|
218 |
|
|
219 |
JPanel grid = new JPanel(new GridLayout(0, 1)); |
|
220 |
for (int i = 0; i < radios.length; i++) { |
|
221 |
grid.add(radios[i]); |
|
222 |
} |
|
223 |
|
|
224 |
JPanel box = new JPanel(); |
|
225 |
box.setBorder(BorderFactory.createEmptyBorder(5, 15, 5, 15)); |
|
226 |
box.setLayout(new BoxLayout(box, BoxLayout.PAGE_AXIS)); |
|
227 |
label.setAlignmentX(Component.LEFT_ALIGNMENT); |
|
228 |
box.add(label); |
|
229 |
box.add(grid); |
|
230 |
grid.setAlignmentX(Component.LEFT_ALIGNMENT); |
|
231 |
|
|
232 |
JPanel buttons = new JPanel(); |
|
233 |
buttons.setLayout(new BoxLayout(buttons, BoxLayout.Y_AXIS)); |
|
234 |
box.add(buttons); |
|
235 |
JButton run = new JButton("Run test"); |
|
236 |
run.addActionListener(this); |
|
237 |
run.setActionCommand("run"); |
|
238 |
run.setMaximumSize(new Dimension(200, 30)); |
|
239 |
buttons.add(run); |
|
240 |
buttons.add(Box.createRigidArea(new Dimension(0, 5))); |
|
241 |
JButton cancel = new JButton("Cancel"); |
|
242 |
cancel.addActionListener(this); |
|
243 |
cancel.setActionCommand("cancel"); |
|
244 |
cancel.setMaximumSize(new Dimension(200, 30)); |
|
245 |
buttons.add(cancel); |
|
246 |
|
|
247 |
numSelectWindow = new JFrame("Select test"); |
|
248 |
numSelectWindow.setLayout(new BoxLayout(numSelectWindow.getContentPane(), BoxLayout.Y_AXIS)); |
|
249 |
numSelectWindow.add(box, BorderLayout.PAGE_START); |
|
250 |
numSelectWindow.pack(); |
|
251 |
numSelectWindow.setVisible(true); |
|
252 |
} |
|
253 |
|
|
254 |
// returns the radio buttons for the getNumDialog |
|
255 |
private JRadioButton[] radios(int testNum){ |
|
256 |
int numTests = 0; |
|
257 |
int startIndex = 0; |
|
258 |
String allText = "All tests"; |
|
259 |
if(testNum == DiagnosticsServer.BOM || testNum == DiagnosticsServer.BOM_DETECTOR || testNum == DiagnosticsServer.BOM_EMITTER){ |
|
260 |
numTests = DiagnosticsServer.NUM_BOMS; |
|
261 |
startIndex = DiagnosticsServer.BOM_OFFSET; |
|
262 |
if(testNum == DiagnosticsServer.BOM) |
|
263 |
allText = "All boms"; |
|
264 |
else if(testNum == DiagnosticsServer.BOM_DETECTOR) |
|
265 |
allText = "All detectors"; |
|
266 |
else if(testNum == DiagnosticsServer.BOM_EMITTER) |
|
267 |
allText = "All emitters"; |
|
268 |
} |
|
269 |
else if(testNum == DiagnosticsServer.RANGEFINDER){ |
|
270 |
numTests = DiagnosticsServer.NUM_RANGEFINDERS; |
|
271 |
startIndex = DiagnosticsServer.RANGEFINDER_OFFSET; |
|
272 |
allText = "All rangefinders"; |
|
273 |
} |
|
274 |
else if(testNum == DiagnosticsServer.MOTOR){ |
|
275 |
numTests = DiagnosticsServer.NUM_MOTORS; |
|
276 |
startIndex = DiagnosticsServer.MOTOR_OFFSET; |
|
277 |
allText = "Both motors"; |
|
278 |
} |
|
279 |
else if(testNum == DiagnosticsServer.ENCODER){ |
|
280 |
numTests = DiagnosticsServer.NUM_ENCODERS; |
|
281 |
startIndex = DiagnosticsServer.ENCODER_OFFSET; |
|
282 |
allText = "Both encoders"; |
|
283 |
} |
|
284 |
|
|
285 |
JRadioButton radios[] = new JRadioButton[numTests+1]; |
|
286 |
numSelectGroup = new ButtonGroup(); |
|
287 |
for(int i=0; i<numTests+1; i++){ |
|
288 |
if(i==0){ |
|
289 |
radios[i] = new JRadioButton(allText); |
|
290 |
radios[i].setSelected(true); |
|
291 |
} |
|
292 |
else{ |
|
293 |
radios[i] = new JRadioButton((i+startIndex-1) + ""); |
|
294 |
radios[i].setSelected(false); |
|
295 |
} |
|
296 |
radios[i].addActionListener(this); |
|
297 |
radios[i].setActionCommand(testNum + " " + (i-1)); |
|
298 |
numSelectGroup.add(radios[i]); |
|
299 |
} |
|
300 |
|
|
301 |
return radios; |
|
302 |
} |
|
303 |
|
|
304 |
// the Action handler |
|
305 |
public void actionPerformed(ActionEvent event) { |
|
306 |
String actionCommand = event.getActionCommand(); |
|
307 |
try{ |
|
308 |
if(actionCommand.equals("stop")){ |
|
309 |
server.stopTest(); |
|
310 |
stop.setBackground(null); |
|
311 |
stop.setEnabled(false); |
|
312 |
} |
|
313 |
else if(actionCommand.equals("cancel")){ |
|
314 |
numSelectWindow.dispose(); |
|
315 |
return; |
|
316 |
} |
|
317 |
else if(actionCommand.equals("run")){ |
|
318 |
Enumeration<AbstractButton> buttons = numSelectGroup.getElements(); |
|
319 |
while(buttons.hasMoreElements()){ |
|
320 |
AbstractButton button = buttons.nextElement(); |
|
321 |
if(button.isSelected()){ |
|
322 |
String command = button.getActionCommand(); |
|
323 |
int spaceIndex = command.indexOf(" "); |
|
324 |
Integer testNum = Integer.parseInt(command.substring(0, spaceIndex)); |
|
325 |
Integer num = Integer.parseInt(command.substring(spaceIndex+1)); |
|
326 |
numSelectWindow.dispose(); |
|
327 |
currentTest = testNum; |
|
328 |
this.testNum = num; |
|
329 |
stop.setBackground(Color.RED); |
|
330 |
stop.setEnabled(true); |
|
331 |
frame.repaint(); |
|
332 |
server.startTest(testNum, num); |
|
333 |
stop.setBackground(null); |
|
334 |
stop.setEnabled(false); |
|
335 |
top.remove(graphPanel); |
|
336 |
graphPanel = graphPanel(); |
|
337 |
top.add(graphPanel); |
|
338 |
top.validate(); |
|
339 |
break; |
|
340 |
} |
|
341 |
} |
|
342 |
} |
|
343 |
else if(actionCommand.startsWith("frame ")){ |
|
344 |
Integer num = Integer.parseInt(actionCommand.substring(6)); |
|
345 |
getNumDialog(num); |
|
346 |
} |
|
347 |
} |
|
348 |
catch(Exception e){ |
|
349 |
System.out.println(e.getMessage()); |
|
350 |
} |
|
351 |
} |
|
352 |
} |
trunk/code/projects/diagnostic_station/server/README | ||
---|---|---|
1 | 1 |
##################################################################### |
2 |
# Server Code Folder
|
|
2 |
# Server Code |
|
3 | 3 |
# |
4 |
# John Sexton
|
|
4 |
# Emily Hart
|
|
5 | 5 |
##################################################################### |
6 | 6 |
|
7 | 7 |
This folder contains code intended to be compiled and run on a |
8 | 8 |
computer acting as the server for the diagnostic station. All data |
9 | 9 |
analysis will occur at this level. |
10 |
|
|
11 |
This code has only been tested on Windows, but probably doesn't need a lot of |
|
12 |
modification to run in Linux. Make sure PORT_DEFAULT, line 14 in |
|
13 |
SerialComm.java, is set correctly when you run this code. The directions below |
|
14 |
are for running this code in Eclipse. |
|
15 |
|
|
16 |
To use this code, the three .jar files need to be added to the build path To do |
|
17 |
this in Eclipse, select the following in the Package Explorer: |
|
18 |
-jcommon-1.0.16.jar |
|
19 |
-jfreechart-1.0.13.jar |
|
20 |
-RXTXcomm.jar |
|
21 |
Right them and select Build Path >> Add to Build Path. The four java |
|
22 |
classes should stop showing errors now. |
|
23 |
|
|
24 |
To run the code, right click Main.java and select Run As >> Java Application. |
trunk/code/projects/diagnostic_station/server/DiagnosticsServer.java | ||
---|---|---|
1 |
import java.io.IOException; |
|
2 |
import java.util.ArrayList; |
|
3 |
import java.util.Scanner; |
|
4 |
|
|
5 |
public class DiagnosticsServer { |
|
6 |
|
|
7 |
/* |
|
8 |
* The following are used to differentiate between tests |
|
9 |
*/ |
|
10 |
public static final int ALL_TESTS = 0; |
|
11 |
public static final int RANGEFINDER = 1; |
|
12 |
public static final int ENCODER = 2; |
|
13 |
public static final int MOTOR = 3; |
|
14 |
public static final int BOM = 4; |
|
15 |
public static final int BOM_EMITTER = 5; |
|
16 |
public static final int BOM_DETECTOR = 6; |
|
17 |
/* |
|
18 |
* The number of different tests |
|
19 |
*/ |
|
20 |
public static final int NUM_TESTS = 7; |
|
21 |
/* |
|
22 |
* How many there are of each type |
|
23 |
* For example, there are 16 BOM components and 2 motors |
|
24 |
*/ |
|
25 |
public static final int NUM_BOMS = 16; |
|
26 |
public static final int NUM_RANGEFINDERS = 5; |
|
27 |
public static final int NUM_MOTORS = 2; |
|
28 |
public static final int NUM_ENCODERS = 2; |
|
29 |
/* |
|
30 |
* Sometimes, we want to test all elements of a specific one |
|
31 |
* For example, all five rangefinders instead of just one of them |
|
32 |
*/ |
|
33 |
public static final int ALL_ELEMENTS = -1; |
|
34 |
/* |
|
35 |
* Specifies the lowest possible number for a type |
|
36 |
* For example, numbering starts at 0 for BOM components and 1 for motors |
|
37 |
*/ |
|
38 |
public static final int RANGEFINDER_OFFSET = 1; |
|
39 |
public static final int ENCODER_OFFSET = 1; |
|
40 |
public static final int MOTOR_OFFSET = 1; |
|
41 |
public static final int BOM_OFFSET = 0; |
|
42 |
|
|
43 |
/* |
|
44 |
* Station -> server message types |
|
45 |
*/ |
|
46 |
private static final int PARSE_ERROR = 0; |
|
47 |
private static final int DATA = 1; |
|
48 |
private static final int COMMENT = 2; |
|
49 |
private static final int READY = 3; |
|
50 |
|
|
51 |
/* |
|
52 |
* The following bitmasks are used to specify the status of a reading |
|
53 |
* from the station |
|
54 |
*/ |
|
55 |
// Emitter status |
|
56 |
private static final int EMITTER = 1; |
|
57 |
private static final int DETECTOR = 2; |
|
58 |
private static final int EMITTER_TOP = 4; |
|
59 |
private static final int EMITTER_RIGHT = 8; |
|
60 |
private static final int EMITTER_LEFT = 16; |
|
61 |
private static final int DETECTOR_IN = 64; |
|
62 |
private static final int DETECTOR_OUT = 128; |
|
63 |
// Rangefinder status |
|
64 |
private static final int RANGEFINDER_IN = 1; |
|
65 |
private static final int RANGEFINDER_OUT = 2; |
|
66 |
// Motor status |
|
67 |
private static final int MOTOR_FORWARD = 1; |
|
68 |
private static final int MOTOR_BACKWARD = 2; |
|
69 |
private static final int MOTOR_ACCELERATING = 4; |
|
70 |
private static final int MOTOR_DECELERATING = 8; |
|
71 |
private static final int MOTOR_CONST_ACCEL = 16; |
|
72 |
// Encoder status |
|
73 |
private static final int ENCODER_FORWARD = 1; |
|
74 |
private static final int ENCODER_BACKWARD = 2; |
|
75 |
|
|
76 |
/* |
|
77 |
* The following arrays of ArrayLists are used to store data received |
|
78 |
* from testing |
|
79 |
* For example, the 0th element of motorPWMData stores an ArrayList of |
|
80 |
* PWM information received from the first motor. |
|
81 |
* The 0th element of motorStatus stores an ArrayList of the same length |
|
82 |
* Each element is a bitmask with information such as the direction of |
|
83 |
* acceleration and whether the motor was running forwards or backwards |
|
84 |
*/ |
|
85 |
private ArrayList[] bomData = new ArrayList[NUM_BOMS]; |
|
86 |
private ArrayList[] bomStatus = new ArrayList[NUM_BOMS]; |
|
87 |
private ArrayList[] rangefinderWallData = new ArrayList[NUM_RANGEFINDERS]; |
|
88 |
private ArrayList[] rangefinderRangeData = new ArrayList[NUM_RANGEFINDERS]; |
|
89 |
private ArrayList[] rangefinderStatus = new ArrayList[NUM_RANGEFINDERS]; |
|
90 |
private ArrayList[] motorPWMData = new ArrayList[NUM_MOTORS]; |
|
91 |
private ArrayList[] motorVelocityData = new ArrayList[NUM_MOTORS]; |
|
92 |
private ArrayList[] motorStatus = new ArrayList[NUM_MOTORS]; |
|
93 |
private ArrayList[] encoderDynamoData = new ArrayList[NUM_ENCODERS]; |
|
94 |
private ArrayList[] encoderValueData = new ArrayList[NUM_ENCODERS]; |
|
95 |
private ArrayList[] encoderStatus = new ArrayList[NUM_ENCODERS]; |
|
96 |
|
|
97 |
// The SerialComm object controls the connection to the station |
|
98 |
private SerialComm serial; |
|
99 |
// We send information to the gui |
|
100 |
private ServerGUI gui; |
|
101 |
|
|
102 |
/* |
|
103 |
* Initializes gui, serial, and data arrays |
|
104 |
*/ |
|
105 |
public DiagnosticsServer(){ |
|
106 |
gui = new ServerGUI(this); |
|
107 |
try{ |
|
108 |
serial = new SerialComm(gui, "COM19", SerialComm.BAUDRATE_DEFAULT, |
|
109 |
SerialComm.DATABITS_DEFAULT, SerialComm.STOPBITS_2, |
|
110 |
SerialComm.PARITY_DEFAULT); |
|
111 |
} |
|
112 |
catch(IOException e){ |
|
113 |
System.out.println("Error connecting to serial"); |
|
114 |
System.out.println(e.getMessage()); |
|
115 |
System.out.println(e.getStackTrace()); |
|
116 |
return; |
|
117 |
} |
|
118 |
for(int i=0; i<NUM_BOMS; i++){ |
|
119 |
bomData[i] = new ArrayList<Integer>(); |
|
120 |
bomStatus[i] = new ArrayList<Integer>(); |
|
121 |
} |
|
122 |
for(int i=0; i<NUM_RANGEFINDERS; i++){ |
|
123 |
rangefinderWallData[i] = new ArrayList<Integer>(); |
|
124 |
rangefinderRangeData[i] = new ArrayList<Integer>(); |
|
125 |
rangefinderStatus[i] = new ArrayList<Integer>(); |
|
126 |
} |
|
127 |
for(int i=0; i<NUM_MOTORS; i++){ |
|
128 |
motorPWMData[i] = new ArrayList<Integer>(); |
|
129 |
motorVelocityData[i] = new ArrayList<Integer>(); |
|
130 |
motorStatus[i] = new ArrayList<Integer>(); |
|
131 |
} |
|
132 |
for(int i=0; i<NUM_ENCODERS; i++){ |
|
133 |
encoderDynamoData[i] = new ArrayList<Integer>(); |
|
134 |
encoderValueData[i] = new ArrayList<Integer>(); |
|
135 |
encoderStatus[i] = new ArrayList<Integer>(); |
|
136 |
} |
|
137 |
} |
|
138 |
/* |
|
139 |
* The returned array has an even number of entries |
|
140 |
* The first of each pair is an ArrayList of X entries |
|
141 |
* The second of each pair is an ArrayList of the corresponding Y entries |
|
142 |
*/ |
|
143 |
public ArrayList[] getData(int testType, int testNum){ |
|
144 |
ArrayList data[] = new ArrayList[2]; |
|
145 |
int arrSize = 2; |
|
146 |
|
|
147 |
switch(testType){ |
|
148 |
case ALL_TESTS: |
|
149 |
data = null; |
|
150 |
break; |
|
151 |
case RANGEFINDER: |
|
152 |
if(testNum == ALL_ELEMENTS){ |
|
153 |
arrSize = 2 * NUM_RANGEFINDERS; |
|
154 |
data = new ArrayList[arrSize]; |
|
155 |
for(int i=0; i<arrSize/2; i++){ |
|
156 |
data[i*2] = rangefinderWallData[i]; |
|
157 |
data[i*2 + 1] = rangefinderRangeData[i]; |
|
158 |
} |
|
159 |
} |
|
160 |
else{ |
|
161 |
data = new ArrayList[arrSize]; |
|
162 |
data[0] = rangefinderWallData[testNum]; |
|
163 |
data[1] = rangefinderRangeData[testNum]; |
|
164 |
} |
|
165 |
break; |
|
166 |
case ENCODER: |
|
167 |
if(testNum == ALL_ELEMENTS){ |
|
168 |
arrSize = 2 * NUM_ENCODERS; |
|
169 |
data = new ArrayList[arrSize]; |
|
170 |
for(int i=0; i<arrSize/2; i++){ |
|
171 |
data[i*2] = encoderDynamoData[i]; |
|
172 |
data[i*2 + 1] = encoderValueData[i]; |
|
173 |
} |
|
174 |
} |
|
175 |
else{ |
|
176 |
data = new ArrayList[arrSize]; |
|
177 |
data[0] = encoderDynamoData[testNum]; |
|
178 |
data[1] = encoderValueData[testNum]; |
|
179 |
} |
|
180 |
break; |
|
181 |
case MOTOR: |
|
182 |
if(testNum == ALL_ELEMENTS){ |
|
183 |
arrSize = 2 * NUM_MOTORS; |
|
184 |
data = new ArrayList[arrSize]; |
|
185 |
for(int i=0; i<arrSize/2; i++){ |
|
186 |
data[i*2] = motorPWMData[i]; |
|
187 |
data[i*2 + 1] = motorVelocityData[i]; |
|
188 |
} |
|
189 |
} |
|
190 |
else{ |
|
191 |
data = new ArrayList[arrSize]; |
|
192 |
data[0] = motorPWMData[testNum]; |
|
193 |
data[1] = motorVelocityData[testNum]; |
|
194 |
} |
|
195 |
break; |
|
196 |
case BOM: |
|
197 |
if(testNum == ALL_ELEMENTS){ |
|
198 |
arrSize = 2 * NUM_BOMS; |
|
199 |
data = new ArrayList[arrSize]; |
|
200 |
for(int i=0; i<arrSize/2; i++){ |
|
201 |
ArrayList<Integer> trials = new ArrayList<Integer>(); |
|
202 |
for(int j=1; j<=bomData[i].size(); j++) |
|
203 |
trials.add(j); |
|
204 |
data[i*2] = trials; |
|
205 |
data[i*2 + 1] = bomData[i]; |
|
206 |
} |
|
207 |
} |
|
208 |
else{ |
|
209 |
data = new ArrayList[arrSize]; |
|
210 |
ArrayList<Integer> trials = new ArrayList<Integer>(); |
|
211 |
for(int j=1; j<=bomData[testNum].size(); j++) |
|
212 |
trials.add(j); |
|
213 |
data[0] = trials; |
|
214 |
data[1] = bomData[testNum]; |
|
215 |
} |
|
216 |
break; |
|
217 |
case BOM_EMITTER: |
|
218 |
if(testNum == ALL_ELEMENTS){ |
|
219 |
arrSize = 2 * NUM_BOMS; |
|
220 |
data = new ArrayList[arrSize]; |
|
221 |
for(int i=0; i<arrSize/2; i++){ |
|
222 |
ArrayList<Integer> bomEmitterData = getSubset(bomData[i], |
|
223 |
bomStatus[i], BOM_EMITTER); |
|
224 |
ArrayList<Integer> trials = new ArrayList<Integer>(); |
|
225 |
for(int j=1; j<=bomEmitterData.size(); j++) |
|
226 |
trials.add(j); |
|
227 |
data[i*2] = trials; |
|
228 |
data[i*2 + 1] = bomEmitterData; |
|
229 |
} |
|
230 |
} |
|
231 |
else{ |
|
232 |
data = new ArrayList[arrSize]; |
|
233 |
ArrayList<Integer> trials = new ArrayList<Integer>(); |
|
234 |
ArrayList<Integer> bomEmitterData = getSubset(bomData[testNum], |
|
235 |
bomStatus[testNum], BOM_EMITTER); |
|
236 |
for(int j=1; j<=bomEmitterData.size(); j++) |
|
237 |
trials.add(j); |
|
238 |
data[0] = trials; |
|
239 |
data[1] = bomEmitterData; |
|
240 |
} |
|
241 |
break; |
|
242 |
case BOM_DETECTOR: |
|
243 |
if(testNum == ALL_ELEMENTS){ |
|
244 |
arrSize = 2 * NUM_BOMS; |
|
245 |
data = new ArrayList[arrSize]; |
|
246 |
for(int i=0; i<arrSize/2; i++){ |
|
247 |
ArrayList<Integer> bomDetectorData = getSubset(bomData[i], |
|
248 |
bomStatus[i], BOM_DETECTOR); |
|
249 |
ArrayList<Integer> trials = new ArrayList<Integer>(); |
|
250 |
for(int j=1; j<=bomDetectorData.size(); j++) |
|
251 |
trials.add(j); |
|
252 |
data[i*2] = trials; |
|
253 |
data[i*2 + 1] = bomDetectorData; |
|
254 |
} |
|
255 |
} |
|
256 |
else{ |
|
257 |
data = new ArrayList[arrSize]; |
|
258 |
ArrayList<Integer> trials = new ArrayList<Integer>(); |
|
259 |
ArrayList<Integer> bomDetectorData = getSubset(bomData[testNum], |
|
260 |
bomStatus[testNum], BOM_DETECTOR); |
|
261 |
for(int j=1; j<=bomDetectorData.size(); j++) |
|
262 |
trials.add(j); |
|
263 |
data[0] = trials; |
|
264 |
data[1] = bomDetectorData; |
|
265 |
} |
|
266 |
break; |
|
267 |
} |
|
268 |
return data; |
|
269 |
} |
|
270 |
|
|
271 |
/* |
|
272 |
* The first entry is the chart title |
|
273 |
* The next two entries are the X and Y axis labels |
|
274 |
* The following entries are the labels for each series |
|
275 |
*/ |
|
276 |
public String[] getLabels(int testType, int testNum){ |
|
277 |
String labels[]; |
|
278 |
int arrSize = 4; |
|
279 |
|
|
280 |
switch(testType){ |
|
281 |
case ALL_TESTS: |
|
282 |
labels = new String[arrSize]; |
|
283 |
labels[0] = ""; |
|
284 |
labels[1] = ""; |
|
285 |
labels[2] = ""; |
|
286 |
labels[3] = ""; |
|
287 |
break; |
|
288 |
case RANGEFINDER: |
|
289 |
if(testNum == -1) |
|
290 |
arrSize += NUM_RANGEFINDERS - 1; |
|
291 |
labels = new String[arrSize]; |
|
292 |
labels[0] = "Rangefinder Data"; |
|
293 |
labels[1] = "Wall Data"; |
|
294 |
labels[2] = "Rangefinder Output"; |
|
295 |
if(testNum == -1){ |
|
296 |
for(int i=0; i<NUM_RANGEFINDERS; i++) |
|
297 |
labels[i+3] = "" + (i + RANGEFINDER_OFFSET); |
|
298 |
} |
|
299 |
else |
|
300 |
labels[3] = "" + (testNum + RANGEFINDER_OFFSET); |
|
301 |
break; |
|
302 |
case ENCODER: |
|
303 |
if(testNum == -1) |
|
304 |
arrSize += NUM_ENCODERS - 1; |
|
305 |
labels = new String[arrSize]; |
|
306 |
labels[0] = "Encoder Data"; |
|
307 |
labels[1] = "Dynamo Data"; |
|
308 |
labels[2] = "Encoder Output"; |
|
309 |
if(testNum == -1){ |
|
310 |
for(int i=0; i<NUM_ENCODERS; i++) |
|
311 |
labels[i+3] = "" + (i + ENCODER_OFFSET); |
|
312 |
} |
|
313 |
else |
|
314 |
labels[3] = "" + (testNum + ENCODER_OFFSET); |
|
315 |
break; |
|
316 |
case MOTOR: |
|
317 |
if(testNum == -1) |
|
318 |
arrSize += NUM_MOTORS - 1; |
|
319 |
labels = new String[arrSize]; |
|
320 |
labels[0] = "Motor Data"; |
|
321 |
labels[1] = "PWM Data"; |
|
322 |
labels[2] = "Motor Velocity Data"; |
|
323 |
if(testNum == -1){ |
|
324 |
for(int i=0; i<NUM_MOTORS; i++) |
|
325 |
labels[i+3] = "" + (i + MOTOR_OFFSET); |
|
326 |
} |
|
327 |
else |
|
328 |
labels[3] = "" + (testNum + MOTOR_OFFSET); |
|
329 |
break; |
|
330 |
case BOM: |
|
331 |
if(testNum == -1) |
|
332 |
arrSize += NUM_BOMS - 1; |
|
333 |
labels = new String[arrSize]; |
|
334 |
labels[0] = "Bom Data"; |
|
335 |
labels[1] = "Test Number"; |
|
336 |
labels[2] = "BOM Reading"; |
|
337 |
if(testNum == -1){ |
|
338 |
for(int i=0; i<NUM_BOMS; i++) |
|
339 |
labels[i+3] = "" + (i + BOM_OFFSET); |
|
340 |
} |
|
341 |
else |
|
342 |
labels[3] = "" + (testNum + BOM_OFFSET); |
|
343 |
break; |
|
344 |
case BOM_EMITTER: |
|
345 |
if(testNum == -1) |
|
346 |
arrSize += NUM_BOMS - 1; |
|
347 |
labels = new String[arrSize]; |
|
348 |
labels[0] = "Bom Emitter Data"; |
|
349 |
labels[1] = "Test Number"; |
|
350 |
labels[2] = "BOM Emitter Reading"; |
|
351 |
if(testNum == -1){ |
|
352 |
for(int i=0; i<NUM_BOMS; i++) |
|
353 |
labels[i+3] = "" + (i + BOM_OFFSET); |
|
354 |
} |
|
355 |
else |
|
356 |
labels[3] = "" + (testNum + BOM_OFFSET); |
|
357 |
break; |
|
358 |
case BOM_DETECTOR: |
|
359 |
if(testNum == -1) |
|
360 |
arrSize += NUM_BOMS - 1; |
|
361 |
labels = new String[arrSize]; |
|
362 |
labels[0] = "Bom Detector Data"; |
|
363 |
labels[1] = "Test Number"; |
|
364 |
labels[2] = "BOM Detector Reading"; |
|
365 |
if(testNum == -1){ |
|
366 |
for(int i=0; i<NUM_BOMS; i++) |
|
367 |
labels[i+3] = "" + (i + BOM_OFFSET); |
|
368 |
} |
|
369 |
else |
|
370 |
labels[3] = "" + (testNum + BOM_OFFSET); |
|
371 |
break; |
|
372 |
default: |
|
373 |
labels = new String[arrSize]; |
|
374 |
labels[0] = ""; |
|
375 |
labels[1] = ""; |
|
376 |
labels[2] = ""; |
|
377 |
labels[3] = ""; |
|
378 |
} |
|
379 |
return labels; |
|
380 |
} |
|
381 |
|
|
382 |
/* |
|
383 |
* Starts running the given test on all elements |
|
384 |
*/ |
|
385 |
public void startTest(int testType) throws Exception{ |
|
386 |
startTest(testType, ALL_ELEMENTS); |
|
387 |
} |
|
388 |
|
|
389 |
/* |
|
390 |
* Starts running the specified test on the specified element |
|
391 |
*/ |
|
392 |
public void startTest(int testType, int num) throws Exception{ |
|
393 |
String command = getStartTestCommand(testType, num); |
|
394 |
if(command == null){ |
|
395 |
System.out.println("Illegal test requested\n"); |
|
396 |
return; |
|
397 |
} |
|
398 |
gui.addTextToConsole(command); |
|
399 |
serial.puts(command); |
|
400 |
boolean ready = false; |
|
401 |
while(!ready){ |
|
402 |
String input = getInput(); |
|
403 |
int parseStatus = parseInput(input); |
|
404 |
if(parseStatus == READY) |
|
405 |
ready = true; |
|
406 |
} |
|
407 |
printData(testType); |
|
408 |
} |
|
409 |
|
|
410 |
/* |
|
411 |
* Stops the running test |
|
412 |
*/ |
|
413 |
public void stopTest() throws Exception{ |
|
414 |
serial.puts("stop\r\n"); |
|
415 |
} |
|
416 |
|
|
417 |
/* |
|
418 |
* Prints out the received data - good for debugging if the grapher is malfunctioning |
|
419 |
*/ |
|
420 |
public void printData(int test){ |
|
421 |
switch(test){ |
|
422 |
case ALL_TESTS: |
|
423 |
printData(RANGEFINDER); |
|
424 |
printData(ENCODER); |
|
425 |
printData(MOTOR); |
|
426 |
printData(BOM); |
|
427 |
break; |
|
428 |
case RANGEFINDER: |
|
429 |
System.out.println("Rangefinder Wall Data:"); |
|
430 |
print(rangefinderWallData); |
|
431 |
System.out.println("Rangefinder Range Data:"); |
|
432 |
print(rangefinderRangeData); |
|
433 |
break; |
|
434 |
case ENCODER: |
|
435 |
System.out.println("Encoder Dynamo Data:"); |
|
436 |
print(encoderDynamoData); |
|
437 |
System.out.println("Encoder Value Data:"); |
|
438 |
print(encoderValueData); |
|
439 |
break; |
|
440 |
case MOTOR: |
|
441 |
System.out.println("Motor PWM Data:"); |
|
442 |
print(motorPWMData); |
|
443 |
System.out.println("Motor Velocity Data:"); |
|
444 |
print(motorVelocityData); |
|
445 |
break; |
|
446 |
case BOM: |
|
447 |
printData(BOM_EMITTER); |
|
448 |
printData(BOM_DETECTOR); |
|
449 |
break; |
|
450 |
case BOM_EMITTER: |
|
451 |
System.out.println("BOM emitter Data:"); |
|
452 |
printStatus(bomData, bomStatus, EMITTER); |
|
453 |
break; |
|
454 |
case BOM_DETECTOR: |
|
455 |
System.out.println("BOM detector Data:"); |
|
456 |
printStatus(bomData, bomStatus, DETECTOR|DETECTOR_OUT); |
|
457 |
break; |
|
458 |
} |
|
459 |
} |
|
460 |
|
|
461 |
/* |
|
462 |
* Picks out the given subset of the given data |
|
463 |
*/ |
|
464 |
private ArrayList<Integer> getSubset(ArrayList data, ArrayList status, int bitmask){ |
|
465 |
ArrayList<Integer> arr = new ArrayList<Integer>(); |
|
466 |
for(int i=0; i< status.size(); i++){ |
|
467 |
if(((Integer)status.get(i) & bitmask) == bitmask){ |
|
468 |
arr.add((Integer)data.get(i)); |
|
469 |
} |
|
470 |
} |
|
471 |
return arr; |
|
472 |
} |
|
473 |
|
|
474 |
/* |
|
475 |
* Prints out the current status |
|
476 |
*/ |
|
477 |
private void printStatus(ArrayList data[], ArrayList status[], int bitmask){ |
|
478 |
for(int i=0; i<status.length; i++){ |
|
479 |
System.out.print(i + ": "); |
|
480 |
printStatus(data[i], status[i], bitmask); |
|
481 |
System.out.println(); |
|
482 |
} |
|
483 |
} |
|
484 |
|
|
485 |
/* |
|
486 |
* Prints the current status |
|
487 |
*/ |
|
488 |
private void printStatus(ArrayList data, ArrayList status, int bitmask){ |
|
489 |
System.out.print("["); |
|
490 |
boolean first = true; |
|
491 |
for(int i=0; i< status.size(); i++){ |
|
492 |
if(((Integer)status.get(i) & bitmask) == bitmask){ |
|
493 |
if(!first) |
|
494 |
System.out.print(", "); |
|
495 |
System.out.print(data.get(i)); |
|
496 |
first = false; |
|
497 |
} |
|
498 |
} |
|
499 |
System.out.print("]"); |
|
500 |
} |
|
501 |
|
|
502 |
/* |
|
503 |
* Prints an ArrayList of arrays |
|
504 |
*/ |
|
505 |
private void print(ArrayList arr[]){ |
|
506 |
for(int i=0; i<arr.length; i++){ |
|
507 |
System.out.print(i + ": "); |
|
508 |
print(arr[i]); |
|
509 |
System.out.println(); |
|
510 |
} |
|
511 |
} |
|
512 |
|
|
513 |
/* |
|
514 |
* Prints an array |
|
515 |
*/ |
|
516 |
private void print(ArrayList arr){ |
|
517 |
System.out.print("["); |
|
518 |
for(int i=0; i< arr.size(); i++){ |
|
519 |
System.out.print(arr.get(i)); |
|
520 |
if(i < arr.size() - 1) |
|
521 |
System.out.print(", "); |
|
522 |
} |
|
523 |
System.out.print("]"); |
|
524 |
} |
|
525 |
|
|
526 |
/* |
|
527 |
* Returns the command to pass to the server, or null if the |
|
528 |
* request is malformed |
|
529 |
*/ |
|
530 |
public String getStartTestCommand(int testType, int num){ |
|
531 |
String command = "start_test"; |
|
532 |
switch(testType){ |
|
533 |
case ALL_TESTS: |
|
534 |
command += " all\n"; |
|
535 |
return command; |
|
536 |
case RANGEFINDER: |
|
537 |
command += " rangefinder"; |
|
538 |
break; |
|
539 |
case ENCODER: |
|
540 |
command += " encoder"; |
|
541 |
break; |
|
542 |
case MOTOR: |
|
543 |
command += " motor"; |
|
544 |
break; |
|
545 |
case BOM: |
|
546 |
command += " bom"; |
|
547 |
break; |
|
548 |
case BOM_EMITTER: |
|
549 |
command += " bom emitter"; |
|
550 |
break; |
|
551 |
case BOM_DETECTOR: |
|
552 |
command += " bom detector"; |
|
553 |
break; |
|
554 |
default: |
|
555 |
return null; |
|
556 |
} |
|
557 |
if(num == -1) |
|
558 |
command += " all"; |
|
559 |
else |
|
560 |
command += " " + num; |
|
561 |
return command + "\n"; |
|
562 |
} |
|
563 |
|
|
564 |
/* |
|
565 |
* Sends the given message to the station |
|
566 |
*/ |
|
567 |
public void send_message(String s) throws Exception{ |
|
568 |
serial.puts(s); |
|
569 |
} |
|
570 |
|
|
571 |
/* |
|
572 |
* Prints out all data received (this method hangs permanently) |
|
573 |
*/ |
|
574 |
public String getInput() throws Exception{ |
|
575 |
while(true){ |
|
576 |
String rec = serial.gets(); |
|
577 |
if(rec != null) |
|
578 |
return rec; |
|
579 |
} |
|
580 |
} |
|
581 |
|
|
582 |
/* |
|
583 |
* Prints any received data (hangs for ms milliseconds) |
|
584 |
*/ |
|
585 |
public String getInput(int ms) throws Exception{ |
|
586 |
long time = System.currentTimeMillis(); |
|
587 |
while(true){ |
|
588 |
if(System.currentTimeMillis() - time > ms){ |
|
589 |
System.out.println("Operation timed out\n"); |
|
590 |
return null; |
|
591 |
} |
|
592 |
String rec = serial.gets(); |
|
593 |
if(rec != null) |
|
594 |
return rec; |
|
595 |
} |
|
596 |
} |
|
597 |
|
|
598 |
/* |
|
599 |
* Parses the input to determine which kind of request is being received |
|
600 |
*/ |
|
601 |
private int parseInput(String s){ |
|
602 |
if(s.charAt(0) == '#' || s.charAt(0) == '\n' || s.charAt(0) == '\r'){ |
|
603 |
System.out.print(s); |
|
604 |
return COMMENT; |
|
605 |
} |
|
606 |
else if(s.startsWith("data")){ |
|
607 |
if(parseData(s.substring(4))) |
|
608 |
return DATA; |
|
609 |
else{ |
|
610 |
System.out.println("Error parsing data >" + s + "<"); |
|
611 |
return PARSE_ERROR; |
|
612 |
} |
|
613 |
} |
|
614 |
else if(s.startsWith("ready")) |
|
615 |
return READY; |
|
616 |
else{ |
|
617 |
System.out.println("Unable to parse message >" + s + "<"); |
|
618 |
return PARSE_ERROR; |
|
619 |
} |
|
620 |
} |
|
621 |
|
|
622 |
/* |
|
623 |
* Parses data messages |
|
624 |
*/ |
|
625 |
private boolean parseData(String s){ |
|
626 |
try{ |
|
627 |
Scanner scan = new Scanner(s); |
|
628 |
String testType = scan.next(); |
|
629 |
if(testType.equals("bom")){ |
|
630 |
ArrayList<Integer> dataArr = new ArrayList<Integer>(); |
|
631 |
ArrayList<Integer> statusArr = new ArrayList<Integer>(); |
|
632 |
|
|
633 |
String emDet = scan.next(); |
|
634 |
int num = scan.nextInt(); |
|
635 |
if(num >= NUM_BOMS){ |
|
636 |
System.out.println("Invalid bom index: " + num); |
|
637 |
return false; |
|
638 |
} |
|
639 |
|
|
640 |
if(emDet.equals("emitter")){ |
|
641 |
while(scan.hasNext()){ |
|
642 |
int mask = EMITTER; |
|
643 |
String data = scan.next(); |
|
644 |
if(data.startsWith("top")) |
|
645 |
mask |= EMITTER_TOP; |
|
646 |
else if(data.startsWith("left")) |
|
647 |
mask |= EMITTER_LEFT; |
|
648 |
else if(data.startsWith("right")) |
|
649 |
mask |= EMITTER_RIGHT; |
|
650 |
else |
|
651 |
return false; |
|
652 |
|
|
653 |
int slashIdx = data.indexOf("/"); |
|
654 |
int value = Integer.valueOf(data.substring( |
|
655 |
slashIdx+1)); |
|
656 |
dataArr.add(value); |
|
657 |
statusArr.add(mask); |
|
658 |
} |
|
659 |
bomData[num].addAll(dataArr); |
|
660 |
bomStatus[num].addAll(statusArr); |
|
661 |
return true; |
|
662 |
} |
|
663 |
else if(emDet.equals("detector")){ |
|
664 |
while(scan.hasNext()){ |
|
665 |
int mask = DETECTOR; |
|
666 |
String data = scan.next(); |
|
667 |
int dataStart; |
|
668 |
if(data.startsWith("in")){ |
|
669 |
mask |= DETECTOR_IN; |
|
670 |
dataStart = 3; |
|
671 |
} |
|
672 |
else if(data.startsWith("out")){ |
|
673 |
mask |= DETECTOR_OUT; |
|
674 |
dataStart = 4; |
|
675 |
} |
|
676 |
else |
|
677 |
return false; |
|
678 |
if(data.charAt(dataStart-1) != '/') |
|
679 |
return false; |
|
680 |
int value = Integer.valueOf(data.substring(dataStart)); |
|
681 |
dataArr.add(value); |
|
682 |
statusArr.add(mask); |
|
683 |
} |
|
684 |
bomData[num].addAll(dataArr); |
|
685 |
bomStatus[num].addAll(statusArr); |
|
686 |
return true; |
|
687 |
} |
|
688 |
else |
|
689 |
return false; |
|
690 |
} |
|
691 |
else if(testType.equals("rangefinder")){ |
|
692 |
ArrayList<Integer> dataWallArr = new ArrayList<Integer>(); |
|
693 |
ArrayList<Integer> dataRangeArr = new ArrayList<Integer>(); |
|
694 |
ArrayList<Integer> statusArr = new ArrayList<Integer>(); |
|
695 |
|
|
696 |
int num = scan.nextInt(); |
|
697 |
if(num >= NUM_RANGEFINDERS){ |
|
698 |
System.out.println("Invalid rangefinder index: " + num); |
|
699 |
return false; |
|
700 |
} |
|
701 |
|
|
702 |
String dir = scan.next(); |
|
703 |
int mask; |
|
704 |
if(dir.equals("in")) |
|
705 |
mask = RANGEFINDER_IN; |
|
706 |
else if(dir.equals("out")) |
|
707 |
mask = RANGEFINDER_OUT; |
Also available in: Unified diff