feat(radar): add radar minimap overlay to the Distance/Bearings frame#10224
feat(radar): add radar minimap overlay to the Distance/Bearings frame#10224egorsiniaev wants to merge 37 commits into
Conversation
I have 500 Internal Server Error after signing it. |
|
We have 3 nodelist displays with different additonal things. This adds a 4th list with a graphical representation. Also overlaps with the functionality of the GPS Compass. Maybe we can have this panel as an option instead of the GPS Compass or even merge it with the compass. |
The CLA server seems to have issues. Can you try again maybe tomorrow? |
I thought about it, but because this is my first PR and contribution - to suggest such merge without long term community vision is a strange step. That's why I decided to have clear separate section that easy to review + easy to disable if people don't need it. |
|
Problem is, we rather would like to make the interface more clear, not pile on it. I see the value in your contribution, i just think i t would really benefit the existing screens rather than open up a new one. |
|
This is cool :) I want to see how it looks on a larger screen, like the sensecap indicator - will try when I get time. Also, appreciate your collaborative approach. |
I updated. Removed separate Radar view and add option to switch Compass mode Radar mode. Plus changed a bit orientation (nodes on the left, radar on the right) to match compass layout. Please take a look. Should I need to update screenshots? They are still showing old layout. |
Will appreciate for checking it. I have no such devices yet. |
|
Hey @caveman99 Thanks for your suggestion. I'v made changes and pushed them. Today made photos and record video for better representation. In short - I extended Compass, add long-press menu to switch to the radar view + changed a bit layout to match compass. Please take a look and let me know if anything else is missing. |
|
Hey @caveman99 @fifieldt |
|
Reviewing the video - I do like the idea and concept. It's well executed and provides a display not so dissimilar to what is in InkHUD. Need to load it up on a couple devices to give it a run through. |
Xaositek
left a comment
There was a problem hiding this comment.
Tested it out on my Cardputer and I can't see it actually working. I tried Zooming In and Out, verified I have a GPS lock, and nodes are pretty close by.
I feel like we need some refinements like "What is my current Zoom level?", "Do I have GPS lock"?
Also the toggle between Compass and Radar likely needs to be similar to what we have on the Clock screen where you click on "Clock Face" and then choose Digital or Analog.
IMG_3250.movVideo of my attempt |
|
I had a similar idea while creating the distance and bearing screen, I ultimately opted to not implement due to the following:
|
…stance Adds a new RadarRenderer that draws a circular radar view with three range rings. The user's node sits at the centre; other nodes with valid GPS positions are plotted as 3×3 squares at their true bearing and proportional distance. A "N" indicator marks north, the info panel to the right shows the current scale, total node count, and the name and distance of the closest node. The screen is registered for non-E-Ink builds that have GPS (HAS_GPS) and can be hidden via the existing hiddenFrames mechanism.
When BMX160 (RAK12034) is connected, Screen::setHeading() is updated by BMX160Sensor::runOnce() after tilt-compensated compass fusion. The radar now reads that heading via screen->hasHeading()/getHeading() and rotates all node bearings and the "N" indicator accordingly, so the direction the device faces is always at the top of the display (heading-up mode). Falls back to GPS-estimated track heading, then north-up when neither is available. The info panel shows "HDG-UP" or "N-UP" so the current mode is always visible.
- Centre the radar circle horizontally, filling the full content height (radius=27 on 128×64, scales up on larger displays) - Replace the wide info panel with a compact ring legend to the right: three stacked distance labels (outer/middle/inner ring scale) plus a small "IMU" indicator when the BMX160 is active - Remove per-screen closest-node text — node positions on the rings now carry the distance information visually
… long-press menu 1. Scale table — all values now multiples of 3 so ring labels (scale/3 and scale*2/3) are always whole numbers (e.g. 30/60/90m, 100/200/300m). 2. Layout — radar shifted to the left edge; right panel shows three ring scale labels, closest node short name, distance, and a node-count + orientation badge (HDG / N^) in the bottom row. 3. Icon — replaced shared icon_compass with a new icon_radar (concentric rings with centre dot) so the radar has its own menu indicator. 4. Menu toggle — "Show/Hide Radar" added to the Show/Hide Frames menu via the existing toggleFrameVisibility / isFrameHidden pattern. 5. Long-press menu — pressing SELECT on the radar screen opens "Radar Options" with: Switch N-UP / HDG-UP (overrides IMU), Zoom In, Zoom Out. Zoom is clamped to ±2 steps from auto-scale; state is held in module- static variables in RadarRenderer.
Problem: on 128×64 OLED with FONT_SMALL≈13px, the 3 ring-label rows
left no space for node info — name/distance were clipped off screen.
Fix:
- Info panel reduced to 4 rows:
Row 0 outer ring scale (scale reference)
Row 1 closest node: name (left) + distance (right-aligned)
Row 2 2nd closest node: name + distance
Row 3 node count + HDG/N^ badge
- Entries sorted by distance ascending before drawing so rows 1/2
always show the two nearest nodes.
- Closest node rendered as a + cross on the radar; all others keep
the 3×3 filled-square marker. The cross lets the user match the
top panel row to the correct dot without cluttering the radar with
text labels.
Each node is assigned a persistent marker shape based on nodeNum % 5: 0 ■ filled square 1 + axis-aligned cross 2 × diagonal X 3 □ hollow square 4 ◆ diamond The same symbol appears on the radar dot AND in the right-panel list, so the user can visually match any dot on the map to its panel entry without text labels cluttering the radar. Info panel: Row 0 outer ring scale Row 1 [sym] closest node name (left) distance (right) Row 2 [sym] 2nd closest (left) distance (right) Row 3 node count (left) orientation badge (right)
Instead of a separate screen slot in the rotation, the radar now lives inside the existing Position/Compass screen. - Remove standalone Radar frame and icon from screen rotation - Add 'Radar View' entry to the position long-press menu (positionBaseMenu) - Long-press in radar mode opens radarPositionMenu with: Compass View, N-UP/HDG-UP toggle, Zoom In, Zoom Out - UIRenderer::drawCompassAndLocationScreen delegates to RadarRenderer::drawRadarOverlay when uiconfig.radar_mode is true - Radar layout: node list (left) + radar circle (right, 2 px padding) - radar_mode persisted as bool field 20 in DeviceUIConfig (proto-compatible) - Removes nodelist_radar from hiddenFrames, framesetInfo.positions, and all frame-toggle machinery
Re-do the previous fix without modifying SharedUIDisplay. The shared drawCommonFooter still does its full-width black wipe — that's the correct behaviour for every other screen — but the radar overlay now owns its own icon-drawing path: - New static drawConnectionIconNoWipe() in RadarRenderer renders just the 5x5 BT/API glyph at x=0..4 with no surrounding fill. Replicates the icon-rendering half of drawCommonFooter inline so radar can stay self-contained. - drawRadarOverlay calls it at the end, after radar + list have been drawn. The icon's footprint (x=0..4) doesn't spatially overlap the radar circle (x=80..126) or list text (x>=7), so leaving the rest of the bottom row untouched preserves the radar arc and the last list row's text. - NodeListRenderer's radar branch drops its drawCommonFooter call — radar handles the icon itself now. SharedUIDisplay.cpp/.h are untouched, so other view modes and menus keep their original footer behaviour.
…t/radar-node-view
|
Updated PR a bit. Fixed layout to better show radar and node list, especially when bluetooth connected. Plus fixed a bug with wrong order of nodes and showing not correct ones. |
|
Looks good, got a chance to test it today 20260517_143536_1.mp4 |
CI cppcheck flagged constVariablePointer on line 244: Variable 'ourNode' can be declared as pointer to const We never mutate the node through the pointer (only read num and pass to copyNodePosition), so the stricter declaration is correct.
CI's Trunk Check Runner flagged two files as unformatted: src/graphics/draw/MenuHandler.cpp src/graphics/draw/RadarRenderer.cpp Ran clang-format (version 17.0.6, project config .trunk/configs/.clang-format). Diff is style-only — include reordering (alphabetical within group) and compacting a single static const array to one line under the 130-col limit. No semantic changes.
|
@HarukiToreda Thanks for checking! |
|
yes, if you can fit it, allowing more nodes to show to take advantage of the higher resolution and space would be great. |
|
@HarukiToreda could you tell me your device name and screen resolution? I also think - let's use Meshtastic community you to test it properly. I wrote it for 128×64 OLED, but there are some TFT and eInk screens. Any idea how & where to populate it to test?
|
|
I was using a Heltec T114 with a large 240x320 screen I personally added, a good one to try with a large enough screen like that is the Tdeck, i think what you have now is good to merge. Fine tuning for larger screens could be a new PR |
|
Hey @Xaositek. Could you please take a look on this PR? |
79e6264 to
3e7ed0d
Compare
| #define meshtastic_DeviceUIConfig_screen_rgb_color_tag 17 | ||
| #define meshtastic_DeviceUIConfig_is_clockface_analog_tag 18 | ||
| #define meshtastic_DeviceUIConfig_gps_format_tag 19 | ||
| #define meshtastic_DeviceUIConfig_bearings_view_radar_tag 20 |
There was a problem hiding this comment.
Can you please make a PR in the meshtastic/protobufs repo to add these there?
…ng labels, list top pad, adaptive radar padding
3e7ed0d to
4d6109c
Compare
|
While waiting for PR - I ordered T-Deck and did some tweaks for highres screens:
FYI @HarukiToreda @HarukiToreda @fifieldt Let me know what do you think. |

