Mavsdk: How to connect mavsdk-server to multiple devices?

Created on 15 Dec 2019  路  14Comments  路  Source: mavlink/MAVSDK

Hey,

I simulate 3 drones on ports 14541,14542 and 14543. How to connect all of them to mavsdk-server?
I tried to use mavlink-routerd with argument
-e 127.0.0.1:14544 0.0.0.0.14540
but it blocks port with bind error :(

Most helpful comment

Might be nice to add a FAQ on this in https://github.com/mavlink/MAVSDK-Python#mavsdk-python - since we get quite a lot of questions. Depends on how soon you think this will be done "properly".

All 14 comments

For now, mavsdk_server does not support multiple drones (i.e. multiple drones running on the same MAVLink port, here 14540). Only MAVSDK-C++ does.

However, you can run multiple instances of mavsdk_server, each listenning to a different mavlink port, by using the latest develop branch of MAVSDK.

That would be something like:

./mavsdk_server -p 50040 udp://:14540
./mavsdk_server -p 50041 udp://:14541
./mavsdk_server -p 50042 udp://:14542

And then you could instantiate multiple instances of a wrapper. For instance in Python:

from mavsdk import System

...

drone1 = System(mavsdk_server_address="localhost", port=50040)
await drone1.connect()
drone2 = System(mavsdk_server_address="localhost", port=50041)
await drone2.connect()
drone3 = System(mavsdk_server_address="localhost", port=50042)
await drone3.connect()

...

And then you could use your drone objects (drone1, drone2 and drone3 separately):

await drone1.action.arm()
await drone2.action.arm()
await drone3.action.arm()

Might be nice to add a FAQ on this in https://github.com/mavlink/MAVSDK-Python#mavsdk-python - since we get quite a lot of questions. Depends on how soon you think this will be done "properly".

I'm trying to run this command, but it fails with bind error
./mavsdk_server -p 50041 udp://:14541

Drone definition in launch file:

<group ns="uav1"> <!-- MAVROS and vehicle configs --> <arg name="ID" value="1"/> <arg name="fcu_url" default="udp://:14541@localhost:14581"/> <!-- PX4 SITL and vehicle spawn --> <include file="$(find px4)/launch/single_vehicle_spawn.launch"> <arg name="x" value="0"/> <arg name="y" value="0"/> <arg name="z" value="0"/> <arg name="R" value="0"/> <arg name="P" value="0"/> <arg name="Y" value="0"/> <arg name="vehicle" value="$(arg vehicle)"/> <arg name="mavlink_udp_port" value="14561"/> <arg name="mavlink_tcp_port" value="4561"/> <arg name="ID" value="$(arg ID)"/> </include> <!-- MAVROS --> <include file="$(find mavros)/launch/px4.launch"> <arg name="fcu_url" value="$(arg fcu_url)"/> <arg name="gcs_url" value=""/> <arg name="tgt_system" value="$(eval 1 + arg('ID'))"/> <arg name="tgt_component" value="1"/> </include> </group>

but it fails with bind error

What does that mean? "Address already in use"? Are you sure that port 50041 is free?

What does that mean? "Address already in use"? Are you sure that port 50041 is free?

When I'm trying to launch server after launching simulation, it's doing that:

kris@kris-VirtualBox:~$ mavsdk_server -p 50041 udp://:14541
[04:21:44|Info ] MAVSDK version: 0.22.0-11-gf0788f6b (mavsdk_impl.cpp:25)
[04:21:44|Debug] New: System ID: 0 Comp ID: 0 (mavsdk_impl.cpp:401)
[04:21:44|Info ] Server started (grpc_server.cpp:38)
[04:21:44|Info ] Server set to listen on 0.0.0.0:50041 (grpc_server.cpp:39)
[04:21:44|Info ] Waiting to discover system on udp://:14541... (connection_initiator.h:22)
[04:21:44|Error] bind error: Address already in use (udp_connection.cpp:85)
[04:21:44|Error] Connection failed: Bind error (connection_initiator.h:48)

port 50041 is free, but server complains about other port...

What if you run mavsdk_server before the simulation? It's weird, because the simulator should not bind to 14541, but broadcast to it... :thinking:

What if you run mavsdk_server before the simulation? It's weird, because the simulator should not bind to 14541, but broadcast to it...

This happens when I'm running Gazebo:

[ INFO] [1576522428.076745275]: FCU URL: udp://:14541@localhost:14581
[ INFO] [1576522428.082737616]: udp0: Bind address: 0.0.0.0:14541
[ INFO] [1576522428.082938627]: udp0: Remote address: 127.0.0.1:14581
[FATAL] [1576522428.083400970]: FCU: DeviceError:udp:bind: Address already in use

when I'm trying to discover device @ port 14581 this happens (also in Gazebo ofc):

INFO  [mavlink] mode: Onboard, data rate: 4000000 B/s on udp port 14581 remote port 14541
WARN  [mavlink] bind failed: Address already in use

when I'm trying to discover device @ port 14561 nothing happens at all...

May I ask which command you use to run multiple instances in gazebo?

May I ask which command you use to run multiple instances in gazebo?

I wrote bash file for that:

#!/bin/bash

cd ~/Pobrane/src/Firmware
source Tools/setup_gazebo.bash $(pwd) $(pwd)/build/px4_sitl_default
export ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH:$(pwd):$(pwd)/Tools/sitl_gazebo
roslaunch px4 3drones.launch

listing of launchfile:

<?xml version="1.0"?>
<launch>
    <!-- MAVROS posix SITL environment launch script -->
    <!-- launches Gazebo environment and 2x: MAVROS, PX4 SITL, and spawns vehicle -->
    <!-- vehicle model and world -->
    <arg name="est" default="ekf2"/>
    <arg name="vehicle" default="iris"/>
    <arg name="world" default="$(find mavlink_sitl_gazebo)/worlds/empty.world"/>
    <!-- gazebo configs -->
    <arg name="gui" default="false"/>
    <arg name="debug" default="false"/>
    <arg name="verbose" default="false"/>
    <arg name="paused" default="false"/>
    <!-- Gazebo sim -->
    <include file="$(find gazebo_ros)/launch/empty_world.launch">
        <arg name="gui" value="$(arg gui)"/>
        <arg name="world_name" value="$(arg world)"/>
        <arg name="debug" value="$(arg debug)"/>
        <arg name="verbose" value="$(arg verbose)"/>
        <arg name="paused" value="$(arg paused)"/>
    </include>
    <!-- UAV0 -->
    <group ns="uav1">
        <!-- MAVROS and vehicle configs -->
        <arg name="ID" value="1"/>
        <arg name="fcu_url" default="udp://:14541@localhost:14581"/>
        <!-- PX4 SITL and vehicle spawn -->
        <include file="$(find px4)/launch/single_vehicle_spawn.launch">
            <arg name="x" value="0"/>
            <arg name="y" value="0"/>
            <arg name="z" value="0"/>
            <arg name="R" value="0"/>
            <arg name="P" value="0"/>
            <arg name="Y" value="0"/>
            <arg name="vehicle" value="$(arg vehicle)"/>
            <arg name="mavlink_udp_port" value="14561"/>
            <arg name="mavlink_tcp_port" value="4561"/>
            <arg name="ID" value="$(arg ID)"/>
        </include>
        <!-- MAVROS -->
        <include file="$(find mavros)/launch/px4.launch">
            <arg name="fcu_url" value="$(arg fcu_url)"/>
            <arg name="gcs_url" value=""/>
            <arg name="tgt_system" value="$(eval 1 + arg('ID'))"/>
            <arg name="tgt_component" value="1"/>
        </include>
    </group>
    <!-- UAV1 -->
    <group ns="uav2">
        <!-- MAVROS and vehicle configs -->
        <arg name="ID" value="2"/>
        <arg name="fcu_url" default="udp://:14542@localhost:14582"/>
        <!-- PX4 SITL and vehicle spawn -->
        <include file="$(find px4)/launch/single_vehicle_spawn.launch">
            <arg name="x" value="1"/>
            <arg name="y" value="0"/>
            <arg name="z" value="0"/>
            <arg name="R" value="0"/>
            <arg name="P" value="0"/>
            <arg name="Y" value="0"/>
            <arg name="vehicle" value="$(arg vehicle)"/>
            <arg name="mavlink_udp_port" value="14562"/>
            <arg name="mavlink_tcp_port" value="4562"/>
            <arg name="ID" value="$(arg ID)"/>
        </include>
        <!-- MAVROS -->
        <include file="$(find mavros)/launch/px4.launch">
            <arg name="fcu_url" value="$(arg fcu_url)"/>
            <arg name="gcs_url" value=""/>
            <arg name="tgt_system" value="$(eval 1 + arg('ID'))"/>
            <arg name="tgt_component" value="1"/>
        </include>
    </group>
    <!-- UAV2 -->
    <group ns="uav3">
        <!-- MAVROS and vehicle configs -->
        <arg name="ID" value="3"/>
        <arg name="fcu_url" default="udp://:14543@localhost:14583"/>
        <!-- PX4 SITL and vehicle spawn -->
        <include file="$(find px4)/launch/single_vehicle_spawn.launch">
            <arg name="x" value="0"/>
            <arg name="y" value="1"/>
            <arg name="z" value="0"/>
            <arg name="R" value="0"/>
            <arg name="P" value="0"/>
            <arg name="Y" value="0"/>
            <arg name="vehicle" value="$(arg vehicle)"/>
            <arg name="mavlink_udp_port" value="14563"/>
            <arg name="mavlink_tcp_port" value="4563"/>
            <arg name="ID" value="$(arg ID)"/>
        </include>
        <!-- MAVROS -->
        <include file="$(find mavros)/launch/px4.launch">
            <arg name="fcu_url" value="$(arg fcu_url)"/>
            <arg name="gcs_url" value=""/>
            <arg name="tgt_system" value="$(eval 1 + arg('ID'))"/>
            <arg name="tgt_component" value="1"/>
        </include>
    </group>
</launch>
<!-- to add more UAVs (up to 10):
Increase the id
Change the name space
Set the FCU to default="udp://:14540+id@localhost:14550+id"
Set the malink_udp_port to 14560+id) -->

