I messed up the merge, so pushing it over to another repo so I don't lose it. Will tidy up and remove later

Dependencies:   BufferedSerial FatFileSystemCpp mbed

Files at this revision

API Documentation at this revision

Comitter:
AndyA
Date:
Tue Nov 15 10:28:47 2022 +0000
Parent:
82:ee6eed2a51bd
Child:
84:8094a1e64ecf
Commit message:
improve message parsing. Efficiency improvement in position conversion.

Changed in this revision

GeoPosition.cpp Show annotated file Show diff for this revision Revisions of this file
GeoPosition.h Show annotated file Show diff for this revision Revisions of this file
PNTSerial.cpp Show annotated file Show diff for this revision Revisions of this file
PNTSerial.h Show annotated file Show diff for this revision Revisions of this file
--- a/GeoPosition.cpp	Mon Nov 14 14:53:12 2022 +0000
+++ b/GeoPosition.cpp	Tue Nov 15 10:28:47 2022 +0000
@@ -31,6 +31,11 @@
   llaValid = false;
   ecefValid = false;
   enuValid = false;
+
+  sinRefLong = 0;
+  cosRefLong = 0;
+  sinRefLat = 0;
+  cosRefLat = 0;
 }
 
 GeoPosition::GeoPosition(GeoPosition *posToClone) {
@@ -50,6 +55,15 @@
     enuValid = true;
     enuPosition = posToClone->GetENU();
   }
+
+  struct LLA refPosLLA = referencePosition->GetLLA();
+  if (!(referencePosition->LLAKnown()))
+    return;
+  sinRefLong = sin(DEG2RAD(refPosLLA.longitude));
+  cosRefLong = cos(DEG2RAD(refPosLLA.longitude));
+  sinRefLat = sin(DEG2RAD(refPosLLA.latitude));
+  cosRefLat = cos(DEG2RAD(refPosLLA.latitude));
+
 }
 
 GeoPosition::~GeoPosition() {
@@ -155,6 +169,14 @@
   ecefValid = false;
   enuValid = true;
   referencePosition = refPos;
+
+  struct LLA refPosLLA = referencePosition->GetLLA();
+  if (!(referencePosition->LLAKnown()))
+    return;
+  sinRefLong = sin(DEG2RAD(refPosLLA.longitude));
+  cosRefLong = cos(DEG2RAD(refPosLLA.longitude));
+  sinRefLat = sin(DEG2RAD(refPosLLA.latitude));
+  cosRefLat = cos(DEG2RAD(refPosLLA.latitude));
 }
 
 void GeoPosition::SetReferancePosition(GeoPosition *refPos) {
@@ -163,6 +185,13 @@
   if ((llaValid) || (ecefValid))
     enuValid = false;
 
+  struct LLA refPosLLA = referencePosition->GetLLA();
+  if (!(referencePosition->LLAKnown()))
+    return;
+  sinRefLong = sin(DEG2RAD(refPosLLA.longitude));
+  cosRefLong = cos(DEG2RAD(refPosLLA.longitude));
+  sinRefLat = sin(DEG2RAD(refPosLLA.latitude));
+  cosRefLat = cos(DEG2RAD(refPosLLA.latitude));
 }
 
 
@@ -401,31 +430,19 @@
     return;
   }
 
