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

Add control handoff messages for multiple GCS #1954

Closed

Conversation

KonradRudin
Copy link
Contributor

@KonradRudin KonradRudin commented Feb 27, 2023

Problem to Solve

In a multi GCS environment, only on GCS should be able to control the system. All other GCS should only act as observers. As an observer, you can still receive telemetry and payload stream, get the parameters and the mission, but cannot command the vehicle and change the parameters and mission. In order to set which GCS is in control, new message sets needs to be created.

Proposed solution

The control handoff sub process in mavlink consists of requesting the control of the target system in a multi GCS environment requesting independently the flight control and/or the payload control. These service can be used in place of CHANGE_OPERATOR_CONTROL and CHANGE_OPERATOR_CONTROL_ACK messages. The process covers:

  • The request of control from a GCS
  • A handoff relay request from the system, if another GCS is in control
  • A periodic status message defining the current GCS in control

The proposed solution for the control handoff subprocess is detailed as:

REQUEST_CONTROL

This message is used to request control of the target system from a GCS. The GCS is able to define the control target being the flight control and/or the payload control. It can further specify a text Id as a string identifying the GCS and give a reason for taking over control. This messages can be relayed to the GCS currently in control to get additional information as to why the control has to be handed over. If no GCS is currently in control, the request is accepted immediately, else, a handoff request to the current GCS in control is send.
Further, a request priority can be given. If the priority is higher than the priority of the GCS currently in control, the control is given over directly without additional request of the current GCS in control. This is used to be able to take the control by force.
Note that the system should check that a GCS has the necessary permission to make a priority request.

REQUEST_CONTROL_ACK

This message is used to give a feedback from the target system to the requesting GCS. It can detail as to why a request has been denied. To avoid diverging information, only the control_status should be check if the GCS is really in control.

CONTROL_STATUS

This message defines the currently in active controller for the flight control and payload control. This message is sent periodically and when a change in the current controller happened.

REQUEST_HANDOFF

This message is used from the target system when a control request is received but another GCS is already in control. It asks the GCS in control to hand over the control to the requesting GCS. it relays the requester id and reason such that the GCS in control can decide if he wants to hando ver the control

HANDOFF_RESPOND

This message is used from the current GCS in control to send it's decision for the handoff request.

RELEASE_CONTROL

This message can be used when a GCS wants to release the control of the flight and/or the payload control. If the control is released, the current controller is set to none in the target system.

A communication diagram is shown here:
Mavlink_distributed_GCS.drawio.pdf

<description>Status message indicating the currently active flight control and payload control entity.
This message should typically be send from the system at a low frequency as well as after a control ownership change to all connected GCS.
</description>
<field type="uint8_t" name="current_flight_controller" enum="CURRENT_CONTROL_ENTITY">Current flight control entity.</field>
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't understand how this works. It is emitted by an autopilot or autopilot payload to say what component or system it is being controlled by right?