It seems to me that MAVROS is the one binding to those ports:

<!-- MAVROS and vehicle configs -->
        <arg name="ID" value="1"/>
        <arg name="fcu_url" default="udp://:14541@localhost:14581"/>

You can't bind both MAVROS and MAVSDK to the same port at the same time. So if you need both MAVROS and MAVSDK, you need to add new mavlink interfaces for MAVSDK.

Do you need MAVROS at all?

Do you need MAVROS at all?

I think I don't need it, because I will be steering drones by MAVSDK; MAVROS was installed from PX4 stack though...

Right. Have a look at this PR, then: https://github.com/PX4/Firmware/pull/13729. I believe this is what you want!

I don't know if this helps anyone, but I spent a shameful couple of hours trying to debug the bind error: 10048 issue. In my case, I wasn't specifying the port properly. I was writing ./mavsdk_server udp://14541 -p 50051 when I should have been writing ./mavsdk_server udp://:14541 -p 50051. Live and learn I guess!

This link helps to understand how mavsdk_server communicates with simulators and mavsdk_clients and helped me figure out my bug: https://github.com/mavlink/MAVSDK/issues/1130#issuecomment-644386229

Thanks for the note @thomasgauvin. I have realized this subtle difference before, and I'm not quite sure where it comes from.

I've created an issue: https://github.com/mavlink/MAVSDK/issues/1299

Was this page helpful?
0 / 5 - 0 ratings

Related issues

tpennypacker picture tpennypacker  路  5Comments

shakthi-prashanth-m picture shakthi-prashanth-m  路  7Comments

physicsman picture physicsman  路  6Comments

bozkurthan picture bozkurthan  路  7Comments

hamishwillee picture hamishwillee  路  6Comments