updates for 0.9.4
[debian/openrocket] / src-extra / altimeter / RotationLogger.java
diff --git a/src-extra/altimeter/RotationLogger.java b/src-extra/altimeter/RotationLogger.java
new file mode 100644 (file)
index 0000000..45e7d76
--- /dev/null
@@ -0,0 +1,356 @@
+package altimeter;
+
+import gnu.io.CommPortIdentifier;
+import gnu.io.PortInUseException;
+import gnu.io.SerialPort;
+import gnu.io.UnsupportedCommOperationException;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Enumeration;
+
+/**
+ * Class to interface the PerfectFlite Alt15K/WD altimeter.
+ * 
+ * Also includes a main method that retrieves all flight profiles and saves them to files.
+ * 
+ * @author Sampo Niskanen <sampo.niskanen@iki.fi>
+ */
+
+public class RotationLogger {
+       private static final boolean DEBUG = false;
+       
+       private static final int BYTES = 65536; 
+       
+       
+       private final CommPortIdentifier portID;
+       private SerialPort port = null;
+       private InputStream is = null;
+       private OutputStream os = null;
+       
+       
+
+       @SuppressWarnings("unchecked")
+       public static String[] getNames() {
+               ArrayList<String> list = new ArrayList<String>();;
+               
+               Enumeration pids = CommPortIdentifier.getPortIdentifiers();
+
+               while (pids.hasMoreElements()) {
+                   CommPortIdentifier pid = (CommPortIdentifier) pids.nextElement();
+
+                   if (pid.getPortType() == CommPortIdentifier.PORT_SERIAL)
+                       list.add(pid.getName());
+               }
+               return list.toArray(new String[0]);
+       }
+
+       
+       
+       
+
+       @SuppressWarnings("unchecked")
+       public RotationLogger(String name) throws IOException {
+               CommPortIdentifier portID = null;
+               
+               Enumeration portIdentifiers = CommPortIdentifier.getPortIdentifiers();
+               while (portIdentifiers.hasMoreElements()) {
+                   CommPortIdentifier pid = (CommPortIdentifier) portIdentifiers.nextElement();
+                   
+                   if(pid.getPortType() == CommPortIdentifier.PORT_SERIAL &&
+                      pid.getName().equals(name)) {
+                       portID = pid;
+                       break;
+                   }
+               }
+               
+               if (portID==null) {
+                       throw new IOException("Port '"+name+"' not found.");
+               }
+               this.portID = portID;
+       }
+       
+       
+       
+       
+       
+       
+       public void readData() throws IOException, PortInUseException {
+               int c;
+               
+               int[] data = new int[BYTES];
+               
+               FileOutputStream rawdump = null;
+               
+               
+               try {
+                       open();
+
+                       System.err.println("Sending dump mode command...");
+                       
+                       for (int i=0; i<16; i++) {
+                               os.write('D');
+                               try {
+                                       Thread.sleep(10);
+                               } catch (InterruptedException ignore) { }
+                       }
+                       
+                       System.err.println("Waiting for response...");
+                       while (true) {
+                               c = is.read();
+                               if (c == 'K') {
+                                       break;
+                               } else {
+                                       System.err.printf("Received spurious c=%d\n",c);
+                               }
+                       }
+                       
+                       System.err.println("Received response.");
+                       
+
+                       
+                       System.err.println("Opening 'rawdump'...");
+                       rawdump = new FileOutputStream("rawdump");
+                       
+                       
+                       
+                       System.err.println("Performing dump...");
+
+                       os.write('A');
+
+                       byte[] buffer = new byte[1024];
+                       int printCount = 0;
+                       for (int count=0; count < BYTES; ) {
+                               if ((BYTES-count) < buffer.length) {
+                                       buffer = new byte[BYTES-count];
+                               }
+                               
+                               int n = is.read(buffer);
+                               if (n < 0) {
+                                       System.err.println("Error condition, n="+n);
+                                       return;
+                               }
+                       
+                               rawdump.write(buffer, 0, n);
+                               
+                               for (int i=0; i<n; i++) {
+                                       data[count+i] = unsign(buffer[i]);
+                               }
+                               count += n;
+                               if (count - printCount > 1024) {
+                                       System.err.println("Read "+count+" bytes...");
+                                       printCount = count;
+                               }
+                       }
+
+
+                       System.err.println("Verifying checksum...");
+                       int reported = is.read();
+                       
+                       byte computed = 0;
+                       for (int i=0; i < data.length; i++) {
+                               computed += data[i];
+                       }
+                       if (computed == reported) {
+                               System.err.println("Checksum ok ("+computed+")");
+                       } else {
+                               System.err.println("Error in checksum, computed="+computed+
+                                               " reported="+reported);
+                       }
+                       
+                       System.err.println("Communication done.");
+                       
+               } catch (UnsupportedCommOperationException e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               } finally {
+                       close();
+                       if (rawdump != null)
+                               rawdump.close();
+               }
+               
+               convertData(data);
+               
+       }
+       
+       
+       
+       ////////////  Data interpretation   //////////////      
+       
+       
+       private static void convertData(int[] data) {
+
+               System.err.println("Converting data...");
+
+               int lastBuffer = data[0xffff];
+               if (lastBuffer < 0 || lastBuffer > 3) {
+                       System.err.println("Illegal last accessed buffer: "+lastBuffer);
+                       return;
+               }
+               System.err.println("Last used buffer: "+lastBuffer);
+               
+               for (int i=4; i>0; i--) {
+                       int n = (lastBuffer + i) % 4;
+                       int bufNumber = 4-i;
+                       
+                       convertBuffer(data, n * (BYTES/4), bufNumber);
+               }
+               
+       }
+       
+       
+       private static void convertBuffer(int[] data, int position, int bufNumber) {
+               int startPosition;
+               
+               startPosition = data[position + 0xfd] << 8 + data[position+0xfe];
+
+               // 50 samples per 128 bytes 
+               int startTime = (startPosition -position) * 50 / 128;
+               
+               System.err.println("  Buffer "+ bufNumber + " (at position "+position+")...");
+               System.err.println("  Start position "+startPosition+" time "+startTime);
+
+               System.out.println("# Buffer "+bufNumber);
+               System.out.println("# Start position t="+startTime);
+               
+               
+               int t = 0;
+               for (int page = 0; page < 128; page++) {
+                       int pageStart = position + page * 128;
+
+                       if (pageStart == startPosition) {
+                               System.out.println("# ---clip---");
+                       }
+
+                       for (int i=0; i<125; i += 5) {
+                               int sample1, sample2;
+                               
+                               int start = pageStart + i;
+//                             System.err.println("page="+page+" i="+i+
+//                                             " position="+position+" pageStart="+pageStart+" start="+start);
+                               
+                               sample1 = (data[start] << 2) + (data[start+1] >> 6);
+                               sample2 = ((data[start+1] & 0x3f) << 4) + (data[start+2] >> 4);
+                               System.out.printf("%d  %4d  %4d %4d\n", bufNumber, t, sample1, sample2);
+                               t++;
+                               
+                               sample1 = ((data[start+2] & 0x0f) << 6) + (data[start+3] >> 2);
+                               sample2 = ((data[start+3] & 3) << 8) + data[start+4];
+                               System.out.printf("%d  %4d  %4d %4d\n", bufNumber, t, sample1, sample2);
+                               t++;
+                       }
+               }
+       }
+
+       
+       
+       private void open() throws PortInUseException, IOException, 
+                       UnsupportedCommOperationException {
+               
+               if (port != null) {
+                       System.err.println("ERROR: open() called with port="+port);
+                       Thread.dumpStack();
+                       close();
+               }
+               
+               if (DEBUG) {
+                       System.err.println("  Opening port...");
+               }
+
+               port = (SerialPort)portID.open("OpenRocket",1000);
+               
+               port.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, 
+                               SerialPort.PARITY_NONE);
+
+               port.setInputBufferSize(1);
+               port.setOutputBufferSize(1);
+
+               is = port.getInputStream();
+               os = port.getOutputStream();
+       }
+       
+       
+       private void close() {
+               if (DEBUG)
+                       System.err.println("  Closing port");
+               
+               SerialPort p = port;
+               port = null;
+               is = null;
+               if (p != null)
+                       p.close();
+       }
+       
+       
+       
+       private static int unsign(byte b) {
+               if (b >= 0)
+                       return b;
+               else
+               return 256 + b;
+       }
+       
+       
+
+       
+       public static void main(String[] arg) throws Exception {
+               
+               if (arg.length > 2) {
+                       System.err.println("Illegal arguments.");
+                       return;
+               }
+               if (arg.length == 1) {
+                       FileInputStream is = new FileInputStream(arg[0]);
+                       byte[] buffer = new byte[BYTES];
+                       int n = is.read(buffer);
+                       if (n != BYTES) {
+                               System.err.println("Could read only "+n+" bytes");
+                               return;
+                       }
+                       
+                       int[] data = new int[BYTES];
+                       for (int i=0; i<BYTES; i++) {
+                               data[i] = unsign(buffer[i]);
+                       }
+
+                       int checksum=0;
+                       for (int i=0; i<BYTES; i++) {
+                               checksum += data[i];
+                       }
+                       checksum = checksum%256;
+                       System.err.println("Checksum: "+checksum);
+                       
+                       convertData(data);
+                       return;                 
+               }
+               
+               
+               String device = null;
+               String[] devices = RotationLogger.getNames();
+               for (int i=0; i<devices.length; i++) {
+                       if (devices[i].matches(".*USB.*")) {
+                               device = devices[i];
+                               break;
+                       }
+               }
+               if (device == null) {
+                       System.err.println("Device not found.");
+                       return;
+               }
+               
+               
+               System.err.println("Selected device "+device);
+               
+               
+               RotationLogger p = new RotationLogger(device);
+               
+               p.readData();
+               
+       }
+       
+       
+}