You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
add an Analyze > MAVLink Bandwidth tool for QGC-to-vehicle and vehicle-to-QGC throughput tests
add a stock MAVFTP backend for PX4 and ArduPilot that sequentially measures upload and download, reports each direction separately, verifies data with SHA-256, and automatically cleans up
make MAVFTP cancellation restart-safe, including cancellation before the initial remote session is established
retain a controlled-rate Streaming backend for ArduPilot using standard MAVLink 2 TUNNEL messages
embed the ArduPilot Lua endpoint in QGC and provide an ArduPilot-only action that replaces the script through MAVFTP and reboots after a successful upload
show the Lua streaming option only while an ArduPilot vehicle is connected; PX4 and disconnected states expose only MAVFTP
report payload goodput and total selected-link traffic; streaming mode also reports packet loss, reordering, and send backpressure
add protocol, deployment, firmware-switch, and PX4-flavored MAVFTP integration coverage, documentation, and screenshots
Motivation
Link baud rate and passive traffic counters do not show how much additional MAVLink traffic an operational QGC/autopilot path can deliver. This tool applies controlled traffic and reports end-to-end application goodput without requiring firmware source changes or a custom MAVLink dialect.
The measurement intentionally does not claim raw RF bitrate. MAVFTP results include reliable-transfer and storage overhead; streaming results include QGC, the selected link, ArduPilot MAVLink queues, and the Lua scheduler.
Usage
Stock PX4 or ArduPilot
Connect a disarmed vehicle and open Analyze > MAVLink Bandwidth.
Select MAVFTP (PX4 or ArduPilot).
Select the test-file size, then start the test.
No vehicle-side installation is required. QGC measures the upload and then downloads the same file, reporting separate payload and selected-link rates for each direction. The download verifies the uploaded data with SHA-256. Temporary files use randomized names under /fs/microsd on PX4 or /APM on ArduPilot and are removed automatically.
ArduPilot streaming
Enable ArduPilot scripting for a supported board and connect it while disarmed.
Select Install Lua Script and Reboot. QGC removes an older copy if present, uploads its embedded endpoint to /APM/scripts/mavlink_bandwidth.lua, and requests reboot only after the upload succeeds.
After the vehicle reconnects, select Streaming (ArduPilot Lua) and probe the endpoint.
Select a direction, rate, and duration, then start the test.
The install action and streaming choice appear only for ArduPilot. Streaming tests are capped at 2 Mbit/s and 60 seconds. All tests are disarmed-only and abort if the vehicle arms, the active vehicle changes, or the primary link changes.
the PX4 MockLink full MAVFTP test completed upload, download, verification, and cleanup
start, immediate stop, and restart completed without stale MAVFTP session state
firmware switching exposes streaming only for ArduPilot
the embedded Lua resource exactly matches the bytes uploaded to /APM/scripts/mavlink_bandwidth.lua, followed by an accepted reboot/disconnect
all four focused tests passed
physical CubePilot/ArduPilot MAVFTP upload over USB:
1 MiB completed and verified
95.4 kbit/s payload goodput
106.7 kbit/s total link transmit traffic and 34.6 kbit/s total link receive traffic
ctest --test-dir build --output-on-failure -L Unit
213/214 passed
the unrelated BluetoothWorkerTest fails locally because BlueZ emits environment-dependent invalid-address/device-powered-off warnings
focused qmllint, clang-format --dry-run --Werror, and luac5.4 -p
focused Q_ASSERT, categorized-logging, vehicle-null, fixed-wait, and typo pre-commit guards
isolated ArduPlane SITL streaming validation:
MAVLink 2 TUNNEL handshake passed
QGC-to-vehicle smoke: 60 packets received
vehicle-to-QGC smoke: 149 packets received
interactive QGC/ArduPlane SITL streaming run at 100 kbit/s completed with zero reported packet loss
The full local just lint sweep remains blocked by unrelated environment/baseline issues: the installed Node 18 cannot install markdownlint-cli requiring Node 22, the local Vale hook cannot enable Go VCS stamping in this sandbox, and existing repository files fail full-file format/mode hooks.
⚠️Build results unavailable — artifact download from one or more platform workflows failed (likely artifact retention expiry or transient API error). The combined report cannot be generated for this run.
Follow-up f1168a04a fixes a start → immediate stop → start MAVFTP race found during hardware testing. If cancellation happened before CreateFile returned its session ID, QGC completed locally without resetting vehicle-side MAVFTP sessions; a late CreateFile could leave the next upload failing with Fail. Early cancellation now resets remote sessions first, cleanup treats an already-absent temporary file as success, and MAVLinkBandwidthControllerTest covers the complete stop/restart sequence. just build and the focused controller/protocol/FTP manager tests pass.
Follow-up 117869c15 simplifies MAVFTP into one full test: measured upload followed by measured download of the same file, with separate live/final rates for both directions and one SHA-256 verification/cleanup pass. The direction selector now applies only to ArduPilot streaming mode. Focused build, controller/protocol, and FTP regression gates pass.
Follow-up 0d4a6b044 makes the test-mode list firmware-aware. PX4 and disconnected states expose only stock MAVFTP; connecting ArduPilot adds the Lua streaming option and selects it by default. The new firmware-switch regression and all focused bandwidth/FTP tests pass.
Follow-up 998f2d641 embeds the ArduPilot Lua endpoint and adds an ArduPilot-only Install Lua Script and Reboot action. It safely removes an older copy, uploads the exact embedded resource with progress, handles vehicle/link/arming cancellation, and requests reboot only after success. The integration test verifies byte-for-byte deployment and the resulting reboot disconnect.
Cleanup 3b17062e4 moves the embedded Lua source beside the MAVLink Bandwidth implementation and removes the extra tools bundle, README, screenshots, and SITL params. PR screenshots now use immutable historical commit URLs so they remain visible without shipping those assets.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
TUNNELmessagesMotivation
Link baud rate and passive traffic counters do not show how much additional MAVLink traffic an operational QGC/autopilot path can deliver. This tool applies controlled traffic and reports end-to-end application goodput without requiring firmware source changes or a custom MAVLink dialect.
The measurement intentionally does not claim raw RF bitrate. MAVFTP results include reliable-transfer and storage overhead; streaming results include QGC, the selected link, ArduPilot MAVLink queues, and the Lua scheduler.
Usage
Stock PX4 or ArduPilot
No vehicle-side installation is required. QGC measures the upload and then downloads the same file, reporting separate payload and selected-link rates for each direction. The download verifies the uploaded data with SHA-256. Temporary files use randomized names under
/fs/microsdon PX4 or/APMon ArduPilot and are removed automatically.ArduPilot streaming
/APM/scripts/mavlink_bandwidth.lua, and requests reboot only after the upload succeeds.The install action and streaming choice appear only for ArduPilot. Streaming tests are capped at 2 Mbit/s and 60 seconds. All tests are disarmed-only and abort if the vehicle arms, the active vehicle changes, or the primary link changes.
Screenshots
Streaming mode
MAVFTP mode on a CubePilot
Validation
just buildctest --test-dir build --output-on-failure -R '^(MAVLinkBandwidthControllerTest|MAVLinkBandwidthProtocolTest|FTPControllerTest|FTPManagerTest)$'/APM/scripts/mavlink_bandwidth.lua, followed by an accepted reboot/disconnectctest --test-dir build --output-on-failure -L UnitBluetoothWorkerTestfails locally because BlueZ emits environment-dependent invalid-address/device-powered-off warningsqmllint,clang-format --dry-run --Werror, andluac5.4 -pTUNNELhandshake passedThe full local
just lintsweep remains blocked by unrelated environment/baseline issues: the installed Node 18 cannot installmarkdownlint-clirequiring Node 22, the local Vale hook cannot enable Go VCS stamping in this sandbox, and existing repository files fail full-file format/mode hooks.