Autogeneration
MAVSDK is available in a number of different languages. These all share the same "core" MAVLink implementation (written in C++), but almost all of the API-specific code for other languages is autogenerated from API definition files (and language-specific templates).
This approach means that we don't have to maintain a separate MAVLink implementation or API for each language. New features are implemented (just once) in C++, and are then automatically available in Python, Java, etc.
This page provides an overview of the architecture and explains how to add a feature using the autogeneration.
Overview
The common MAVLink implementation is written in C++ (it is part of MAVSDK-C++).
The mavsdk_server
exposes the MAVSDK-C++ API over gRPC to the language bindings.
The API for all languages is autogenerated from a single common definition.
The following parts are autogenerated:
- MAVSDK-C++ API (i.e. header files)
- Most of
mavsdk_server
- Most of the language bindings
Those parts are maintained manually:
- MAVSDK-C++ implementation (i.e. the MAVLink business logic)
- New plugins need to be added to
mavsdk_server
(this may be automated in future) - The
System
wrapper in language bindings usually needs to be updated whenever a new plugin is added (this may be automated in future)
The heart of the autogeneration system is the MAVSDK-Proto repository which is described below.
Autogeneration Mechanisms
The autogeneration pipeline is shown below:
The main parts are:
protoc-gen-mavsdk
, which is aprotoc
custom plugin generating MAVSDK's code.- The API definition, in the form of proto files.
- Template files (per language, see e.g. the Python templates or the C++ templates).
protoc
takes the custom plugin (protoc-gen-mavsdk
) and the template files as inputs, and generate source code out of it.
The way it currently works is that it generates one source file out of each *.proto
file. For instance, action.proto
becomes Action.java
in MAVSDK-Java.
In some languages (typically C++), we need to generate multiple source files out of one proto definition file, and this is the reason why the C++ generation script runs protoc in multiple passes, once for each template (e.g. "templates/plugin_h" defines the templates to generate action.h
, telemetry.h
, ..., and "templates/plugin_cpp" is responsible for action.cpp
, telemetry.cpp
, ...).
All the MAVSDK repositories contain some kind of generate_from_proto.sh
file, and a templates/
directory:
- MAVSDK-C++: script, templates
- MAVSDK-Python: script, templates
- MAVSDK-Swift: script, templates
- MAVSDK-Java: script, templates
- MAVSDK-C#: script, templates
- MAVSDK-Go: script, templates
Adding a New Feature
When adding a new feature to MAVSDK it is important to think first about the API that is required, and later about the implementation needed to enable the feature. This is not only because MAVSDK strives to have a simple and safe API but also comes from the fact that a new feature needs to be defined in the API first and can then be implemented (using the autogenerated files) in a later step.
To add a new feature, follow the steps on how to write plugins.