Sitelet https://github.com/betaflight/betaflight/pull/15416
Skip to content

Autopilot: OSD waypoint elements, CLI mission status, MAVLink SET_CURRENT - #15416

Merged
blckmn merged 2 commits into
betaflight:masterfrom
blckmn:feat/flight-plan-osd-mavlink-pr
Jul 17, 2026
Merged

blckmn merged 2 commits into
betaflight:masterfrom
blckmn:feat/flight-plan-osd-mavlink-pr

Conversation

@blckmn

@blckmn blckmn commented Jul 14, 2026 •

Copy link
Copy Markdown
Member

Pilot surface and MAVLink completion for the flight-plan feature, following #15413.

  • OSD: wire the eight OSD_WP_* elements (current/next waypoint number, current waypoint lat/lon/alt, distance, direction arrow, ETA). Their ids and CLI positions shipped earlier without any rendering code. Add flightPlanNavGetDistanceToWaypointM / BearingToWaypointDeciDeg / EtaSeconds over the executor's existing target-distance computation, shared by the elements and the CLI. Add WP LANDING and WP COMPLETE cues to the OSD warnings line, below every critical warning.
  • CLI: complete the waypoint status runtime section (state, current waypoint, distance, bearing, ETA, abort reason); it was a stub.
  • MAVLink: handle MISSION_SET_CURRENT (re-dispatch to the requested leg while flying, set the engage start index while idle), and add a host unit test covering the mission round-trip (upload decode to the stored plan, download encode, MISSION_ITEM_REACHED, MISSION_CURRENT, SET_CURRENT). SITL builds no MAVLink telemetry, so the unit test is the automated coverage for that path; real transport is hardware-in-the-loop.

OSD is not built in SITL, so the elements are verified by the F405 + USE_FLIGHT_PLAN build and the accessor unit tests. User-facing documentation will live on the betaflight.com website rather than in the firmware repo.

Part of the autopilot programme tracked in #15411.

Summary by CodeRabbit

  • New Features

    • Added real-time flight-plan status reporting in the CLI, including navigation state, waypoint progress, distance, bearing, ETA, and abort details.
    • Added new flight-plan waypoint OSD elements for current/next waypoint and live navigation metrics (with placeholders when unavailable).
    • Added MAVLink support for selecting the active mission waypoint and publishing updated mission cursor status.
    • Added “WP LANDING” and “WP COMPLETE” flight-plan alerts on the OSD.
  • Bug Fixes

    • Improved waypoint selection/engagement behavior and live navigation geometry used for OSD/telemetry.

Copilot AI review requested due to automatic review settings July 14, 2026 11:08
@github-actions

Copy link
Copy Markdown

Do you want to test this code? You can flash it directly from the Betaflight App:

  • Simply put #15416 (this pull request number) in the Select commit field in the Firmware Flasher tab (you need to Enable expert mode, Show release candidates and Development).

WARNING: It may be unstable. Use only for testing!

@coderabbitai

coderabbitai Bot commented Jul 14, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 8c14839e-2049-445b-bccb-03b3ac077a1f

📥 Commits

Reviewing files that changed from the base of the PR and between 6628897 and 03cd175.

📒 Files selected for processing (5)
  • src/main/cli/cli.c
  • src/main/flight/flight_plan_nav.c
  • src/main/flight/flight_plan_nav.h
  • src/main/osd/osd_elements.c
  • src/main/telemetry/mavlink_mission.c
🚧 Files skipped from review as they are similar to previous changes (5)
  • src/main/telemetry/mavlink_mission.c
  • src/main/flight/flight_plan_nav.h
  • src/main/cli/cli.c
  • src/main/osd/osd_elements.c
  • src/main/flight/flight_plan_nav.c

Walkthrough

Adds active waypoint selection and geometry APIs, MAVLink mission cursor handling, CLI status output, flight-plan OSD elements and warnings, plus unit coverage for navigation and mission telemetry behavior.