So CURRENT_CONTROL_ENTITY_NONE makes sense "i'm not being controlled", but this is nonsensical:

  • `CURRENT_CONTROL_ENTITY_OWNER: Setting if the receiving GCS is the control entity.

Why? Because the message is received by everything on the network, so if there are multiple GCS they will all think they are the control entity right?

For this I would just emit a mavlink address. Perhaps future proof by making it a uint16_t.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Ditto for field below.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This message is not intended to be broadcasted to all GCS at the same time. As you correctly pointed out, that would not work with the enum entity. On the other hand i wanted to avoid using the system Id, as in the RAS-A protocol, they want to get rid of the system Id and replace it with the underlying transport protocol address (IP address/port in most cases). So we would need to send this message targeted for each GCS independently stating that they are in control or someone else. AS i don't expect a hugh amount of simultaneous connections, it should be feasible to send such targeted Messages.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I understand the point, but this will not work with MAVLink as it actually is. To be in common messages need to be standard - possible for anyone to take and use with the MAVLink 2 protocol. That is not the case, so I can't really engage on this.

Copy link
Collaborator

Choose a reason for hiding this comment

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

What I think you are saying is that a system that wants to send the message would not broadcast it. Instead it would send it to a specific recipient (say GCS A) using whatever mechanism is used for addressing (now system ID, but on RAS-A maybe some other address) and that system would get the enum value that was relevant - i.e. "you are the controller" or "something else is the controller". Is that right?

So this would be sent round robin to all GCS or other things that might want control?

The normal way in mavlink to do this would be to broadcast the the ID of the owning item.

@hamishwillee
Copy link
Collaborator

Big picture, is the problem you are trying to solve here how to have a separate GCS sending commands related to a payload and another for sending commands related to flight control?

I have questions:

  1. What is the set of payload commands? I mean specifically what set of commands and messages should be only accepted from a GCS that owns payload responsibility?
  2. Sometimes you're wanting to control the payload with, say, a joystick using MANUAL_CONTROL. How does the flight stack know that a particular MANUAL_CONTROL should be routed to the payload and not the flight control?
  3. Unlike CHANGE_OPERATOR_CONTROL any system can gain control, if it has priority, without having a key. Are you saying that this is only intended to be used on a secure network where all possible GCS are fully trusted?
  4. Can there be more than one payload ever?
  5. What are the possible payloads? Is a gimbal a payload? Is a camera a payload. A winch? If any of these are true, how do this API interact with any existing control mechanisms
  6. How does priority get set? Is it just that all GCS get a default priority and this can be changed by any GCS?

I am not sure about the handover mechanism; I'm more convinced by the priority bumping mechanism and forcing proper manual setup of the relative priorities.


Detail picture, this set of messages defines a possible approach for multiple GCS and a single vehicle. There is no way this will work for multiple vehicles because you have no target_system or target_component addressing. All messages are broadcast.

So for example if you send out a REQUEST_CONTROL you might get control over every vehicle on the network. Everything will get the ACK.

Assuming those are added it is worth thinking about addressing. At the moment you are setting the target-of-control as a payload or a flight stack.
Since a payload does not know it is a payload that means you need to always send the command to the autopilot and the autopilot needs to manage the relationship with the payload.

@KonradRudin
Copy link
Contributor Author

Big picture, is the problem you are trying to solve here how to have a separate GCS sending commands related to a payload and another for sending commands related to flight control?

Yes, potentially, One GCS can also be in control of both. But furthermore, there could be more GCS only observing the system state amd stream without being able to change the current mission/control/payloads.

I have questions:

  1. What is the set of payload commands? I mean specifically what set of commands and messages should be only accepted from a GCS that owns payload responsibility?

So far we have defined several MAV command which are either only be accepted by the controller or some which are also accepted from the observer. There no other messages we use for the payload control. All can request:

  • "MAV_CMD_REQUEST_CAMERA_SETTINGS",
  • "MAV_CMD_REQUEST_CAMERA_INFORMATION",
  • "MAV_CMD_REQUEST_VIDEO_STREAM_INFORMATION",
  • "MAV_CMD_REQUEST_VIDEO_STREAM_STATUS",
  • "MAV_CMD_REQUEST_STORAGE_INFORMATION",
  • "MAV_CMD_REQUEST_CAMERA_CAPTURE_STATUS",

Other MAV commands are only accepted by the payload controller. Those are:

  • "MAV_CMD_SET_CAMERA_MODE",
  • "MAV_CMD_STORAGE_FORMAT",
  • "MAV_CMD_IMAGE_START_CAPTURE",
  • "MAV_CMD_IMAGE_STOP_CAPTURE",
  • "MAV_CMD_VIDEO_START_CAPTURE",
  • "MAV_CMD_VIDEO_STOP_CAPTURE",
  • "MAV_CMD_VIDEO_START_STREAMING",
  • "MAV_CMD_VIDEO_STOP_STREAMING",
  • "MAV_CMD_CAMERA_TRACK_POINT",
  • "MAV_CMD_CAMERA_TRACK_RECTANGLE",
  • "MAV_CMD_CAMERA_STOP_TRACKING",
  • "MAV_CMD_DO_MOUNT_CONFIGURE",
  • "MAV_CMD_DO_MOUNT_CONTROL",
  • "MAV_CMD_DO_MOUNT_CONTROL_QUAT"
  1. Sometimes you're wanting to control the payload with, say, a joystick using MANUAL_CONTROL. How does the flight stack know that a particular MANUAL_CONTROL should be routed to the payload and not the flight control?

Maybe i misinterpreted the MANUAL_CONTROL message, but can you use that as well for the payload? It only has a target_system but not a target_component. How can you then distinguish it between a command for the payload and one for the flight controller?

  1. Unlike CHANGE_OPERATOR_CONTROL any system can gain control, if it has priority, without having a key. Are you saying that this is only intended to be used on a secure network where all possible GCS are fully trusted?

I wanted to have the control request and GCS authentication separated. A GCS should be authenticated even before sending a control request message, in order to decide if it can also receive the telemetry data. This message definitions are only for controller GCS but observer GCS would never send such a command. If a GCS is authenticated, the system should also know, if the GCS has the right to control it and which priority level the GCS has.

  1. Can there be more than one payload ever?

There can be, with this definition, only one GCS would control all payloads, this cannot be split to more GCSs. We just don't thought that this would be a use case, would need to extend it for several payloads.

  1. What are the possible payloads? Is a gimbal a payload? Is a camera a payload. A winch? If any of these are true, how do this API interact with any existing control mechanisms

Yes. those are all payloads. We have an app listening on all the GCS links which routes the mavlink messages. This app keeps track of the status of all GCSs which are in control/are observers only. It routes or denys the commands and streams between the GCS and the system (a bit like a firewall)

  1. How does priority get set? Is it just that all GCS get a default priority and this can be changed by any GCS?

The GCS can set the priority it wants for the request, but the System needs to check if the GCS is allowed to have this priority. This should be done with the GCS authentication, to authenticate, if the GCS can connect and a configuration stored onboard, which GCS has which priviledges (can it control the system? what priority level does it have?).
The priority in the control request is a means to forcefully take over the control from another GCS.

I am not sure about the handover mechanism; I'm more convinced by the priority bumping mechanism and forcing proper manual setup of the relative priorities.

I think the handover mechanism should be the normal way to gracefully hand over the control from one GCS to another. This allows for an in MAVLink way to communicate a control request between two GCSs without the need to coordinate the control request over another channel. Just forcefully take over control will not be a good practice when the GCS in control is currently using the system for some important operations.

Detail picture, this set of messages defines a possible approach for multiple GCS and a single vehicle. There is no way this will work for multiple vehicles because you have no target_system or target_component addressing. All messages are broadcast.

Ok, maybe i missed some params in the message definitions. The messages should not be broadcasts. (Coming from the RAS-A discussions, where the system if is not used anymore but directly replaced by the link address.). Where necessary, we would need to add the target_system value as well.

So for example if you send out a REQUEST_CONTROL you might get control over every vehicle on the network. Everything will get the ACK.

Assuming those are added it is worth thinking about addressing. At the moment you are setting the target-of-control as a payload or a flight stack. Since a payload does not know it is a payload that means you need to always send the command to the autopilot and the autopilot needs to manage the relationship with the payload.

@hamishwillee
Copy link
Collaborator

Thanks for your answer. If you want this considered in the standard it has to be able to work on MAVLink 2 and then if RAS-A want to do some other transport/routing they need to consider this in terms of a "removal".

I need to think about the rest and get more people on this. We can perhaps discuss it in next weeks MAVlink call. Do you think you might attend?

@hamishwillee
Copy link
Collaborator

PS

Maybe i misinterpreted the MANUAL_CONTROL message, but can you use that as well for the payload? It only has a target_system but not a target_component. How can you then distinguish it between a command for the payload and one for the flight controller?

True. But all messages have a source, so while everyone will get this, in theory a payload can know that it accepts this from a particular source. I'm not advocating :-)

@KonradRudin
Copy link
Contributor Author

Thanks for your answer. If you want this considered in the standard it has to be able to work on MAVLink 2 and then if RAS-A want to do some other transport/routing they need to consider this in terms of a "removal".

Yes, the goal would be to make the protocol work for both. I just was in the "RAS-A" world and forgot to include the target_system field in all the messages. I have added them already to specify, that the message is not intended as broadcast. The only thing we need to think about is the control_status message.

I need to think about the rest and get more people on this. We can perhaps discuss it in next weeks MAVlink call. Do you think you might attend?

Yes i intend to join the meeting to discuss this further since it is not only a single messsage. I also made a RFCs PR mavlink/rfcs#22 for this reason to discuss it in the next call.

@ThomasDebrunner
Copy link
Contributor

ThomasDebrunner commented Mar 13, 2023

We assume here that multiple GCS can have the same system ID.

For this protocol specifically, requiring each GCS to have a unique, deconflicted system-id adds a unnecessary constraint on the usefulness of this.

The system ID in mavlink is used for both routing and identification.

Mavlink does not have a process to assign system IDs.
All the routing software there is for mavlink does dynamic discovery and assumes that all heartbeats from all connected
systems are always present. Unless we re-invent all the routing infrastructure that has been done for IP
for mavlink, this absolutely does not scale.

At the same time, unless we do in-protocol routing (like mavlink does at the moment), all packets come from an identifyable source. Most notably, on IP networks, all packets come from a distinguishable IP/Port combo.

In RAS-A, we say that there is no more in-protocol routing. This means, that the system ID loses its significance (it is depreacted in there). Each component can distinguish the incoming streams based on their routing protocol origin (in the case of IP, its the IP/Port combo). This solves routing. A user can use all off-the shelf hard and software for routing packets. The underlying routing protocol is responsible for routing, not mavlink.

This does not solve identification. Identification does not have to happen with every packet. Since each incoming stream is distinguishable by its origin from the routing protocol. You only have to identify each origin once.

Now, do we really need identification? Maybe we do. If we do, it might as well be some sort of globally unique mavlink-id that is rasonable big, since it only has to be transmitted once. This would allow to re-identify a unqiue mavlink system. But we shouldn't mix that with routing.

Note that also using IP addresses for identification (not routing) is bad, since IP / ports will change when you have NATs in the system. This is not a problem, as IP handles routing through NATs just fine, it's just that IPs are not global identifiers in general.

@ThomasDebrunner
Copy link
Contributor

ThomasDebrunner commented Mar 13, 2023

In RAS-A, we say that there is no more in-protocol routing.

On system level that is, the component ID is still considered valid for on-vehicle routing. Since there, the whole configuration is known at assembly time, the IDs can be deconflicted ahead of the time, so it is not an issue there.

@hamishwillee
Copy link
Collaborator

@ThomasDebrunner Mavlink does have a process to assign system IDs - manual assignment :-). Designing an automated assignment mechanism for them would be pretty easy, just has never been anyone who wanted to do stand up as the stakeholder. I wish there was - it's really an obvious necessity as you scale past more than a few vehicles.

But that's not really the point you're making, which I take to be that RAS-A plans to use IP addresses for routing. I think I need to understand more about this.

Imagine I have a new-style IP MAVLink network. I connect 2 GCS (A, B) and 3 drones (X, Y, Z). All the drones are broadcasting telemetry. GCS A wants to send a command to drone Y.

  1. When the nodes connect to the network, how do they get addresses? DHCP?
  2. How do nodes discover each other? Is it that as currently they are required to broadcast a heartbeat. From this heartbeat the recipient is able to determine the source IP address, and that is used for addressing?
  3. So GCS A discovers all the drones and has their addresses, but it isn't supposed to use that for identity - how does it send the command to drone Y? How does drone Y respond, if it doesn't know that GCS A has perhaps moved?

@ThomasDebrunner
Copy link
Contributor

ThomasDebrunner commented Mar 15, 2023

@ThomasDebrunner Mavlink does have a process to assign system IDs - manual assignment :-). Designing an automated assignment mechanism for them would be pretty easy, just has never been anyone who wanted to do stand up as the stakeholder. I wish there was - it's really an obvious necessity as you scale past more than a few vehicles.

But that's not really the point you're making, which I take to be that RAS-A plans to use IP addresses for routing. I think I need to understand more about this.

Imagine I have a new-style IP MAVLink network. I connect 2 GCS (A, B) and 3 drones (X, Y, Z). All the drones are broadcasting telemetry. GCS A wants to send a command to drone Y.

  1. When the nodes connect to the network, how do they get addresses? DHCP?

This is then outside of the scope of mavlink - As this becomes just a network configuration issue. Depending on the setup, one has different options. In most cases DHCP, since that's the standard, but for certain setups, also manual assignment is possible. Also, for complicated setuo you may have multiple sub-nets with routing rules between them, or NAT. All is possible and solved, no need to re-invent.

Also, mavlink itself should not depend on an IP address actually being preset, or even that it is being sent over an IP network. All it should care about, is that the underlying routing protocol you use can differentiate between different origins, and can send messages to various places. IP is the most common routing protocol that fulfills this, but mavlink shouldn't have a hard dependency on IP either. That's the case for other protocols, e.g. TCP does not necesseraily have to go over IP.

  1. How do nodes discover each other? Is it that as currently they are required to broadcast a heartbeat. From this heartbeat the recipient is able to determine the source IP address, and that is used for addressing?

Effectively a mavlink "server" knows about the existence of another mavlink device when it receives its heartbeat. A mavlink client sends a heartbeat to a "server" to initiate the connection. How does the "client" know about the existence of the server? Well, that's also something current mavlink doesn't solve. In current implementations if you use serial, then the data goes wherever the serial goes, if you use UDP, you either know where to establish the stream to or you broadcast in the entire network segment.

In reality, in all mavlink gcs <> drone setups that I have seen so far, one of the participants knows the IP of the other, or they use serial. If we want to have real dynamic discovery, again, this is something that can be easily be solved with existing technologies. For local discovery in an IP network segment, one can use mDNS to discover services on other devices, mavlink can be one of them.

  1. So GCS A discovers all the drones and has their addresses, but it isn't supposed to use that for identity - how does it send the command to drone Y? How does drone Y respond, if it doesn't know that GCS A has perhaps moved?

It sends the command to the IP / Port where the drone is. Drone Y responds to where the command came from.
Also if they are both "connected", they keep sending each other HEARTBEATS. With "moved" you mean that it changed IP address? In that case, you'd have connection loss to GCS A, and then a new GCS connects again on a different IP address. The drone wouldn't know it is the same GCS.

This is what i meant with potentially introducing some sort of global "mavlink id", in that case, the drone could request some "global mavlink id" on a new connection, and then re-identify the connected GCS as GCS A. Now, this id could be quite large, e.g. 256bit (32 bytes). Such long integers could quite easily be random generated and be globally unique, even contain vendor prefix etc. This ID is then only transmitted on request, since it is not used for routing. Routing is part of the underlying protocol.

I don't think we need such a "global mavlink id" right now though, as any GCS that switches IP is then just considered a new GCS, re-identification is not necessarlily required.

@ThomasDebrunner
Copy link
Contributor

Designing an automated assignment mechanism for them would be pretty easy

Somebody in RAS-A looked quite intensively into that and came up with a proposal. What you get in the end is essentially MAVDHCP. I wouldn't say that is is terribly difficult, but do we really want to re-implement every network protocol from the 1980's, slightly worse, and with a "mav" prefix? :)

@hamishwillee
Copy link
Collaborator

Designing an automated assignment mechanism for them would be pretty easy

Somebody in RAS-A looked quite intensively into that and came up with a proposal. What you get in the end is essentially MAVDHCP. I wouldn't say that is is terribly difficult, but do we really want to re-implement every network protocol from the 1980's, slightly worse, and with a "mav" prefix? :)

No, but we probably want this one - albeit not for your case. The "over IP" is a RAS-A constraint to which MAVLink is not tied. If the MAVLink 2.1 proposal goes in then there will be 16 bit addresses and the normal MAVLink will need it.

@hamishwillee
Copy link
Collaborator

@KonradRudin Thanks for coming to the call last night. The summary of my understanding is:

  • Use case makes a lot of sense.
  • The ownership message won't work as is. Using round robin to notify all connected targets in order to emulate broadcast might make sense in the RAS-A world, but is not a sensible design for current MAVLink.
  • Setting priority in the requestor won't work "psychologically"; users will just set max.
  • The operating pilot always needs to be able to take control in a way that can't be superseded. Upshot, ownership of the priority system needs to be rethought.
  • Having the payload thing mediate handover looks good.
  • Where possible use MAV_CMDs - that way you get an ACK of success.

@ThomasDebrunner
Copy link
Contributor

@hamishwillee But the broadcast approach itself doesn't scale, no? The design of mavlink suggests that if a message has no target system or target component, it would have to be broadcast to alll systems on the network. In the case of multiple drones, each drone would end up with the full telemetry of all other drones, as the GCS would always have to re-broadcast the telemetry from one drone to all the other drones.

Unless there are some implicit routing rules, that a GCS doesn't broadcast? Or that two systems connected to the same GCS are two distinct mavlink networks? In that case, the GCS would then need a system ID per vehicle it could connect to.

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.

None yet

3 participants