this version has all of Jim's fixes for reading the GPS and IMU data synchronously

Dependencies:   MODSERIAL SDFileSystem mbed SDShell CRC CommHandler FP LinkedList LogUtil

Revision:
29:dead10cce6e9
Parent:
26:c2208b0ff78b
Child:
30:96d133f3008e
--- a/PCMessaging.h	Wed Nov 13 22:12:04 2013 +0000
+++ b/PCMessaging.h	Thu Jan 09 14:09:05 2014 +0000
@@ -1,382 +1,40 @@
 //these are defines for the messages that are sent from the PC across the USB
 //these messages produce reactions on the mbed
-const unsigned char  POSVEL_MSG         =0;
-const unsigned char  FIRE_TRIGGER_MSG   =1;
-const unsigned char  STATUS_MSG         =2;
-const unsigned char  STARTDATA_MSG      =3;
-const unsigned char  STOPDATA_MSG       =4;
-const unsigned char  STARTSTREAM_MSG    =5;
-const unsigned char  STOPSTREAM_MSG     =6;
-const unsigned char  STARTLOGINFO_MSG   =7;
-const unsigned char  STOPLOGINFO_MSG    =8;
-const unsigned char  GETFILE_MSG        =9; // added to get a file from the SD card
-
-const double  DEGREES_TO_RADIANS = acos(-1.0)/180.0;
-const double eccen          = 0.0818191908426;  //WGS84 earth eccentricity
-const double earthRadius    = 6378137;          //WGS84 earthRadius in meters
+const unsigned char  FIRE_TRIGGER_MSG   = 1;
 
 const unsigned short serBuffMax = 18;
 char serBuf[serBuffMax];
 int serBufChars=0;
 
 //flags to control the PC command actions
-bool sendPosVel     =false;
-bool sendStatus     =false;
-bool sendRecData    =false;
-bool streamPos      =false;
-bool sendStreamPos  =false;
-bool logMsgInfo     =false;
-bool sendLogMsgInfo =false;
-bool recordData     =false;
 bool fireTrigger    =false;
-bool get_file_msg   =false; // added for GETFILE command
 
-
-const unsigned char numMessages = 10;    //number of potential messages (updated to 10 sg-)
-char msgList[numMessages][32];          //text array storing the command messages from the PC
-char minMessageSize = 11;               //minimum size of a text message
 unsigned char CR = 0x0d;                //ASCII Carriage Return
 unsigned char LF = 0x0a;                //ASCII Line Feed
 
-char preamble[5] = "WMsg";
-char testPreamble[5];
 bool validMessage = false;
 
 
-void setUpMessages(void)
-{ 
-    //set up the ASCII text records that are candidates to be passed from the PC
-    sprintf(msgList[STATUS_MSG],        "WMsg STATUS");
-    sprintf(msgList[POSVEL_MSG],        "WMsg POSVEL");
-    sprintf(msgList[STARTDATA_MSG],     "WMsg RECORDDATA Y");
-    sprintf(msgList[STOPDATA_MSG],      "WMsg RECORDDATA N");
-    sprintf(msgList[STARTSTREAM_MSG],   "WMsg POSSTREAM Y");
-    sprintf(msgList[STOPSTREAM_MSG],    "WMsg POSSTREAM N");
-    sprintf(msgList[STARTLOGINFO_MSG],  "WMsg LOGINFO Y");
-    sprintf(msgList[STOPLOGINFO_MSG],   "WMsg LOGINFO N");
-    sprintf(msgList[FIRE_TRIGGER_MSG],  "WMsg TRIGGER");
-    sprintf(msgList[GETFILE_MSG],       "WMsg GETFILE");    // added to get the file off of sd cards
-    //message length is from 10 to 16 chars
-    
- //   toPC.printf(" finished setting up messages \n");
-}
-
 void readFromPC()
 {
     //  should this be a while rather than if ??? -- may have multiple bytes in buffer
     if (toPC.readable()) //read a PC serial byte and test it for a command
     {
-        // Read in next character  -- why not read all available??
+        // Read in next character
+        // why not read all available bytes
         unsigned char inChar = 0;
         inChar = toPC.getc();  //read char from the USB serial link to the PC
-        //toPC.printf("%02x ",inChar);
         
         //incoming messages will end witb a CR / LF -- disregard these chars
         if (inChar == CR || inChar == LF)  return; //CR is a 0x0a
         
-        //all received messages assumed to have a WMsg preamble
-        //if we have read 4 chars, test these for "WMsg", if they are not WMsg, reset the buffer counter
-        //if we receive an occasional bad byte that messes up a message, this will resynch fast to a next message
-        //this will let us miss a message --- but hopefully only one
-        
-        // serBuffMax = 18 -- largest serBuffMax is 16 -- but we add one below for the '\0'
-        // if the following occurs we have had a trash byte following a WMsg header
-        if (serBufChars >= (serBuffMax-2)) {toPC.printf("WMsg restart message search\n"); serBufChars = 0; }
-        
-        serBuf[serBufChars] = inChar; //set this char in a char array for testing complete message
-  
-        testPreamble[serBufChars] = inChar;  //char array for testing the preamble
-        serBufChars++;
-        
-        if (serBufChars == 4)  //four initial chars detected (0, 1, 2, 3)
-        {
-            testPreamble[4] = '\0';  //form null-terminated string for compare
-            if (strncmp(testPreamble, preamble, 5) != 0)   //compare the chars to the WMsg preamble
-            {
-                toPC.printf("WMsg preamble mismatch \n");
-                serBufChars = 0;  //if they dont match -- restart the search for a preamble
-                return;
-            }
-        }
-        
-        //if we get here, we have found a preamble and we are looking for a complete message
-        //no need to continue if numChars are less than the shortest candidate message
-        if (serBufChars < minMessageSize) return;
-                
-        // Append end of string
-        // We always assume we have a complete message string and test for this below
-        serBuf[serBufChars] = '\0';
-        
-        validMessage = false;
-        
-        // Check for valid message -- there are numMessages possible messages
-        //this assumes that the message buffer contains an exact message
-        for (int m = 0; m < numMessages && !validMessage; m++) //check for all messages ... 
-        {
-            //toPC.printf(" \n\n found chars to test %3d %3d %s \n\n\n ", serBufChars, strlen(msgList[m]), serBuf );
-
-            //check the current partial message against ALL possible messages
-            //messages must match in both strength length and text
-            if (serBufChars == strlen(msgList[m]) && strncmp(serBuf, msgList[m], serBufChars) == 0 )
-            {
-            
-                //toPC.printf( "\n       found valid message %s  \n\n", serBuf);
-                rxMsg = !rxMsg;
-
-                validMessage = true;
-                serBufChars = 0; //reset the character count to reset for next message
-                
-                //set programmatic action flags based on the message
-                switch(m)
-                {
-                    case STATUS_MSG:
-                        sendStatus = true;  //send a status message back to PC
-                        break;
-                        
-                    case POSVEL_MSG:
-                        sendPosVel = true;  //send a posvel message back to PC
-                        timeFromPosVelMessageReceipt.reset();  //start time and close SD card file if too long
-                        break;
-                    
-                    case STARTDATA_MSG:  //start the data recording to the SD card
-                        recordData = true;
-                        sendRecData = true;
-                        break;
-                    
-                    case STOPDATA_MSG:   //stop the data recording to the SD card
-                        recordData = false;
-                        sendRecData = true;
-                        break;
-                    
-                    case STARTSTREAM_MSG:
-                    case STOPSTREAM_MSG:
-                        streamPos = (m == STARTSTREAM_MSG);
-                        sendStreamPos = true;
-                        break;
-                    
-                    case STARTLOGINFO_MSG:
-                    case STOPLOGINFO_MSG:
-                        logMsgInfo = (m == STARTLOGINFO_MSG);
-                        sendLogMsgInfo = true;
-                        break;  
-                    
-                    case FIRE_TRIGGER_MSG:
-                        fireTrigger = true;
-                        toPC.printf("WMsg MBED received trigger command \n");
-                        break;
-                    
-                    case GETFILE_MSG:
-                        get_file_msg = true;    // signal to main that we can unload the file that was written
-                        toPC.printf("WMsg  request to get SD card file \n");
-                        break;
-                    
-                }  //end Switch statement
-                break;
-            } //end test for a valid message
-            
-        }  //end message text loop
+        //all incoming messages will start with "mbedMessage", "messageType", numberDataBytes, and will end with CR & LF
+        //1) look for the mbedMessage and then get the next byte as numberDataBytes;
+        //2) read the next numberDataBytes and then look for CR & LF
+        //if 1) & 2)  are successful, declare a valid incoming message
+        //if message is valid, then send a response as a repeat of the original message
+        //
         
     }  //end pc.readable
 };
 
