Repository navigation
Plan: add an ALL mission type to edit mission, fence and rally items … - #3780
Autonomost wants to merge 10 commits into
Conversation
…together The mission type dropdown on the Plan screen gains an ALL entry. In that mode the single command grid holds mission, fence and rally items at once; a row's type follows its command (RALLY_POINT, FENCE_* or anything else), so no extra columns are needed. The map draws all three sets in one overlay with type-aware midline handles, and the fence polygon tools work in this mode. Read and Write open a small picker (Mission / Fence / Rally, all ticked by default) so one click transfers everything or any subset. Reading a subset keeps the grid rows of the types that were not fetched. Uploads go in mission, fence, rally order; a type the vehicle rejects (for example fence items on old firmware) is reported without aborting the rest. The MAVFTP download path now updates the cache matching the item type instead of always writing the mission cache.
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved critical and moderate issues affect mixed-item handling and transfers.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
Adds an ALL mission type combining mission, fence, and rally items in Flight Planner.
Changes:
- Adds unified editing and type-aware map rendering.
- Adds selective Mission/Fence/Rally read and write support.
- Updates MAVFTP caching by item type.
File summaries
| File | Summary |
|---|---|
GCSViews/FlightPlanner.cs |
Implements ALL-mode planning, transfers, rendering, and cache updates. |
Controls/MissionTypePicker.cs |
Adds the Mission/Fence/Rally selection dialog. |
Review details
Suppressed comments (3)
GCSViews/FlightPlanner.cs:722
- After a subset is selected here, the existing confirmation below still says the read will clear all existing points, while
getWPs(sender, types)deliberately preserves rows whose types were not fetched. The prompt is false for the new partial-read flow and can make users cancel a safe refresh; make it conditional on all types being selected or change its wording.
types = MissionTypePicker.Show(this, "Read");
if (types == null || types.Count == 0)
return;
GCSViews/FlightPlanner.cs:8006
- This infers the midline type from the physical row immediately before
pnt2, but ALL-mode mission midlines are built after fence/rally points are filtered out. A mission edge can therefore span fence rows; dragging it sees a fence vertex atpnt2 - 2and inserts/recalculates a fence command instead of a mission waypoint. Determine the type from the midline's tagged endpoints or attach the type when creating the marker.
if (midtype == MAVLink.MAV_MISSION_TYPE.ALL)
midtype = IsFencePolygonVertexRow(pnt2 - 2)
? MAVLink.MAV_MISSION_TYPE.FENCE
: MAVLink.MAV_MISSION_TYPE.MISSION;
GCSViews/FlightPlanner.cs:850
- The picker is shown only after the preflight loop above validates every grid row. In ALL mode, choosing only one type still fails on an invalid number or zero-altitude warning in an unselected fence/rally row, so the new subset write cannot ignore that type. Select the types before validation or limit validation to rows whose command type is selected.
types = MissionTypePicker.Show(this, "Write", counts);
- Files reviewed: 2/2 changed files
- Comments generated: 5
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
- Classify FENCE_HOME_CIRCLE_INCLUSION (legacy home centred fence) as a fence item so it is not uploaded as a mission command. - Reading a subset of types now says it replaces only those types instead of claiming all points will be cleared. - Ask which types to write before checking the grid, and only apply the altitude checks to rows of a type that is being sent. - Distance, gradient and bearing are computed from a mission-only list in ALL mode, so mission legs no longer span fence or rally rows and those rows are left alone. - Dragging a mission midline takes its type from the row it starts at rather than the physical row before its end, which could be a fence vertex in ALL mode. - Insert the home sentinel when the downloaded mission is empty, not only when the mission was not refreshed, so the first fence or rally row is not stripped as home. - When several types are written, a type the vehicle rejects is logged and the remaining types are still sent; the failures are reported together at the end. A single type fails as before. - MissionTypePicker takes its captions from Strings.resx so the dialog is translated like the rest of the planner.
Autonomost
left a comment
There was a problem hiding this comment.
Made the changes as requested.
|
@meee1 this should be good to go now |
There was a problem hiding this comment.
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Copilot review overview
Review effort: Lite
Findings: 6
Open (7)
SelectedMissionType only checks SelectedValue, but ComboBox data-binding can yield enums via… · New These new/modified user-facing strings are hardcoded (prompt) and the partial read/write failures… · New In ALL mode, UNKNOWN rows are treated assendingunconditionally, which can cause validation… · New In ALL mode, UNKNOWN rows are treated assendingunconditionally, which can cause validation… · New These new/modified user-facing strings are hardcoded (prompt) and the partial read/write failures… · New These new/modified user-facing strings are hardcoded (prompt) and the partial read/write failures… · Newusing System.Drawing;is unused in this file. Removing it avoids unnecessary dependencies and… · New
Resolved since last review (5)
ALL-modeprocessToScreenalways removes the first item as the mission home. If a successful… EveryUploadMissionItemsexception escapes the outertry, so a rejected or unsupported type… In ALL modewpOverlay.pointlistcontains mission, fence, and rally points, but…FENCE_HOME_CIRCLE_INCLUSION(MAV_CMD 5005) is also a fence mission item, but this classifier… This new WinForms dialog hardcodes all user-visible text (Read,Write,Cancel,Mission,…
Files not reviewed (1)
- ExtLibs/Strings/Strings.Designer.cs: Generated file
Brings the 32-bit system id work (e6454cc, 0077a89, 1517bce) so the branch merges cleanly again. Stops short of ae8c290, whose regenerated Mavlink.cs does not compile. Conflict: upstream dropped the (byte) cast on sysidcurrent in the item upload code, which this branch had moved into UploadMissionItems; the cast is dropped there instead.
- The confirmation prompt, the ALL mode hint and the two "some items could not be read / sent" messages come from Strings.resx like the picker's text, and the per-type failures use the picker's localized type names. - Before a write, a row's item type comes from MissionTypeOfRow, which reads an UNKNOWN row's command id from the Command cell's Tag the way the upload does. An UNKNOWN row of a type the user did not select is no longer validated (it used to count as being sent, so its zero altitude check could block a fence-only or rally-only write). - MissionTypePicker drops an unused using.
Found by a review pass over the whole PR before pushing: - Switching the dropdown to ALL with no mission cached deleted the first fence or rally row, because processToScreen strips row 0 as home. GetAllCachedItems now puts a placeholder in front in that case, the same one getWPs uses; it sits at 0, 0 so the "Reset Home" prompt cannot fire on it. - Dropping the first mission midline (home to waypoint 1) inserted a fence vertex whenever the row above the first waypoint was a fence vertex. The midline marker now carries the type of leg it was drawn on (writeKML: mission, addFenceMidlines: fence) and the drop uses that; the row inference and IsFencePolygonVertexRow are gone. - The Write picker ticks only the types that have rows, so a mission-only plan no longer sends an empty fence and rally, which cleared them on the vehicle. - Automatic reads (after a guided upload, on connect, from a plugin) fetch the mission only, as before ALL existed: no picker, and no fence or rally download that fails on older firmware. A full ALL read no longer parses the grid first, so a half edited cell cannot stop it; a partial read still keeps the rows of the types it does not fetch. - Home is read back once after a write instead of once per type, and the terrain prefetch covers home and the mission legs that were sent instead of every grid row. A MAVFTP upload now updates the vehicle side cache like the item by item path does, so switching the dropdown afterwards shows what was sent. - The pointlist the KML server and the 3D view read holds the mission legs only. - "Some items could not be read / sent" is shown as the message itself rather than as an unexpected error with a stack trace, and saveWPs releases giveComport in a finally. - Progress text uses the localized type names on read and write, MAVFTP's -1 progress passes through unscaled, the write validation reuses the parsed grid instead of re-reading the Command cells, the remaining raw dropdown casts use SelectedMissionType, ReCalcFence uses IsFencePolygonVertex, and the Strings.Designer comment for AllModeHint has the full text.
|
Three commits since the last review:
Built on Windows (MissionPlanner.csproj, Release). The |
A read or write of several item types carried on after any failure. That suits a vehicle that refuses a type, such as fence items it does not support, but not one that stopped answering: every remaining type waited out the same timeouts, and a write could start the next transfer while the vehicle was still inside the one that timed out. The mission protocol throws TimeoutException when its retries run out and a plain exception for a refusal, so a timeout now ends the read or write, and the message names the types that were skipped. A refusal still moves on to the next type. With MAVFTP on, a write went through MAVFtp.UploadFile, which ignores the results of its create and write steps. A vehicle that did not answer therefore looked like a finished upload: the write reported success and never fell back to sending the items one by one. The upload now runs those steps itself and falls back when they get no reply, so a silent vehicle ends in a timeout and one without MAVFTP still receives the items. A session reset with no answer already means no MAVFTP, so the file steps, which wait about 30 s each, are skipped then. A read already fell back when the open got no reply, by way of a null reference; that case is now handled explicitly. The three @mission paths are in one helper used by both directions, and the partial result message is built in one place.
|
One more commit, 05dc47f, from a last look at how ALL mode behaves when the vehicle stops answering:
Built on Windows (MissionPlanner.csproj, Release). In our fork a test runs the upload against a simulated vehicle that keeps sending heartbeats but answers nothing: it now ends in a timeout after about 8 s instead of reporting success. Not yet tried on a real vehicle. |
Switching the mission type dropdown loaded the new type from the vehicle's copy and threw the grid away, so rally points dropped in RALLY mode were gone after a look at the mission, and rows edited in ALL mode were lost on the way to any single type. The grid's rows are now kept per type when the dropdown leaves a type (all three types apart when it leaves ALL), and a type that has been shown comes back as it was, sent to the vehicle or not. A type never shown still comes from the vehicle's copy, and a read or a file load replaces what is shown as before. ALL joins the kept or cached parts in its usual order, with the home placeholder in front when there is no mission.
The dropdown's first event fires while the page is being built, and it kept the empty grid as an empty mission list, which came back as a lone home placeholder. processToScreen with a non-empty list calls Invoke, which throws before the page has a handle; the ComboBox data binding swallowed the exception, so the placeholder row stayed in the grid and quickadd was left set. Kept rows that are empty now stay empty (nothing to strip, so no placeholder), and ALL with nothing to show is empty too, which is the path the page took before rows were kept.
|
Two more commits: switching the dropdown no longer throws the grid away.
The keep/show helpers behind the dropdown handler are covered by unit tests in my fork: rows kept per type, the home placeholder in front of kept mission rows and none when they are empty, the ALL split and join, a type never shown coming from the vehicle's copy, and a new page starting with an empty grid. @meee1 could you take another look? |
|
@meee1 any chance you can merge this in? |



…together
The mission type dropdown on the Plan screen gains an ALL entry. In that mode the single command grid holds mission, fence and rally items at once; a row's type follows its command (RALLY_POINT, FENCE_* or anything else), so no extra columns are needed. The map draws all three sets in one overlay with type-aware midline handles, and the fence polygon tools work in this mode.
Read and Write open a small picker (Mission / Fence / Rally, all ticked by default) so one click transfers everything or any subset. Reading a subset keeps the grid rows of the types that were not fetched. Uploads go in mission, fence, rally order; a type the vehicle rejects (for example fence items on old firmware) is reported without aborting the rest.
The MAVFTP download path now updates the cache matching the item type instead of always writing the mission cache.