Changes

Flight-plan runtime integration

Layer / File(s) Summary
Navigation cursor and geometry APIs
src/main/flight/flight_plan_nav.*
Adds deferred and active waypoint selection, shared target-delta calculation, and distance, bearing, and ETA accessors with documented sentinel values.
MAVLink mission cursor telemetry
src/main/telemetry/mavlink_mission.c
Centralizes MISSION_CURRENT generation, handles MISSION_SET_CURRENT, and preserves periodic mission telemetry updates.
CLI, OSD, and flight-plan status displays
src/main/cli/cli.c, src/main/cms/cms_menu_osd.c, src/main/osd/*
Displays navigation state, waypoint geometry, mission progress warnings, and configurable flight-plan OSD elements.
Mission integration tests and build wiring
src/test/Makefile, src/test/unit/*flight_plan_nav*, src/test/unit/*telemetry_mavlink_mission*
Adds unit coverage for waypoint selection, geometry, mission upload/download conversion, telemetry, injected plans, and cursor updates.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant GCS
  participant mavMissionHandleMessage
  participant flightPlanNavSetCurrentIndex
  participant sendMissionCurrent
  GCS->>mavMissionHandleMessage: Send MISSION_SET_CURRENT
  mavMissionHandleMessage->>flightPlanNavSetCurrentIndex: Update waypoint cursor
  mavMissionHandleMessage->>sendMissionCurrent: Build and send MISSION_CURRENT
  sendMissionCurrent->>GCS: Return mission cursor and state
Loading

Possibly related PRs

Suggested labels: RN: IMPROVEMENT

Suggested reviewers: haslinghuis, nerdcopter

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 8.20% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main autopilot changes: OSD waypoint elements, CLI mission status, and MAVLink SET_CURRENT.
Description check ✅ Passed The description covers the feature scope, linked issues, testing notes, and caveats well enough for this repository template.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends Betaflight’s flight-plan/autopilot feature set by adding user-facing mission progress surfaces (OSD + CLI), MAVLink mission control support (MISSION_SET_CURRENT), and corresponding host-side unit tests and documentation.

Changes:

  • Implemented OSD rendering for waypoint-related elements and added AUTOPILOT mission progress cues (“WP LANDING”, “WP COMPLETE”) to the warnings line.
  • Completed CLI waypoint status runtime reporting using shared flight-plan geometry accessors (distance/bearing/ETA).
  • Added MAVLink MISSION_SET_CURRENT handling plus a new unit test that exercises mission upload/download and progress reporting.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/test/unit/telemetry_mavlink_mission_unittest.cc New host unit test covering MAVLink mission round-trip and SET_CURRENT behavior
src/test/unit/flight_plan_nav_unittest.cc Adds unit tests for SET_CURRENT semantics and geometry accessors
src/test/Makefile Registers the new MAVLink mission unit test sources/defines; adjusts clang warning flags
src/main/telemetry/mavlink_mission.c Adds MISSION_SET_CURRENT handling and refactors MISSION_CURRENT sending
src/main/osd/osd_warnings.c Adds mission progress cues to OSD warnings when AUTOPILOT is active
src/main/osd/osd_elements.c Implements waypoint OSD elements (WP number/next/coords/alt/dist/dir/ETA)
src/main/flight/flight_plan_nav.h Exposes new nav geometry accessors and SET_CURRENT API contract
src/main/flight/flight_plan_nav.c Implements geometry accessors + SET_CURRENT behavior and idle start-index staging
src/main/cms/cms_menu_osd.c Exposes the waypoint OSD elements in the CMS OSD elements menu
src/main/cli/cli.c Completes waypoint status runtime section (state/cursor/distance/bearing/ETA/abort reason)
docs/flight_plan.md New documentation for flight plan/autopilot modes, CLI, MAVLink, safety, and OSD elements

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/main/osd/osd_elements.c
Comment thread src/main/telemetry/mavlink_mission.c
Comment thread src/main/cli/cli.c Outdated
Comment thread src/main/cli/cli.c Outdated
Comment thread src/main/flight/flight_plan_nav.h Outdated
…T_CURRENT + mission test

Wire the eight OSD_WP_* elements (draw functions, draw table, active-element
scan, CMS rows); their ids and CLI positions shipped earlier without rendering
code. Add flightPlanNavGetDistanceToWaypointM/BearingToWaypointDeciDeg/
EtaSeconds over the executor's existing target-distance computation, used by
the elements and the CLI waypoint status runtime section (was a stub).

Add WP LANDING and WP COMPLETE mission-progress cues to the OSD warnings line,
below every critical warning; the existing sanity-abort reasons stay.

Add MISSION_SET_CURRENT handling: flightPlanNavSetCurrentIndex re-dispatches to
the requested leg while flying and sets the engage start index while idle.

Cover the MAVLink mission round-trip with a host unit test (upload decode to the
PG plan, download encode, MISSION_ITEM_REACHED, MISSION_CURRENT, SET_CURRENT);
SITL builds no MAVLink telemetry, so this is the automated proof of that path.
@blckmn
blckmn force-pushed the feat/flight-plan-osd-mavlink-pr branch from 87256ad to 6628897 Compare July 14, 2026 11:18

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
docs/flight_plan.md (1)

51-59: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Specify a language for the fenced code block.

To resolve Markdown linting warnings and improve rendering, consider specifying text as the language for this CLI code block.

📝 Proposed fix
-```
+```text
 waypoint list
 waypoint status
 waypoint insert <idx> <lat.ddddddd> <lon.ddddddd> <alt_cm> <spd_cms> <type> <dur_ds> <pattern>
 waypoint update <idx> <lat.ddddddd> <lon.ddddddd> <alt_cm> <spd_cms> <type> <dur_ds> <pattern>
 waypoint remove <idx>
 waypoint clear
 save
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @docs/flight_plan.md around lines 51 - 59, Specify text as the language for
the fenced CLI command block containing the waypoint commands and save
instruction, changing the opening fence from an unannotated fence to a
text-language fence while preserving its contents.


</details>

<!-- cr-comment:v1:2a19fb97b3c610b0fb6e5f23 -->

_Source: Linters/SAST tools_

</blockquote></details>
<details>
<summary>src/test/unit/telemetry_mavlink_mission_unittest.cc (1)</summary><blockquote>

`225-227`: _📐 Maintainability & Code Quality_ | _🔵 Trivial_ | _💤 Low value_

**Positional struct literals for `flightPlanWaypoint_t` are fragile.**

`plan->waypoints[N] = { ... }` relies on 7 unnamed fields matching the struct's exact declaration order; a future field reorder in the struct definition would silently misassign values without a compile error. Designated initializers would make this self-documenting and reorder-safe.

<details>
<summary>♻️ Optional refactor using designated initializers</summary>

```diff
-    plan->waypoints[0] = { 100, 200, 1200, 0, 0, WAYPOINT_TYPE_TAKEOFF, WAYPOINT_PATTERN_NONE };
-    plan->waypoints[1] = { 300, 400, 2000, 0, 300 /* 30 s */, WAYPOINT_TYPE_HOLD, WAYPOINT_PATTERN_ORBIT };
-    plan->waypoints[2] = { 500, 600, 0, 0, 0, WAYPOINT_TYPE_LAND, WAYPOINT_PATTERN_NONE };
+    plan->waypoints[0] = { .latitude = 100, .longitude = 200, .altitude = 1200, .type = WAYPOINT_TYPE_TAKEOFF, .pattern = WAYPOINT_PATTERN_NONE };
+    plan->waypoints[1] = { .latitude = 300, .longitude = 400, .altitude = 2000, .duration = 300 /* 30 s */, .type = WAYPOINT_TYPE_HOLD, .pattern = WAYPOINT_PATTERN_ORBIT };
+    plan->waypoints[2] = { .latitude = 500, .longitude = 600, .type = WAYPOINT_TYPE_LAND, .pattern = WAYPOINT_PATTERN_NONE };

