Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PlanManager: Increase Timeouts for Mission Transfer #12184

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

menschel
Copy link

@menschel menschel commented Dec 9, 2024

PlanManager: Increase Timeouts for Mission Transfer

Description

This patch fixes runtime issues with Mission Upload/Download when the vehicle connection is based on a 900MHz ELRS System. (See Mavlink via ELRS feature.)

Two timeouts in PlanManager are increased.

The initial timeout is increased to cope with a delay when writing a Mission to the Flight Controller,
i.e. the Flight Controller needs some time to process Way-Points, Fences, Rally-Points etc. and this is enough to trigger the previously used timeout value. It is observed when initially starting the Mission Upload and when consecutively Fences and Rally-Points are written, regardless if there are any to be written.

The repeat timeout is increased to counter mix-up of requests resulting in sequence errors, i.e. when downloading the mission from the remote vehicle, QGroundControl already requested the item X+1 when the delayed response to this item X is received.

Test Steps

Test requires a PC or an arbitrary device running QGroundControl,
a 900MHz ELRS System running the Mavlink Connection and a Flight Controller with Ardupilot.

  • Prepare the PC and enable an Access-Point for the ELRS backpack to connect to.
  • Switch on the ELRS TX System and connect the ELRS BackPack to the Access-Point.
  • Switch on the Flight Controller together with the ELRS RX System.
  • Start QGroundControl.
  • Watch QGroundControl connect to the remote vehicle and progress past the Mission Download (validates the repeat timeout).
  • Go to Mission Plan, create a random mission and upload to remote vehicle. Mission Upload does complete without error (validates the initial timeout).

ELRS Hardware is somewhat standardized, so it should not matter what Manufacturer is used.
I use a Radiomaster TX12MK2 Handset together with a Radiomaster Bandit Transmitter and a BetaFPV SuperD Receiver.

Checklist:

Related Issue

Fixes #12076

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@@ -68,9 +68,9 @@ class PlanManager : public QObject

// These values are public so the unit test can set appropriate signal wait times
// When passively waiting for a mission process, use a longer timeout.
static const int _ackTimeoutMilliseconds = 1500;
static const int _ackTimeoutMilliseconds = 2500;
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems super long. This would only take affect on things like a go to location command. Are you sure this is needed? For mission download only the retry timeout comes into play.

Copy link
Author

Choose a reason for hiding this comment

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

Correct, the retry timeout was causing the issues on initial connect and mission download from vehicle to ground station.

The regular timeout hits when uploading a mission from ground station to the vehicle.
I'm not familiar with the sequence but there seems to be the situation where the vehicle should ask the ground station for the mission items and this ends up in this error.

_sendError(ProtocolError, tr("Vehicle did not request all items from ground station: %1").arg(_ackTypeToString(_expectedAck)));
https://github.com/mavlink/qgroundcontrol/blob/master/src/MissionManager/PlanManager.cc#L220

I'll attach a log once I figure out why I don't get any logging if I build Release Goal.

Copy link
Author

Choose a reason for hiding this comment

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

I had to build in debug goal to get logging again. This is the section when uploading mission to vehicle without touching the regular timeout.