What this PR does
Adds a radar minimap view as an alternative rendering of the existing Distance/Bearings frame — no new screen slot in the rotation.
From the node-list long-press menu, a new "Tracking View" picker (clock-face style) lets the user switch between the regular Bearings list and the Radar overlay. While in radar mode, long-pressing opens a radar-specific menu (Tracking View, N-UP/HDG-UP toggle, Favorites Only toggle, Zoom In/Out). Both choices are persistent across reboots (
bearings_view_radarandradar_favorites_onlyinDeviceUIConfig, proto fields 20 and 21).Radar layout
Radar 5km/Radar 1.5mi(units followdisplay.units)#ifndef USE_EINKblock inNodeListRenderer.cpp, so the radar code isn't compiled in for e-ink buildsFiles changed
src/graphics/draw/RadarRenderer.cpp/.h— radar overlay renderer; owns its own header so the title can carry the current rangesrc/graphics/draw/NodeListRenderer.cpp— delegates toRadarRenderer::drawRadarOverlaywhenbearings_view_radaris setsrc/graphics/draw/MenuHandler.cpp/.h— addstrackingViewPicker()andradarBearingsMenu(); wires "Tracking View" into the node-list menusrc/graphics/Screen.cpp— routes long-press on the bearings frame toradarBearingsMenuwhen radar is activesrc/mesh/generated/meshtastic/device_ui.pb.h— addsbool bearings_view_radar(field 20) andbool radar_favorites_only(field 21), both backwards-compatible🤝 Attestations
Note: Happy to get help testing on other hardware from the community.
Video: https://photos.app.goo.gl/Tj3y2PKypFPwczE58