For our last post on ArduPilot, we will be diving into the variability found in the project. We examine aspects like the architectural decisions such as hardware abstraction. A more in-depth analysis of the architecture of ArduPilot can be found in our second post.
Variability in a software allows having different features to support different needs, like different environments or complexity levels. It can be expressed at several points along the development, such as offering different versions of the software or different configurations within it1.
Variability in ArduPilot
Let us first explore what kind of variability exists in ArduPilot, by looking at which features vary and then summarizing it in a feature model. Looking back to our analysis of its vision and features in our first post, we see that variability is central to ArduPilot because one of its principles is being versatile, which translates to supporting variability to meet anyone’s needs.
Which Features Vary and Who Benefits from It?
Immediately we see how ArduPilot features various vehicle types (copters, planes, rovers, boats, submarines) and supports many platforms (boards and operating systems). This provides end users the benefit of accessibility: everyone can use ArduPilot for essentially any vehicle project, using the board(s) of their preference. The inclusiveness is enriching also to developers in the drone business who seek to promote their hardware.
ArduPilot also exhibits variability by accommodating different sensor types using libraries, and any user interface program (or “ground station”) that is compatible via MAVLink (an open source drone communication software project with its own protocols). This high flexibility caters to a wide range of end users, from hobbyists seeking a simple control interface, to researchers wanting to do specific measurements in water or in air, or to aerospace enterprises testing out new vehicle concepts. Everyone can use the interface and sensors that suit their needs. Meanwhile developers benefit from not having to maintain a single complex interface that needs to please everyone.
Given that the support for each individual hardware and software option is a feature, we see that ArduPilot has many variable features, which we demonstrate in our model.
Is Any Feature Combination Possible?
ArduPilot’s extreme versatility may seem utopic at this point, but it is of course not possible to use every single feature at once. For example, helicopter firmware and applications will not work well for planes or the such, hence there being different codebases for different vehicles. As for subtler incompatibilities, due to the codebases developing independently, one vehicle’s firmware may support a new board while the other firmware will not have it until its next release2. Nevertheless, thanks to ArduPilot’s design meant to function like an abstract microcontroller3, a vehicle designer can choose virtually any sensor or actuator combination on any vehicle.
How do we Summarize the Variability?
Taking our architectural analysis of ArduPilot as a basis, and by consulting relevant documentation pages (overview4, sensors5, boards6, I/O3) and GitHub directories7, we can visually express the variability found in ArduPilot with a “feature model”, as shown below. However, ArduPilot’s variability is present not only in its own implemented code, but also in the system around it. Hence we have the second feature model to depict variability in an ArduPilot system.
We used Feature IDE to make the models. To elaborate on the legends, only one feature from an “alternative group” can be selected. “Concrete features” refer to features directly implemented in the code while “abstract features” are not implemented as themselves, but are collective names to define groups of implemented features8.
Variability within ArduPilot is manageable via the detailed documentation available for each of the main stakeholders. Throughout this section, we gathered the sources of information relevant to each of the stakeholders identified in our first post, mainly: the business owners, developers, and users of ArduPilot. These sources can thus be utilized by them to run different configurations/products and adequately update ArduPilot.
The business owners of ArduPilot properly manage variability by having access to various information such as financial metrics and a platform to overview proposals for new functionalities. This platform acts a direct line of communication with the ArduPilot domain experts, and is used for adding new features, or update old ones. Below is an example of a discussion between one of the domain experts of ArduPilot and a business owner, in which the latter is assessing the funding needed for a new capability9.
- ArduPilot’s developers have access to a multitude of documents relating to understanding and contributing to the code, testing, and debugging. Updating the code and adding new functionalities is thus made easier via the “Learning the code”10 section, which provides the developers with an introduction into the different codes of the various vehicles: adding parameters, adding new modes for flying or driving, a view of the libraries, etc. Additionally, ArduPilot has a strong developer community which communicates via weekly development calls, chats or by asking questions on Gitter or Mumble11 12.
In order to decrease the complexity of variability management for the developers, ArduPilot offers an Autotest Framework13 (based on ArduPilot’s SITL architecture) which allows for the creation of repeatable tests to prevent regressions in ArduPilot’s behaviour:
- It shortens the time spent for running the same scenario over and over again, and therefore renders the development process more efficient
- It allows to repeatedly replicate bad behaviour in ArduPilot, and assigns the specific tasks to each developer to handle it (“test-driven-development”)
- It reduces the risks of a regression in ArduPilot’s behaviour
- Coming to ArduPilot’s end-users, the latter have access to a thorough documentation describing the available features to be deployed, along with tutorials on how to correctly run ArduPilot on a vehicle, and leverage the tools available to control and monitor it. This documentation includes a detailed review of the different vehicles and tools available. Additionally, ArduPilot gives access to tutorials for running a project from start (setting up, flying/ driving, configuring the parameters, going through the logs, etc.) to end. Aiming to ease this variability management from a user’s point of view, ArduPilot thus offers a “First Time Setup and Configuration”14 for the different vehicles’ implementation, explaining critical aspects as relating to installing the ground station software, running the autopilot, loading the firmware on the boards, connecting mission planner to Autopilot and finally configuring the overall system. A tutorial on the users’ “first drive”15 or “first flight” is also available depending on the vehicle. Furthermore, for Windows users using the ground station Mission Planner, graphical interfaces help to set up and configure vehicles16.
ArduPilot’s Way of Implementing Variability
Having the different options within ArduPilot is cool, but it has to be implemented in some way or another. The most notable variability is the different vehicles it supports. As known, ArduPilot offers autopilot for various vehicle types, which means they have to deal with some of the vehicle specific features: a rover rides over land and a copter uses its rotor to fly. Another variability we will talk about are the operating systems ArduPilot support and how that is implemented.
Variability in Hardware: Vehicles
The users can utilize ArduPilot for their copter, or they may choose to use a plane, or any other supported vehicle type. Depending on the chosen vehicle, the user has to simply build the code using a specific command for the different vehicles. ArduPilot recommends users to use the build automation tool Waf to ease this building process17 18, which also serves as the mechanism for variability. Based on the command, Waf will compile the files specific for that vehicle. This enables the user to build different versions using the build environment mechanism. To keep everything clean, ArduPilot’s codebase has different folders for each vehicle type that only contain the code for that specific vehicle. This includes features that may be commonly shared among the vehicles, think of radio contact with the ground control. This results in very similar functions such as
do_aux_function_change_mode to appear in all vehicle codes. ArduPilot most likely chose to do this to ensure consistency, as some functions related to the radio contact are vehicle specific (think of initialization). The number of duplicate functions is not high to warrant a shared library for it, which may make things more complicated.
As the vehicle code is chosen during the building phase, we can say that the variability is bound at compile-time. After building the code, it is not possible to change anything without recompiling the code again.
If in the future a new vehicle type is added, ArduPilot would create a new folder that will be dedicated to that vehicle type. When building the code, only the specific code in that folder will be used.
Variability in Platform: Operating Systems
ArduPilot mainly supports two operating systems. These are Linux and ChibiOS. ChibiOS can be used for boards that uses the STM32 microcontroller in order to ensure real-time actions19. Linux can be used for most other boards, including the STM3220. Choosing which OS you want to use is done similar to choosing which vehicle code is used. Shown in this figure below are some of the commands to select the OS wanted on the board.
The option for OS is bound after building this code. Therefore, the variability in OS is compile-time binding as well. If more operating systems are going to be supported in the future, ArduPilot will most likely implement it by adding a new folder to the libraries folder. Currently, both for Linux and ChibiOS, a folder exists called
AP_HAL_ChibiOS. In here, the hardware abstraction layer (HAL) is present. Adding support for another OS means that a HAL needs to be created for that specific OS that can act as the middleman between the different libraries and the external hardware (more info about the layers is found in our second post).
Assessing ArduPilot’s Variability Decisions
The way ArduPilot implemented the variability is well thought out. The way their architecture is built based on the 3 layers (vehicle code, shared libraries and HAL) makes it easy to extend one of the layers, without changing any of the 2 other layers. Structuring the different layers in different folders gives a good overview and it is easy for users to contribute to specific parts of the code. Maintaining a good overview is important for the contributors, because no one likes spaghetticode, right? When one of the layers is expanded, the compiler needs to know where the new files are located. The build environment needs to be adjusted to add a new command and the files that needs to be build17. Luckily, this is not hard to scale. All in all, ArduPilot seems to have thought about scalability when new features are added, which is very important with rapid developments.
The overall variability is managed through the detailed documentation4 and the weekly developer meetings12. However, this only really covers the variability from the developers’ side. Currently, the Mission Planner includes a tool that can load the firmware on the board for ArduRover, ArduPlane and ArduCopter21. Unfortunately, the Mission Planner only works for Windows. We would recommended ArduPilot to expand this tool for other operating systems such as Linux and macOS, and to include loading firmware for ArduSub.
As for developers, it would be nice to have a feature model given in the documentation as we have presented earlier in this post. It will help, especially the contributors that are new to ArduPilot, to have a clear understanding of all dependencies and how they are grouped.