-void earthCoefficients(double latitudeRad, double longitudeRad, double height, double &latRateFac, double &lonRateFac)
-{
-    //compute the lat and lon factors for use in the interpolation of the lat and lon between 1 sec epochs
-    //latRateFac & lonRateFac multiplied by Vnorth or VEast to get latRate and lonRate
-    //see this document (page 32)    www.fas.org/spp/military/program/nav/basicnav.pdf
-
-    double eccenSinLat = eccen * sin(latitudeRad); 
-    double temp1 = 1.0 - eccenSinLat*eccenSinLat;
-    double temp2 = sqrt(temp1);
-    double r_meridian = earthRadius * ( 1.0 - eccen*eccen)/ (temp1 * temp2);
-    double r_normal   = earthRadius / temp2;
-        
-    //divide Vnorth by latRateFac to get the latitude rate in deg per sec
-    latRateFac = (r_meridian + height)* DEGREES_TO_RADIANS;
-    
-    //divide VEast by lonRateFac to get the longitude rate in deg per sec
-    lonRateFac =  (r_normal + height) * cos(latitudeRad)* DEGREES_TO_RADIANS;
-}
-
-void sendPosVelMessageToPC(OEM615BESTPOS posMsg, OEM615BESTVEL velMsg)
-{
-            //north and east velocity from the horizontal speed and heading
-            //velMsg may not be the "current" message --- but is the one also associated with a position message
-            double nVel = velMsg.horizontalSpeed*cos(velMsg.heading*DEGREES_TO_RADIANS);
-            double eVel = velMsg.horizontalSpeed*sin(velMsg.heading*DEGREES_TO_RADIANS);
-            
-            double latRateFac;
-            double lonRateFac;
-                        
-            earthCoefficients(  posMsg.latitude*DEGREES_TO_RADIANS, 
-                                posMsg.longitude*DEGREES_TO_RADIANS, 
-                                posMsg.height, 
-                                latRateFac, lonRateFac);
-            
-            //commented calculations are for a spherical earth (Chris's original computation)
-            // For the 1 second deltas with which we are dealing
-            // This calculation should be close enough for now
-            // Approximately 1 nautical mile / minute latitude, 60 minutes/degree, 1852 meters/nautical mile
-            //double latMetersPerDeg = 60.0*1852.0;
-            // longitude separation is approximately equal to latitude separation * cosine of latitude
-            //double lonMetersPerDeg = latMetersPerDeg*cos(posMsg.latitude*DEGREES_TO_RADIANS);
-
-            // Elapsed time since last known GPS position
-            //PPSTimeOffset is a result of possibly missing a prior GPS position message
-            // timeFromPPS.read() is always the time from the most recent 1PPS
-            double elTime = (double)PPSTimeOffset + timeFromPPS.read();
-            
-             //this is the best estimate of the GPS time of the requested POSVEL data
-            double posTime = GPSTimemsecs/1000.0 + elTime;
-            
-            // Position time -- posMsgTime is the time of the last valid GPS position message
-            // this time may differ from GPSTimemsecs if the last position message (42) was missed due to CRC error 
-            double posMsgTime = posMsg.msgHeader.GPSTime_msecs/1000.0;
-            
-            //toPC.printf(" elTime = %6.3f PPSimeOffset = %6.3f \n", elTime, PPSTimeOffset);
-            //toPC.printf(" latRateFac = %10.3f  lonRateFac = %10.3f \n", latRateFac, lonRateFac);
-            //toPC.printf(" latRateFac = %10.3f  lonRateFac = %10.3f \n", latMetersPerDeg, lonMetersPerDeg);
-
-            // Estimated position based on previous position and velocity
-            // posMsg is the last time when the BESTVEL and BESTPOS messages had identical times
-            //double latPos = posMsg.latitude  + (nVel/latMetersPerDeg)*elTime;
-            //double lonPos = posMsg.longitude + (eVel/lonMetersPerDeg)*elTime;
-            
-            double latPos = posMsg.latitude  + (nVel/latRateFac)*(posTime - posMsgTime);
-            double lonPos = posMsg.longitude + (eVel/lonRateFac)*(posTime - posMsgTime);            
-            double htPos  = posMsg.height    + velMsg.verticalSpeed/(60*1852)*elTime;
-            
-            char solReady = 'N';
-            //solStatus 
-            if (posMsg.solStatus == 0) //see description of solution status in OEMV615.h
-            {
-                solReady = 'Y';
-            }
-            
-            toPC.printf("WMsg POSVEL %5.3lf %1d %c %8.6lf %9.6lf %4.3lf %4.3lf %4.3lf %4.3lf\n", 
-                         posTime, 
-                         posMsg.numSolSV,
-                         solReady,
-                         latPos,
-                         lonPos,
-                         htPos,
-                         nVel,
-                         eVel,
-                         velMsg.verticalSpeed
-                         );
-             txMsg = !txMsg;
-}
-
-void processPCmessages(FILE* &fpNav, OEM615BESTPOS posMsg, OEM615BESTVEL velMsg)
-{
-
-
-        
-        //we should put the below stuff into the readPC() procedure.
-        //only do these actions in response to a command so no need for the tests w/o an inoput byte from the PC
-        //perform the activities as a response to the commands
-        if (sendPosVel)  //true if we want to return a position solution
-        {
-            //if we are receiving POSVEL requests -- always open the file for storage and store the data
-            //th file is closed(in main) if we dont receive POSVAL messages for 60 secs
-            if (fpNav == NULL)
-            { 
-                toPC.printf("WMsg opening the SD card file at first PosVel message \n");
-                fpNav = fopen("/sd/Data/NAV.bin", "wb");
-                wait_ms(10);
-                recordData = true;
-            }
-            sendPosVel=false; //set to true if a POSVEL is requested from the PC
-            sendPosVelMessageToPC(posMsg, velMsg);
-        }
-        
-        //all this does is assess the GPS convergence -- really available in the above
-        if (sendStatus)  //send the status message to the PC
-        {
-            txMsg = !txMsg;
-            sendStatus=false;
-            char solReady = 'N';
-            //solStatus 
-            if (posMsg.solStatus == 0) //see description of solution status in OEMV615.h
-            {
-                solReady = 'Y';
-            }
-            toPC.printf("WMsg STATUS %5.3lf %c\n", 
-                         GPSTimemsecs, 
-                         solReady
-                         );
-        }
-        
-        //should just record ALL the data -- can pick over it in the post-processing
-        if (sendRecData)  //begin to (or stop) record the serial data
-        {
-            sendRecData=false;  //reset the flag so we dont continue to come through here
-            char recChar = 'N';
-            //recordData set to true only if we receive a STARTDATA from the PC
-            if (recordData)  //here we have received a message to record the data
-            {
-                if ((fpNav == NULL))  //if file not opened -- open it
-                {
-                    toPC.printf(" opening the SD card file from RECORD message \n");
-                    fpNav = fopen("/sd/Data/NAV.bin", "wb");
-                    wait_ms(10);
-                }
-                if (fpNav != NULL)  //if the file was already opened we will respond to the PC with a Y 
-                {
-                    recChar = 'Y';
-                }
-                else //is the file was not opened we will write a message to the PC
-                {
-                    toPC.printf(" Could not open the SD card \n\n");
-                }
-            }
-            //recordData set to false only if we receive a STOPDATA from the PC
-            else //here we have received a message to stop the recording
-            {
-                if (fpNav != NULL)  //if the file is open -- close it
-                {
-                    toPC.printf(" closing the SD card file from RECORD message\n\n");
-                    fflush(fpNav);
-                    fclose(fpNav);
-                    wait_ms(100);
-                    //toPC.printf("\n after closing the SD card file \n\n");
-                    fpNav = NULL;
-                }
-                //if stop recording received and the file is already closed -- just do nothing
-                recordData = false;
-
-            }
-            toPC.printf("WMsg RECORDDATA %c\n", 
-                         recChar
-                         );
-        }
-        
-        if (sendStreamPos)  //stream the position data to the PC
-        {
-            sendStreamPos=false;
-            char streamChar = 'N';
-            if (streamPos)
-            {
-                streamChar = 'Y';
-            }
-            toPC.printf("WMsg POSSTREAM %c\n", 
-                         streamChar
-                         );
-        }
-        
-        //not sure this is ever used ..
-        if (sendLogMsgInfo)  //send log info to the PC
-        {
-            sendLogMsgInfo=false;
-            char logChar = 'N';
-            if (logMsgInfo)
-            {
-                logChar = 'Y';
-            }
-            toPC.printf("WMsg LOGINFO %c\n", 
-                         logChar
-                         );
-        }
-        
-
-}