mavlink / MAVSDK

API and library for MAVLink compatible systems written in C++17
https://mavsdk.mavlink.io
BSD 3-Clause "New" or "Revised" License
635 stars 508 forks source link

mavlink error when adding a udp connection with port forwarding On #2256

Closed SebastianRosewick closed 7 months ago

SebastianRosewick commented 8 months ago

Hello!

I would like to connect to the same PX4 sitl instance from multiple processes using an instance of mavsdk::Mavsdk. When i add a udp connection with the option ForwardingOn, the terminal with the px4 sitl instance that i tried to connect to is flooded with the warning: _WARN [mavlink] ODOMETRY: estimatortype 8 unsupported

The Mavsdk process also reports: _MAVLink: critical: ODOMETRY: estimatortype 8 unsupported

Any help would be much appreciated! Kinds Regards!

julianoes commented 8 months ago

Are you trying to do anything with odometry?

The error message is generated in PX4 here: https://github.com/PX4/PX4-Autopilot/blob/4a553938fb6bc7a853b83d175544fff26b404f68/src/modules/mavlink/mavlink_receiver.cpp#L1484

SebastianRosewick commented 7 months ago

Hi Julian,

i wasn't trying to do anything with odom, but i think i already found my mistake by falsely forwarding messages between two systems causing the estimator_type error. My goal was to use the telemetry plugin from two processes to get data from a leader drone. I guess PX4's remote port can only be used by one mavsdk instance at a time so i tried to write a broadcaster for the leading drone and to use the mavlink-router instead. Or is there actually a way to use two telemetry plugin instances on the same remote port?

Many thanks for your help! Sebastian

julianoes commented 7 months ago

Or is there actually a way to use two telemetry plugin instances on the same remote port?

Hm, why would you need that?

SebastianRosewick commented 7 months ago

I'm trying to simulate a leader drone with multiple followers that need to receive telemetry data from the leader.

julianoes commented 7 months ago

Ok, so the multiple followers are separate MAVLink components, or is it all one process?

If it's the former, you can use MAVLink forwarding. And if it is the latter you should be able to just subscribe multiple times to a telemetry subscription.

SebastianRosewick commented 7 months ago

Hello Julian,