(Field names above are guesses — adjust to match the actual flightPlanWaypoint_t member names.)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/test/unit/telemetry_mavlink_mission_unittest.cc` around lines 225 - 227,
Replace the positional initializers assigned to plan->waypoints[0],
plan->waypoints[1], and plan->waypoints[2] with designated initializers using
the actual flightPlanWaypoint_t member names. Preserve all existing values and
comments while making each assignment independent of struct declaration order.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/main/flight/flight_plan_nav.c`:
- Around line 1074-1087: Update flightPlanNavGetEtaSeconds to use a strictly
horizontal 2D distance when calculating etaS, matching the existing ENU_E/ENU_N
horizontal speed; do not use distanceToNavTargetM if it includes altitude, and
preserve the current inactive-target, low-speed, saturation, and rounding
behavior.

In `@src/main/telemetry/mavlink_mission.c`:
- Around line 648-659: Update the MAVLINK_MSG_ID_MISSION_SET_CURRENT handling to
validate sc.seq before converting it to uint8_t. Reject or otherwise preserve
the existing no-op behavior for values above UINT8_MAX, and only call
flightPlanNavSetCurrentIndex with the unmodified value when it is representable.

---

Nitpick comments:
In `@docs/flight_plan.md`:
- Around line 51-59: Specify text as the language for the fenced CLI command
block containing the waypoint commands and save instruction, changing the
opening fence from an unannotated fence to a text-language fence while
preserving its contents.

