Ver código fonte

nmea: count low-quality-fix rejections toward rejected_count

RMC status=V, GGA quality=0, and the sat-count/HDOP/fix-type gate all
set location_valid = LOC_INVALID without logging a reject, so a long
stretch of gated-out fixes (e.g. weak indoor reception) showed rej=0
in the summary, indistinguishable from a clean run. Add
REJECT_REASON_QUALITY and count all three, guarded per-epoch so RMC
and GGA rejecting the same epoch isn't double-counted.

Also drop syslog.h's duplicate REJECT_REASON_* defines in favor of
including common.h, the shared header they were meant to move into.
k4be 1 semana atrás
pai
commit
c3378005c5
4 arquivos alterados com 28 adições e 8 exclusões
  1. 1 0
      soft/common.h
  2. 24 3
      soft/nmea.c
  3. 2 0
      soft/syslog.c
  4. 1 5
      soft/syslog.h

+ 1 - 0
soft/common.h

@@ -46,6 +46,7 @@
 #define REJECT_REASON_DISTDIFF	1	/* distance jump inconsistent with recent history */
 #define REJECT_REASON_MINDIST	2	/* too small a position change since last saved point */
 #define REJECT_REASON_ALTDIFF	3	/* altitude jump inconsistent with recent history */
+#define REJECT_REASON_QUALITY	4	/* low satellite count, poor HDOP, or non-3D fix */
 
 /* System.conf.flags bit indices, read/set via get_flag(index)/set_flag(index,
  * val) - both sides index the same way (a bit position within a flags byte

+ 24 - 3
soft/nmea.c

@@ -73,6 +73,9 @@ static struct {
 	unsigned char gga_ok : 1;
 	unsigned char gsa_ok : 1;
 	unsigned char logged : 1;
+	unsigned char quality_rejected : 1; /* REJECT_REASON_QUALITY already
+		counted this epoch - RMC status=V and GGA quality=0 both fire on the
+		same no-fix epoch, and would otherwise double-count one rejection */
 } epoch;
 
 #define FIELD_BUF_LEN	32
@@ -168,6 +171,7 @@ static time_t gp_rmc_parse(const char *str) {
 	epoch.gga_ok = 0;
 	epoch.gsa_ok = 0;
 	epoch.logged = 0;
+	epoch.quality_rejected = 0;
 
 	p = gp_col(str, 1);		/* Get h:m:s */
 	if (!p)
@@ -191,6 +195,10 @@ static time_t gp_rmc_parse(const char *str) {
 	if (!p || *p != 'A') {
 		System.location_valid = LOC_INVALID;
 		FLAGS &= ~F_GPSOK;
+		if (!epoch.quality_rejected) {
+			epoch.quality_rejected = 1;
+			log_reject(REJECT_REASON_QUALITY);
+		}
 		return 0;			/* Return 0 even is time is valid (comes from module's internal RTC) */
 	}
 
@@ -250,6 +258,10 @@ static void gp_gga_parse(const char *str) {
 		return;
 	if (*p == '0') {
 		System.location_valid = LOC_INVALID;
+		if (!epoch.quality_rejected) {
+			epoch.quality_rejected = 1;
+			log_reject(REJECT_REASON_QUALITY);
+		}
 		return;
 	}
 
@@ -265,12 +277,21 @@ static void gp_gga_parse(const char *str) {
 	 * System.fix_type is set by GSA, parsed after GGA within the epoch, so
 	 * it's last epoch's value here - same staleness as HDOP above, but a
 	 * bad 2D fix reliably spans several consecutive epochs, so a one-epoch
-	 * lag isn't a practical gap here (unlike a true point fix). */
+	 * lag isn't a practical gap here (unlike a true point fix).
+	 * log_reject() logs System.hdop_x100 (GSA's, same one-epoch-stale value
+	 * checked above), not this epoch's GGA hdop_x100 just computed here -
+	 * close enough for the coalesced diagnostic line, and keeps every
+	 * REJECT_REASON logging the same field, sourced the same way. */
 	if (!System.sat_count_low && hdop_x100 <= FIX_QUALITY_HDOP_MAX_X100
-			&& System.fix_type == FIX_TYPE_3D)
+			&& System.fix_type == FIX_TYPE_3D) {
 		System.location_valid = LOC_VALID_NEW;
-	else
+	} else {
 		System.location_valid = LOC_INVALID;
+		if (!epoch.quality_rejected) {
+			epoch.quality_rejected = 1;
+			log_reject(REJECT_REASON_QUALITY);
+		}
+	}
 
 	/* parse location */
 	p = gp_col(str, 2);		/* latitude */

+ 2 - 0
soft/syslog.c

@@ -12,12 +12,14 @@ __flash const char reject_reason_kalman[] = "kalman";
 __flash const char reject_reason_distdiff[] = "distdiff";
 __flash const char reject_reason_mindist[] = "mindist";
 __flash const char reject_reason_altdiff[] = "altdiff";
+__flash const char reject_reason_quality[] = "quality";
 
 __flash const char *reject_reason_names[] = {
 	[REJECT_REASON_KALMAN] = reject_reason_kalman,
 	[REJECT_REASON_DISTDIFF] = reject_reason_distdiff,
 	[REJECT_REASON_MINDIST] = reject_reason_mindist,
 	[REJECT_REASON_ALTDIFF] = reject_reason_altdiff,
+	[REJECT_REASON_QUALITY] = reject_reason_quality,
 };
 
 __flash const char status_no_power[] = "no power";

+ 1 - 5
soft/syslog.h

@@ -1,10 +1,6 @@
 #pragma once
 
-/* Reasons a candidate point can be rejected before being written */
-#define REJECT_REASON_KALMAN	0	/* Kalman-filtered position error too large */
-#define REJECT_REASON_DISTDIFF	1	/* distance jump inconsistent with recent history */
-#define REJECT_REASON_MINDIST	2	/* too small a position change since last saved point */
-#define REJECT_REASON_ALTDIFF	3	/* altitude jump inconsistent with recent history */
+#include "common.h"
 
 extern __flash const char *reject_reason_names[];