yes, the followers would be separate MAVLink components running as own processes, e.g. on the follower-drones companion computer. What i understood from the documentation is that port forwarding is used within the same program only? When i try to connect to the same PX4 remote port (e.g. udp://:14540) from different processes with mavsdk::Mavsdk I always got a bind error: bind error: Address already in use (udp_connection.cpp:85) Connection error: Bind error

Sorry if Im slow on the uptake here, Thanks again!

julianoes commented 7 months ago

Oh, I see the confusion, no problem.

So what I mean is that you add two connections (or more) and you enable following between them. This means the messages are forwarded to another port, so that an additional MAVLink component (or MAVSDK process) can use it.

You can see an example here: https://github.com/julianoes/siyi-a8-mini-camera-manager/blob/main/camera-manager/camera_manager.cpp#L73-L83

And to prevent bind errors, you will have to use different ports.

SebastianRosewick commented 7 months ago

Thank you for the example.

I've been trying to setup the connections as following:

Process on the Follower:

ConnectionResult connection_result = mavsdk.add_any_connection("udp://127.0.0.1:14530", ForwardingOption::ForwardingOn);
    if (connection_result != ConnectionResult::Success) {
        std::cerr << "Connection error: " << connection_result << '\n';
        return 1;
    } else {
        std::cerr << "Succesful connection to udp://127.0.0.1:14530" << '\n';
    }

    while(mavsdk.systems().size() == 0){
        std::cout << "Waiting for system" << std::endl;
        sleep_for(std::chrono::seconds(1));
    }
    auto follower = mavsdk.systems().back();
    Telemetry tel_follower(follower);

    while(1){
        printf("%f\n", tel_follower.position().absolute_altitude_m);
        sleep_for(std::chrono::seconds(5));
    }

and the forwarding process:

ConnectionResult connection_result = mavsdk.add_any_connection("udp://127.0.0.1:14530", ForwardingOption::ForwardingOn);
    if (connection_result != ConnectionResult::Success) {
        std::cerr << "Connection error: " << connection_result << '\n';
        return 1;
    } else {
        std::cerr << "Succesful connection to udp://127.0.0.1:14530" << '\n';
    }
    sleep_for(std::chrono::seconds(3));

    // connect to px4_sitl
    connection_result = mavsdk.add_any_connection("udp://:14540", ForwardingOption::ForwardingOn);
    if (connection_result != ConnectionResult::Success) {
        std::cerr << "Connection error: " << connection_result << '\n';
        return 1;
    }
    while(mavsdk.systems().size() == 0){
        sleep_for(std::chrono::seconds(1));
    }
    std::cout << "Systems: " << mavsdk.systems().size() << std::endl;
    while(1) 
        sleep_for(std::chrono::seconds(2));

All connections are setup succesfully and the second process can also discover the drone. Unfortunately the discovery is not forwarded to the 'Follower' process. Screenshot_20240330_130127

julianoes commented 7 months ago

There is a difference between:

Listening on a port (on any network interface):

udp://:14530

Sending UDP to an IP and port:

udp://127.0.0.1:14530

Also see (https://github.com/mavlink/MAVSDK/blob/b87a21d9044b9385e570fe0dd3389b74a3d52c2d/src/mavsdk/core/include/mavsdk/mavsdk.h#L78-L81) (@JonasVautherin we need to fix this, people run into it again and again).

So, you need to change one of your two processes to:

ConnectionResult connection_result = mavsdk.add_any_connection("udp://:14530", ForwardingOption::ForwardingOn);
...
SebastianRosewick commented 7 months ago

My bad, it is described very well here in the docs. What i did now was on the forwarding process:

mavsdk.add_any_connection("udp://127.0.0.1:14530", ForwardingOption::ForwardingOn);
mavsdk.add_any_connection("udp://:14540", ForwardingOption::ForwardingOn);

for a bidirectional connection and on the subscribing process:

mavsdk.add_any_connection("udp://:14530", ForwardingOption::ForwardingOff);

So the system discovery is forwarded to the other process succesfully. On the subscribing process however i got errors and warnings looking like this:

[02:57:07|Error] Retrying failed (520) (mavlink_command_sender.cpp:344)
[02:57:08|Error] Retrying failed (512) (mavlink_command_sender.cpp:344)
.
.
.
[02:58:52|Warn ] sending again after 0.509955 s, retries to do: 3  (512). (mavlink_command_sender.cpp:317)
[02:58:52|Warn ] Request was for msg ID: 242 (mavlink_command_sender.cpp:323)

So maybe it is better to use mavsdk::TelemetryServer instead of forwarding the entire mavlink traffic of one system just to create a Telemetry Plugin in a different process?

I was able to get something good enough running for my purposes, so i would feel bad holding you back with this issue any more. Thanks again for your help and patience!

julianoes commented 7 months ago

Glad I could help! By any chance, do both of your mavsdk instances have the same sysid, compid? I would try to set the configuration custom and vary it, so that you don't end up with conflicts, which is what these retries could be caused by.

SebastianRosewick commented 7 months ago

You're right, after i set system_id and component_id explicitly, it did fix the error on the forwarding side. On the mavsdk instance that is handed the forwarded connection i still get errors for msg 242:

[01:44:22|Warn ] Request was for msg ID: 242 (mavlink_command_sender.cpp:323)
[01:44:22|Error] Retrying failed (512) (mavlink_command_sender.cpp:344)

So the subscriber to the forwarded connection is requested to send a MAV_CMD_PREFLIGHT_SET_SENSOR_OFFSETS, which it keeps failing to send? Both Configuration Types are set to ComponentType::Custom

In the mean time i set up a TelemetryServer instead and it is working without problems so far.

julianoes commented 7 months ago

242 would be a request for HOME_POSITION.

julianoes commented 7 months ago

Closing this. Comment again if it's still unclear.

SebastianRosewick commented 7 months ago

Yes, this can be closed. Sorry for the late reply and thank you again very much!