In `@src/test/unit/telemetry_mavlink_mission_unittest.cc`:
- Around line 225-227: Replace the positional initializers assigned to
plan->waypoints[0], plan->waypoints[1], and plan->waypoints[2] with designated
initializers using the actual flightPlanWaypoint_t member names. Preserve all
existing values and comments while making each assignment independent of struct
declaration order.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a5c93702-6fed-4186-913a-5eb0da0239ec

📥 Commits

Reviewing files that changed from the base of the PR and between ebce860 and 87256ad.

📒 Files selected for processing (11)
  • docs/flight_plan.md
  • src/main/cli/cli.c
  • src/main/cms/cms_menu_osd.c
  • src/main/flight/flight_plan_nav.c
  • src/main/flight/flight_plan_nav.h
  • src/main/osd/osd_elements.c
  • src/main/osd/osd_warnings.c
  • src/main/telemetry/mavlink_mission.c
  • src/test/Makefile
  • src/test/unit/flight_plan_nav_unittest.cc
  • src/test/unit/telemetry_mavlink_mission_unittest.cc

Comment thread src/main/flight/flight_plan_nav.c
Comment thread src/main/telemetry/mavlink_mission.c

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
src/main/flight/flight_plan_nav.c (1)

1074-1087: ⚠️ Potential issue | 🟡 Minor

Dimensional mismatch in ETA calculation.

The ETA calculation divides distanceToNavTargetM(est) (which evaluates to a 3D slant distance when the command includes altitude) by a strictly 2D horizontal speed. For waypoints involving steep climbs or descents, this dimensional mismatch will drastically overestimate the ETA.

Consider calculating a strictly 2D horizontal distance to divide by the 2D horizontal speed.

