Files
trail-mate/docs/skyplot.md
T

9.6 KiB
Raw Blame History

You are a senior embedded GUI engineer. Please use LVGL 8.x (C/C++) to implement a "GNSS Sky Plot (Satellite Sky Map)" page. Screen resolution: landscape 480(w) × 222(h). Requirements: Draw strictly according to the pixel layout given below; do not change the layout on your own; do not change element copy; the color system must revolve around the main color 0xEBA341 and be consistent with the warm color engineering style; all controls must be reusable and data refreshable.

============================================================

  1. Overall page layout (pixel level) ============================================================
  • Page root container root: size 480×222, background color is light warm beige (see style token).

  • Divided into three parts: A. Top TopBar: height 30px, full width 480 B. Content area Content: height 222-30=192px, y=30

  • left SkyPlotPanel: x=8, y=38, w=277, h=176

  • right StatusPanel: x=293, y=38, w=179, h=176 Note: Leave 8px spacing at the top of the Content area, so y=30+8=38 for the two panels; leave 8px spacing between the left and right panels.

  • Global rounded corners: 8px

  • Global stroke: 2px (main color emphasizes the edge)

============================================================ 2) Style and color token (must be used, unified style)

Main color (Amber): #EBA341 (0xEBA341) Main color dark (AmberDark): #C98118 Background (WarmBG): #F6E6C6 Panel bottom (PanelBG): #FAF0D8 Line: #E7C98F Text: #6B4A1E TextDim: #8A6A3A Warn: #B94A2C Success (Ok): #3E7D3E Information blue (Info): #2D6FB6

Constellation color (for SYS/legend): GPS: #E3B11F GLN: #2D6FB6 GAL: #3E7D3E BD: #B94A2C

SNR status color (for outer ring/padding of points): SNR_GOOD:#3E7D3E SNR_FAIR:#8FBF4D SNR_WEAK:#C18B2C NOT_USED:#B94A2C IN_VIEW: #6E6E6E (gray)

Font:

  • Title/column header: 20px (or LVGL Built-in approximate font size)
  • Header: 14px
  • List content: 16px
  • Bottom summary: 14px

============================================================ 3) TopBar (height 30)

TopBar container: x=0,y=0,w=480,h=30, background WarmBG, bottom divider 2px Line. Left title:

  • label_title: changed to Summary text: "USE: 7/18|HDOP: 1.6|FIX: 3D"
  • The three sections of USE/HDOP/FIX use different colors, and the whole is coordinated with the theme

Battery display on the right (only placeholder, does not implement the battery algorithm):

  • battery_icon: x=410, y=6, w=26, h=14, stroke 2px TextDim, filled with transparent, small bump on the right 3×6.
  • label_batt: x=442, y=5, text "100%", color TextDim, font size 18.

============================================================ 4) Left SkyPlotPanel (x=8,y=38,w=292,h=176)

Panel container:

  • panel_sky: Rounded Corners 10, Background PanelBG, Stroke 2px AmberDark.

Draw a "sky circle chart" internally:

  • Circle chart circumscribed square area sky_area: x=10, y=2, w=170, h=170 (relative to panel_sky) => Circle center C = (10+85, 2+85) = (95,87) relative to panel_sky Internal coordinates => Radius R = 82 (leaving space for stroke and text)

Drawing content (you can use lv_canvas or self-drawn objects, but they must be rendered): a) Outer circle (horizon 0°): Ring stroke Line 2px b) 3 concentric circles (30°/60°/90°):

  • r=R*2/3 (about 55)
  • r=R*1/3 (about 27)
  • r=0 (center point) Use Line 1px dotted line effect for the circular line (if you cannot do a dotted line, you can also use a thin solid line) c) Cross bearing lines: N-S and E-W pass through the center of the circle, line color Line 1px d) Direction text:
  • "N" placed above the circle: the center is aligned with the center x, y=2-2 (close to the outside of the circle)
  • "E" Place on the right side: x=10+170+8,y=95-10
  • "W" Place on the left side: x=2,y=95-10 (in the blank space on the left side of the circle) Text color, font size 18 e) Elevation angle scale text:
  • Change the scale to "pointing to the 10:30 direction": mark "90°" (near the outer circle), "60°" (r=55), and "30°" (r=27) on the diagonal line from the center of the circle to the 10:30 direction.
  • The text is arranged along the diagonal line, and the overall visual connection points to the 10 and a half direction Text color TextDim, font size 16 f) Marking near the center of the circle:
  • label_horizon: placed slightly below the center of the circle: text "0° Horizon", color TextDim, font size 12