PlanMasterControllerLog: PlanMasterController::sendToVehicle start mission sendToVehicle
MissionControllerLog: MissionControllerLog::sendToVehicle
MissionControllerLog: _convertToMissionItems seqNum:lastSeqNum:command 0 0 "Mission Start"
MissionControllerLog: _convertToMissionItems seqNum:lastSeqNum:command 1 1 "Takeoff"
MissionControllerLog: _convertToMissionItems seqNum:lastSeqNum:command 2 2 "Waypoint"
MissionControllerLog: _convertToMissionItems seqNum:lastSeqNum:command 3 3 "Waypoint"
MissionControllerLog: _convertToMissionItems seqNum:lastSeqNum:command 4 4 "Waypoint"
MissionControllerLog: _convertToMissionItems seqNum:lastSeqNum:command 5 5 "Waypoint"
MissionControllerLog: _convertToMissionItems seqNum:lastSeqNum:command 6 8 "Landing Pattern"
PlanManagerLog: "writeMissionItems T:Mission count:" 9
PlanManagerLog: _setTransactionInProgress "T:Mission" 2
PlanManagerLog: "_writeMissionCount T:Mission count:_retryCount" 9 0
PlanManagerLog: "Retrying T:Mission MISSION_COUNT retry Count" 1
PlanManagerLog: "_writeMissionCount T:Mission count:_retryCount" 9 1
PlanManagerLog: "_handleMissionRequest T:Mission sequenceNumber" 0
PlanManagerLog: "_handleMissionRequest T:Mission sequenceNumber:command" 0 16
PlanManagerLog: "_handleMissionRequest T:Mission sequenceNumber" 0
PlanManagerLog: "_handleMissionRequest T:Mission sequence number requested which has already been sent, sending again:" 0
PlanManagerLog: "_handleMissionRequest T:Mission sequenceNumber:command" 0 16
PlanManagerLog: "_handleMissionRequest T:Mission sequenceNumber" 1
PlanManagerLog: "_handleMissionRequest T:Mission sequenceNumber:command" 1 22
QString::arg: Argument missing: _handleMissionAck ArduPilot sending possibly bogus MAV_MISSION_INVALID_SEQUENCE, T:Mission
PlanManagerLog: "_handleMissionAck ArduPilot sending possibly bogus MAV_MISSION_INVALID_SEQUENCE" 0
PlanManagerLog: "_handleMissionRequest T:Mission sequenceNumber" 2
PlanManagerLog: "_handleMissionRequest T:Mission sequenceNumber:command" 2 16
PlanManagerLog: "_handleMissionRequest T:Mission sequenceNumber" 2
PlanManagerLog: "_handleMissionRequest T:Mission sequence number requested which has already been sent, sending again:" 2
PlanManagerLog: "_handleMissionRequest T:Mission sequenceNumber:command" 2 16
PlanManagerLog: "_handleMissionRequest T:Mission sequenceNumber" 3
PlanManagerLog: "_handleMissionRequest T:Mission sequenceNumber:command" 3 16
PlanManagerLog: "_handleMissionRequest T:Mission sequenceNumber" 3
PlanManagerLog: "_handleMissionRequest T:Mission sequence number requested which has already been sent, sending again:" 3
PlanManagerLog: "_handleMissionRequest T:Mission sequenceNumber:command" 3 16
QString::arg: Argument missing: _handleMissionAck ArduPilot sending possibly bogus MAV_MISSION_INVALID_SEQUENCE, T:Mission
PlanManagerLog: "_handleMissionAck ArduPilot sending possibly bogus MAV_MISSION_INVALID_SEQUENCE" 0
PlanManagerLog: "_handleMissionRequest T:Mission sequenceNumber" 4
PlanManagerLog: "_handleMissionRequest T:Mission sequenceNumber:command" 4 16
QString::arg: Argument missing: _handleMissionAck ArduPilot sending possibly bogus MAV_MISSION_INVALID_SEQUENCE, T:Mission
PlanManagerLog: "_handleMissionAck ArduPilot sending possibly bogus MAV_MISSION_INVALID_SEQUENCE" 0
PlanManagerLog: "_handleMissionRequest T:Mission sequenceNumber" 4
PlanManagerLog: "_handleMissionRequest T:Mission sequence number requested which has already been sent, sending again:" 4
PlanManagerLog: "_handleMissionRequest T:Mission sequenceNumber:command" 4 16
PlanManagerLog: "_handleMissionRequest T:Mission sequenceNumber" 5
PlanManagerLog: "_handleMissionRequest T:Mission sequenceNumber:command" 5 16
QString::arg: Argument missing: _handleMissionAck ArduPilot sending possibly bogus MAV_MISSION_INVALID_SEQUENCE, T:Mission
PlanManagerLog: "_handleMissionAck ArduPilot sending possibly bogus MAV_MISSION_INVALID_SEQUENCE" 0
PlanManagerLog: "_handleMissionRequest T:Mission sequenceNumber" 5
PlanManagerLog: "_handleMissionRequest T:Mission sequence number requested which has already been sent, sending again:" 5
PlanManagerLog: "_handleMissionRequest T:Mission sequenceNumber:command" 5 16
PlanManagerLog: "_handleMissionRequest T:Mission sequenceNumber" 6
PlanManagerLog: "_handleMissionRequest T:Mission sequenceNumber:command" 6 189
QString::arg: Argument missing: _handleMissionAck ArduPilot sending possibly bogus MAV_MISSION_INVALID_SEQUENCE, T:Mission
PlanManagerLog: "_handleMissionAck ArduPilot sending possibly bogus MAV_MISSION_INVALID_SEQUENCE" 0
PlanManagerLog: "_handleMissionRequest T:Mission sequenceNumber" 7
PlanManagerLog: "_handleMissionRequest T:Mission sequenceNumber:command" 7 31
PlanManagerLog: "Sending error - _planTypeString(T:Mission) errorCode(2) errorMsg(Vehicle did not request all items from ground station: MISSION_REQUEST)"
PlanManagerLog: _setTransactionInProgress "T:Mission" 0
PlanMasterControllerLog: PlanMasterController::sendToVehicle start GeoFence sendToVehicle
PlanManagerLog: "writeMissionItems T:GeoFence count:" 0
PlanManagerLog: _setTransactionInProgress "T:GeoFence" 2
PlanManagerLog: "_writeMissionCount T:GeoFence count:_retryCount" 0 0
PlanManagerLog: "_handleMissionRequest T:GeoFence Incorrect mission_type received expected:actual" 1 0
PlanManagerLog: "_handleMissionRequest T:GeoFence Incorrect mission_type received expected:actual" 1 0
PlanManagerLog: "_handleMissionAck T:GeoFence type:" "Mission accepted."
PlanManagerLog: "_handleMissionAck write sequence complete T:GeoFence"
PlanManagerLog: _setTransactionInProgress "T:GeoFence" 0
PlanMasterControllerLog: PlanMasterController::sendToVehicle start rally sendToVehicle
PlanManagerLog: "writeMissionItems T:Rally count:" 0
PlanManagerLog: _setTransactionInProgress "T:Rally" 2
PlanManagerLog: "_writeMissionCount T:Rally count:_retryCount" 0 0
PlanManagerLog: "_handleMissionAck T:Rally type:" "Mission accepted."
PlanManagerLog: "_handleMissionAck write sequence complete T:Rally"
PlanManagerLog: _setTransactionInProgress "T:Rally" 0
PlanMasterControllerLog: PlanMasterController::sendToVehicle Rally Point send complete
PlanMasterControllerLog: PlanMasterController::sendToVehicle Rally Point send complete
PlanMasterControllerLog: PlanMasterController::sendToVehicle Rally Point send complete
PlanMasterControllerLog: PlanMasterController::sendToVehicle start mission sendToVehicle
MissionControllerLog: MissionControllerLog::sendToVehicle
MissionControllerLog: _convertToMissionItems seqNum:lastSeqNum:command 0 0 "Mission Start"
MissionControllerLog: _convertToMissionItems seqNum:lastSeqNum:command 1 1 "Takeoff"
MissionControllerLog: _convertToMissionItems seqNum:lastSeqNum:command 2 2 "Waypoint"
MissionControllerLog: _convertToMissionItems seqNum:lastSeqNum:command 3 3 "Waypoint"
MissionControllerLog: _convertToMissionItems seqNum:lastSeqNum:command 4 4 "Waypoint"
MissionControllerLog: _convertToMissionItems seqNum:lastSeqNum:command 5 5 "Waypoint"
MissionControllerLog: _convertToMissionItems seqNum:lastSeqNum:command 6 8 "Landing Pattern"
PlanManagerLog: "writeMissionItems T:Mission count:" 9
PlanManagerLog: _setTransactionInProgress "T:Mission" 2
PlanManagerLog: "_writeMissionCount T:Mission count:_retryCount" 9 0
PlanManagerLog: "_handleMissionRequest T:Mission sequenceNumber" 8
PlanManagerLog: "_handleMissionRequest T:Mission sequenceNumber:command" 8 21
PlanManagerLog: "Fell off end of switch statement T:Mission 15"
PlanManagerLog: "_handleMissionAck T:Mission type:" "Unknown error: 15. Item #8 Command: Land"
PlanManagerLog: "Fell off end of switch statement T:Mission 15"
PlanManagerLog: "Sending error - _planTypeString(T:Mission) errorCode(5) errorMsg(Unknown error: 15. Item #8 Command: Land)"
PlanManagerLog: _setTransactionInProgress "T:Mission" 0
PlanMasterControllerLog: PlanMasterController::sendToVehicle start GeoFence sendToVehicle
PlanManagerLog: "writeMissionItems T:GeoFence count:" 0
PlanManagerLog: _setTransactionInProgress "T:GeoFence" 2
PlanManagerLog: "_writeMissionCount T:GeoFence count:_retryCount" 0 0
PlanManagerLog: "Sending error - _planTypeString(T:GeoFence) errorCode(2) errorMsg(Mission write failed, vehicle failed to send final ack.)"
PlanManagerLog: _setTransactionInProgress "T:GeoFence" 0
PlanMasterControllerLog: PlanMasterController::sendToVehicle start rally sendToVehicle
PlanManagerLog: "writeMissionItems T:Rally count:" 0
PlanManagerLog: _setTransactionInProgress "T:Rally" 2
PlanManagerLog: "_writeMissionCount T:Rally count:_retryCount" 0 0
PlanManagerLog: "_handleMissionRequest T:Rally Incorrect mission_type received expected:actual" 2 0
PlanManagerLog: "_handleMissionAck T:Rally Incorrect mission_type received expected:actual" 2 0
PlanManagerLog: "_handleMissionAck T:Rally Incorrect mission_type received expected:actual" 2 1
PlanManagerLog: "_handleMissionAck T:Rally type:" "Mission accepted."
PlanManagerLog: "_handleMissionAck write sequence complete T:Rally"
PlanManagerLog: _setTransactionInProgress "T:Rally" 0
PlanMasterControllerLog: PlanMasterController::sendToVehicle Rally Point send complete
PlanMasterControllerLog: PlanMasterController::sendToVehicle Rally Point send complete
PlanMasterControllerLog: PlanMasterController::sendToVehicle Rally Point send complete
PlanMasterControllerLog: PlanMasterController::sendToVehicle start mission sendToVehicle
MissionControllerLog: MissionControllerLog::sendToVehicle
MissionControllerLog: _convertToMissionItems seqNum:lastSeqNum:command 0 0 "Mission Start"
MissionControllerLog: _convertToMissionItems seqNum:lastSeqNum:command 1 1 "Takeoff"
MissionControllerLog: _convertToMissionItems seqNum:lastSeqNum:command 2 2 "Waypoint"
MissionControllerLog: _convertToMissionItems seqNum:lastSeqNum:command 3 3 "Waypoint"
MissionControllerLog: _convertToMissionItems seqNum:lastSeqNum:command 4 4 "Waypoint"
MissionControllerLog: _convertToMissionItems seqNum:lastSeqNum:command 5 5 "Waypoint"
MissionControllerLog: _convertToMissionItems seqNum:lastSeqNum:command 6 8 "Landing Pattern"
PlanManagerLog: "writeMissionItems T:Mission count:" 9
PlanManagerLog: _setTransactionInProgress "T:Mission" 2
PlanManagerLog: "_writeMissionCount T:Mission count:_retryCount" 9 0
PlanManagerLog: "Retrying T:Mission MISSION_COUNT retry Count" 1
PlanManagerLog: "_writeMissionCount T:Mission count:_retryCount" 9 1
PlanManagerLog: "_handleMissionRequest T:Mission sequenceNumber" 0
PlanManagerLog: "_handleMissionRequest T:Mission sequenceNumber:command" 0 16
PlanManagerLog: "_handleMissionRequest T:Mission sequenceNumber" 0
PlanManagerLog: "_handleMissionRequest T:Mission sequence number requested which has already been sent, sending again:" 0
PlanManagerLog: "_handleMissionRequest T:Mission sequenceNumber:command" 0 16
PlanManagerLog: "_handleMissionRequest T:Mission sequenceNumber" 1
PlanManagerLog: "_handleMissionRequest T:Mission sequenceNumber:command" 1 22
PlanManagerLog: "Sending error - _planTypeString(T:Mission) errorCode(2) errorMsg(Vehicle did not request all items from ground station: MISSION_REQUEST)"
PlanManagerLog: _setTransactionInProgress "T:Mission" 0
PlanMasterControllerLog: PlanMasterController::sendToVehicle start GeoFence sendToVehicle
PlanManagerLog: "writeMissionItems T:GeoFence count:" 0
PlanManagerLog: _setTransactionInProgress "T:GeoFence" 2
PlanManagerLog: "_writeMissionCount T:GeoFence count:_retryCount" 0 0
PlanManagerLog: "_handleMissionAck T:GeoFence Incorrect mission_type received expected:actual" 1 0
PlanManagerLog: "_handleMissionRequest T:GeoFence Incorrect mission_type received expected:actual" 1 0
PlanManagerLog: "_handleMissionAck T:GeoFence type:" "Mission accepted."
PlanManagerLog: "_handleMissionAck write sequence complete T:GeoFence"
PlanManagerLog: _setTransactionInProgress "T:GeoFence" 0
PlanMasterControllerLog: PlanMasterController::sendToVehicle start rally sendToVehicle
PlanManagerLog: "writeMissionItems T:Rally count:" 0
PlanManagerLog: _setTransactionInProgress "T:Rally" 2
PlanManagerLog: "_writeMissionCount T:Rally count:_retryCount" 0 0
PlanManagerLog: "_handleMissionRequest T:Rally Incorrect mission_type received expected:actual" 2 0
PlanManagerLog: "_handleMissionAck T:Rally type:" "Mission accepted."
PlanManagerLog: "_handleMissionAck write sequence complete T:Rally"
PlanManagerLog: _setTransactionInProgress "T:Rally" 0
PlanMasterControllerLog: PlanMasterController::sendToVehicle Rally Point send complete
PlanMasterControllerLog: PlanMasterController::sendToVehicle Rally Point send complete
PlanMasterControllerLog: PlanMasterController::sendToVehicle Rally Point send complete
PlanMasterControllerLog: PlanMasterController::sendToVehicle start mission sendToVehicle
MissionControllerLog: MissionControllerLog::sendToVehicle
MissionControllerLog: _convertToMissionItems seqNum:lastSeqNum:command 0 0 "Mission Start"
MissionControllerLog: _convertToMissionItems seqNum:lastSeqNum:command 1 1 "Takeoff"
MissionControllerLog: _convertToMissionItems seqNum:lastSeqNum:command 2 2 "Waypoint"
MissionControllerLog: _convertToMissionItems seqNum:lastSeqNum:command 3 3 "Waypoint"
MissionControllerLog: _convertToMissionItems seqNum:lastSeqNum:command 4 4 "Waypoint"
MissionControllerLog: _convertToMissionItems seqNum:lastSeqNum:command 5 5 "Waypoint"
MissionControllerLog: _convertToMissionItems seqNum:lastSeqNum:command 6 8 "Landing Pattern"
PlanManagerLog: "writeMissionItems T:Mission count:" 9
PlanManagerLog: _setTransactionInProgress "T:Mission" 2
PlanManagerLog: "_writeMissionCount T:Mission count:_retryCount" 9 0
PlanManagerLog: "_handleMissionRequest T:Mission sequenceNumber" 2
PlanManagerLog: "_handleMissionRequest T:Mission sequenceNumber:command" 2 16
PlanManagerLog: "_handleMissionRequest T:Mission sequenceNumber" 0
PlanManagerLog: "_handleMissionRequest T:Mission sequenceNumber:command" 0 16
QString::arg: Argument missing: _handleMissionAck ArduPilot sending possibly bogus MAV_MISSION_INVALID_SEQUENCE, T:Mission
PlanManagerLog: "_handleMissionAck ArduPilot sending possibly bogus MAV_MISSION_INVALID_SEQUENCE" 0
PlanManagerLog: "Sending error - _planTypeString(T:Mission) errorCode(2) errorMsg(Vehicle did not request all items from ground station: MISSION_REQUEST)"
PlanManagerLog: _setTransactionInProgress "T:Mission" 0
PlanMasterControllerLog: PlanMasterController::sendToVehicle start GeoFence sendToVehicle
PlanManagerLog: "writeMissionItems T:GeoFence count:" 0
PlanManagerLog: _setTransactionInProgress "T:GeoFence" 2
PlanManagerLog: "_writeMissionCount T:GeoFence count:_retryCount" 0 0
PlanManagerLog: "_handleMissionRequest T:GeoFence Incorrect mission_type received expected:actual" 1 0
PlanManagerLog: "_handleMissionAck T:GeoFence type:" "Mission accepted."
PlanManagerLog: "_handleMissionAck write sequence complete T:GeoFence"
PlanManagerLog: _setTransactionInProgress "T:GeoFence" 0
PlanMasterControllerLog: PlanMasterController::sendToVehicle start rally sendToVehicle
PlanManagerLog: "writeMissionItems T:Rally count:" 0
PlanManagerLog: _setTransactionInProgress "T:Rally" 2
PlanManagerLog: "_writeMissionCount T:Rally count:_retryCount" 0 0
PlanManagerLog: "_handleMissionRequest T:Rally Incorrect mission_type received expected:actual" 2 0
PlanManagerLog: "_handleMissionAck T:Rally type:" "Mission accepted."
PlanManagerLog: "_handleMissionAck write sequence complete T:Rally"
PlanManagerLog: _setTransactionInProgress "T:Rally" 0
PlanMasterControllerLog: PlanMasterController::sendToVehicle Rally Point send complete
PlanMasterControllerLog: PlanMasterController::sendToVehicle Rally Point send complete
PlanMasterControllerLog: PlanMasterController::sendToVehicle Rally Point send complete

