pud: force a state change to moving when 'no info received' changes
authorFerry Huberts <ferry.huberts@pelagic.nl>
Thu, 28 Jul 2016 17:55:16 +0000 (19:55 +0200)
committerFerry Huberts <ferry.huberts@pelagic.nl>
Fri, 29 Jul 2016 11:40:01 +0000 (13:40 +0200)
Signed-off-by: Ferry Huberts <ferry.huberts@pelagic.nl>
lib/pud/src/receiver.c
lib/pud/src/state.c
lib/pud/src/state.h

index 25d372c..0dc22c0 100644 (file)
@@ -535,7 +535,7 @@ static void pud_gateway_timer_callback(void *context __attribute__ ((unused))) {
         * State Determination
         */
 
-       determineStateWithHysteresis(SUBSTATE_GATEWAY, movingNow, &externalState, &externalStateChange, NULL);
+       determineStateWithHysteresis(SUBSTATE_GATEWAY, movingNow, &externalState, &externalStateChange, NULL, false);
 
        /*
         * Update transmitGpsInformation
@@ -847,6 +847,8 @@ static void detemineMovingFromPosition(PositionUpdateEntry * avg, PositionUpdate
  - true otherwise
  */
 bool receiverUpdateGpsInformation(unsigned char * rxBuffer, size_t rxCount) {
+       static bool gpnonPrev = false;
+
        static const char * rxBufferPrefix = "$GP";
        static const size_t rxBufferPrefixLength = 3;
 
@@ -858,6 +860,8 @@ bool receiverUpdateGpsInformation(unsigned char * rxBuffer, size_t rxCount) {
        bool externalStateChange;
        bool updateTransmitGpsInformation = false;
        MovementState externalState;
+       bool gpnon;
+       bool gpnonChanged;
 
        /* do not process when the message does not start with $GP */
        if ((rxCount < rxBufferPrefixLength) || (strncmp((char *) rxBuffer,
@@ -871,11 +875,9 @@ bool receiverUpdateGpsInformation(unsigned char * rxBuffer, size_t rxCount) {
        nmeaTimeSet(&incomingEntry->nmeaInfo.utc, &incomingEntry->nmeaInfo.present, NULL);
        nmeaParserParse(&nmeaParser, (char *) rxBuffer, rxCount, &incomingEntry->nmeaInfo);
 
-       /* ignore when no useful information */
-       if (incomingEntry->nmeaInfo.smask == NMEALIB_SENTENCE_GPNON) {
-               retval = true;
-               goto end;
-       }
+       gpnon = !nmeaInfoIsPresentAll(incomingEntry->nmeaInfo.present, NMEALIB_PRESENT_SMASK) || (incomingEntry->nmeaInfo.smask == NMEALIB_SENTENCE_GPNON);
+       gpnonChanged = gpnon != gpnonPrev;
+       gpnonPrev = gpnon;
 
        nmeaInfoSanitise(&incomingEntry->nmeaInfo);
 
@@ -886,7 +888,7 @@ bool receiverUpdateGpsInformation(unsigned char * rxBuffer, size_t rxCount) {
         * Averaging
         */
 
-       if (getInternalState(SUBSTATE_POSITION) == MOVEMENT_STATE_MOVING) {
+       if ((getInternalState(SUBSTATE_POSITION) == MOVEMENT_STATE_MOVING) || gpnonChanged) {
                /* flush average: keep only the incoming entry */
                flushPositionAverageList(&positionAverageList);
        }
@@ -906,7 +908,7 @@ bool receiverUpdateGpsInformation(unsigned char * rxBuffer, size_t rxCount) {
         */
 
        determineStateWithHysteresis(SUBSTATE_POSITION, movementResult.moving, &externalState, &externalStateChange,
-                       &subStateExternalStateChange);
+                       &subStateExternalStateChange, gpnonChanged);
 
        /*
         * Update transmitGpsInformation
@@ -938,7 +940,6 @@ bool receiverUpdateGpsInformation(unsigned char * rxBuffer, size_t rxCount) {
 
        retval = true;
 
-       end:
        return retval;
 }
 
index 5d91b5f..8356dc6 100644 (file)
@@ -112,9 +112,11 @@ MovementState getExternalState(void) {
  * a pointer to the variable in which to store whether the external state changed
  * @param subStateExternalStateChange
  * a pointer to the variable in which to store whether the sub-state external state changed
+ * @param gpnonChanged
+ * true when there was a state change w.r.t. 'no info received'
  */
 void determineStateWithHysteresis(SubStateIndex subStateIndex, TristateBoolean movingNow, MovementState * externalState,
-               bool * externalStateChange, bool * subStateExternalStateChange) {
+               bool * externalStateChange, bool * subStateExternalStateChange, bool gpnonChanged) {
        MovementState newState;
        bool internalStateChange;
        bool subStateExternalStateChanged;
@@ -124,7 +126,7 @@ void determineStateWithHysteresis(SubStateIndex subStateIndex, TristateBoolean m
         * Substate Internal State
         */
 
-       if (movingNow == TRISTATE_BOOLEAN_SET) {
+       if ((movingNow == TRISTATE_BOOLEAN_SET) || gpnonChanged) {
                newState = MOVEMENT_STATE_MOVING;
        } else if (movingNow == TRISTATE_BOOLEAN_UNSET) {
                newState = MOVEMENT_STATE_STATIONARY;
@@ -167,7 +169,11 @@ void determineStateWithHysteresis(SubStateIndex subStateIndex, TristateBoolean m
                        /* internal state is MOVING, external state is STATIONARY */
 
                        /* delay going to moving a bit */
-                       subState->hysteresisCounter++;
+                       if (gpnonChanged) {
+                         subState->hysteresisCounter = subState->hysteresisCounterToMoving;
+                       } else {
+                         subState->hysteresisCounter++;
+                       }
 
                        if (subState->hysteresisCounter >= subState->hysteresisCounterToMoving) {
                                /* outside the hysteresis range, go to moving */
index d9e623f..19216e0 100644 (file)
@@ -92,6 +92,6 @@ void initState(void);
 MovementState getExternalState(void);
 MovementState getInternalState(SubStateIndex subStateIndex);
 void determineStateWithHysteresis(SubStateIndex subStateIndex, TristateBoolean movingNow, MovementState * externalState,
-               bool * externalStateChange, bool * subStateExternalStateChange);
+               bool * externalStateChange, bool * subStateExternalStateChange, bool gpnonChanged);
 
 #endif /* _PUD_STATE_H_ */