-
   void GeoPosition::ENU2ECEF() {
 
   if (!enuValid || ecefValid || !referencePosition)
     return;
 
-  struct LLA refPosLLA = referencePosition->GetLLA();
   struct ECEF refPosECEF = referencePosition->GetECEF();
-
-  if (!(referencePosition->LLAKnown()))
-    return;
   if (!(referencePosition->ECEFKnown()))
     return;
 
-  double sinRefLong = sin(DEG2RAD(refPosLLA.longitude));
-  double cosRefLong = cos(DEG2RAD(refPosLLA.longitude));
-  double sinRefLat = sin(DEG2RAD(refPosLLA.latitude));
-  double cosRefLat = cos(DEG2RAD(refPosLLA.latitude));
-
   ecefPosition.X = -sinRefLong * enuPosition.E - sinRefLat*cosRefLong*enuPosition.N + cosRefLat*cosRefLong*enuPosition.U + refPosECEF.X;
   ecefPosition.Y = cosRefLong* enuPosition.E - sinRefLat*sinRefLong*enuPosition.N + cosRefLat*sinRefLong*enuPosition.U + refPosECEF.Y;
   ecefPosition.Z = cosRefLat*enuPosition.N + sinRefLat*enuPosition.U + refPosECEF.Z;
   ecefValid = true;
-
-
 }
 
 void GeoPosition::ECEF2ENU() {
@@ -433,24 +450,15 @@
   if (enuValid || !ecefValid || !referencePosition)
     return;
 
-  struct LLA refPosLLA = referencePosition->GetLLA();
   struct ECEF refPosECEF = referencePosition->GetECEF();
 
-  if (!(referencePosition->LLAKnown()))
-    return;
   if (!(referencePosition->ECEFKnown()))
     return;
 
-  double sinRefLong = sin(DEG2RAD(refPosLLA.longitude));
-  double cosRefLong = cos(DEG2RAD(refPosLLA.longitude));
-  double sinRefLat = sin(DEG2RAD(refPosLLA.latitude));
-  double cosRefLat = cos(DEG2RAD(refPosLLA.latitude));
-
   double xDelta = ecefPosition.X - refPosECEF.X;
   double yDelta = ecefPosition.Y - refPosECEF.Y;
   double zDelta = ecefPosition.Z - refPosECEF.Z;
 
-
   enuPosition.E = -sinRefLong * xDelta + cosRefLong * yDelta;
   enuPosition.N = -sinRefLat * cosRefLong * xDelta - sinRefLat*sinRefLong*yDelta + cosRefLat*zDelta;
   enuPosition.U = cosRefLat * cosRefLong * xDelta + cosRefLat*sinRefLong*yDelta + sinRefLat*zDelta;
--- a/GeoPosition.h	Mon Nov 14 14:53:12 2022 +0000
+++ b/GeoPosition.h	Tue Nov 15 10:28:47 2022 +0000
@@ -67,7 +67,7 @@
   // Changing reference position will flag ENU as invalid if LLA or ECEF are known
   // If you want to manitain ENU then first call SetENU(GetENU());
   // this will flag LLA and ECEF as invalid and maintain the ENU over a reference change.
-  // Directly changing the values of the GeoPosition being used as a reference after using it for conversions could have some weird effects.
+  // Changing the values of the GeoPosition being used as a reference after setting it as reference will give invalid results due to speed optimisations.
   void SetReferancePosition(GeoPosition *refPos);
   
 
@@ -116,6 +116,11 @@
 
   GeoPosition *referencePosition;
 
+  double sinRefLong;
+  double cosRefLong;
+  double sinRefLat;
+  double cosRefLat;
+
   struct LLA  llaPosition;
   struct ECEF ecefPosition;
   struct ENU  enuPosition;
--- a/PNTSerial.cpp	Mon Nov 14 14:53:12 2022 +0000
+++ b/PNTSerial.cpp	Tue Nov 15 10:28:47 2022 +0000
@@ -1,248 +1,219 @@
+#include "PNTSerial.h"
 #include "LTCApp.h"
-#include "PNTSerial.h"
-//#include <cstdint>
-//#include <cstring>
-
-//#define IdleTxBuffer (txBuf == TXBuffer1)?TXBuffer2:TXBuffer1
-//#define ActiveTxBuffer (txBuf == TXBuffer1)?TXBuffer1:TXBuffer2
-
-const int RLMessageLength = 63;
 
 
-PNTSerial::PNTSerial(const PinName Tx, const PinName Rx) : PosSource(Tx,Rx)
-{
-    originSet = false;
+PNTSerial::PNTSerial(const PinName Tx, const PinName Rx) : PosSource(Tx, Rx) {
+  originSet = false;
 }
 
 void PNTSerial::setOrigin(double Latitude, double Longitude, float altitude) {
-    origin.SetDecimalDegrees(Latitude, Longitude, altitude);
-    dataPoint.SetReferancePosition(&origin);
-    originSet = true;
+  origin.SetDecimalDegrees(Latitude, Longitude, altitude);
+  dataPoint.SetReferancePosition(&origin);
+  originSet = true;
 }
 
-void PNTSerial::run(void)
-{
-    _port.attach(callback(this, &PNTSerial::onSerialRx));
+void PNTSerial::run(void) {
+  _port.attach(callback(this, &PNTSerial::onSerialRx));
 }
 
-void PNTSerial::onSerialRx(void)
-{
-    while (_port.readable()) {
-        if (BypassMode) {
-            vipsBypassRx(_port.getc());
-        } else {
-            uint8_t charIn = _port.getc();
-            if (messagePrt == 0) {
-                if (charIn == '$') {
-                    messageInBuffer[messagePrt++] = charIn;
-                }
-            } else {
-                messageInBuffer[messagePrt++] = charIn;
-                if (charIn == '/n') {
-                    parsePostion();
-                    messagePrt = 0;
-                } else if (messagePrt == MaxBuffSize) {
-                    messagePrt = 0;
-                }
-            }
+void PNTSerial::onSerialRx(void) {
+  while (_port.readable()) {
+    if (BypassMode) {
+      vipsBypassRx(_port.getc());
+    } else {
+      uint8_t charIn = _port.getc();
+      if (messagePrt == 0) { // wait for start character
+        if (charIn == '$') {
+          messageInBuffer[messagePrt++] = charIn;
         }
+      } else {
+        messageInBuffer[messagePrt++] = charIn;
+        // basic sanity check that second byte is expected value.
+        if ((messagePrt==2) && (messageInBuffer[1] != 'R')) 
+            messagePrt = 0;
+        // got the full message 
+        else if (messagePrt == PNTSerialConstants::MessageLength) {
+          parsePostion();
+          messagePrt = 0;
+        }
+      }
     }
+  }
 }
 
-/*
-uint32_t PNTSerial::NMEATimeToMS() {
-    int hours = (messageInBuffer[messageParsePtr]-'0')*10+(messageInBuffer[messageParsePtr+1]-'0');
-    int minutes = (messageInBuffer[messageParsePtr+2]-'0')*10+(messageInBuffer[messageParsePtr+3]-'0');
-    int seconds = (messageInBuffer[messageParsePtr+4]-'0')*10+(messageInBuffer[messageParsePtr+5]-'0');
-    int ms = 0;
-    messageParsePtr+=6;
-    if (messageInBuffer[messageParsePtr] == '.') {
-        messageParsePtr++;
-        ms = (messageInBuffer[messageParsePtr++]-'0')*100;
-        if (messageInBuffer[messageParsePtr] != ',') {
-            ms += (messageInBuffer[messageParsePtr++]-'0')*10;
-            if (messageInBuffer[messageParsePtr] != ',') {
-                ms += (messageInBuffer[messageParsePtr++]-'0');
-            }
-        }
-    }
-    while (messageInBuffer[messageParsePtr] != ',')
-        messageParsePtr++;
-}
-*/
-
 bool PNTSerial::CheckValidMessage() {
-
-//check length
-    if (messagePrt != RLMessageLength)
-        return false;
+  // check length
+  if (messagePrt != PNTSerialConstants::MessageLength)
+    return false;
 
-    // check header
-if (messageInBuffer[0] != '$')
-        return false;
-    if (messageInBuffer[1] != 'R')
-        return false;
-    if (messageInBuffer[2] != 'L')
-        return false;
-    if (messageInBuffer[3] != 'P')
-        return false;
-    if (messageInBuffer[4] != 'N')
-        return false;
-    if (messageInBuffer[5] != 'T')
-        return false;
-    if (messageInBuffer[6] != '$')
-        return false;
-    if (messageInBuffer[7] != ',')
-        return false;
+  // check header
+  if (messageInBuffer[0] != '$')
+    return false;
+  if (messageInBuffer[1] != 'R')
+    return false;
+  if (messageInBuffer[2] != 'L')
+    return false;
+  if (messageInBuffer[3] != 'P')
+    return false;
+  if (messageInBuffer[4] != 'N')
+    return false;
+  if (messageInBuffer[5] != 'T')
+    return false;
+  if (messageInBuffer[6] != '$')
+    return false;
+  if (messageInBuffer[7] != ',')
+    return false;
 
-// check CRC
-    uint16_t Polynomial = 4129;
-    uint16_t CRC=0;
-    for (int i=0;i<RLMessageLength-2;i++) { 
-        int tmp = messageInBuffer[i];
-        CRC ^= tmp<<8;
-        for (int bit=8;bit>0;bit--) {
-            if (CRC & 0x8000) {
-                    CRC <<= 1;
-                    CRC ^= Polynomial;
-            } else {
-                 CRC <<= 1;
-            }
-        }
-        CRC &= 0xffff;
+  // check CRC
+  uint16_t Polynomial = 4129;
+  uint16_t CRC = 0;
+  for (int i = 0; i < PNTSerialConstants::MessageLength - 2; i++) {
+    int tmp = messageInBuffer[i];
+    CRC ^= tmp << 8;
+    for (int bit = 8; bit > 0; bit--) {
+      if (CRC & 0x8000) {
+        CRC <<= 1;
+        CRC ^= Polynomial;
+      } else {
+        CRC <<= 1;
+      }
     }
-    uint16_t messageCRC = ((uint16_t)messageInBuffer[RLMessageLength-2])<<8 | messageInBuffer[RLMessageLength-1];
-    return messageCRC == CRC;
+    CRC &= 0xffff;
+  }
+  uint16_t messageCRC = ((uint16_t)messageInBuffer[PNTSerialConstants::MessageLength - 2]) << 8 |
+                        messageInBuffer[PNTSerialConstants::MessageLength - 1];
+  return messageCRC == CRC;
 }
 
 uint32_t PNTSerial::readUInt32(int &start, int bytes) {
-    uint32_t value = 0;
-    do {
-        value <<= 8;
-        value |= messageInBuffer[start++];
-       } while (--bytes);
-    return value;
+  uint32_t value = 0;
+  do {
+    value <<= 8;
+    value |= messageInBuffer[start++];
+  } while (--bytes);
+  return value;
 }
 
 int32_t PNTSerial::readInt32(int &start, int bytes) {
-    int32_t value = 0;
-    if (messageInBuffer[start] & 0x80) // negative value
-        value = -1; // set to all 1's
+  int32_t value = 0;
+  if (messageInBuffer[start] & 0x80) // negative value
+    value = -1;                      // set to all 1's
 
-    do {
-        value <<= 8;
-        value |= messageInBuffer[start++];
-       } while (--bytes);
-    return value;
+  do {
+    value <<= 8;
+    value |= messageInBuffer[start++];
+  } while (--bytes);
+  return value;
 }
 
 int64_t PNTSerial::readInt64(int &start, int bytes) {
-    int64_t value = 0;
-    if (messageInBuffer[start] & 0x80) // negative value
-        value = -1; // set to all 1's
+  int64_t value = 0;
+  if (messageInBuffer[start] & 0x80) // negative value
+    value = -1;                      // set to all 1's
+  do {
+    value <<= 8;
+    value |= messageInBuffer[start++];
+  } while (--bytes);
 
-    do {
-        value <<= 8;
-        value |= messageInBuffer[start++];
-       } while (--bytes);
-    
-    return value;
+  return value;
 }
 
-
 void PNTSerial::parsePostion() {
-    int messageIndex = 0;
-    lastPositions[nextPosition].time = TimeSinceLastFrame.read_us();
-    if (!CheckValidMessage())
-        return;
-    // 8 byte header ("$RLPNT$,")
-    messageIndex = 9;
-    // index 9 = 1 byte sat count
-    lastPositions[nextPosition].pos.beacons = messageInBuffer[messageIndex++];
+  int messageIndex = 0;
+  lastPositions[nextPosition].time = TimeSinceLastFrame.read_us();
+  if (!CheckValidMessage())
+    return;
+  // 8 byte header ("$RLPNT$,")
+  messageIndex = 8;
+  // index 8 = 1 byte sat count
+  lastPositions[nextPosition].pos.beacons = messageInBuffer[messageIndex++];
 
-    // 3 bytes time since midnight (10ms per tick)   
-    lastPositions[nextPosition].pos.time = readUInt32(messageIndex,3)*10;
+  // 3 bytes time since midnight (10ms per tick)
+  lastPositions[nextPosition].pos.time = readUInt32(messageIndex, 3) * 10;
 
-    // 5 byte lattitude in 0.000000001 degrees steps (9 decimal places)
-    int64_t latInt = readInt64(messageIndex,5);
-    // 5 byte longitude in 0.000000001 degrees steps (9 decimal places)
-    int64_t lonInt = readInt64(messageIndex,5);
+  // 5 byte lattitude in 0.000000001 degrees steps (9 decimal places)
+  int64_t latInt = readInt64(messageIndex, 5);
+  // 5 byte longitude in 0.000000001 degrees steps (9 decimal places)
+  int64_t lonInt = readInt64(messageIndex, 5);
 
-    // 3 byte velocity
-    messageIndex+=3;
-    // 2 byte heading
-    messageIndex+=2;
-    // 3 byte altitude
-    int32_t altInt = readInt32(messageIndex,3);
-    if (originSet) {
-        dataPoint.SetDecimalDegrees(latInt*0.000000001,lonInt *0.000000001,altInt*0.01);
-        double tmpDouble;
-        dataPoint.GetENU(&(lastPositions[nextPosition].pos.X),&(lastPositions[nextPosition].pos.Y),&tmpDouble);
-        lastPositions[nextPosition].pos.Height = (float)tmpDouble;
-        lastPositions[nextPosition].pos.LLAPosition = false;
-    } else {
-        lastPositions[nextPosition].pos.X = latInt*0.000000001;
-        lastPositions[nextPosition].pos.Y = lonInt *0.000000001;
-        lastPositions[nextPosition].pos.Height = altInt*0.01f;
-        lastPositions[nextPosition].pos.LLAPosition = true;
-    }
+  // 3 byte velocity
+  messageIndex += 3;
+  // 2 byte heading
+  messageIndex += 2;
+  // 3 byte altitude
+  int32_t altInt = readInt32(messageIndex, 3);
+  if (originSet) {
+    dataPoint.SetDecimalDegrees(latInt * 0.000000001, lonInt * 0.000000001,
+                                altInt * 0.01);
+    double tmpDouble;
+    dataPoint.GetENU(&(lastPositions[nextPosition].pos.X),
+                     &(lastPositions[nextPosition].pos.Y), &tmpDouble);
+    lastPositions[nextPosition].pos.Height = (float)tmpDouble;
+    lastPositions[nextPosition].pos.LLAPosition = false;
+  } else {
+    lastPositions[nextPosition].pos.X = latInt * 0.000000001;
+    lastPositions[nextPosition].pos.Y = lonInt * 0.000000001;
+    lastPositions[nextPosition].pos.Height = altInt * 0.01f;
+    lastPositions[nextPosition].pos.LLAPosition = true;
+  }
 
-    // 3 byte vert velocity
-    messageIndex+=3;
-    
-    // 1 byte solution type
-    lastPositions[nextPosition].pos.solutionType = messageInBuffer[messageIndex++];
+  // 3 byte vert velocity
+  messageIndex += 3;
+
+  // 1 byte solution type
+  lastPositions[nextPosition].pos.solutionType =
+      messageInBuffer[messageIndex++];
 
-// 2 byte pitch
-        lastPositions[nextPosition].pos.pitch = readInt32(messageIndex,2)*0.01;
-// 2 byte roll
-        lastPositions[nextPosition].pos.roll = readInt32(messageIndex,2)*0.01;
-// 2 byte yaw
-        lastPositions[nextPosition].pos.yaw = readInt32(messageIndex,2)*0.01;
+  // 2 byte pitch
+  lastPositions[nextPosition].pos.pitch = readInt32(messageIndex, 2) * 0.01;
+  // 2 byte roll
+  lastPositions[nextPosition].pos.roll = readInt32(messageIndex, 2) * 0.01;
+  // 2 byte yaw
+  lastPositions[nextPosition].pos.yaw = readInt32(messageIndex, 2) * 0.01;
 
-// 2 byte pitch, roll, yaw rates
-messageIndex+=6;
-
-// 2 byte X,Y,Z accelerations
-messageIndex+=6;
+  // 2 byte pitch, roll, yaw rates
+  messageIndex += 2*3;
 
-// 2 byte KF status
-        lastPositions[nextPosition].pos.KFStatus = (uint16_t)readUInt32(messageIndex,2);
+  // 2 byte X,Y,Z accelerations
+  messageIndex += 2*3;
+
+  // 2 byte KF status
+  lastPositions[nextPosition].pos.KFStatus = (uint16_t)readUInt32(messageIndex, 2);
 
-// 3 byte wheel speed
-messageIndex+=3;
-// 1 byte spoof/jam mask
-messageIndex++;
-// 1 byte spoof/jam indicator
-messageIndex++;
-// 2 byte date
-messageIndex+=2;
-
-
+  // 3 byte wheel speed
+  messageIndex += 3;
+  // 1 byte spoof/jam mask
+  messageIndex++;
+  // 1 byte spoof/jam indicator
+  messageIndex++;
+  // 2 byte date
+  messageIndex += 2;
 
-    if (UserSettings.AutoHyperSmooth) {
-        int testValue = (lastPositions[nextPosition].pos.KFStatus & 0xE634);
+  if (UserSettings.AutoHyperSmooth) {
+    int testValue = (lastPositions[nextPosition].pos.KFStatus & 0xE634);
 
-        if ( ( ( testValue & 0x400) == 0x400) && (!hyperSmoothEnabled)) {
-            EnableSmoothing(true);
-            //pc.write("Auto HS On\r\n", 12);
-        } else if ( ( ( testValue & 0x400) != 0x400) && (hyperSmoothEnabled) && (!forcedHyperSmooth)) {
-            EnableSmoothing(false);
-            //pc.write("Auto HS Off\r\n", 13);
-        } //Auto Hypersmooth
-    }
+    if (((testValue & 0x400) == 0x400) && (!hyperSmoothEnabled)) {
+      EnableSmoothing(true);
+      // pc.write("Auto HS On\r\n", 12);
+    } else if (((testValue & 0x400) != 0x400) && (hyperSmoothEnabled) &&
+               (!forcedHyperSmooth)) {
+      EnableSmoothing(false);
+      // pc.write("Auto HS Off\r\n", 13);
+    } // Auto Hypersmooth
+  }
 
-    smoothOutputPacket(&(lastPositions[nextPosition].pos));
+  smoothOutputPacket(&(lastPositions[nextPosition].pos));
+
+  if (enableAllUpdates) {
+    //        printf("Add pos\r\n");
+    outputPtr = &outputPosition;
+    memcpy(outputPtr, &(lastPositions[nextPosition].pos), sizeof(position));
+  }
 
-    if (enableAllUpdates) {
-//        printf("Add pos\r\n");
-        outputPtr = &outputPosition;
-        memcpy(outputPtr,&(lastPositions[nextPosition].pos),sizeof(position));
-    }
+  nextPosition++;
+  if (nextPosition == posHistoryLen) {
+    nextPosition = 0;
+  }
+  pointCount++;
+}
 
-    nextPosition++;
-    if (nextPosition == posHistoryLen) {
-        nextPosition = 0;
-    }
-    pointCount++;
-}
--- a/PNTSerial.h	Mon Nov 14 14:53:12 2022 +0000
+++ b/PNTSerial.h	Tue Nov 15 10:28:47 2022 +0000
@@ -10,6 +10,11 @@
 
 struct UserSettings_s;
 
+namespace PNTSerialConstants {
+// full message length
+const int MessageLength = 7+1+1+3+5+5+3+2+3+3+1+2*3+2*3+2*3+1+1+2+2;
+}
+
 class PNTSerial : public PosSource {
 
 public:
@@ -53,6 +58,5 @@
     GeoPosition origin;
     GeoPosition dataPoint;
 
-
 };