This commit is contained in:
Kevin Hester 2020-10-05 14:43:44 +08:00
parent ff9b49ddaa
commit b072eec4ac
10 changed files with 39116 additions and 63 deletions

File diff suppressed because one or more lines are too long

View File

@ -1,8 +1,11 @@
gps todo - bug 376 gps todo - bug 376
for taiwan region:
bin/run.sh --set region 8
handle the various GPS modes handle the various GPS modes
handle wake and sleep times fix poll interval for sending commands to ublox
handle maxint parameters handle maxint parameters
@ -18,10 +21,15 @@ force gps sleep when in LightSleep and force wake only once <- confirm
fix has_gps based on new logic fix has_gps based on new logic
have loop methods return allowable sleep time (from their perspective)
increase main cpu sleep time
add set router mode in python tool - it will also set GPS to stationary add set router mode in python tool - it will also set GPS to stationary
(which will shrink DARK and NB period to zero and (which will shrink DARK and NB period to zero and
make light_sleep very long) make light_sleep very long)
warn people about crummy gps antennas - add to faq
gps states gps states
Active - for gps_attempt_time seconds Active - for gps_attempt_time seconds

2
proto

@ -1 +1 @@
Subproject commit c250aaa459d7d6727b01b8f4d9f31d315f738d61 Subproject commit 0d4ad90e4aca509e942e1dacdb947076dc01e2ab

View File