Copy link
Author

Choose a reason for hiding this comment

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

I have to amend my initial comment. I just had the same issue when just uploading a mission that already is on the vehicle but I have a wireshark recording from the issue.

@menschel
Copy link
Author

menschel commented Dec 10, 2024

Just asking, is there a recipe for logging response times on mavlink, maybe with mavproxy or something?
I think we need to measure this instead of guessing.

EDIT: This looks promising. I'll try wireshark next
https://mavlink.io/en/guide/wireshark.html

@HTRamsey
Copy link
Collaborator

I think the technical way to find a response time would be to save the time diff from a PING message and add for processing time, but that's probably a little complicated for this purpose

@menschel
Copy link
Author

Is this flow chart mandatory?
https://mavlink.io/en/services/mission.html#uploading_mission
upload

Because it's the wrong message id then. 3 is the ELRS BackPack and 1 is the PC.
wireshark_mavlink_upload

@menschel
Copy link
Author

Ok, from what I figured out, I need to check how these duplicates from QGC to Vehicle happen.
And I need to create some dedicated timeout just for the mission transfer. Converting to draft therefore.

-2

@menschel menschel marked this pull request as draft December 12, 2024 16:16
@DonLakeFlyer
Copy link
Contributor

Does Mission Planner work or does it show the same problem?

Because it's the wrong message id then. 3 is the ELRS BackPack and 1 is the PC.

Don't know what you mean by this.

@menschel
Copy link
Author

Does Mission Planner work or does it show the same problem?

I have no working setup with MissionPlanner via UDP. Windows 10 Issue.

Because it's the wrong message id then. 3 is the ELRS BackPack and 1 is the PC.

Don't know what you mean by this.

This is a side finding, message is deprecated since 2020.
https://mavlink.io/en/messages/common.html#MISSION_REQUEST

@DonLakeFlyer
Copy link
Contributor

message is deprecated since 2020.

That's just the difference between the INT version of messages and the non-INT versions. QGC supports both.

@menschel menschel force-pushed the pr-fix-elrs-900-timings branch from 4a1247d to b5f418a Compare December 14, 2024 12:30
@menschel
Copy link
Author

Intermediate change with additional timeout value. I'm checking if I must prevent repetition of MISSION_ITEM_INT being sent because flow chart does not account for it.

I noticed that there are tests. Is there also coverage somewhere?

@menschel
Copy link
Author

I have just learned of TIMESYNC service but I can't grep it inside qgroundcontrol repo.
Am I correct that this is not implemented yet in qgroundcontrol?

@DonLakeFlyer
Copy link
Contributor

You should be testing this first with mission uploads. That way QGC side is in control of the protocol state. Then I would up the timeouts to something like 5 minutes. Then try an upload. If you get double messages in the vehicle->qgc direction then this isn't a timeout problem it is a hardware setup problem.

QGC doesn't support TIMESYNC. Don't see how that is related to this either way though.

@menschel
Copy link
Author

TIMESYNC is the successor of PING. The documentation is just completely outdated. So I requested change there as well.
mavlink/mavlink-devguide#585

IMO, tracing link latency would end up somewhere in the LinkInterface.

@menschel
Copy link
Author

menschel commented Dec 15, 2024

I have the measured round trip times, collected by a simple python script.

from datetime import datetime
from statistics import median
from pymavlink import mavutil

if __name__ == "__main__":
    from argparse import ArgumentParser

    parser = ArgumentParser()
    parser.add_argument("--baudrate", type=int,
                        help="master port baud rate", default=115200)
    parser.add_argument("--device", required=True, help="serial device")
    parser.add_argument("--source-system", dest='SOURCE_SYSTEM', type=int,
                        default=255, help='MAVLink source system for this GCS')
    args = parser.parse_args()

    master = mavutil.mavlink_connection(args.device, baud=args.baudrate, source_system=args.SOURCE_SYSTEM)
    for i in range(10):
        print(master.recv_match())
    master.wait_heartbeat(blocking=True)
    print("heartbeat")
    round_trip_times = []
    start_time = datetime.now()
    start_time_ns = int(start_time.timestamp() * 10 ** 9)
    master.mav.timesync_send(tc1=0, ts1=start_time_ns)
    for i in range(200):
        message = master.recv_match(type="TIMESYNC", blocking=True)
        if message.ts1 == start_time_ns:
            round_trip_time = datetime.now()-start_time
            print("Link Latency {0}".format(round_trip_time))
            start_time = datetime.now()
            start_time_ns = int(start_time.timestamp() * 10 ** 9)
            master.mav.timesync_send(tc1=0, ts1=start_time_ns)
            round_trip_times.append(round_trip_time)
    print("Statistics: {0} {1} {2}".format(min(round_trip_times), median(round_trip_times), max(round_trip_times)))

