kopia lustrzana https://github.com/meshtastic/firmware
Fix buggy phone positions (#2876)
* Guard-clause channel util. to reduce nesting * Try-fix PhoneAPI position not updating * Trunk * Missed it * Really disable GPS when asked to --------- Co-authored-by: Jonathan Bennett <jbennett@incomsystems.biz>pull/2872/head^2 v2.2.11.10265aa
rodzic
8780d93941
commit
10265aabd5
|
@ -611,7 +611,7 @@ int32_t GPS::runOnce()
|
||||||
return 2000; // Setup failed, re-run in two seconds
|
return 2000; // Setup failed, re-run in two seconds
|
||||||
|
|
||||||
// We have now loaded our saved preferences from flash
|
// We have now loaded our saved preferences from flash
|
||||||
if (config.position.gps_enabled == false && config.position.fixed_position == false) {
|
if (config.position.gps_enabled == false) {
|
||||||
return disable();
|
return disable();
|
||||||
}
|
}
|
||||||
// ONCE we will factory reset the GPS for bug #327
|
// ONCE we will factory reset the GPS for bug #327
|
||||||
|
@ -703,8 +703,8 @@ int32_t GPS::runOnce()
|
||||||
// If state has changed do a publish
|
// If state has changed do a publish
|
||||||
publishUpdate();
|
publishUpdate();
|
||||||
|
|
||||||
if (config.position.gps_enabled == false) // This should trigger if GPS is disabled but fixed_position is true
|
if (config.position.fixed_position == true && hasValidLocation)
|
||||||
return disable();
|
return disable(); // This should trigger when we have a fixed position, and get that first position
|
||||||
|
|
||||||
// 9600bps is approx 1 byte per msec, so considering our buffer size we never need to wake more often than 200ms
|
// 9600bps is approx 1 byte per msec, so considering our buffer size we never need to wake more often than 200ms
|
||||||
// if not awake we can run super infrquently (once every 5 secs?) to see if we need to wake.
|
// if not awake we can run super infrquently (once every 5 secs?) to see if we need to wake.
|
||||||
|
|
|
@ -687,8 +687,8 @@ void NodeDB::updatePosition(uint32_t nodeId, const meshtastic_Position &p, RxSou
|
||||||
LOG_INFO("updatePosition LOCAL pos@%x, time=%u, latI=%d, lonI=%d, alt=%d\n", p.timestamp, p.time, p.latitude_i,
|
LOG_INFO("updatePosition LOCAL pos@%x, time=%u, latI=%d, lonI=%d, alt=%d\n", p.timestamp, p.time, p.latitude_i,
|
||||||
p.longitude_i, p.altitude);
|
p.longitude_i, p.altitude);
|
||||||
|
|
||||||
|
setLocalPosition(p);
|
||||||
info->position = ConvertToPositionLite(p);
|
info->position = ConvertToPositionLite(p);
|
||||||
localPosition = p;
|
|
||||||
} else if ((p.time > 0) && !p.latitude_i && !p.longitude_i && !p.timestamp && !p.location_source) {
|
} else if ((p.time > 0) && !p.latitude_i && !p.longitude_i && !p.timestamp && !p.location_source) {
|
||||||
// FIXME SPECIAL TIME SETTING PACKET FROM EUD TO RADIO
|
// FIXME SPECIAL TIME SETTING PACKET FROM EUD TO RADIO
|
||||||
// (stop-gap fix for issue #900)
|
// (stop-gap fix for issue #900)
|
||||||
|
|
|
@ -131,6 +131,13 @@ class NodeDB
|
||||||
meshtastic_NodeInfoLite *getMeshNode(NodeNum n);
|
meshtastic_NodeInfoLite *getMeshNode(NodeNum n);
|
||||||
size_t getNumMeshNodes() { return *numMeshNodes; }
|
size_t getNumMeshNodes() { return *numMeshNodes; }
|
||||||
|
|
||||||
|
void setLocalPosition(meshtastic_Position position)
|
||||||
|
{
|
||||||
|
LOG_DEBUG("Setting local position: latitude=%i, longitude=%i, time=%i\n", position.latitude_i, position.longitude_i,
|
||||||
|
position.time);
|
||||||
|
localPosition = position;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Find a node in our DB, create an empty NodeInfoLite if missing
|
/// Find a node in our DB, create an empty NodeInfoLite if missing
|
||||||
meshtastic_NodeInfoLite *getOrCreateMeshNode(NodeNum n);
|
meshtastic_NodeInfoLite *getOrCreateMeshNode(NodeNum n);
|
||||||
|
|
|
@ -44,10 +44,11 @@ bool PositionModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, mes
|
||||||
|
|
||||||
// FIXME this can in fact happen with packets sent from EUD (src=RX_SRC_USER)
|
// FIXME this can in fact happen with packets sent from EUD (src=RX_SRC_USER)
|
||||||
// to set fixed location, EUD-GPS location or just the time (see also issue #900)
|
// to set fixed location, EUD-GPS location or just the time (see also issue #900)
|
||||||
|
bool isLocal = false;
|
||||||
if (nodeDB.getNodeNum() == getFrom(&mp)) {
|
if (nodeDB.getNodeNum() == getFrom(&mp)) {
|
||||||
LOG_DEBUG("Incoming update from MYSELF\n");
|
LOG_DEBUG("Incoming update from MYSELF\n");
|
||||||
// LOG_DEBUG("Ignored an incoming update from MYSELF\n");
|
isLocal = true;
|
||||||
// return false;
|
nodeDB.setLocalPosition(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log packet size and data fields
|
// Log packet size and data fields
|
||||||
|
@ -64,7 +65,8 @@ bool PositionModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, mes
|
||||||
tv.tv_sec = secs;
|
tv.tv_sec = secs;
|
||||||
tv.tv_usec = 0;
|
tv.tv_usec = 0;
|
||||||
|
|
||||||
perhapsSetRTC(RTCQualityFromNet, &tv);
|
// Set from phone RTC Quality to RTCQualityNTP since it should be approximately so
|
||||||
|
perhapsSetRTC(isLocal ? RTCQualityNTP : RTCQualityFromNet, &tv);
|
||||||
}
|
}
|
||||||
|
|
||||||
nodeDB.updatePosition(getFrom(&mp), p);
|
nodeDB.updatePosition(getFrom(&mp), p);
|
||||||
|
@ -94,8 +96,9 @@ meshtastic_MeshPacket *PositionModule::allocReply()
|
||||||
|
|
||||||
// Populate a Position struct with ONLY the requested fields
|
// Populate a Position struct with ONLY the requested fields
|
||||||
meshtastic_Position p = meshtastic_Position_init_default; // Start with an empty structure
|
meshtastic_Position p = meshtastic_Position_init_default; // Start with an empty structure
|
||||||
|
// if localPosition is totally empty, put our last saved position (lite) in there
|
||||||
if (localPosition.latitude_i == 0 && localPosition.longitude_i == 0) {
|
if (localPosition.latitude_i == 0 && localPosition.longitude_i == 0) {
|
||||||
localPosition = ConvertToPosition(node->position);
|
nodeDB.setLocalPosition(ConvertToPosition(node->position));
|
||||||
}
|
}
|
||||||
localPosition.seq_number++;
|
localPosition.seq_number++;
|
||||||
|
|
||||||
|
@ -184,6 +187,8 @@ void PositionModule::sendOurPosition(NodeNum dest, bool wantReplies, uint8_t cha
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define RUNONCE_INTERVAL 5000;
|
||||||
|
|
||||||
int32_t PositionModule::runOnce()
|
int32_t PositionModule::runOnce()
|
||||||
{
|
{
|
||||||
if (sleepOnNextExecution == true) {
|
if (sleepOnNextExecution == true) {
|
||||||
|
@ -199,60 +204,58 @@ int32_t PositionModule::runOnce()
|
||||||
uint32_t now = millis();
|
uint32_t now = millis();
|
||||||
uint32_t intervalMs = getConfiguredOrDefaultMs(config.position.position_broadcast_secs, default_broadcast_interval_secs);
|
uint32_t intervalMs = getConfiguredOrDefaultMs(config.position.position_broadcast_secs, default_broadcast_interval_secs);
|
||||||
uint32_t msSinceLastSend = now - lastGpsSend;
|
uint32_t msSinceLastSend = now - lastGpsSend;
|
||||||
|
// Only send packets if the channel util. is less than 25% utilized or we're a tracker with less than 40% utilized.
|
||||||
|
if (!airTime->isTxAllowedChannelUtil(config.device.role != meshtastic_Config_DeviceConfig_Role_TRACKER)) {
|
||||||
|
return RUNONCE_INTERVAL;
|
||||||
|
}
|
||||||
|
|
||||||
if (lastGpsSend == 0 || msSinceLastSend >= intervalMs) {
|
if (lastGpsSend == 0 || msSinceLastSend >= intervalMs) {
|
||||||
// Only send packets if the channel is less than 40% utilized.
|
if (hasValidPosition(node)) {
|
||||||
if (airTime->isTxAllowedChannelUtil(config.device.role != meshtastic_Config_DeviceConfig_Role_TRACKER)) {
|
lastGpsSend = now;
|
||||||
if (hasValidPosition(node)) {
|
|
||||||
lastGpsSend = now;
|
|
||||||
|
|
||||||
lastGpsLatitude = node->position.latitude_i;
|
lastGpsLatitude = node->position.latitude_i;
|
||||||
lastGpsLongitude = node->position.longitude_i;
|
lastGpsLongitude = node->position.longitude_i;
|
||||||
|
|
||||||
// If we changed channels, ask everyone else for their latest info
|
// If we changed channels, ask everyone else for their latest info
|
||||||
|
bool requestReplies = currentGeneration != radioGeneration;
|
||||||
|
currentGeneration = radioGeneration;
|
||||||
|
|
||||||
|
LOG_INFO("Sending pos@%x:6 to mesh (wantReplies=%d)\n", localPosition.timestamp, requestReplies);
|
||||||
|
sendOurPosition(NODENUM_BROADCAST, requestReplies);
|
||||||
|
}
|
||||||
|
} else if (config.position.position_broadcast_smart_enabled) {
|
||||||
|
const meshtastic_NodeInfoLite *node2 = service.refreshLocalMeshNode(); // should guarantee there is now a position
|
||||||
|
|
||||||
|
if (hasValidPosition(node2)) {
|
||||||
|
// The minimum time (in seconds) that would pass before we are able to send a new position packet.
|
||||||
|
const uint32_t minimumTimeThreshold =
|
||||||
|
getConfiguredOrDefaultMs(config.position.broadcast_smart_minimum_interval_secs, 30);
|
||||||
|
|
||||||
|
auto smartPosition = getDistanceTraveledSinceLastSend(node->position);
|
||||||
|
|
||||||
|
if (smartPosition.hasTraveledOverThreshold && msSinceLastSend >= minimumTimeThreshold) {
|
||||||
bool requestReplies = currentGeneration != radioGeneration;
|
bool requestReplies = currentGeneration != radioGeneration;
|
||||||
currentGeneration = radioGeneration;
|
currentGeneration = radioGeneration;
|
||||||
|
|
||||||
LOG_INFO("Sending pos@%x:6 to mesh (wantReplies=%d)\n", localPosition.timestamp, requestReplies);
|
LOG_INFO("Sending smart pos@%x:6 to mesh (distanceTraveled=%fm, minDistanceThreshold=%im, timeElapsed=%ims, "
|
||||||
|
"minTimeInterval=%ims)\n",
|
||||||
|
localPosition.timestamp, smartPosition.distanceTraveled, smartPosition.distanceThreshold,
|
||||||
|
msSinceLastSend, minimumTimeThreshold);
|
||||||
sendOurPosition(NODENUM_BROADCAST, requestReplies);
|
sendOurPosition(NODENUM_BROADCAST, requestReplies);
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (config.position.position_broadcast_smart_enabled) {
|
|
||||||
// Only send packets if the channel is less than 25% utilized or we're a tracker.
|
|
||||||
if (airTime->isTxAllowedChannelUtil(config.device.role != meshtastic_Config_DeviceConfig_Role_TRACKER)) {
|
|
||||||
const meshtastic_NodeInfoLite *node2 = service.refreshLocalMeshNode(); // should guarantee there is now a position
|
|
||||||
|
|
||||||
if (hasValidPosition(node2)) {
|
// Set the current coords as our last ones, after we've compared distance with current and decided to send
|
||||||
// The minimum time (in seconds) that would pass before we are able to send a new position packet.
|
lastGpsLatitude = node->position.latitude_i;
|
||||||
const uint32_t minimumTimeThreshold =
|
lastGpsLongitude = node->position.longitude_i;
|
||||||
getConfiguredOrDefaultMs(config.position.broadcast_smart_minimum_interval_secs, 30);
|
|
||||||
|
|
||||||
auto smartPosition = getDistanceTraveledSinceLastSend(node->position);
|
/* Update lastGpsSend to now. This means if the device is stationary, then
|
||||||
|
getPref_position_broadcast_secs will still apply.
|
||||||
if (smartPosition.hasTraveledOverThreshold && msSinceLastSend >= minimumTimeThreshold) {
|
*/
|
||||||
bool requestReplies = currentGeneration != radioGeneration;
|
lastGpsSend = now;
|
||||||
currentGeneration = radioGeneration;
|
|
||||||
|
|
||||||
LOG_INFO("Sending smart pos@%x:6 to mesh (distanceTraveled=%fm, minDistanceThreshold=%im, timeElapsed=%ims, "
|
|
||||||
"minTimeInterval=%ims)\n",
|
|
||||||
localPosition.timestamp, smartPosition.distanceTraveled, smartPosition.distanceThreshold,
|
|
||||||
msSinceLastSend, minimumTimeThreshold);
|
|
||||||
sendOurPosition(NODENUM_BROADCAST, requestReplies);
|
|
||||||
|
|
||||||
// Set the current coords as our last ones, after we've compared distance with current and decided to send
|
|
||||||
lastGpsLatitude = node->position.latitude_i;
|
|
||||||
lastGpsLongitude = node->position.longitude_i;
|
|
||||||
|
|
||||||
/* Update lastGpsSend to now. This means if the device is stationary, then
|
|
||||||
getPref_position_broadcast_secs will still apply.
|
|
||||||
*/
|
|
||||||
lastGpsSend = now;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 5000; // to save power only wake for our callback occasionally
|
return RUNONCE_INTERVAL; // to save power only wake for our callback occasionally
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SmartPosition PositionModule::getDistanceTraveledSinceLastSend(meshtastic_PositionLite currentPosition)
|
struct SmartPosition PositionModule::getDistanceTraveledSinceLastSend(meshtastic_PositionLite currentPosition)
|
||||||
|
@ -264,6 +267,23 @@ struct SmartPosition PositionModule::getDistanceTraveledSinceLastSend(meshtastic
|
||||||
float distanceTraveledSinceLastSend = GeoCoord::latLongToMeter(
|
float distanceTraveledSinceLastSend = GeoCoord::latLongToMeter(
|
||||||
lastGpsLatitude * 1e-7, lastGpsLongitude * 1e-7, currentPosition.latitude_i * 1e-7, currentPosition.longitude_i * 1e-7);
|
lastGpsLatitude * 1e-7, lastGpsLongitude * 1e-7, currentPosition.latitude_i * 1e-7, currentPosition.longitude_i * 1e-7);
|
||||||
|
|
||||||
|
#ifdef GPS_EXTRAVERBOSE
|
||||||
|
LOG_DEBUG("--------LAST POSITION------------------------------------\n");
|
||||||
|
LOG_DEBUG("lastGpsLatitude=%i, lastGpsLatitude=%i\n", lastGpsLatitude, lastGpsLongitude);
|
||||||
|
|
||||||
|
LOG_DEBUG("--------CURRENT POSITION---------------------------------\n");
|
||||||
|
LOG_DEBUG("currentPosition.latitude_i=%i, currentPosition.longitude_i=%i\n", lastGpsLatitude, lastGpsLongitude);
|
||||||
|
|
||||||
|
LOG_DEBUG("--------SMART POSITION-----------------------------------\n");
|
||||||
|
LOG_DEBUG("hasTraveledOverThreshold=%i, distanceTraveled=%d, distanceThreshold=% u\n",
|
||||||
|
abs(distanceTraveledSinceLastSend) >= distanceTravelThreshold, abs(distanceTraveledSinceLastSend),
|
||||||
|
distanceTravelThreshold);
|
||||||
|
|
||||||
|
if (abs(distanceTraveledSinceLastSend) >= distanceTravelThreshold) {
|
||||||
|
LOG_DEBUG("\n\n\nSMART SEEEEEEEEENDING\n\n\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return SmartPosition{.distanceTraveled = abs(distanceTraveledSinceLastSend),
|
return SmartPosition{.distanceTraveled = abs(distanceTraveledSinceLastSend),
|
||||||
.distanceThreshold = distanceTravelThreshold,
|
.distanceThreshold = distanceTravelThreshold,
|
||||||
.hasTraveledOverThreshold = abs(distanceTraveledSinceLastSend) >= distanceTravelThreshold};
|
.hasTraveledOverThreshold = abs(distanceTraveledSinceLastSend) >= distanceTravelThreshold};
|
||||||
|
|
Ładowanie…
Reference in New Issue