Waypoint cleanup

This commit is contained in:
HarukiToreda
2025-10-13 16:57:42 -04:00
parent 4ca56ec9cb
commit 8fb825e0e0

View File

@@ -14,6 +14,9 @@
WaypointModule *waypointModule; WaypointModule *waypointModule;
static inline float degToRad(float deg) { return deg * PI / 180.0f; }
static inline float radToDeg(float rad) { return rad * 180.0f / PI; }
ProcessMessage WaypointModule::handleReceived(const meshtastic_MeshPacket &mp) ProcessMessage WaypointModule::handleReceived(const meshtastic_MeshPacket &mp)
{ {
#if defined(DEBUG_PORT) && !defined(DEBUG_MUTE) #if defined(DEBUG_PORT) && !defined(DEBUG_MUTE)
@@ -52,31 +55,15 @@ ProcessMessage WaypointModule::handleReceived(const meshtastic_MeshPacket &mp)
bool WaypointModule::shouldDraw() bool WaypointModule::shouldDraw()
{ {
#if !MESHTASTIC_EXCLUDE_WAYPOINT #if !MESHTASTIC_EXCLUDE_WAYPOINT
if (screen == nullptr) if (!screen || !devicestate.has_rx_waypoint) return false;
return false;
// If no waypoint to show
if (!devicestate.has_rx_waypoint)
return false;
// Decode the message, to find the expiration time (is waypoint still valid) meshtastic_Waypoint wp{}; // <- replaces memset
// This handles "deletion" as well as expiration if (pb_decode_from_bytes(devicestate.rx_waypoint.decoded.payload.bytes,
meshtastic_Waypoint wp; devicestate.rx_waypoint.decoded.payload.size,
memset(&wp, 0, sizeof(wp));
if (pb_decode_from_bytes(devicestate.rx_waypoint.decoded.payload.bytes, devicestate.rx_waypoint.decoded.payload.size,
&meshtastic_Waypoint_msg, &wp)) { &meshtastic_Waypoint_msg, &wp)) {
// Valid waypoint return wp.expire > getTime();
if (wp.expire > getTime())
return devicestate.has_rx_waypoint = true;
// Expired, or deleted
else
return devicestate.has_rx_waypoint = false;
} }
return false; // no LOG_ERROR, no flag writes
// If decoding failed
LOG_ERROR("Failed to decode waypoint");
devicestate.has_rx_waypoint = false;
return false;
#else #else
return false; return false;
#endif #endif
@@ -85,53 +72,46 @@ bool WaypointModule::shouldDraw()
/// Draw the last waypoint we received /// Draw the last waypoint we received
void WaypointModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) void WaypointModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{ {
if (screen == nullptr) if (!screen) return;
return;
// Prepare to draw // Prepare to draw
display->setFont(FONT_SMALL); display->setFont(FONT_SMALL);
display->setTextAlignment(TEXT_ALIGN_LEFT); display->setTextAlignment(TEXT_ALIGN_LEFT);
const int w = display->getWidth();
const int h = display->getHeight();
// Handle inverted display // Handle inverted display
// Unsure of expected behavior: for now, copy drawNodeInfo
if (config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_INVERTED) if (config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_INVERTED)
display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL); display->fillRect(x, y, w, FONT_HEIGHT_SMALL);
// Decode the waypoint // Decode the waypoint
const meshtastic_MeshPacket &mp = devicestate.rx_waypoint; const meshtastic_MeshPacket &mp = devicestate.rx_waypoint;
meshtastic_Waypoint wp; meshtastic_Waypoint wp{};
memset(&wp, 0, sizeof(wp));
if (!pb_decode_from_bytes(mp.decoded.payload.bytes, mp.decoded.payload.size, &meshtastic_Waypoint_msg, &wp)) { if (!pb_decode_from_bytes(mp.decoded.payload.bytes, mp.decoded.payload.size, &meshtastic_Waypoint_msg, &wp)) {
// This *should* be caught by shouldDrawWaypoint, but we'll short-circuit here just in case
display->drawStringMaxWidth(0 + x, 0 + y, x + display->getWidth(), "Couldn't decode waypoint");
devicestate.has_rx_waypoint = false; devicestate.has_rx_waypoint = false;
return; return;
} }
// Get timestamp info. Will pass as a field to drawColumns // Get timestamp info. Will pass as a field to drawColumns
static char lastStr[20]; char lastStr[20];
getTimeAgoStr(sinceReceived(&mp), lastStr, sizeof(lastStr)); getTimeAgoStr(sinceReceived(&mp), lastStr, sizeof(lastStr));
// Will contain distance information, passed as a field to drawColumns // Will contain distance information, passed as a field to drawColumns
static char distStr[20]; char distStr[20];
// Get our node, to use our own position // Get our node, to use our own position
meshtastic_NodeInfoLite *ourNode = nodeDB->getMeshNode(nodeDB->getNodeNum()); meshtastic_NodeInfoLite *ourNode = nodeDB->getMeshNode(nodeDB->getNodeNum());
// Text fields to draw (left of compass) // Text fields to draw (left of compass)
// Last element must be NULL. This signals the end of the char*[] to drawColumns // Last element must be NULL. This signals the end of the char*[] to drawColumns
const char *fields[] = {"Waypoint", lastStr, wp.name, distStr, NULL}; const char *fields[] = {"Waypoint", lastStr, wp.name, wp.description, distStr, nullptr};
// Dimensions / co-ordinates for the compass/circle // Dimensions / co-ordinates for the compass/circle
int16_t compassX = 0, compassY = 0; const uint16_t compassDiam = graphics::CompassRenderer::getCompassDiam(w, h);
uint16_t compassDiam = graphics::CompassRenderer::getCompassDiam(display->getWidth(), display->getHeight()); const int16_t compassX = x + w - (compassDiam / 2) - 5;
const int16_t compassY = (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT)
? y + h / 2
: y + FONT_HEIGHT_SMALL + (h - FONT_HEIGHT_SMALL) / 2;
if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT) {
compassX = x + display->getWidth() - compassDiam / 2 - 5;
compassY = y + display->getHeight() / 2;
} else {
compassX = x + display->getWidth() - compassDiam / 2 - 5;
compassY = y + FONT_HEIGHT_SMALL + (display->getHeight() - FONT_HEIGHT_SMALL) / 2;
}
// If our node has a position: // If our node has a position:
if (ourNode && (nodeDB->hasValidPosition(ourNode) || screen->hasHeading())) { if (ourNode && (nodeDB->hasValidPosition(ourNode) || screen->hasHeading())) {
@@ -141,7 +121,7 @@ void WaypointModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state,
myHeading = 0; myHeading = 0;
} else { } else {
if (screen->hasHeading()) if (screen->hasHeading())
myHeading = (screen->getHeading()) * PI / 180; // gotta convert compass degrees to Radians myHeading = degToRad(screen->getHeading());
else else
myHeading = screen->estimatedHeading(DegD(op.latitude_i), DegD(op.longitude_i)); myHeading = screen->estimatedHeading(DegD(op.latitude_i), DegD(op.longitude_i));
} }
@@ -157,34 +137,28 @@ void WaypointModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state,
graphics::CompassRenderer::drawNodeHeading(display, compassX, compassY, compassDiam, bearingToOther); graphics::CompassRenderer::drawNodeHeading(display, compassX, compassY, compassDiam, bearingToOther);
float bearingToOtherDegrees = (bearingToOther < 0) ? bearingToOther + 2 * PI : bearingToOther; float bearingToOtherDegrees = (bearingToOther < 0) ? bearingToOther + 2 * PI : bearingToOther;
bearingToOtherDegrees = bearingToOtherDegrees * 180 / PI; bearingToOtherDegrees = radToDeg(bearingToOtherDegrees);
// Distance to Waypoint // Distance to Waypoint
float d = GeoCoord::latLongToMeter(DegD(wp.latitude_i), DegD(wp.longitude_i), DegD(op.latitude_i), DegD(op.longitude_i)); float d = GeoCoord::latLongToMeter(DegD(wp.latitude_i), DegD(wp.longitude_i), DegD(op.latitude_i), DegD(op.longitude_i));
if (config.display.units == meshtastic_Config_DisplayConfig_DisplayUnits_IMPERIAL) { if (config.display.units == meshtastic_Config_DisplayConfig_DisplayUnits_IMPERIAL) {
if (d < (2 * MILES_TO_FEET)) float feet = d * METERS_TO_FEET;
snprintf(distStr, sizeof(distStr), "%.0fft %.0f°", d * METERS_TO_FEET, bearingToOtherDegrees); snprintf(distStr, sizeof(distStr),
else feet < (2 * MILES_TO_FEET) ? "%.0fft %.0f°" : "%.1fmi %.0f°",
snprintf(distStr, sizeof(distStr), "%.1fmi %.0f°", d * METERS_TO_FEET / MILES_TO_FEET, bearingToOtherDegrees); feet < (2 * MILES_TO_FEET) ? feet : feet / MILES_TO_FEET, bearingToOtherDegrees);
} else { } else {
if (d < 2000) snprintf(distStr, sizeof(distStr),
snprintf(distStr, sizeof(distStr), "%.0fm %.0f°", d, bearingToOtherDegrees); d < 2000 ? "%.0fm %.0f°" : "%.1fkm %.0f°",
else d < 2000 ? d : d / 1000, bearingToOtherDegrees);
snprintf(distStr, sizeof(distStr), "%.1fkm %.0f°", d / 1000, bearingToOtherDegrees);
} }
} }
// If our node doesn't have position
else { else {
// ? in the compass
display->drawString(compassX - FONT_HEIGHT_SMALL / 4, compassY - FONT_HEIGHT_SMALL / 2, "?"); display->drawString(compassX - FONT_HEIGHT_SMALL / 4, compassY - FONT_HEIGHT_SMALL / 2, "?");
// ? in the distance field // ? in the distance field
if (config.display.units == meshtastic_Config_DisplayConfig_DisplayUnits_IMPERIAL) snprintf(distStr, sizeof(distStr), "? %s ?°",
strncpy(distStr, "? mi ?°", sizeof(distStr)); (config.display.units == meshtastic_Config_DisplayConfig_DisplayUnits_IMPERIAL) ? "mi" : "km");
else
strncpy(distStr, "? km ?°", sizeof(distStr));
} }
// Draw compass circle // Draw compass circle
@@ -195,8 +169,6 @@ void WaypointModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state,
if (config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_INVERTED) { if (config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_INVERTED) {
display->setColor(BLACK); display->setColor(BLACK);
} }
// Must be after distStr is populated
graphics::NodeListRenderer::drawColumns(display, x, y, fields); graphics::NodeListRenderer::drawColumns(display, x, y, fields);
} }
#endif #endif