-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
Proposal for fast yet simple and fully mavlink conform parameter upload #1918
Comments
Thanks @olliw42 . I'll add it to the dev call. My two bits:
I plan to advocate for this, because I think its a great compatibility solution; no guarantees though - we need at least two flight stacks to show interest. You can help by providing more detail on where the existing solution and ardupilot solutions fail for components. |
many thx for these quick thoughtfull thoughts
yes. I don't see however how this would be different with any change to a "new" protocol aspect, i.e., e.g. different to the situation with MAVFtp vs PARAM
gladly, sampe implementations are available. We have ArduPilot & MissionPlanner, and it is even in GQC. I.e., it should be simple to implement it in QGC, since most of the "tricky" code (if one wants to call it so) is already there.
yes, doing nothing is always easier. But often a significant blocker for any progress. See also response to next point.
anyone can easily test this: Use QGC with ArduPilot with MAVFtp enabled and some components with parameters attached to it. QGC will NOT show any components, e.g. in the Vehicle->Parameters sections. Use MissionPlanner with ArduPilot with MAVFtp enabled and some components with parameters attached to it. MP will NOT bother with uploading the components parameters. You will have to go to the component page, and press "refresh" yourself to get them. MP will also be struggling with showning the MAVFtp button. It will show a strange @sys. ... MP has just become a pain with reagrds to components. I assume that it does this because it uploads via MAVFtp at connection, for reasons layed out.
yes, but be fair, it is going to be a fight only because it is not just about rational engineering but all the stuff beyond. |
W.r.t component metadata, if you want to use it then you're buying into the implementing MAVFTP. I have read your previous arguments about this actually restricting the use to GCS/Autopilot, and to a large extent I agree. What we are doing is trying to make sure that at least essential metadata is in messages - such as https://mavlink.io/en/messages/development.html#COMPONENT_INFORMATION_BASIC - and other cases we might take on a case-by-case basis. NOTE, you raised a few other issues. I might not get to look at them until next week. |
I then was not clear enough with my words. First off, the issue is in both MP and QGC. Second, the issue is that if you get the params from ArduPilot via MAVFtp you do NOT want to also send a PARAM_REQUEST_LIST as broadcast (since, this would make ArduPilot send its params again, and now even via slow PARAM ;)). Both MP and QGC simply do not send any PARAM_REQUEST_LIST to anyone upon connection (for QGC I know for sure since I looked also at the code, for MP it's what I deduce from its behavior). Getting around it is possible, but a "pain", at least with GQC it requires quite some rework (as much as I can see). Without proper handling of component params it doesn't make so much sense to do COMP_METADATA.
I am ... but in this case I would go beyond what I have done so far only if there would be some general approval (so far I have done (only) as much as I needed to see it and convince me of the concept, but I didn't push my efforts that far to produce any code I would want to show)(I won't for the obvious reason that all the work is for the bin otherwise). chicken egg situation
STorM32 supports MAVFtp since more than 3 years ... since the early days of COMP_INFO ( :) ) ... yet it won't ever support ArduPilot's param upload (for various reason I don't want to defend here). This part of the game is all there :) COMP_INFO_BASIC + COMP_METADATA is essentially the old COMP_INFO, but split into two messages, which makes sense, I like it :) |
This really doesn't sound that bad for backwards compatibility. If PARAM_VALUE ARRAY is not implemented, the component will just respond to a PARAM_REQUEST_LIST using PARAM_VALUE. If the GCS does not implement PARAM_VALUE_ARRAY, then it will trigger the timeout to resend the PARAM_REQUEST_LIST message. A component can see that it has gotten two PARAM_REQUEST_LIST messages consecutively, infer that the GCS does not support PARAM_VALUE_ARRAY, and then fallback to just sending PARAM_VALUE. Am I missing something? I'd be willing to help with the QGC implementation. I'm not as familiar with the PX4 parameter streaming, the only complicated piece of this is the fallback from PARAM_VALUE_ARRAY to PARAM_VALUE in the case of missing GCS support. |
many thx for the thoughts. You pointed to the one situation were achieving backwards compatibility is not so clear. Two comments pl.
|
I'm on other work today, but IMO this would be easy to sort out with a protocol bit that indicates support for the new protocol. |
unfortunately not. The situation considered here is that a OLD gcs is used, which does not know about PARAM_VALUE_ARRAY, but the component supports PARAM_VALUE_ARRAY, i.e. old gcs - new component ... but if the gcs is old, it then also does not know about any newly added protocol bits ... and moreover it would not have a means to tell the component that the component should send PARAM_VALUE and not PARAM_VALUE_ARRAY. note that all other combinations, new gcs - new component, new gcs - old component, old gcs - old component are unproblematic, they just work. |
Old GCS - new component ... this is actually very common -- the HereLink. It runs a v4.0.8 fork of QGC but it can be updated. Although it's an older QGC version, it should be relatively easy for the project maintainer(s) to add support for the new message and push it in a new release. A ton of people use the HereLink so for that reason we need to make sure they are aligned with this proposal. @hamishwillee do you know the right person at cube pilot to bring into the discussion? |
Pretty sure you're not under-estimating that. But don't underestimate it :-) I expect someone would point out that mavftp is a solid generic transport mechanism, and that adding support for Please note that we also transfer other "bulk" items like fence items and mission items using mavftp, so there's re-use there. And yes, the opaque, not-yet-standardised formats for these transfers bothers me a bit. @olliw42 's musing on I think I'd agree with @olliw42 's suggestion about the need for Q:
It should fall back - I've seen it do so. You know I don't use it day-to-day, 'though :-) In terms of QGC versions - there are a lot of people out there running things like the "H16" controllers with variable versions of QGC on them. These are likely to be entrenched for some time - long time constants on features coming in and out for actual users of our software :-) |
AP's FTP format now also reports the default value for every parameter, so the user can easily see what has been changed. This functionality should be maintained by any new protocol. There we have a flag bit saying if the param value is currently the default, if it is not we double the data length and send the current value and the default. |
@olliw42 and @dakejahl Thanks. I see the problem. Yes a solution could be
Yes, if the proposal gets that far. |
@peterbarker et al. I am not underestimating the resistance, and not just from ArduPilot. There is also this assumption in QGC/PX4 that as long as we don't have to download parameters more than once you can live with the current protocol (because they keep a cache value for the downloaded set and track the individual changes). The "business justification" for ArduPilot is that if this is adopted in the standard then fast parameter upload will go into QGC. This is very much a case where what is better design might not be worth particular flight stacks adopting. I can see a future where PX4 primarily works around the problem by running only over faster links so doesn't spend the effort of having a faster parameter protocol. I can see ArduPilot never having fast parameter download on anything other than Mission Planner. I hope that we can get somewhere with this. Not everyone in the world can upgrade to fast links, and some users would like a common protocol. IMO all the rest of this discussion is IMO just resolvable technical detail/compromise. I'm not planning on investing too much time on it unless I can get broad agreement that this idea can be considered for the standard. That means at least two significant stakeholders need to show commitment to implement, or at least recognition its a good idea for the standard - i.e. if one party wants to go ahead with this that the other will not block it. I'll raise at the dev call. PS Yes, the issues with existing protocol and components should be fixed. I assume that should happen as bugs against the respective GCS. |
I think the way forward is to have a lightweight nice C or C++ library that implements MAVLink FTP and is easy to be integrated into a peripheral/component. That way we can all make use of MAVLink FTP which has proven to work and don't have to re-invent yet more protocols/solutions to do reliable transfer of bytes. |
@olliw42 This was discussed in the mav call and we don't think this should proceed. I'm disappointed because I would have liked a path towards a single parameter protocol; even if PX4 adopts the ardupilot file based parameter transfer we still have param protocol, extended protocol, etc. Thanks for taking the time to post this. Closing, but you can reopen if you believe I have been pre-emptory. |
many thx for taking the effort to bring it to discussion, really much appreciated. I am not totally surprised by the outcome. From the responses it seems that the disadvantages of param ftp have not fully be comprehended and dito the benefits of the proposed scheme. It is also not surprising that ArduPilot's appetite was low, I am however convinced that PX4 is going to make a wrong decission. Anyway, I don't regret having taken the time to put it up. The idea is now at least around. Components continue to have a hard time :) |
PX4 will make a pragmatic decision for PX4; I just hope that this on balance does not mean that "standardization suffers". Thanks for keeping the dream alive :-) |
Some time ago, ArduPilot has introduced upload of the parameters via MAVFtp, and the speed-up as compared to ArduPilot's normal upload via the PARAM messages is certainly stunning. However, this is largely a stunt, as will be demonstrated below. The same can in fact be achieved without all the burden of MAVFtp and in a clean "mavlink-ish" way, as will also be shown.
Furthermore, ArduPilot's MAVFtp parameter upload seriously conflicts with components in the system, like gimbals and cameras. The problem is that in order to get the parameters of the components, one would send a PARAM_REQUEST_LIST message as broadcast, which however can confuse ArduPilot as it would now get both the hint to downlaod via MAVFtp and via PARAM. A way out would be to send PARAM_REQUEST_LIST messages targeted for each component individually, which isn't been done however. As a matter of fact, both MissionPlanner and QGC today show worse behavior concerning components than years back.
The alternative scheme suggested here is equally good to MAVFtp in terms of download performance but totally avoids the said issue, and also provides further signifcant benefits and advantages, as will be discussed at the end.
In order to follow some calculus below, for reference some numbers:
Analysis of the situation, experimental data
Let's start with discussing why param upload via MAVFtp is a stunt. This is important to understand, to not be missled by whatever one may have heard or read or have been told or have seen oneselves.
The download speed is determined by these factors:
Obviously, a fair comparison between different schemes would require that the (average) data rate (bytes per sec) is equal.
If this is not respected, then the total download time and thus the subjective impression of a user may be quite different for two schemes, but for total trivial reasons.
For instance, if two schemes A and B send their packets at the same rate, but in scheme A the packets are 10 times larger than in scheme B, then it is obvious that scheme A will be 10 times faster than scheme B, and a user might be heavily impressed, even though all what has happened is that simply a 10 times higher bandwidth was allowed for scheme A!
Exactly this is what largely happens in case of ArduPilot's MAVFtp and PARAM schemes. For MAVFtp, the parameter data packets are send out as frequently as possible. The packets are in fact send out that densely and agressively that not even the 1 Hz HEARTBEAT would be send out inbetween. In contrast, for the PARAM scheme ArduPilot has a pretty weired streaming method, which results in that PARAM_VALUE messages are send out in typically 20 ms intervals. Ergo, the download time is ca 1200 * 0.02 sec = 24 sec, even on a high speed link.
A fair comparison would also allow the PARAM_VALUE messages to be send out as densely as possible.
This unfair comparison accounts for most of the subjective impression of the MAVFtp scheme.
Nevertheless, truth is, ArduPilot's MAVFtp scheme does introduce some nice ideas, and does objectively bring some speedup, for these reasons:
Let's consider the size of a full mavlink frame of 267 bytes. This number of bytes is good for 6.9 PARAM_VALUE messages (size = 37 bytes), so the overhead is 61 % (37/23 - 1). In comparsion, a MAVFtp packet provides 240 bytes payload and thus can carry 10.4 parameters. The overhead is thus only 11% (267/240 - 1).
In other words: In the time it takes to transmit 267 bytes one can transmit 10.4 parameters with MAVFtp or 6.9 parameters with PARAM.
ArduPilot's MAVFtp implements a nice compression scheme (which can be further improved btw). On my system it yields a compression ratio of ca 2.2.
This estimate is obtained as follows: With MAVFtp I find that ca 52 messages are required to transfer all parameters, that is 10.4 bytes / parameter (52 * 240 / 1200 = 10.4). This can be compared to the flat size of 23 bytes per parameter. This yields a compression by 23/10.4 = 2.2.
Therefore, all together, MAVFtp provides a 3.3 (10.4/6.9 * 2.2) times faster download than PARAM.
3.3, that's the objective measure for the "very efficiently" and "a lot faster" parameter download of MAVFtp.
Proposal
However, this can equally be achieved also without all the burden and blunder of MAVFtp, in a total simple and easy to migrate fashion.
The idea is to introduce a new message PARAM_VALUE_ARRAY, which can host a number of parameters, which can be compressed in exactly the same way as in ArduPilot's MAVFtp scheme. The message I am using in my tests is:
The usage is simple: In response to a PARAM_REQUEST_LIST, the component sends out as many PARAM_VALUE_ARRAY messages as needed, instead of the stream of individual PARAM_VALUE messages. Everything else of the PARAM microservice remains as before. The parameters can be packed into PARAM_VALUE_ARRAY using the very same compression scheme as used by ArduPilot's MAVFtp. The flags may allow different schemes in future.
Obviously, this approach trivially resolves the issue with components described before. Also, obviously, it can be as efficient as ArduPilot's MAVFtp.
In theory, this message might offer even slightly higher efficiency than the MAVFtp message, given that the available payload size for the parameter data is slightly larger (247 vs 240) and the overhead hence slightly smaller. However, this isn't fully realizable, since e.g. the first param name in each PARAM_VALUE_ARRAY must be stored full size (common_len = 0). It should be darn obvious however that using PARAM_VALUE_ARRAY is on any practical level as efficient as using MAVFtp messages.
Advantages compared to MAVFtp param upload
Next steps
I do have a test implementation using BetaPilot and mLRS. If the above proposal, after some discussion as needed, finds general agreement, I would finalize these test implementations based on the results of said discussion, could attempt an implementation in QGC, and make all that available to the public. This may serve as proof of principle, and maybe as example code.
Cheers,
Olli :)
The text was updated successfully, but these errors were encountered: