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

Proposal for mavlink radio links & receivers: Concept and set of new messages #1921

Open
olliw42 opened this issue Nov 16, 2022 · 7 comments

Comments

@olliw42
Copy link
Contributor

olliw42 commented Nov 16, 2022

Exchanging mavlink messages via a wireless link is obviously one of the most crucial application of mavlink. These links are characterized by lossiness and limited data rate, in contrast to ground- or vehicle-based links (which can be safely assumed to be loss-free and run at high baudrates). The current mavlink standard provides a couple of messages and methods to deal with radio links, which however have some serious limitations and pain points.

This post is about suggesting a new concept and set of messages, to replace the old messages and procedures. The thread will be accompanied by PRs. The concept touches four aspects which are described below. However, while 3 of them are finalized from my side and ready to be presented and discussed, the 4th (flow control) is quite a beast in itself and I will only mention it here, to emphasize that this aspect is part of the concept.

For what follows, only the vehicle-side shall matter, and a setup shall be considered which consists of a receiver, an autopilot, and possibly further mavlink components, all connected via UART/serial links in some topology. The "receiver" may consist of more than one hardware item, like a SiK radio and a Frsky receiver, but this detail shall not matter. There will also be a transmitter on the ground of course.

IMHO, we need to consider these aspects:

  • rc channels: In many cases the wireless link should not only transport the bi-directional mavlink data, but also rc channels data to control the vehicle. On the vehicle, this currently requires 3 wires between receiver and autopilot: two for the UART connection and a 3rd for the rc channels data (SBus, CRSF, etc). The 3rd wire is however obviously superfluous as the rc data could also be send via the UART connection. In fact, this can have significant advantages also with regards to the receiver hardware (one uart less needed).

  • link statistics: Obviously, one wants to get informative info on the status of the link. For instance, rssi and LQ (link quality), but also other info like data rates, or more detailed info in case of diversity systems.

  • routing: One needs some special routing rules for this set of messages, for known reasons explained below.

  • flow control: By "flow control" we will understand the mechanism by which the receiver can make the autopilot and the other components on the vehicle adjust their rates with which they send data to the reciever, such that the over-the-air link from receiver to transmitter is not overloaded.

Note that the last three bullets in principle are also relevent for the ground side, but the procedures discussed here can obviously be transferred to the ground side. Let's not overcomplicate the topic; so let's only consider the vehicle side of things.

Current Situation

Current mavlink provides means to deal with all aspects, but in either insufficient or even "dirty" ways, i.e., comes with significant limitations and pain points. These shall be adressed now (possibly incomplete):

rc channels pain points

Let's first more clearly specify what the goal is. Currently, we would use e.g. a SiK radio and Frsky receiver to provide the 2-wire UART and the 1-wire rc data, or a more advanced system which does both in one hardware. Importantly, logically we have these 3 wires also on the air link, i.e., the rc data are send in some link-proprietary format, separate from the air mavlink stream, i.e., are not carried as dedicated mavlink messages injected into the air mavlink stream. Doing so has in fact serious advantages, since the rc data can, e.g., be send in a much more compact format saving bandwidth, can be decorated with some saftey bits to improve reliability, and so on.

So, what we want is actually a system which does NOT inject the rc data into the over-the-air mavlink stream but transmits it in some dedicate format over the air, but OUTPUTS the rc data also on the UART used for mavlink, instead of on a separate wire.

Mavlink provides the messages RC_CHANNELS and RC_CHANNELS_OVERRIDE (let's ignore RC_CHANNELS_RAW, RC_CHANNELS_SCALED). However, neither of them is intended for that purpose. RC_CHANNELS is clearly intended to report to the ground, and as matter of fact is (usually) streamed by the autopilot. There would be a collision if the receiver would send them too. RC_CHANNELS_OVERRIDE is actually often used for exactly the desired purpose, but this kills its intention, namely to allow to override the signals coming from a physical receiver on the vehicle (i.e. a primary source of rc data)!

Hence, a message which is intended to be sent by a receiver to the autopilot as replacement for the 1-wire connection is clearly missing.

There are further pain points with the existing messages. The rc data is in PPM (us) units, which is essentially just 10 bit (= quite a waste given they occupy 16 bits). They are also used to report rssi, but not other desired stats like LQ. They do not (fully) benefit from MAVLink v2's zero-padding, which can be quite some bandwidth waste. They are limited to 18 channels (which is a lot but is not always sufficient). And so on.

link statistics pain points

Essentially, only rssi is supported. Notably, not LQ, which became quite popular in recent years, and might be in fact more interesting. RADIO_STATUS provides some more statistics, but again not LQ, and also no diversity information. Its most serious issue however is that it also carries txbuf, which is for flow control, and thus conceptually and logical totally distinct from the link stats (a similar logical concern arrises for rssi reported in RC_CHANNELS and alike). Frankly, the situation is a mess, and e.g. writing code just to read the rssi and report it to a radio transmitter is a challenge, if one wants to cover the many and different procedures and configurations and situations.

There is an attempt to improve the situation with LINK_NODE_STATUS. However, it is flawed (#1821), and also entangles "statistics" with "flow control". IMHO it cannot be considered.

routing pain points

This point is actually not a pain point, but just a point to realize, accept and deal with. And it is actually no news either, as present also with RADIO_STATUS.

The issue is this: The set of messages emitted by the receiver should NOT be fully broadcast and not fully targeted. They should be send to all components on the vehicle but not send to other systems. In routing language, target_system should be the vehicle's system id (usually defined by the autopilot) and target_component should be 0 or broadcast.

Clearly, it doesn't make any sense to send the receiver rc channels to e.g. other vehicles. However, it makes fully sense to send them to all components on the vehicle. In fact, this would be a very welcome extension to a 1-wired receiver, as in this way not only the autopilot but all components would have native access to the receiver rc data. For instance, STorM32 gimbals would benefit.

The natural idea would be to include in these messages a target_system field, and let the existig routing infrastructure do its thing. However, the problem then is that the receiver needs to know the correct value for this target_system field!! This either would require the user to explictely configure it, which is very undesirable, or the receiver to retrieve that info from e.g. listening to the autopilot heartbeat, which however is also very undesirable as the receiver could then start outputing the rc data only once it got that info! We want a receiver which outputs the rc channels even if only stand alone (no autopilot).

Therefore, using the existing mavlink-routing methods won't work (in a desirable way). I.e., the receiver cannot be treated as normal mavlink component, and we need to specify special rules for it.

The solution is simple, as described below.

flow control pain points

To be discussed elsewhere.

Suggested Solutions, Concept, Messages

A key idea is to disentangle the various aspects, and to reflect this in the messages. For instance, one should not put together the fields for flow control with those for link statistics or those for rc channel data. They should be in separate messages.

There are a couple of immediate reasons for this (more may exist). First off, they may be sent at very different rates. For instance, the rc channels data may be send at high rate, like 20 Hz or 50 Hz, but the flow control data would be send at a much lower rate, like 1 Hz. In fact, the rate of the flow control messages may be adaptive, and e.g. vary from 1 Hz to let's say 5 Hz depending on current need. Similarly so, the link statistics data may not have to be send at 50 Hz, 10 Hz could be fully sufficient and satisfying. Next, it would make maintaining the messages more difficult. Let's assume the link statistics should be extended by a new field, it obviously would be cleaner/easier if only that dedicated message would have to be discussed. Similarly so for e.g. flow control. Let's assume, a new better approach is invented, then one certainly wants to only modify or bring up a new flow control message, but not also have to fool around with e.g. the link statistics message. And so on. In short, apples and bananas should be treated as different fruits.

With this "insight", the following is rather obvious from the above.

rc channels: RADIO_RC_CHANNELS

A new message RADIO_RC_CHANNELS is proposed, with these features.

  • Support of 24 channels, there the channels are an extension. This makes it that they are located at the end of the on-the-wire data stream and hence fully benefit from zero-padding. That's admittedly a "dirty tweak", but that's how mavlink works.
  • The resolution is 13 bits, which allows conversion into other formats using 16 bit arithmetics, and should be really plenty in terms of resolution.
  • The channel data shall be centerd around 0, i.e., the range is -4095...4095, with 0 meaning stick center.
  • A flag to report failsafe (and possibly other info, like missing frames, but that's discussable).

It is proposed in #1919.

link statistics: RADIO_LINK_STATS

A new message RADIO_LINK_STATS is proposed, with these features.

  • All sort of link statistic, from rssi to LQ, and for diversity systems too. This message is of course discussable. I designed it according to what I do see at this point in time. It is influenced by RADIO_STATUS, LINK_NODE, and CRSF's link stats messages.

This message should be considered a "high-frequency" message, i.e., carry only link stats which one may want to actually get frequently. For instance, it can make lots of sense to send both RADIO_RC_CHANNELS and RADIO_LINK_STATS at the same rate (if the rate is not to high), since the data in RADIO_LINK_STATS may be updated by the receiver with every new RADIO_RC_CHANNELS (like e.g. rssi or which antenna is used). This is obviously very receiver dependent, but we should consider this possibility.

Data such as e.g. power of the transmitter or receiver, or the mode or the rate, should in contrast be considered "low-frequency". It is thus suggested to put such data into yet another message. We do not want to spoil RADIO_LINK_STATS with all sorts of blunder. This addition statistics message could be called RADIO_LINK_INFORMATION.

It is proposed in #1920.

A proposal for RADIO_LINK_INFORMATION can be found in my repos, but I assume it would be too much now.

routing:

The solution to the problem mentioned in the above is simple, and largely known: The messages don't have target fields (as they could not be populated) but should be routed as if they would have target_system = autopilot_sysid and target_component = 0. So, routers need to be written such that these messages are routed that way.

Note that routers do have already special rules for RADIO_STATUS (at least those I know of), so this should not be a very shocking suggestion and not raise big concerns.

While these messages could be identified in the routers by their message id, it is suggested to make the detection dependent on the receiver's component id, which we should require to always be MAV_COMP_ID_TELEMETRY_RADIO.

Therefore in short, in a router, the code would look like

target_system = 0;
target_component = 0;
get target_system, target_component for message;
if (msg.compid == MAV_COMP_ID_TELEMETRY_RADIO) {
    target_system = mysysid;
    target_component = 0;
}
route the message as normal;

For the reasons presented in the above, the receiver cannot be seen as part of the vehicle (i.e. have the same system id as e.g. the autopilot), but needs to have its own system id. As default they could use system_id = 51, as used by the SiK radios.

Canonically, the receiver should not send out hearbeat messages; a message with component_id = MAV_COMP_ID_TELEMETRY_RADIO should be sufficient evidence of the receiver's presence.

However, if the receiver wants to support some MAVLink services, like e.g. parameters, then it of course should be conform to mavlink and behave like a normal component, i.e., send out a heartbeat, and so on, so that concerning the services it blends into the existing infrastructure.

flow control: RADIO_LINK_FLOW_CONTROL

As discussed, this topic is a beast by its own and will not be further discussed here.

Implementation and Experimental Evaluation

I have implemented the above (except flow control) in mLRS, which is an open source LoRa-based high-performance long-range radio link, and in the BetaCopter fork of ArduPilot. See

So, the ideas and messages presented here have seen already some experimental/practical evaluation. The intention of this issue and the related PRs is to bring them to regular use.

Conclusion

proposals for RADIO_RC_CHANNELS is in #1919, and for RADIO_LINK_STATS in #1920.

Looking forward to hear your responses.

Olli

This was referenced Nov 16, 2022
@olliw42 olliw42 changed the title Proposal for mavlink radio links & receivers: Concept of set of new messages Proposal for mavlink radio links & receivers: Concept and set of new messages Nov 16, 2022
@hamishwillee
Copy link
Collaborator

hamishwillee commented Nov 23, 2022

@olliw42 I ran out of time again today. But this is on my list to consider tomorrow. Apologies.

Because this might be outside my expertise I am seeking advice: https://discord.com/channels/899843920987562014/902774723925147649/1044813176526610433

@olliw42
Copy link
Contributor Author

olliw42 commented Nov 23, 2022

many thx, sir, your effort & time is much appreciated

the link led me to nirvana, I don't know discord well, it seems I have not access to whatever is behind the link, so I will out of loop of the discussion going on there, just to let you know

@hamishwillee
Copy link
Collaborator

I've run out of time again. Just so you know what was posted:


OllieW has created and issue and a few associated PRs to improve handling of mavlink radio links & receivers.
I know very little about the problems and possible solutions, so I need technical advice on whether

  • this has "merit",
  • whether the benefit outweigh potential costs,
  • whether this is appropriately generalized.
  • Whether this is something ArduPilot and PX4 would consider implementing.

Hunting for advice/analysis Tridge, Daniel Agar, JamesP


Response from @auturgy

He’s definitely put some thought into it. I think it should be linked into the work with MANUAL_CONTROL and the Auterion mavlink controller pr. They’re all inter-related, as they deal with the human pilot interface, and imho should be cohesive.

@olliw42
Copy link
Contributor Author

olliw42 commented Nov 24, 2022

many thx, sir

I have seen that there is work on MANUAL_CONTROL, but haven't realized it might be of relevance and am indeed not familiar with this work. Helpfull feedback. I will look at what's going on with MANUAL_CONTROL and this mav controller pr (as much as it's visible). Thx.

From a usage perspective I'd like to emphasize again, that not needing 3 wires but just 2 and getting link stat info like LQ is a big thing for some users of mLRS (and IMHO it makes a lot sense). So, a path to some solution would be really cool.

@olliw42
Copy link
Contributor Author

olliw42 commented Nov 28, 2022

I could not find any info on the web which would help me to understand what "work with MANUAL_CONTROL and the Auterion mavlink controller pr" refers to. So, can't comment.

I looked into how MANUAL_CONTROL is used in ArduPilot, and it happens to essentially do exactly what RC_CHANNELS_OVERRIDE is doing, and in fact calls exactly the same underlying function.

Ergo, I will argue that my comments in the first post on RC_CHANNELS_OVERRIDE equally apply to MANUAL_CONTROL, and that it serves a quite different purpose than the proposed RADIO_RC_CHANNELS. The other suggested messages RADIO_LINK_STATS, RADIO_LINK_INFORMATION, RADIO_LINK_FLOW_CONTROL could or should be relevant for the work with MANUAL_CONTROL, as they describe links in general. However, the implication is that if work is done in the context of MANUAL_CONTROL which touch these aspects, this work should consider that they would be relevant for links in general - and thus be designed such.

@auturgy
Copy link
Collaborator

auturgy commented Nov 29, 2022

I probably need to expand a little.
The proposal addresses 4 aspects: rc channels, link statistics, routing, and flow control.
As highlighted by @olliw42 many current (and future) implementations of mavlink over RF have extended beyond what is supported by the existing message set / design. I haven’t really considered link stats, routing or flow control in my comments below – they’re much wider reaching and require more thought. My first round of thinking on this (as per the comment Hamish posted above) was regarding rc channels.
“Clearly, it doesn't make any sense to send the receiver rc channels to e.g. other vehicles. However, it makes fully sense to send them to all components on the vehicle. In fact, this would be a very welcome extension to a 1-wired receiver, as in this way not only the autopilot but all components would have native access to the receiver rc data. For instance, STorM32 gimbals would benefit.”
I’m going to argue this somewhat: Perhaps I’m missing something, but I don’t agree that broadcasting to every component is a good idea: either the components are integrated with the autopilot/mission computer, in which case the autopilot/mission computer should manage commands to them, or they’re independent, in which case they should be directly addressed as a targeted component. Obviously this requires configuration, and I know you’ve indicated that this is undesirable – but configuration of the radio, autopilot and target component is necessary anyway. Otherwise how would a component know which channels are intended for it?

“Ergo, I will argue that my comments in the first post on RC_CHANNELS_OVERRIDE equally apply to MANUAL_CONTROL, and that it serves a quite different purpose than the proposed RADIO_RC_CHANNELS.” I’ve copied the relevant piece in:
“RC_CHANNELS_OVERRIDE is actually often used for exactly the desired purpose, but this kills its intention, namely to allow to override the signals coming from a physical receiver on the vehicle (i.e. a primary source of rc data)!
Hence, a message which is intended to be sent by a receiver to the autopilot as replacement for the 1-wire connection is clearly missing.”
Both messages are in regular use by “smart controller” handsets over telemetry links, as an alternative to using a standard rc receiver. In spite of the “override” name, there is no requirement for a standard rc receiver to be present, and using them in this way doesn't kill their intent (what it does mean is that some of the logic in the RC libraries is missing when using mavlink overrides, which is undesirable). An attempt to further expand on the “smart controller” concept is here: #1848 which is what I referred to as the Auterion mavlink controller pr. Evolution of MANUAL_CONTROL is discussed here: #1694. There’s also work going on in ArduPilot for better joystick support using MANUAL_CONTROL.
The reason I wanted to link these with the RADIO_RC_CHANNELS proposal is that whilst differing approaches are used, the intent is much the same: direct/human-in-the-loop vehicle control using mavlink messages. I would much prefer converging to a common API/microservice than end up with a third, but I quite like the simplicity of your message.
I would agree that (at least in the case of ArduPilot) there is merit in bringing mavlink rc channels/overrides down into AP_RCProtocol (as you’ve done in BetaPilot), so it’s a peer with normal RC input.
There’s quite a few words, and not a lot of direction/suggestion. So I’ll close with some comments against Hamish’s post above:
“OllieW has created and issue and a few associated PRs to improve handling of mavlink radio links & receivers.
I know very little about the problems and possible solutions, so I need technical advice on whether
• this has "merit",
• whether the benefit outweigh potential costs,
• whether this is appropriately generalized.
• Whether this is something ArduPilot and PX4 would consider implementing.
Hunting for advice/analysis Tridge, Daniel Agar, JamesP”
This has merit – yes, although I’m not sold on the routing change.
Whether the benefit outweigh potential costs – for the specific use case being addressed, yes. Generally, not yet but I think we can get there.
Whether this is appropriately generalized – no. Nor is it specific enough to remove some of the arguments, but this can be worked on. I think we need to logically separate “manual control over mavlink” and “RC control over mavlink” to progress this concept, and also probably create a couple of new component ID’s so that point to point, mesh, and other radio types can be managed as different link types (with appropriate stats/data) whilst maintaining backwards compatibility.
Whether this is something ArduPilot and PX4 would consider implementing – ArduPilot is looking at improving rc over mavlink, so this issue/pr is timely. RF link management is a known issue and has been looked at a few times – this might kickstart thinking on that again.

@olliw42
Copy link
Contributor Author

olliw42 commented Nov 30, 2022

@auturgy
MANY thx for the detailed response, and especially also for the 1st link, which indeed haven't seen before and helped me getting a better insight into what we are talking about.

RC_CHANNELS_OVERRIDE/MANUAL_CONTROL

While I think they say it, I may not have choosen my words in the 1st post carefully enough to bring across some aspects of the RC_CHANNELS_OVERRIDE/MANUAL_CONTROL properly. I'd like to first add to this.

Both messages are in regular use by “smart controller” handsets over telemetry links, as an alternative to using a standard rc receiver. In spite of the “override” name, there is no requirement for a standard rc receiver to be present, and using them in this way doesn't kill their intent

I was not trying to imply that the current use of these messages by GCSes would be improper or so, to the contrary. I fully understand that they are used in that way, have been introduced for this puprose, irrespective if there is a standard RC receiver or not. My point however is:

we need to logically separate “manual control over mavlink” and “RC control over mavlink”

exactly, and in my mind there is such a very clear logical separation line (which I obviously failed to transmit well enough in the 1st post):

RC_CHANNELS_OVERRIDE/MANUAL_CONTROL are about the ground side, while RADIO_RC_CHANNELS is about the vehicle side!!

One also can say:

RC_CHANNELS_OVERRIDE/MANUAL_CONTROL are send from the ground to the vehicle as part of the serial mavlink stream, while RADIO_RC_CHANNELS are not but instead are generated on the vehicle side from rc data which are send from ground to vehicle on the same air wave but using a protocol layer different to that for the serial mavlink stream.

My statement " RC_CHANNELS_OVERRIDE is actually often used for exactly the desired purpose, but this kills its intention, namely to allow to override the signals coming from a physical receiver on the vehicle (i.e. a primary source of rc data)! Hence, a message which is intended to be sent by a receiver to the autopilot as replacement for the 1-wire connection is clearly missing." is to be read in this context. It tries to say that if a receiver would also send out RC_CHANNELS_OVERRIDE/MANUAL_CONTROL it would impair the situation - exactly because these are already used by ground-side stuff like GCSes!!

Now you could argue that there shoulds always be only one, a reciever or a GCSs, and if there would be more of any it should be possible to sort out from the message's source ids, and that there thus won't be a conflict if a receiver also would use them: Yes and no.

First I argue that MANUAL_CONTROL should not be send by a receiver, for the simple reason that it requires a mapping of channels to the respective function, which would be a real pain for users if this would have to be done in the receiver. Furthermore, it only provides a limited number of full channels, and otherwise only buttons. These are major cons (IMHO).

RC_CHANNELS_OVERRIDE could indeed be used also be the receiver (and this is what is currently done!). It unfortunately has some drawbacks too, on the technical level. E.g. it suffers from not fully benefitting from zero-padding, not including failsafe info, providing low resolution in some "weird" uinits, and so. So, from the technical level RADIO_RC_CHANNELS can be seen as revised replacement learning the lessons. However, it also has drawbacks from a conceptual level, in that it exactly would spoil the distinction line between what is ground and what is vehicle.

Now you could argue that all the functionality required by all versions of stick/rc control can be embeeded into one "generalized" message, i.e., to put everything of the old and a new MANUAL_CONTROL and of RADIO_RC_CHANNELS into one flexible container. Yes, that's of course possible. I however argue that this is anything than desired, or a "cleaner/better" concept. One will have to add flags, variable fields, etc pp to embeed all the required functionality and features.

I hope you will not dare to argue this could be sorted by component metadata, i.e., that at a vehicle based receiver must be able to do component metadata stuff (like it is argued for ground-side joysticks in #1848).

So, if I compare a world there all that is squeezed into one super message or a world there the ground side and vehicle side each have their messages to do their thing, I definitely go with the latter world. 100%.

In short, I think your arguments, and the discussion in #1848, very much furthers the concept proposed here.

At this point, you may still argue, why should it be desirable in the first place to send the rc data over air not as part of the serial mavlink stream but as a different protocol and then to convert that data to a mavlink message in the receiver. In biref: resilence, reliability, link stability, latency, ...

Routing/Broadcasting

I also want to comment on this section of your argument.

I don’t agree that broadcasting to every component is a good idea

I must admit I don't really understand what you are saying here, e.g. a sentence like "either the components are integrated with the autopilot/mission computer, in which case the autopilot/mission computer should manage commands to them" doesn't make sense to me, since components are not integrated with autopilots but autopilots are a component, and there are no commands to manage in the discussion here at all.

The only counter argument I could see to not broadcast (to all components of a system) is traffic, i.e., the stipulation that in typical cases (whatever typical means here) the traffic in a vehicle's network would be lower if RADIO_RC_CHANNELS would be targeted. That's however usually not correct, to the contrary. Let's consider a typcial case: ArduPilot with some component like a gimbal connected to it, and the receiver connected to it. If the messages wouzld be targeted, there would have to be TWICE as much traffic on the connection receiver-ArduPilot as compared to the broadcasting scenario. You can go now through some other typcial scenarions, including e.g. also a companion, and you will find that in most cases the traffic is actually lower with broadcasting. Of course cases exist, in which it is the opposite, but they are the minority.

Obviously this requires configuration, and I know you’ve indicated that this is undesirable – but configuration of the radio, autopilot and target component is necessary anyway. Otherwise how would a component know which channels are intended for it?

it would be done exactly as of today, by configuration of the RECIPIENT of the RADIO_RC_CHANNELS message, and not by configuration in the receiver for each and every component in the vehicle system.

in plain words, ArduPilot would do it in ArduPilot, exactly as it does today for all rc protocols - zero change needed. For a gimbal it would have to be configured in the gimbal, like it is for STorM32, or BaseCam, and probably all others - zero change needed.

If you want to seriusoly do what you suggest, namely to do all the mappings etc for each component in the receiver, it would be a ultra-ugly scenario.

Yes, all components need some configuration, but the receiver does not need to be configured at all. It spits out RADIO_RC_CHANNELS at the rate it gets rc data, that's all what is needed.

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

No branches or pull requests

3 participants