mirror of
https://github.com/meshtastic/firmware.git
synced 2025-02-26 22:33:24 +00:00
wip for #376
This commit is contained in:
parent
ff9b49ddaa
commit
b072eec4ac
Binary file not shown.
38977
docs/hardware/u-blox8-M8_ReceiverDescrProtSpec_(UBX-13003221).pdf
Normal file
38977
docs/hardware/u-blox8-M8_ReceiverDescrProtSpec_(UBX-13003221).pdf
Normal file
File diff suppressed because one or more lines are too long
@ -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
2
proto
@ -1 +1 @@
|
||||
Subproject commit c250aaa459d7d6727b01b8f4d9f31d315f738d61
|
||||
Subproject commit 0d4ad90e4aca509e942e1dacdb947076dc01e2ab
|
108
src/gps/GPS.cpp
108
src/gps/GPS.cpp
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user