💡 Proposed fix
 uint16_t flightPlanNavGetEtaSeconds(void)
 {
     if (!fp.active || !positionNavHasActiveTarget()) {
         return 0;
     }
     const positionEstimate3d_t *est = positionEstimatorGetEstimate();
     const float speedMps = sqrtf(sq(est->velocity.v[ENU_E]) + sq(est->velocity.v[ENU_N])) * 0.01f;
     if (speedMps < 0.5f) {
         return 0;
     }
-    const float etaS = distanceToNavTargetM(est) / speedMps;
+    vector3_t deltaM;
+    navTargetDeltaEnuM(est, &deltaM);
+    const float distance2dM = sqrtf(sq(deltaM.v[ENU_E]) + sq(deltaM.v[ENU_N]));
+    const float etaS = distance2dM / speedMps;
     return (etaS >= (float)UINT16_MAX) ? UINT16_MAX : (uint16_t)lrintf(etaS);
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/flight/flight_plan_nav.c` around lines 1074 - 1087, Update
flightPlanNavGetEtaSeconds to calculate ETA using a strictly 2D horizontal
distance that matches the existing ENU horizontal speed, rather than
distanceToNavTargetM(est) when altitude contributes a slant distance. Preserve
the current inactive-target, low-speed, saturation, and rounding behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@src/main/flight/flight_plan_nav.c`:
- Around line 1074-1087: Update flightPlanNavGetEtaSeconds to calculate ETA
using a strictly 2D horizontal distance that matches the existing ENU horizontal
speed, rather than distanceToNavTargetM(est) when altitude contributes a slant
distance. Preserve the current inactive-target, low-speed, saturation, and
rounding behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: c4dcb206-3ff8-4c55-9c56-1491274338ec

📥 Commits

Reviewing files that changed from the base of the PR and between 87256ad and 6628897.

📒 Files selected for processing (10)
  • src/main/cli/cli.c
  • src/main/cms/cms_menu_osd.c
  • src/main/flight/flight_plan_nav.c
  • src/main/flight/flight_plan_nav.h
  • src/main/osd/osd_elements.c
  • src/main/osd/osd_warnings.c
  • src/main/telemetry/mavlink_mission.c
  • src/test/Makefile
  • src/test/unit/flight_plan_nav_unittest.cc
  • src/test/unit/telemetry_mavlink_mission_unittest.cc
🚧 Files skipped from review as they are similar to previous changes (9)
  • src/main/cms/cms_menu_osd.c
  • src/main/osd/osd_warnings.c
  • src/test/unit/flight_plan_nav_unittest.cc
  • src/test/unit/telemetry_mavlink_mission_unittest.cc
  • src/test/Makefile
  • src/main/cli/cli.c
  • src/main/telemetry/mavlink_mission.c
  • src/main/flight/flight_plan_nav.h
  • src/main/osd/osd_elements.c

@blckmn
blckmn merged commit 6e9b7fd into betaflight:master Jul 17, 2026
53 checks passed
@github-project-automation github-project-automation Bot moved this to Done in 2026.6.0 Jul 17, 2026
@blckmn
blckmn deleted the feat/flight-plan-osd-mavlink-pr branch July 17, 2026 08:18
gwlim pushed a commit to gwlim/betaflight that referenced this pull request Jul 25, 2026
…RENT (betaflight#15416)

* Flight plan: OSD waypoint elements + warnings, CLI status, MAVLink SET_CURRENT + mission test

Wire the eight OSD_WP_* elements (draw functions, draw table, active-element
scan, CMS rows); their ids and CLI positions shipped earlier without rendering
code. Add flightPlanNavGetDistanceToWaypointM/BearingToWaypointDeciDeg/
EtaSeconds over the executor's existing target-distance computation, used by
the elements and the CLI waypoint status runtime section (was a stub).

Add WP LANDING and WP COMPLETE mission-progress cues to the OSD warnings line,
below every critical warning; the existing sanity-abort reasons stay.

Add MISSION_SET_CURRENT handling: flightPlanNavSetCurrentIndex re-dispatches to
the requested leg while flying and sets the engage start index while idle.

Cover the MAVLink mission round-trip with a host unit test (upload decode to the
PG plan, download encode, MISSION_ITEM_REACHED, MISSION_CURRENT, SET_CURRENT);
SITL builds no MAVLink telemetry, so this is the automated proof of that path.

* Address PR review: WP element guard, SET_CURRENT range check, CLI status formatting, 2D ETA
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants