From 8fb825e0e00c513c393f2a7782680aa862bc1a41 Mon Sep 17 00:00:00 2001 From: HarukiToreda <116696711+HarukiToreda@users.noreply.github.com> Date: Mon, 13 Oct 2025 16:57:42 -0400 Subject: [PATCH] Waypoint cleanup --- src/modules/WaypointModule.cpp | 94 ++++++++++++---------------------- 1 file changed, 33 insertions(+), 61 deletions(-) diff --git a/src/modules/WaypointModule.cpp b/src/modules/WaypointModule.cpp index 4b05d5fa1..bebf684e9 100644 --- a/src/modules/WaypointModule.cpp +++ b/src/modules/WaypointModule.cpp @@ -14,6 +14,9 @@ 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) { #if defined(DEBUG_PORT) && !defined(DEBUG_MUTE) @@ -52,31 +55,15 @@ ProcessMessage WaypointModule::handleReceived(const meshtastic_MeshPacket &mp) bool WaypointModule::shouldDraw() { #if !MESHTASTIC_EXCLUDE_WAYPOINT - if (screen == nullptr) - return false; - // If no waypoint to show - if (!devicestate.has_rx_waypoint) - return false; + if (!screen || !devicestate.has_rx_waypoint) return false; - // Decode the message, to find the expiration time (is waypoint still valid) - // This handles "deletion" as well as expiration - meshtastic_Waypoint wp; - memset(&wp, 0, sizeof(wp)); - if (pb_decode_from_bytes(devicestate.rx_waypoint.decoded.payload.bytes, devicestate.rx_waypoint.decoded.payload.size, + meshtastic_Waypoint wp{}; // <- replaces memset + if (pb_decode_from_bytes(devicestate.rx_waypoint.decoded.payload.bytes, + devicestate.rx_waypoint.decoded.payload.size, &meshtastic_Waypoint_msg, &wp)) { - // Valid waypoint - if (wp.expire > getTime()) - return devicestate.has_rx_waypoint = true; - - // Expired, or deleted - else - return devicestate.has_rx_waypoint = false; + return wp.expire > getTime(); } - - // If decoding failed - LOG_ERROR("Failed to decode waypoint"); - devicestate.has_rx_waypoint = false; - return false; + return false; // no LOG_ERROR, no flag writes #else return false; #endif @@ -85,53 +72,46 @@ bool WaypointModule::shouldDraw() /// Draw the last waypoint we received void WaypointModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) { - if (screen == nullptr) - return; + if (!screen) return; // Prepare to draw display->setFont(FONT_SMALL); display->setTextAlignment(TEXT_ALIGN_LEFT); + const int w = display->getWidth(); + const int h = display->getHeight(); // Handle inverted display - // Unsure of expected behavior: for now, copy drawNodeInfo 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 const meshtastic_MeshPacket &mp = devicestate.rx_waypoint; - meshtastic_Waypoint wp; - memset(&wp, 0, sizeof(wp)); + meshtastic_Waypoint 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; return; } // Get timestamp info. Will pass as a field to drawColumns - static char lastStr[20]; + char lastStr[20]; getTimeAgoStr(sinceReceived(&mp), lastStr, sizeof(lastStr)); // 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 meshtastic_NodeInfoLite *ourNode = nodeDB->getMeshNode(nodeDB->getNodeNum()); // Text fields to draw (left of compass) // 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 - int16_t compassX = 0, compassY = 0; - uint16_t compassDiam = graphics::CompassRenderer::getCompassDiam(display->getWidth(), display->getHeight()); + const uint16_t compassDiam = graphics::CompassRenderer::getCompassDiam(w, h); + 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 (ourNode && (nodeDB->hasValidPosition(ourNode) || screen->hasHeading())) { @@ -141,7 +121,7 @@ void WaypointModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, myHeading = 0; } else { if (screen->hasHeading()) - myHeading = (screen->getHeading()) * PI / 180; // gotta convert compass degrees to Radians + myHeading = degToRad(screen->getHeading()); else 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); float bearingToOtherDegrees = (bearingToOther < 0) ? bearingToOther + 2 * PI : bearingToOther; - bearingToOtherDegrees = bearingToOtherDegrees * 180 / PI; + bearingToOtherDegrees = radToDeg(bearingToOtherDegrees); // Distance to Waypoint 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 (d < (2 * MILES_TO_FEET)) - snprintf(distStr, sizeof(distStr), "%.0fft %.0f°", d * METERS_TO_FEET, bearingToOtherDegrees); - else - snprintf(distStr, sizeof(distStr), "%.1fmi %.0f°", d * METERS_TO_FEET / MILES_TO_FEET, bearingToOtherDegrees); + float feet = d * METERS_TO_FEET; + snprintf(distStr, sizeof(distStr), + feet < (2 * MILES_TO_FEET) ? "%.0fft %.0f°" : "%.1fmi %.0f°", + feet < (2 * MILES_TO_FEET) ? feet : feet / MILES_TO_FEET, bearingToOtherDegrees); } else { - if (d < 2000) - snprintf(distStr, sizeof(distStr), "%.0fm %.0f°", d, bearingToOtherDegrees); - else - snprintf(distStr, sizeof(distStr), "%.1fkm %.0f°", d / 1000, bearingToOtherDegrees); + snprintf(distStr, sizeof(distStr), + d < 2000 ? "%.0fm %.0f°" : "%.1fkm %.0f°", + d < 2000 ? d : d / 1000, bearingToOtherDegrees); } - } - // If our node doesn't have position else { - // ? in the compass display->drawString(compassX - FONT_HEIGHT_SMALL / 4, compassY - FONT_HEIGHT_SMALL / 2, "?"); // ? in the distance field - if (config.display.units == meshtastic_Config_DisplayConfig_DisplayUnits_IMPERIAL) - strncpy(distStr, "? mi ?°", sizeof(distStr)); - else - strncpy(distStr, "? km ?°", sizeof(distStr)); + snprintf(distStr, sizeof(distStr), "? %s ?°", + (config.display.units == meshtastic_Config_DisplayConfig_DisplayUnits_IMPERIAL) ? "mi" : "km"); } // Draw compass circle @@ -195,8 +169,6 @@ void WaypointModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, if (config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_INVERTED) { display->setColor(BLACK); } - - // Must be after distStr is populated graphics::NodeListRenderer::drawColumns(display, x, y, fields); } #endif