pull/456/head
Kevin Hester 2020-10-05 14:43:44 +08:00
rodzic ff9b49ddaa
commit b072eec4ac
10 zmienionych plików z 39116 dodań i 63 usunięć

File diff suppressed because one or more lines are too long

Wyświetl plik

@ -1,8 +1,11 @@
gps todo - bug 376
for taiwan region:
bin/run.sh --set region 8
handle the various GPS modes
handle wake and sleep times
fix poll interval for sending commands to ublox
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
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
(which will shrink DARK and NB period to zero and
make light_sleep very long)
warn people about crummy gps antennas - add to faq
gps states
Active - for gps_attempt_time seconds

2
proto

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

Wyświetl plik

@ -1,5 +1,6 @@
#include "GPS.h"
#include "NodeDB.h"
#include "configuration.h"
#include "sleep.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
void perhapsSetRTC(const struct timeval *tv)
bool perhapsSetRTC(const struct timeval *tv)
{
if (!timeSetFromGPS) {
timeSetFromGPS = true;
@ -56,10 +57,13 @@ void perhapsSetRTC(const struct timeval *tv)
DEBUG_MSG("ERROR TIME SETTING NOT IMPLEMENTED!\n");
#endif
readFromRTC();
return true;
} else {
return false;
}
}
void perhapsSetRTC(struct tm &t)
bool perhapsSetRTC(struct tm &t)
{
/* 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
@ -71,10 +75,12 @@ void perhapsSetRTC(struct tm &t)
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);
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);
else
perhapsSetRTC(&tv);
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);
return false;
} else {
return perhapsSetRTC(&tv);
}
}
uint32_t getTime()
@ -101,22 +107,65 @@ bool GPS::setup()
*/
void GPS::setAwake(bool on)
{
if(!wakeAllowed && on) {
if (!wakeAllowed && on) {
DEBUG_MSG("Inhibiting because !wakeAllowed\n");
on = false;
}
if (isAwake != on) {
DEBUG_MSG("WANT GPS=%d\n", on);
if (on)
if (on) {
lastWakeStartMsec = millis();
wake();
else
} else {
lastSleepStartMsec = millis();
sleep();
}
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()
{
if (whileIdle()) {
@ -128,47 +177,44 @@ void GPS::loop()
uint32_t now = millis();
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
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
if (isAwake) {
DEBUG_MSG("looking for location\n");
bool gotTime = lookForTime();
// DEBUG_MSG("looking for location\n");
whileActive();
// If we've already set time from the GPS, no need to ask the GPS
bool gotTime = timeSetFromGPS || lookForTime();
bool gotLoc = lookForLocation();
if (gotLoc)
hasValidLocation = true;
mustPublishUpdate |= gotLoc;
// 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) {
lastUpdateMsec = now;
if (gotLoc || tooLong) {
if (gotLoc)
hasValidLocation = true;
if (tooLong) {
// we didn't get a location during this ack window, therefore declare loss of lock
hasValidLocation = 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)
{
if (on) {
DEBUG_MSG("Looking for GPS lock\n");
lastUpdateMsec = 0; // Force an update ASAP
lastSleepStartMsec = 0; // Force an update ASAP
wakeAllowed = true;
} else {
wakeAllowed = false;

Wyświetl plik

@ -6,8 +6,8 @@
#include "sys/time.h"
/// If we haven't yet set our RTC this boot, set it from a GPS derived time
void perhapsSetRTC(const struct timeval *tv);
void perhapsSetRTC(struct tm &t);
bool perhapsSetRTC(const struct timeval *tv);
bool perhapsSetRTC(struct tm &t);
// Generate a string representation of DOP
const char *getDOPString(uint32_t dop);
@ -28,7 +28,7 @@ void readFromRTC();
class GPS
{
private:
uint32_t lastUpdateMsec = 0;
uint32_t lastWakeStartMsec = 0, lastSleepStartMsec = 0;
bool hasValidLocation = false; // default to false, until we complete our first read
@ -91,6 +91,9 @@ class GPS
*/
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.
* Override this method to check for new locations
@ -118,6 +121,20 @@ class GPS
* calls sleep/wake
*/
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;

Wyświetl plik

@ -2,9 +2,7 @@
#include "error.h"
#include <assert.h>
UBloxGPS::UBloxGPS()
{
}
UBloxGPS::UBloxGPS() {}
bool UBloxGPS::tryConnect()
{
@ -41,7 +39,7 @@ bool UBloxGPS::setup()
delay(200); // Give time for the GPS to startup after we gave power
#endif
// ublox.enableDebugging(Serial);
ublox.enableDebugging(Serial);
// try a second time, the ublox lib serial parsing is buggy?
// see https://github.com/meshtastic/Meshtastic-device/issues/376
@ -120,6 +118,14 @@ bool UBloxGPS::factoryReset()
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.
* Override this method to check for new locations
@ -128,7 +134,7 @@ bool UBloxGPS::factoryReset()
*/
bool UBloxGPS::lookForTime()
{
if (ublox.getT(maxWait())) {
if (fixType >= 2 && ublox.getT(maxWait())) {
/* 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 (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;
perhapsSetRTC(t);
return true;
}
else
{
} else {
return false;
}
}
@ -160,12 +164,8 @@ bool UBloxGPS::lookForLocation()
{
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
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);
longitude = ublox.getLongitude(0);
@ -178,7 +178,7 @@ bool UBloxGPS::lookForLocation()
// Also: apparently when the GPS is initially reporting lock it can output a bogus latitude > 90 deg!
foundLocation =
(latitude != 0) && (longitude != 0) && (latitude <= 900000000 && latitude >= -900000000) && (numSatellites > 0);
}
}
return foundLocation;
}
@ -186,14 +186,17 @@ bool UBloxGPS::lookForLocation()
bool UBloxGPS::whileIdle()
{
// if using i2c or serial look too see if any chars are ready
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
/// 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() {
if (isConnected)
ublox.powerOff();
}
void UBloxGPS::sleep()
{
if (isConnected) {
DEBUG_MSG("FIXME, enter low power mode\n");
// won't work on 6M
// ublox.powerOff();
}
}

Wyświetl plik

@ -12,6 +12,7 @@
class UBloxGPS : public GPS
{
SFE_UBLOX_GPS ublox;
uint8_t fixType = 0;
public:
UBloxGPS();
@ -35,6 +36,9 @@ class UBloxGPS : public GPS
*/
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.
* Override this method to check for new locations
@ -55,7 +59,6 @@ class UBloxGPS : public GPS
virtual void sleep();
private:
/// Attempt to connect to our GPS, returns false if no gps is present
bool tryConnect();

Wyświetl plik

@ -21,9 +21,9 @@
*/
#include "Air530GPS.h"
#include "MeshRadio.h"
#include "MeshService.h"
#include "Air530GPS.h"
#include "NodeDB.h"
#include "PowerFSM.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
// feel slow
msecstosleep = 10;
msecstosleep = 200; // FIXME, stop early if something happens
// TODO: This should go into a thread handled by FreeRTOS.
handleWebResponse();

Wyświetl plik

@ -39,7 +39,6 @@ typedef enum _RegionCode {
typedef enum _GpsOperation {
GpsOperation_GpsOpUnset = 0,
GpsOperation_GpsOpStationary = 1,
GpsOperation_GpsOpMobile = 2,
GpsOperation_GpsOpTimeOnly = 3,
GpsOperation_GpsOpDisabled = 4
@ -137,7 +136,7 @@ typedef struct _RadioConfig_UserPreferences {
RegionCode region;
LocationSharing location_share;
GpsOperation gps_operation;
uint32_t gps_update_rate;
uint32_t gps_update_interval;
uint32_t gps_attempt_time;
bool factory_reset;
pb_size_t ignore_incoming_count;
@ -369,7 +368,7 @@ typedef struct _ToRadio {
#define RadioConfig_UserPreferences_region_tag 15
#define RadioConfig_UserPreferences_location_share_tag 32
#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_factory_reset_tag 100
#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, location_share, 32) \
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, BOOL, factory_reset, 100) \
X(a, STATIC, REPEATED, UINT32, ignore_incoming, 103)