MAVSDK
MAVSDK copied to clipboard
Add Functionality to Broadcast to Interface without Explicit Vehicle Connection
I am working on recreating the QGC RTK Base station functionality in a C++ application on a raspberry pi. I have the PX4 GPS driver running and now I am trying to figure out how to get mavsdk to broadcast the RTK corrections to all vehicles on two different interfaces. One serial and the other is UDP.
It does not appear that mavsdk can do a broadcast to all connected vehicles. My approach is to discover all connected vehicles on the serial and UDP connections, then iterate through all of them doing a mavlink passthrough message to send the RTK corrections to each vehicle independently.
Would you mind sharing which MAVLink messages are being sent for RTK? I think it may make sense to add them in MAVSDK (instead of having to use the passthrough).
It does not appear that mavsdk can do a broadcast to all connected vehicles.
I would need more details about what you mean by "broadcast", because I find it generally ambiguous. Do you mean that you expect MAVSDK to send the message once over the air and have it reach all your vehicles, or do you want a helper such that you don't have to write a for loop to send the message once per discovered system?
This is the functionality in QGC. https://github.com/mavlink/qgroundcontrol/blob/master/src/GPS/RTCM/RTCMMavlink.cc#L24
It is sending GPS_RTCM_DATA. https://mavlink.io/en/messages/common.html#GPS_RTCM_DATA
I think the broadcast of RTCM data in QGC is similar to how the heartbeat message is sent. A helper that could be called that you pass the RTCM data and the interfaces you want it broadcast over would be helpful. Maybe this doesn't align with mavsdk and I should just implement it using the c mavlink headers like QGC does.
MAVSDK does not allow to broadcast messages right now. So right now it would just do the same loop as you do :+1:. I am not sure if broadcasting is in the scope of MAVSDK right now, because many things are not expecting to be broadcasted, right? Like all the commands, or basically any targeted message. Or is that incorrect?
I'm digging through QGC and it looks like it is also looking for vehicle heartbeats then sending targeted messages to them. So I'm not sure it is possible to broadcast to the entire network without knowing what the vehicle IP's are.
I was able to implement this functionality using the mavlink C library. I still think the ability to broadcast using mavsdk would be very useful to a lot of people in the future. You can leave this open or close it if you like.
Broadcasting over serial is easy. Here is the UDP broadcast code:
_socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
if (_socket_fd < 0) {
std::cout << "socket error: " << GET_ERROR(errno) << std::endl;
return ConnectionResult::SocketError;
}
int broadcastEnable = '1';
if(setsockopt(_socket_fd,SOL_SOCKET,SO_BROADCAST,&broadcastEnable,sizeof(broadcastEnable)) < 0) {
std::cout << "Error in setting Broadcast option: " << GET_ERROR(errno) << std::endl;
return ConnectionResult::SocketError;
}
uint8_t buffer[MAVLINK_MAX_PACKET_LEN];
uint16_t buffer_len = mavlink_msg_to_send_buffer(buffer, &message);
struct sockaddr_in addr {};
addr.sin_family = AF_INET;
addr.sin_port = htons(_broadcast_port_number);
addr.sin_addr.s_addr = inet_addr(_broadcast_ip.c_str());
sendto(_socket_fd,buffer,buffer_len,0,(sockaddr *)&addr,sizeof(addr));
I understand that broadcasting some messages may make sense (typically a GNSS base station wants to do just that). But at the MAVSDK level, the user does something like drone.action.takeoff()
, where drone
represents a MAVLink system (i.e. a pair of <sysid, compid>). Should MAVSDK allow for broadcasting the takeoff
command? Because a command is a reliable message, MAVSDK expects to receive an ACK, otherwise it will resend the message. How do you broadcast a reliable message? How many ACKs do you expect, and from which <sysid, compid>? What do you do if one of them times out? Do you consider that your takeoff
command failed? Or do you tell the user that it "partially succeeded"? Do you give a list of <sysid, compid>, with the result code for each of them?
I don't think it is trivial, but of course we are open to PRs if somebody figures out an nice API doing that in MAVSDK :blush:.
Maybe this is a hint that the MavlinkPassthrough plugin should not be a plugin but a direct API of the Mavsdk class. We could then add some sort of flag to signal the broadcast option.