28. starling-mavros
¶
This image acts to bridge MAVLink communications to ROS2 topics. At present this is achieved by a ROS1/2 bridge and the ROS1 version of MAVROS. The ROS2 port of MAVROS is currently under development and we anticipate switching over in the future, eliminating the need for the ROS1/2 bridge.
28.1 Contents¶
28.2 Overview¶
The image is a wrapper around MAVROS, as such, most of the documentation for MAVROS is of use when working with this
image. The image has both mavros
and mavros-extras
installed so all plugins should be available.
The published topics are namespaced to allow for running multiple vehicles on the same ROS network. By default, this
namespace will be /vehicle_N
, where N
is the MAVLink system ID of the vehicle. MAVROS topics are published within
this namespace, e.g. /vehicle_1/mavros/state
.
The image has been setup to automatically configure itself in some scenarios:
- Running on a vehicle
- Running in Kubernetes
There are also some additional general nodes running in the background. In particular:
- Emergency Stop listener on the
/emergency_stop
topic of typestd_msgs/msg/Empty
. It is hard-wired to forcefully disarm the vehicle (stop motors) for both PX4 and Ardupilot in simulation and reality.
28.3 Configuration Options¶
There are many configuration options available for this image to allow it to be used flexibly across different deployment scenarios. The most important of these are those relating to the vehicle and GCS connections, and MAVROS configuration. A full summary is given in the table below.
Name | Default Value | Description |
---|---|---|
MAVROS_FCU_CONN |
"udp" | Protocol for autogenerated FCU URL |
MAVROS_FCU_IP |
"127.0.0.1" | IP for autogenerated FCU_URL |
MAVROS_FCU_UDP_BASE |
"14830" | Base port for autogenerated FCU_URL |
MAVROS_TGT_SYSTEM |
"auto" | Target system ID, if set to a number, this will override the automatic behaviour |
PX4_INSTANCE_BASE |
0 | Base instance for autogenerated instance matching |
MAVROS_TGT_FIRMWARE |
"px4" | Firmware profile used by MAVROS. Only other valid value currently is "apm" |
MAVROS_GCS_URL |
"udp-pb://@:14550" | MAVROS URL for ground control station connection |
MAVROS_FCU_URL |
{unset} | MAVROS URL for FCU connection. Set to override automatic behaviour |
VEHICLE_NAMESPACE |
{unset} | Namespace for mavros topics. Set to override default value of vehicle_${TGT_SYSTEM} |
MAVROS_PLUGINLISTS_PATH |
"/mavros_pluginlists_px4.yaml" | Path for MAVROS pluginlists file |
MAVROS_CONFIG_PATH |
"/mavros_config_px4.yaml" | Path for initial MAVROS configuration file |
MAVROS_MOD_CONFIG_PATH |
"/mavros_config_mod.yaml" | Path for modified MAVROS config to be written to |
BRIDGE_CONFIG_PATH |
"/bridge_config.yaml" | Path for initial bridge config file |
BRIDGE_MOD_CONFIG_PATH |
"/bridge_config_mod.yaml" | Path for modified bridge config to be written to |
BRIDGE_LAUNCH_DELAY |
2.0 | Time delay in seconds between starting ROS1 mavros and the ROS1-2 bridge. Increasing this value reduces the chance of a race condition causing mavros failure due to the bridge being unable to read ros1 parameters. See this issue for more details. Recommendation is to increase the value to 10 seconds if this occurs. |
28.3.1 Configuring the Connection¶
MAVROS is told to connect to a MAVLink source with a URL. This URL can be configured in a number of ways. The most
straightforward is to simply set the MAVROS_FCU_URL
environment variable. This will override any other behaviour.
docker run -e MAVROS_FCU_URL=serial:///dev/ttyUSB0:115200 uobflightlabstarling/starling-mavros
When setting MAVROS_FCU_URL
directly, note that a query string (e.g. ?ids=n,240
) will be added during launch.
You need to ensure that your input for MAVROS_FCU_URL
supports this syntax. Of particular note is the need for a
trailing /
in most formats, but not for the serial://
format. Also note that the plain file format does not support
this. See the MAVROS docs for more
information on URL formats.
MAVROS_FCU_URL
is can also be set automatically by the container depending on its environment. If there is a
vehicle.config
file mounted in the image, the value of VEHICLE_FCU_URL
from that file will be used as the fcu_url
.
This is especially useful when deploying the container onto physical vehicles. The same warning about trailing slashes
above goes for the value put in vehicle.config
.
If there is no vehicle.config
file, the image will configure itself based on the values of MAVROS_FCU_CONN
,
MAVROS_FCU_IP
and MAVROS_FCU_UDP_BASE
. An additional parameter, INSTANCE
is also used in the construction of the
URL. This is generated based on the container hostname and is intended for use in Kubernetes deployments to distinguish
multiple instances. PX4_INSTANCE_BASE
can be used to offset the fcu_url
will be constructed as below:
$MAVROS_FCU_CONN://$MAVROS_FCU_IP:$((MAVROS_FCU_UDP_BASE + INSTANCE))@/
With all values at default, this ends up as:
udp://127.0.0.1:14830@/
28.3.2 Configuring the Target System¶
Another important configuration option is the target system ID. This controls the target system that MAVROS sends in
some messages. As for the fcu_url
, the value can be explicitly overridden, this time using the MAVROS_TGT_SYSTEM
environment variable. Setting this will overrise all other values. If it is set to an invalid system ID, MAVROS will
be set to use a target ID of 1
.
If the environment variable is left at its default value of auto
, a similar flow to the fcu_url
occurs: if a
vehicle.config
file exists, the value of VEHICLE_MAVLINK_SYSID
from that file will be used. Otherwise, the value is
autogenerated based on the INSTANCE
parameter derived from the container hostname. Note that the INSTANCE
number is
0-indexed, while MAVLink system IDs start at 1
. Therefore, the system ID is set to one more than the INSTANCE
.
28.3.3 Configuring the MAVROS Configuration¶
Two sets of config.yaml
and pluginlists.yaml
files are installed in the root directory to provide alternatives for
PX4 and ArduPilot autopilots. These are named: /mavros_config_px4.yaml
and /mavros_pluginlists_px4.yaml
for the PX4
versions and /mavros_config_ap.yaml
and /mavros_pluginlists_ap.yaml
for the ArduPilot versions.
The easiest way to choose between the two is to set the MAVROS_CONFIG_PATH
and MAVROS_PLUGINLISTS_PATH
environment
variables. By default these point to the PX4 versions. To use the ArduPilot versions set both variables as below:
docker run -e MAVROS_CONFIG_PATH=/mavros_config_ap.yaml -e MAVROS_PLUGINLISTS_PATH=/mavros_pluginlists_ap.yaml ...
It is also possible to mount alternative configurations into the image and use the environment variables to configure MAVROS with them.
TODO: Example of mounted configuration
28.4 Deployments¶
28.4.1 Running on a vehicle¶
If the container is running on a drone, it expects to be able to find the /etc/starling/vehicle.config
file. This file
contains some information that MAVROS needs to be able to communicate with the flight controller. An example
vehicle.config
file is included below.
Note that the extended form of the serial URL is required for MAVROS's target "query string" to work.
VEHICLE_FCU_URL=serial:///dev/px4fmu:115200
VEHICLE_FIRMWARE=px4
VEHICLE_MAVLINK_SYSID=23
VEHICLE_NAME=clover23
28.4.2 Running under Kubernetes StatefulSet¶
When running as part of a Kubernetes StatefulSet, each pod's hostname has a trailing ordinal, of the form: HOSTNAME-N
.
The setup script parses the ordinal of its containing pod from the hostname and uses this, in combination with the
PX4_INSTANCE_BASE
variable to determine the INSTANCE
parameter. As outlined above, this is used to set up the ports
and the system ID. By default, these are configured to match those generated by a PX4 SITL instance set up with the same
ordinal. If the setup script fails to get the ordinal from the hostname, it will attempt to connect to a PX4 SITL with
PX4_INSTANCE=0
.
INSTANCE
is computed as $((PX4_INSTANCE_BASE + ORDINAL))
MAVROS_TGT_SYSTEM
will end up as $((INSTANCE + 1))
28.4.3 Running isolated¶
Default values will be used, equivalent to the Kubernetes case with ORDINAL=0
28.5 Implementation Details¶
28.5.1 Build Process¶
To ensure support for custom message types, ros1_bridge
needs to be built from source with the messages types to be
bridged available in both ROS1 and ROS2. The Dockerfile first installs MAVROS for ROS1 and the MAVROS messages for ROS2.
There are some additional steps to complete the installation of MAVROS under ROS1. Following this, the bridge is built.
This takes a long time (~20min) and gives little output, but have faith!
28.5.2 Entrypoint¶
The entrypoint to the container is the ros_entrypoint.sh
script. This script sources the environment setup files for
both the ROS1 and ROS2 environments. It then sources the environment setup file for the bridge, and finally the
mavros_setup.sh
file. This file contains the logic that sets up MAVROS in a specific way based on both environment
variables and files potentially mounted in the image.
The first part of this is checking for the existance of the /stc/starling/vehicle.config
file. If this file exists, it
is assumed that the container is running on a real vehicle. In this case, the file is sourced and values for the MAVLink
system ID, vehicle name, FCU URL, and firmware type are obtained.
The next phase is determining the appropriate target system ID. This is configured by the
Once the setup script has run, the default behaviour is to launch the mavros_bridge.launch.xml
file. This behaviour
should be usable in almost all cases. This is a ROS2 launch file. It instructs ros2 launch
to run the
ros1_bridge
node and an instance of ROS1's roslaunch
. This in turn launches the ROS1 mavros.launch
file,
which contains instructions to run the MAVROS node.
The ROS2 mavros_bridge.launch.xml
script defines a set of arguments to enable configuration of the MAVROS node.
These are ususally filled by the environment variables defined above. If the configurability provided here is
insufficient, the image can be run with a different command.
28.5.3 Names¶
MAVROS has a set of frame names that are embedded in its config file. To enable the use of multiple vehicles,
vehicle-specific frames need to be made unique. To that end a bunch of sedding happens at the end of mavros_setup.sh
to modify the frame names before they are passed on to MAVROS.
A similar scenario occurs with the topic names for the parameter bridge. This is hopefully a short-term problem while MAVROS finishes its port to ROS2.
28.6 Advanced Topics¶
28.6.1 Adding additional MAVROS plugins¶
This should be possible by mounting a volume with your plugin into the container. Assuming ROS tools are able to find it, MAVROS should load the plugin (if directed by the pluginlists file).