On the UDP port of the target PC with ELRS 900M,
I see everything from 0.8 to 1.8 seconds and the median is roughly 1 second.

Same Test with 2G4 ELRS results in 0.1 to 0.5 seconds and the median is 0.2 seconds.
That explains why 2G4 has absolutely no timing issues with QGroundControl.

@DonLakeFlyer
Copy link
Contributor

With close to two second latency mission problems would be the tip of the iceberg. Nearly all traffic to the vehicle which requires acks will fail.

Did you verify that there isn't a double send problem vehicle->qgc that is unrelated to things timing out?

@menschel
Copy link
Author

menschel commented Dec 15, 2024

I believe the measurements are valid.
I have not checked in wireshark but the script's invariant should guarantee no double messages.

It seems to be a bandwidth issue on ELRS and how ELRS splits bandwidth between RC and Mavlink, according to LUA script, the bandwidths are:
900M + 200Hz +1:2 TelemRatio -> 3921bps
2G4 + 1000Hz +1:2 TelemRatio -> 19921bps

Note: The link-latency is half the round-trip-time, so 900ms worst-case according to measurements.

@menschel
Copy link
Author

menschel commented Dec 16, 2024

PCAPNG attached, again, this time only the relevant packets...
link_latency.zip

@menschel
Copy link
Author

