diff --git a/protobufs b/protobufs index a73083db5..2b55d8421 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit a73083db549d7f0a4e47b0ebd5e6d363f130fcf9 +Subproject commit 2b55d8421b2f872f8c50e001bd107a2bc56a5157 diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 5aa0ca458..3a7055aed 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -165,6 +165,8 @@ void NodeDB::installDefaultConfig() config.lora.hop_limit = HOP_RELIABLE; config.position.gps_enabled = true; config.position.position_broadcast_smart_enabled = true; + config.position.broadcast_smart_minimum_distance = 100; + config.position.broadcast_smart_minimum_interval_secs = 30; if (config.device.role != meshtastic_Config_DeviceConfig_Role_ROUTER) config.device.node_info_broadcast_secs = 3 * 60 * 60; config.device.serial_enabled = true; @@ -231,9 +233,7 @@ void NodeDB::installRoleDefaults(meshtastic_Config_DeviceConfig_Role role) } else if (role == meshtastic_Config_DeviceConfig_Role_REPEATER) { config.display.screen_on_secs = 1; } else if (role == meshtastic_Config_DeviceConfig_Role_TRACKER) { - config.position.position_broadcast_smart_enabled = false; - config.position.position_broadcast_secs = 120; - config.position.gps_update_interval = 60; + config.position.gps_update_interval = 30; } else if (role == meshtastic_Config_DeviceConfig_Role_SENSOR) { moduleConfig.telemetry.environment_measurement_enabled = true; moduleConfig.telemetry.environment_update_interval = 300; diff --git a/src/mesh/generated/meshtastic/config.pb.h b/src/mesh/generated/meshtastic/config.pb.h index fd949cde9..34f013250 100644 --- a/src/mesh/generated/meshtastic/config.pb.h +++ b/src/mesh/generated/meshtastic/config.pb.h @@ -262,6 +262,10 @@ typedef struct _meshtastic_Config_PositionConfig { uint32_t rx_gpio; /* (Re)define GPS_TX_PIN for your board. */ uint32_t tx_gpio; + /* The minimum distance in meters traveled (since the last send) before we can send a position to the mesh if position_broadcast_smart_enabled */ + uint32_t broadcast_smart_minimum_distance; + /* The minumum number of seconds (since the last send) before we can send a position to the mesh if position_broadcast_smart_enabled */ + uint32_t broadcast_smart_minimum_interval_secs; } meshtastic_Config_PositionConfig; /* Power Config\ @@ -524,7 +528,7 @@ extern "C" { /* Initializer values for message structs */ #define meshtastic_Config_init_default {0, {meshtastic_Config_DeviceConfig_init_default}} #define meshtastic_Config_DeviceConfig_init_default {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0} -#define meshtastic_Config_PositionConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0} +#define meshtastic_Config_PositionConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} #define meshtastic_Config_PowerConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0} #define meshtastic_Config_NetworkConfig_init_default {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_default, ""} #define meshtastic_Config_NetworkConfig_IpV4Config_init_default {0, 0, 0, 0} @@ -533,7 +537,7 @@ extern "C" { #define meshtastic_Config_BluetoothConfig_init_default {0, _meshtastic_Config_BluetoothConfig_PairingMode_MIN, 0} #define meshtastic_Config_init_zero {0, {meshtastic_Config_DeviceConfig_init_zero}} #define meshtastic_Config_DeviceConfig_init_zero {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0} -#define meshtastic_Config_PositionConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0} +#define meshtastic_Config_PositionConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} #define meshtastic_Config_PowerConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0} #define meshtastic_Config_NetworkConfig_init_zero {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_zero, ""} #define meshtastic_Config_NetworkConfig_IpV4Config_init_zero {0, 0, 0, 0} @@ -558,6 +562,8 @@ extern "C" { #define meshtastic_Config_PositionConfig_position_flags_tag 7 #define meshtastic_Config_PositionConfig_rx_gpio_tag 8 #define meshtastic_Config_PositionConfig_tx_gpio_tag 9 +#define meshtastic_Config_PositionConfig_broadcast_smart_minimum_distance_tag 10 +#define meshtastic_Config_PositionConfig_broadcast_smart_minimum_interval_secs_tag 11 #define meshtastic_Config_PowerConfig_is_power_saving_tag 1 #define meshtastic_Config_PowerConfig_on_battery_shutdown_after_secs_tag 2 #define meshtastic_Config_PowerConfig_adc_multiplier_override_tag 3 @@ -653,7 +659,9 @@ X(a, STATIC, SINGULAR, UINT32, gps_update_interval, 5) \ X(a, STATIC, SINGULAR, UINT32, gps_attempt_time, 6) \ X(a, STATIC, SINGULAR, UINT32, position_flags, 7) \ X(a, STATIC, SINGULAR, UINT32, rx_gpio, 8) \ -X(a, STATIC, SINGULAR, UINT32, tx_gpio, 9) +X(a, STATIC, SINGULAR, UINT32, tx_gpio, 9) \ +X(a, STATIC, SINGULAR, UINT32, broadcast_smart_minimum_distance, 10) \ +X(a, STATIC, SINGULAR, UINT32, broadcast_smart_minimum_interval_secs, 11) #define meshtastic_Config_PositionConfig_CALLBACK NULL #define meshtastic_Config_PositionConfig_DEFAULT NULL @@ -758,7 +766,7 @@ extern const pb_msgdesc_t meshtastic_Config_BluetoothConfig_msg; #define meshtastic_Config_LoRaConfig_size 77 #define meshtastic_Config_NetworkConfig_IpV4Config_size 20 #define meshtastic_Config_NetworkConfig_size 195 -#define meshtastic_Config_PositionConfig_size 42 +#define meshtastic_Config_PositionConfig_size 54 #define meshtastic_Config_PowerConfig_size 43 #define meshtastic_Config_size 198 diff --git a/src/mesh/generated/meshtastic/deviceonly.pb.h b/src/mesh/generated/meshtastic/deviceonly.pb.h index c43777bdf..dbda5b239 100644 --- a/src/mesh/generated/meshtastic/deviceonly.pb.h +++ b/src/mesh/generated/meshtastic/deviceonly.pb.h @@ -188,7 +188,7 @@ extern const pb_msgdesc_t meshtastic_OEMStore_msg; /* Maximum encoded size of messages (where known) */ #define meshtastic_ChannelFile_size 638 #define meshtastic_DeviceState_size 22040 -#define meshtastic_OEMStore_size 3008 +#define meshtastic_OEMStore_size 3020 #ifdef __cplusplus } /* extern "C" */ diff --git a/src/mesh/generated/meshtastic/localonly.pb.h b/src/mesh/generated/meshtastic/localonly.pb.h index 41d6d70aa..f31e47f20 100644 --- a/src/mesh/generated/meshtastic/localonly.pb.h +++ b/src/mesh/generated/meshtastic/localonly.pb.h @@ -156,7 +156,7 @@ extern const pb_msgdesc_t meshtastic_LocalModuleConfig_msg; #define meshtastic_LocalModuleConfig_fields &meshtastic_LocalModuleConfig_msg /* Maximum encoded size of messages (where known) */ -#define meshtastic_LocalConfig_size 442 +#define meshtastic_LocalConfig_size 454 #define meshtastic_LocalModuleConfig_size 420 #ifdef __cplusplus diff --git a/src/modules/PositionModule.cpp b/src/modules/PositionModule.cpp index d923dad8a..92a8b4c0c 100644 --- a/src/modules/PositionModule.cpp +++ b/src/modules/PositionModule.cpp @@ -144,10 +144,10 @@ int32_t PositionModule::runOnce() // We limit our GPS broadcasts to a max rate uint32_t now = millis(); - uint32_t intervalMs = config.position.position_broadcast_secs > 0 ? config.position.position_broadcast_secs * 1000 - : default_broadcast_interval_secs * 1000; - if (lastGpsSend == 0 || (now - lastGpsSend) >= intervalMs) { + uint32_t intervalMs = getConfiguredOrDefaultMs(config.position.position_broadcast_secs, default_broadcast_interval_secs); + uint32_t msSinceLastSend = now - lastGpsSend; + if (lastGpsSend == 0 || msSinceLastSend >= intervalMs) { // Only send packets if the channel is less than 40% utilized. if (airTime->isTxAllowedChannelUtil()) { if (node->has_position && (node->position.latitude_i != 0 || node->position.longitude_i != 0)) { @@ -165,39 +165,32 @@ int32_t PositionModule::runOnce() } } } else if (config.position.position_broadcast_smart_enabled) { - - // Only send packets if the channel is less than 25% utilized. - if (airTime->isTxAllowedChannelUtil(true)) { - + // 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)) { meshtastic_NodeInfo *node2 = service.refreshMyNodeInfo(); // should guarantee there is now a position if (node2->has_position && (node2->position.latitude_i != 0 || node2->position.longitude_i != 0)) { // The minimum distance to travel before we are able to send a new position packet. - const uint32_t distanceTravelMinimum = 30; + const uint32_t distanceTravelThreshold = + config.position.broadcast_smart_minimum_distance > 0 ? config.position.broadcast_smart_minimum_distance : 100; - // The minimum time that would pass before we are able to send a new position packet. - const uint32_t timeTravelMinimum = 30; + // 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); // Determine the distance in meters between two points on the globe - float distance = GeoCoord::latLongToMeter(lastGpsLatitude * 1e-7, lastGpsLongitude * 1e-7, - node->position.latitude_i * 1e-7, node->position.longitude_i * 1e-7); + float distanceTraveledSinceLastSend = + GeoCoord::latLongToMeter(lastGpsLatitude * 1e-7, lastGpsLongitude * 1e-7, node->position.latitude_i * 1e-7, + node->position.longitude_i * 1e-7); - // Yes, this has a bunch of magic numbers. Sorry. This is to make the scale non-linear. - const float distanceTravelMath = 1203 / (sqrt(pow(myNodeInfo.bitrate, 1.5) / 1.1)); - uint32_t distanceTravelThreshold = - (distanceTravelMath >= distanceTravelMinimum) ? distanceTravelMath : distanceTravelMinimum; - - // Yes, this has a bunch of magic numbers. Sorry. - uint32_t timeTravel = - ((1500 / myNodeInfo.bitrate) >= timeTravelMinimum) ? (1500 / myNodeInfo.bitrate) : timeTravelMinimum; - // If the distance traveled since the last update is greater than distanceTravelMinimum meters - // and it's been at least timeTravelMinimum seconds since the last update - if ((abs(distance) >= distanceTravelThreshold) && (now - lastGpsSend) >= (timeTravel * 1000)) { + if ((abs(distanceTraveledSinceLastSend) >= distanceTravelThreshold) && msSinceLastSend >= minimumTimeThreshold) { bool requestReplies = currentGeneration != radioGeneration; currentGeneration = radioGeneration; - LOG_INFO("Sending smart pos@%x:6 to mesh (wantReplies=%d, d=%d, dtt=%d, tt=%d)\n", node2->position.timestamp, - requestReplies, distance, distanceTravelThreshold, timeTravel); + LOG_INFO("Sending smart pos@%x:6 to mesh (distanceTraveled=%fm, minDistanceThreshold=%im, timeElapsed=%ims, " + "minTimeInterval=%ims)\n", + node2->position.timestamp, abs(distanceTraveledSinceLastSend), distanceTravelThreshold, + 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