Satellite point drawing (dynamic): -Use a small dot object sat_dot for each satellite (recommended lv_obj + fillet = radius) -Point radius: 10px (diameter 20) -Display satellites within the point ID (two or three digits), text white or dark brown (contrast is automatically selected according to the background color, white is preferred) -The position of the point is mapped to the circle by (azimuth, elevation): r = R * (1 - elevation/90) x = Cx + r * sin(azimuth) y = Cy - r * cos(azimuth) (azimuth: 0°=N, 90°=E) -Point fill color: by constellation (GPS/GLN/GAL/BD)

  • Click outer ring/small mark: press SNR status (GOOD/FAIR/WEAK/NOT_USED/IN_VIEW):
  • GOOD/FAIR/WEAK: use the corresponding color to make a 2px outer ring
  • NOT_USED: outer ring Warn
  • IN_VIEW: outer ring Gray
  • If the satellite used_in_fix=true, add a small label "USE" next to the point:
  • use_tag: Rounded corners 6, background Ok, text white, font size 12
  • Position: Offset the lower left corner of the pasting point (dx=-12, dy=12) to avoid blocking the numbers

Legend (in the lower right corner area of SkyPlotPanel):

  • legend_sys (constellation legend) is placed on the right side of the circle chart, below:
  • Small color block 10×10 + Text (GPS/GLONASS/Galileo/BeiDou)
  • Position: starting from x=190, y=105, line height 15
  • legend_snr (SNR legend) is placed above legend_sys and aligned to its left (upper right corner area of SkyPlotPanel):
  • Text order: "SNR Good" "SNR Weak" "Not Used" "In View"
  • Use small dots (diameter 10) + text
  • Position: starting from x=190, arranged vertically (line height 15), the whole is above legend_sys; the distance from legend_sys is 6px; the whole is moved up 30px; small dots and text arrangement rules are the same as legend_sys (color block y+4, text x+14)
  • text color TextDim, font size 12

============================================================ 5) Right StatusPanel (x=293, y=38, w=179, h=176)

Panel container:

  • panel_status: rounded corners 10, background PanelBG, stroke 2px AmberDark

Title bar (height 26):

  • header: x=0,y=0,w=179,h=26, background Amber, upper half of rounded corners maintained
  • label: centered "SATELLITE STATUS", text color #2A1A05, font size 14 bold

Header row (height 22, y=26):

  • Background: #F2D9A5
  • Columns: ID / SYS / ELEV / SNR / USE
  • Column width (pixels): ID=24, SYS=38, ELEV=39, SNR=38, USED=39 (ELEV=USED, SNR=SYS)
  • Text centered, color TextDim, font size 12

Data list area (y=48 to y=176, height 128): -Rendered in "fixed row height" mode, row height 17px, 7 rows can be displayed (remaining scrolling/pagination is not implemented, but the structure must be reserved) -5 columns in each row to align the header

  • Line bottom divider 1px Line
  • SYS text color according to constellation color (GPS/GLN/GAL/BD)
  • USED column: if used=true, display "YES" color Ok; otherwise "NO" color Warn
  • Other column text colors Text
  • When the number of satellites exceeds the number of rows that can be displayed, the list is displayed in the following priority order: USED=YES first, high SNR first, then high elevation, then PRN/SVID in ascending order

The summary area at the bottom is removed, and all space is given to the data list area

============================================================ 6) Data structure and refresh interface (must be provided)

Define data structure (example):

  • struct SatInfo { int id; // PRN/SVID enum Sys {GPS, GLN, GAL, BD} sys; float azimuth; // 0..359 deg float elevation; // 0..90 deg int snr; // dB-Hz bool used; enum SNRState {GOOD, FAIR, WEAK, NOT_USED, IN_VIEW} snr_state; };

  • struct GnssStatus { int sats_in_use; int sats_in_view; float hdop; enum Fix {NOFIX, FIX2D, FIX3D} fix; };

Must implement two refresh functions (for upper layer calls):

  • void ui_gnss_skyplot_set_sats(const SatInfo* sats, int count); -> Update circular chart satellite points (create/reuse objects), update the first N rows of the right table
  • void ui_gnss_skyplot_set_status(GnssStatus st); -> Update bottom summary text and FIX Color

============================================================ 7) Interaction (minimal)

  • The Back button position is allowed to be reserved in the upper left corner (but this requirement does not have to be implemented).
  • The page does not require touch interaction; only the display needs to be refreshed.
  • Backspace key behavior: trigger the Back button logic of TopBar, consistent with other pages.

============================================================ 8) Deliverable requirements

  • Provide a function ui_gnss_skyplot_create(lv_obj_t* parent) to return the page root object.
  • All object pointers are stored in static/structural bodies, supporting repeated page entry without leakage.
  • Do not use external image resources; draw everything with LVGL.
  • Output code should be directly compilable (pseudocode is not accepted).

Generate complete LVGL page code according to the above requirements.