A side note:
MissionPlanner Mission Upload without using MavFTP is also broken.
It may be an option to switch mission upload to MavFTP in QGroundControl.

@HTRamsey
Copy link
Collaborator

Just out of curiosity could you update to the latest commit and see if the latency is any different? I moved an expensive operation out of the UDP receive slot and it should make a noticeable difference

@menschel menschel force-pushed the pr-fix-elrs-900-timings branch from b5f418a to 1c616ec Compare December 16, 2024 15:58
@menschel
Copy link
Author

menschel commented Dec 16, 2024

Just out of curiosity could you update to the latest commit and see if the latency is any different? I moved an expensive operation out of the UDP receive slot and it should make a noticeable difference

infinite errors on my setup

qgc.comms.udplink: Failed to join multicast group "224.0.0.1"
qgc.comms.udplink: Communication error: "Failed to join multicast group"

@DonLakeFlyer
Copy link
Contributor

DonLakeFlyer commented Dec 16, 2024

It may be an option to switch mission upload to MavFTP in QGroundControl.

That would only help missions. Parameter downloads/uploads will likely fail intermittently. Commands will fail because acks don't come back fast enough. QGC just isn't designed to work with round trip latencies close to two seconds.

@HTRamsey
Copy link
Collaborator

@menschel your issue should be resolved in #12216. The multicast error shouldn't have been fatal to the link