@ -1,5 +1,6 @@
#include "GPS.h" #include "GPS.h"
#include "NodeDB.h"
#include "configuration.h" #include "configuration.h"
#include "sleep.h" #include "sleep.h"
#include <assert.h> #include <assert.h>
@ -45,7 +46,7 @@ void readFromRTC()
} }
/// If we haven't yet set our RTC this boot, set it from a GPS derived time /// If we haven't yet set our RTC this boot, set it from a GPS derived time
void perhapsSetRTC(const struct timeval *tv) bool perhapsSetRTC(const struct timeval *tv)
{ {
if (!timeSetFromGPS) { if (!timeSetFromGPS) {
timeSetFromGPS = true; timeSetFromGPS = true;
@ -56,10 +57,13 @@ void perhapsSetRTC(const struct timeval *tv)
DEBUG_MSG("ERROR TIME SETTING NOT IMPLEMENTED!\n"); DEBUG_MSG("ERROR TIME SETTING NOT IMPLEMENTED!\n");
#endif #endif
readFromRTC(); readFromRTC();
return true;
} else {
return false;
} }
} }
void perhapsSetRTC(struct tm &t) bool perhapsSetRTC(struct tm &t)
{ {
/* Convert to unix time /* Convert to unix time
The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of seconds that have elapsed since January 1, 1970 The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of seconds that have elapsed since January 1, 1970
@ -71,10 +75,12 @@ void perhapsSetRTC(struct tm &t)
tv.tv_usec = 0; // time.centisecond() * (10 / 1000); tv.tv_usec = 0; // time.centisecond() * (10 / 1000);
// DEBUG_MSG("Got time from GPS month=%d, year=%d, unixtime=%ld\n", t.tm_mon, t.tm_year, tv.tv_sec); // DEBUG_MSG("Got time from GPS month=%d, year=%d, unixtime=%ld\n", t.tm_mon, t.tm_year, tv.tv_sec);
if (t.tm_year < 0 || t.tm_year >= 300) if (t.tm_year < 0 || t.tm_year >= 300) {
DEBUG_MSG("Ignoring invalid GPS month=%d, year=%d, unixtime=%ld\n", t.tm_mon, t.tm_year, tv.tv_sec); // DEBUG_MSG("Ignoring invalid GPS month=%d, year=%d, unixtime=%ld\n", t.tm_mon, t.tm_year, tv.tv_sec);
else return false;
perhapsSetRTC(&tv); } else {
return perhapsSetRTC(&tv);
}
} }
uint32_t getTime() uint32_t getTime()
@ -108,15 +114,58 @@ void GPS::setAwake(bool on)
if (isAwake != on) { if (isAwake != on) {
DEBUG_MSG("WANT GPS=%d\n", on); DEBUG_MSG("WANT GPS=%d\n", on);
if (on) if (on) {
lastWakeStartMsec = millis();
wake(); wake();
else } else {
lastSleepStartMsec = millis();
sleep(); sleep();
}
isAwake = on; isAwake = on;
} }
} }
/** Get how long we should stay looking for each aquisition in msecs
*/
uint32_t GPS::getWakeTime() const
{
uint32_t t = radioConfig.preferences.gps_attempt_time;
// fixme check modes
if (t == 0)
t = 30;
t *= 1000; // msecs
return t;
}
/** Get how long we should sleep between aqusition attempts in msecs
*/
uint32_t GPS::getSleepTime() const
{
uint32_t t = radioConfig.preferences.gps_update_interval;
// fixme check modes
if (t == 0)
t = 30;
t *= 1000;
return t;
}
void GPS::publishUpdate()
{
DEBUG_MSG("publishing GPS lock=%d\n", hasLock());
// Notify any status instances that are observing us
const meshtastic::GPSStatus status =
meshtastic::GPSStatus(hasLock(), isConnected, latitude, longitude, altitude, dop, heading, numSatellites);
newStatus.notifyObservers(&status);
}
void GPS::loop() void GPS::loop()
{ {
if (whileIdle()) { if (whileIdle()) {
@ -128,47 +177,44 @@ void GPS::loop()
uint32_t now = millis(); uint32_t now = millis();
bool mustPublishUpdate = false; bool mustPublishUpdate = false;
if ((now - lastUpdateMsec) > 30 * 1000 && !isAwake) { if ((now - lastSleepStartMsec) > getSleepTime() && !isAwake) {
// We now want to be awake - so wake up the GPS // We now want to be awake - so wake up the GPS
setAwake(true); setAwake(true);
mustPublishUpdate =
true; // Even if we don't have an update this time, we at least want to occasionally publish the current state
} }
// While we are awake // While we are awake
if (isAwake) { if (isAwake) {
DEBUG_MSG("looking for location\n"); // DEBUG_MSG("looking for location\n");
bool gotTime = lookForTime(); whileActive();
// If we've already set time from the GPS, no need to ask the GPS
bool gotTime = timeSetFromGPS || lookForTime();
bool gotLoc = lookForLocation(); bool gotLoc = lookForLocation();
// We've been awake too long - force sleep
bool tooLong = (now - lastWakeStartMsec) > getWakeTime();
// Once we get a location we no longer desperately want an update
if (gotLoc || tooLong) {
if (gotLoc) if (gotLoc)
hasValidLocation = true; hasValidLocation = true;
mustPublishUpdate |= gotLoc; if (tooLong) {
// we didn't get a location during this ack window, therefore declare loss of lock
hasValidLocation = false;
}
// Once we get a location we no longer desperately want an update
if (gotLoc) {
lastUpdateMsec = now;
setAwake(false); setAwake(false);
publishUpdate(); // publish our update for this just finished acquisition window
} }
} }
if (mustPublishUpdate) {
DEBUG_MSG("publishing GPS lock=%d\n", hasLock());
// Notify any status instances that are observing us
const meshtastic::GPSStatus status =
meshtastic::GPSStatus(hasLock(), isConnected, latitude, longitude, altitude, dop, heading, numSatellites);
newStatus.notifyObservers(&status);
}
} }
void GPS::forceWake(bool on) void GPS::forceWake(bool on)
{ {
if (on) { if (on) {
DEBUG_MSG("Looking for GPS lock\n"); DEBUG_MSG("Looking for GPS lock\n");
lastUpdateMsec = 0; // Force an update ASAP lastSleepStartMsec = 0; // Force an update ASAP
wakeAllowed = true; wakeAllowed = true;
} else { } else {
wakeAllowed = false; wakeAllowed = false;

View File

@ -6,8 +6,8 @@
#include "sys/time.h" #include "sys/time.h"
/// If we haven't yet set our RTC this boot, set it from a GPS derived time /// If we haven't yet set our RTC this boot, set it from a GPS derived time
void perhapsSetRTC(const struct timeval *tv); bool perhapsSetRTC(const struct timeval *tv);
void perhapsSetRTC(struct tm &t); bool perhapsSetRTC(struct tm &t);
// Generate a string representation of DOP // Generate a string representation of DOP
const char *getDOPString(uint32_t dop); const char *getDOPString(uint32_t dop);
@ -28,7 +28,7 @@ void readFromRTC();
class GPS class GPS
{ {
private: private:
uint32_t lastUpdateMsec = 0; uint32_t lastWakeStartMsec = 0, lastSleepStartMsec = 0;
bool hasValidLocation = false; // default to false, until we complete our first read bool hasValidLocation = false; // default to false, until we complete our first read
@ -91,6 +91,9 @@ class GPS
*/ */
virtual bool whileIdle() = 0; virtual bool whileIdle() = 0;
/** Idle processing while GPS is looking for lock */
virtual void whileActive() {}
/** /**
* Perform any processing that should be done only while the GPS is awake and looking for a fix. * Perform any processing that should be done only while the GPS is awake and looking for a fix.
* Override this method to check for new locations * Override this method to check for new locations
@ -118,6 +121,20 @@ class GPS
* calls sleep/wake * calls sleep/wake
*/ */
void setAwake(bool on); void setAwake(bool on);
/** Get how long we should stay looking for each aquisition
*/
uint32_t getWakeTime() const;
/** Get how long we should sleep between aqusition attempts
*/
uint32_t getSleepTime() const;
/**
* Tell users we have new GPS readings
*/
void publishUpdate();
}; };
extern GPS *gps; extern GPS *gps;

View File

@ -2,9 +2,7 @@
#include "error.h" #include "error.h"
#include <assert.h> #include <assert.h>
UBloxGPS::UBloxGPS() UBloxGPS::UBloxGPS() {}
{
}
bool UBloxGPS::tryConnect() bool UBloxGPS::tryConnect()
{ {
@ -41,7 +39,7 @@ bool UBloxGPS::setup()
delay(200); // Give time for the GPS to startup after we gave power delay(200); // Give time for the GPS to startup after we gave power
#endif #endif
// ublox.enableDebugging(Serial); ublox.enableDebugging(Serial);
// try a second time, the ublox lib serial parsing is buggy? // try a second time, the ublox lib serial parsing is buggy?
// see https://github.com/meshtastic/Meshtastic-device/issues/376 // see https://github.com/meshtastic/Meshtastic-device/issues/376
@ -120,6 +118,14 @@ bool UBloxGPS::factoryReset()
return ok; return ok;
} }
/** Idle processing while GPS is looking for lock */
void UBloxGPS::whileActive()
{
// If we don't have a fix (a quick check), don't try waiting for a solution)
fixType = ublox.getFixType(maxWait());
DEBUG_MSG("GPS fix type %d\n", fixType);
}
/** /**
* Perform any processing that should be done only while the GPS is awake and looking for a fix. * Perform any processing that should be done only while the GPS is awake and looking for a fix.
* Override this method to check for new locations * Override this method to check for new locations
@ -128,7 +134,7 @@ bool UBloxGPS::factoryReset()
*/ */
bool UBloxGPS::lookForTime() bool UBloxGPS::lookForTime()
{ {
if (ublox.getT(maxWait())) { if (fixType >= 2 && ublox.getT(maxWait())) {
/* Convert to unix time /* Convert to unix time
The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of seconds that have elapsed since January The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of seconds that have elapsed since January
1, 1970 (midnight UTC/GMT), not counting leap seconds (in ISO 8601: 1970-01-01T00:00:00Z). 1, 1970 (midnight UTC/GMT), not counting leap seconds (in ISO 8601: 1970-01-01T00:00:00Z).
@ -143,9 +149,7 @@ bool UBloxGPS::lookForTime()
t.tm_isdst = false; t.tm_isdst = false;
perhapsSetRTC(t); perhapsSetRTC(t);
return true; return true;
} } else {
else
{
return false; return false;
} }
} }
@ -160,12 +164,8 @@ bool UBloxGPS::lookForLocation()
{ {
bool foundLocation = false; bool foundLocation = false;
// If we don't have a fix (a quick check), don't try waiting for a solution)
uint8_t fixtype = ublox.getFixType(maxWait());
DEBUG_MSG("GPS fix type %d\n", fixtype);
// we only notify if position has changed due to a new fix // we only notify if position has changed due to a new fix
if ((fixtype >= 3 && fixtype <= 4) && ublox.getP(maxWait())) // rd fixes only if ((fixType >= 3 && fixType <= 4) && ublox.getP(maxWait())) // rd fixes only
{ {
latitude = ublox.getLatitude(0); latitude = ublox.getLatitude(0);
longitude = ublox.getLongitude(0); longitude = ublox.getLongitude(0);
@ -189,11 +189,14 @@ bool UBloxGPS::whileIdle()
return ublox.checkUblox(); // See if new data is available. Process bytes as they come in. return ublox.checkUblox(); // See if new data is available. Process bytes as they come in.
} }
/// If possible force the GPS into sleep/low power mode /// If possible force the GPS into sleep/low power mode
/// Note: ublox doesn't need a wake method, because as soon as we send chars to the GPS it will wake up /// Note: ublox doesn't need a wake method, because as soon as we send chars to the GPS it will wake up
void UBloxGPS::sleep() { void UBloxGPS::sleep()
if (isConnected) {
ublox.powerOff(); if (isConnected) {
} DEBUG_MSG("FIXME, enter low power mode\n");
// won't work on 6M
// ublox.powerOff();
}
}

View File

@ -12,6 +12,7 @@
class UBloxGPS : public GPS class UBloxGPS : public GPS
{ {
SFE_UBLOX_GPS ublox; SFE_UBLOX_GPS ublox;
uint8_t fixType = 0;
public: public:
UBloxGPS(); UBloxGPS();
@ -35,6 +36,9 @@ class UBloxGPS : public GPS
*/ */
virtual bool whileIdle(); virtual bool whileIdle();
/** Idle processing while GPS is looking for lock */
virtual void whileActive();
/** /**
* Perform any processing that should be done only while the GPS is awake and looking for a fix. * Perform any processing that should be done only while the GPS is awake and looking for a fix.
* Override this method to check for new locations * Override this method to check for new locations
@ -55,7 +59,6 @@ class UBloxGPS : public GPS
virtual void sleep(); virtual void sleep();
private: private:
/// Attempt to connect to our GPS, returns false if no gps is present /// Attempt to connect to our GPS, returns false if no gps is present
bool tryConnect(); bool tryConnect();

View File

@ -21,9 +21,9 @@
*/ */
#include "Air530GPS.h"
#include "MeshRadio.h" #include "MeshRadio.h"
#include "MeshService.h" #include "MeshService.h"
#include "Air530GPS.h"
#include "NodeDB.h" #include "NodeDB.h"
#include "PowerFSM.h" #include "PowerFSM.h"
#include "UBloxGPS.h" #include "UBloxGPS.h"
@ -429,7 +429,7 @@ void loop()
// FIXME - until button press handling is done by interrupt (see polling above) we can't sleep very long at all or buttons // FIXME - until button press handling is done by interrupt (see polling above) we can't sleep very long at all or buttons
// feel slow // feel slow
msecstosleep = 10; msecstosleep = 200; // FIXME, stop early if something happens
// TODO: This should go into a thread handled by FreeRTOS. // TODO: This should go into a thread handled by FreeRTOS.
handleWebResponse(); handleWebResponse();

View File

@ -39,7 +39,6 @@ typedef enum _RegionCode {
typedef enum _GpsOperation { typedef enum _GpsOperation {
GpsOperation_GpsOpUnset = 0, GpsOperation_GpsOpUnset = 0,
GpsOperation_GpsOpStationary = 1,
GpsOperation_GpsOpMobile = 2, GpsOperation_GpsOpMobile = 2,
GpsOperation_GpsOpTimeOnly = 3, GpsOperation_GpsOpTimeOnly = 3,
GpsOperation_GpsOpDisabled = 4 GpsOperation_GpsOpDisabled = 4
@ -137,7 +136,7 @@ typedef struct _RadioConfig_UserPreferences {
RegionCode region; RegionCode region;
LocationSharing location_share; LocationSharing location_share;
GpsOperation gps_operation; GpsOperation gps_operation;
uint32_t gps_update_rate; uint32_t gps_update_interval;
uint32_t gps_attempt_time; uint32_t gps_attempt_time;
bool factory_reset; bool factory_reset;
pb_size_t ignore_incoming_count; pb_size_t ignore_incoming_count;
@ -369,7 +368,7 @@ typedef struct _ToRadio {
#define RadioConfig_UserPreferences_region_tag 15 #define RadioConfig_UserPreferences_region_tag 15
#define RadioConfig_UserPreferences_location_share_tag 32 #define RadioConfig_UserPreferences_location_share_tag 32
#define RadioConfig_UserPreferences_gps_operation_tag 33 #define RadioConfig_UserPreferences_gps_operation_tag 33
#define RadioConfig_UserPreferences_gps_update_rate_tag 34 #define RadioConfig_UserPreferences_gps_update_interval_tag 34
#define RadioConfig_UserPreferences_gps_attempt_time_tag 36 #define RadioConfig_UserPreferences_gps_attempt_time_tag 36
#define RadioConfig_UserPreferences_factory_reset_tag 100 #define RadioConfig_UserPreferences_factory_reset_tag 100
#define RadioConfig_UserPreferences_ignore_incoming_tag 103 #define RadioConfig_UserPreferences_ignore_incoming_tag 103
@ -530,7 +529,7 @@ X(a, STATIC, SINGULAR, BOOL, wifi_ap_mode, 14) \
X(a, STATIC, SINGULAR, UENUM, region, 15) \ X(a, STATIC, SINGULAR, UENUM, region, 15) \
X(a, STATIC, SINGULAR, UENUM, location_share, 32) \ X(a, STATIC, SINGULAR, UENUM, location_share, 32) \
X(a, STATIC, SINGULAR, UENUM, gps_operation, 33) \ X(a, STATIC, SINGULAR, UENUM, gps_operation, 33) \
X(a, STATIC, SINGULAR, UINT32, gps_update_rate, 34) \ X(a, STATIC, SINGULAR, UINT32, gps_update_interval, 34) \
X(a, STATIC, SINGULAR, UINT32, gps_attempt_time, 36) \ X(a, STATIC, SINGULAR, UINT32, gps_attempt_time, 36) \
X(a, STATIC, SINGULAR, BOOL, factory_reset, 100) \ X(a, STATIC, SINGULAR, BOOL, factory_reset, 100) \
X(a, STATIC, REPEATED, UINT32, ignore_incoming, 103) X(a, STATIC, REPEATED, UINT32, ignore_incoming, 103)