@menschel
Copy link
Author

@menschel your issue should be resolved in #12216. The multicast error shouldn't have been fatal to the link

ok, I'll rebase on that. I had to revert all 3 changes to Comms to get it working again.

@HTRamsey
Copy link
Collaborator

HTRamsey commented Dec 16, 2024

was there an issue with the serial link too? I think I might have a similar thing with being too harsh about the errors

HTRamsey and others added 2 commits December 16, 2024 20:35
This patch fixes runtime issues which are observed
on 900MHz ELRS.

During mission download from the vehicle, repeat timeout
occurs, causing mixup of request-response pairs which
results in sequence errors of mission items.
The repeat timeout is therefore increased to 1.5 seconds.
GCS based message repetition eventually bites with ELRS
stubborn sender feature.

During mission upload to the vehicle, the regular timeout
of 1.5 seconds is too tight and causes reported errors about
not all mission items retrieved by vehicle.
Therefore a separate timeout for MISSION_REQUEST_INT service
is added with a value of 2.5 seconds which seems appropriate.

For clarity the word default is added to the name of the
original timeout values.
@menschel menschel force-pushed the pr-fix-elrs-900-timings branch from ec7b85d to 54a27d4 Compare December 16, 2024 19:39
@menschel
Copy link
Author

was there an issue with the serial link too? I think I might have a similar thing with being too harsh about the errors

The commit with serial link had some effect on the parameter retrieval, no clue what the issue was.

With 54a27d4 everything works again.

I'll see that I write some function in LinkInterface to mimic what my python script has been doing and use that as timeout for these operations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

QGC 4.4.2 + AP4.5.7 Waypoint and Rally Point Read Write Issues
3 participants