Designing robust quadcopter software based on a real-time partitioned operating system and formal verification techniques

. Currently, the creation of reliable unmanned aerial vehicles (drones) is an important task in science and technology because such devices can have a lot of use-cases in digital economy and modern life, so we need to ensure their reliability. In this article, we propose to assemble a quadcopter from low-cost components in order to obtain a hardware prototype, and also to develop a software solution for the flight controller with high-reliability requirements, which will meet avionics software standards, using existing open-source software solutions. We apply the results as a model for teaching courses «Components of operating systems» and «Software verification». In the study, we analyze the structure of quadcopters and flight controllers for them, and present a self-assembly solution. We describe Ardupilot as open-source software for unmanned aerial vehicles, the appropriate APM controller and methods of PID control. Today's avionics standard of reliable software for flight controllers is a real-time partitioned operating system that is capable to respond to events from devices with an expected speed, as well as to share processor time and memory between isolated partitions. A good example of such OS is the open-source POK (Partitioned Operating Kernel). In its repository, it contains an example design of a system for a quadcopter using AADL language for modeling its hardware and software. We apply such a technique with Model-driven engineering to a demo system that runs on real hardware and contains a flight management process with PID control as a partitioned process. Using a partitioned OS brings the reliability of flight system software to the next level. To increase the level of control logic correctness we propose to use formal verification methods. We also provide examples of verifiable properties at the level of code using the deductive approach as well as at the level of the cyber-physical system using Differential dynamic logic to prove the stability.


Introduction
Unmanned aerial vehicles (UAVs) also called drones are becoming a big part of our digital life. In this paper, we consider quadcopters -vehicles with four software-controllable motors. They can be used for taking nice videos, for delivering parcels from Internet stores to end-customer by air, and some people even proposed to use them on the FIFA World Cup to deliver the balls. However, in some countries, the use of UAVs is prohibited in public places, mostly because of fears of a poorly functioning machine falling from the air onto people. An example of last year's public testing of Russian Post delivering drone, which crashed after a few seconds from the start, shows us that we need to build highly reliable software for it, which should prevent the drone from failure and fall in the most of cases (breakages of hardware or software, incorrect and contradictory commands from a pilot). Also, we should take in mind that a drone is a representation of a normal air vehicle. Most of the technologies to build the quadcopter, to create the software for it, to control safety and liveness properties, to model physical properties of flight are the same as for big air vehicles, so it could be a cheap model to design of highly reliable aircraft. The scope of the work includes the following.  Assembling a flying quadcopter for the purpose of obtaining a hardware prototype (from components that are mass-marketed);  Developing a flight controller software solution with high-reliability requirements, which will coincide with the standards of avionics software (to some extent);  Obtaining a model for teaching courses on the design of operating system components and software verification. The first task covers selection of existing hardware components including passive (i.e., frame, battery, etc.) and active parts (their state could be read and changed by software, i.e., GPS sensor, accelerometer, controllable motors, etc.) with maximum compatibility; and selection of a basic flight controller, which manages the whole hardware system; we are going to write software for it. The second task is devoted to creating an operating system for the drone, which will be based on ARINC 653 [1] -an industrial standard interface of applied software for avionics and existing opensource solutions in a free code for flight controllers to produce control logic and interoperation with the hardware. And the last task is to apply the project achievements in the study process of future software engineers to improve the interest of students in system programming and to offer different tasks as lab works.

Related work
The task of building reliable software for UAVs (and also for aircraft) is strongly connected to developing an operating system that is robust according to the initial design. Today's OS for flight machines should be real-time and should offer memory space and time division capabilities. There exists an avionics industry standard for these requirements, created by the Aeronautical Radio, Inc., ARINC 653 [1]. BSD-licensed open-source POK OS, which satisfies this standard with some limitations, was created in France by Julien Delange [2]. It uses Model-Based Engineering approach [3,4] for describing the system configuration, and its source code is available in [5]. In Russia, JetOS, a certified operating system for aircraft, was created by GosNIIAS and ISP RAS [6,7] as a fork of POK with advanced debugging capabilities, rewritten scheduler, system partition feature and different platforms support. The code is partially available on GitHub under the GPLv3 licence [8]. Building robust software encompasses not only the proper design of the OS for the flight controller. It should also include formal verification of developed code and proof of software correctness to satisfy some requirements. ISP RAS is the leader in this field in Russia, the recent results were published in [9,10,11]. Their principal result is producing testing and deductive verification techniques and an adequate memory model, mainly used in checking of correctness of Linux modules. The task of building software and hardware for a drone is being solved in project Crazyflie [12] and the models are given in [13]. It is used in some universities, e.g., at Chalmers University of Technology where students build dynamic models for Crazyflie drone using the modeling language Modelica and then design control algorithms based on them [14].

The drone: components and terminology
Consider a drone that is assembled from scratch based on components available on the market. It consists of the following components (see fig. 1):  frame connects all the components and provides electrical routing of high-current energy to the motors (here we use a 450mm frame);  brushless motors (4х for a quadcopter) provide lifting force to the propellers, which allows the drone to fly or rotate;  ESC (Electronic Speed Controller) provides a high-level interface to control a corresponding motor, translates required RPM to electric voltage and controls the results of motors rotation;  battery (usually of the LiPo type) provides electricity to the drone, and the time of drone operation depends on it; a 11.1V, 3000mAh 3S battery provides about 10-15 mins of operation and requires a special balancing charger;  power module connected to the battery provides two electrical circuits: a low-current circuit to the flight controller and a high-current one to the motors, also it provides a controlling signal to the flight controller with the current state of the battery;  external GPS/compass module is used for getting current coordinates to use in waypoint algorithms, it should be separated from the flight controller and frame to minimize the effects of electrical noise;  telemetry is a radio transceiver that works at the frequency of 915Mhz and allows to make a channel to a ground control module to send the current state and receive commands by providing radio-transparent UART (communication port);  additional periphery is the useful load of a drone, in the simplest case it may be a camera, in more complex cases it may be for example a fire extinguishing device; such load can be operated by an additional controller or even by the main flight controller with special isolated processes;  flight controller is responsible for controlling the whole drone state (the states of all internal hardware components) and operating it like the car ECU; it has some sensors on-chip and software for flying either with operator's control and stand-alone. Our goal is to create reliable software for it.

Ardupilot / Adrucopter
Ardupilot project [16,17] is the most known open-source project to provide free software to control the drones with its Arducopter codebase (as well as rovers and planes, refer to Ardurover and Arduplane codebases respectively) and high-level abstraction to operate hardware components for them. The source code of control is based on the recent results of the UAV research community, so it is a good base for tracking recent achievements. Inside, it consists of HAL (Hardware Abstraction Layer) that allows to run the system on different hardware platforms, main scheduling loop and a set of different libraries that provide some code to communicate with a particular device (get and store data), mathematical calculations, control algorithms. We are mostly interested in the following libraries:  AC_PID: a library to implement an algorithm of PID-control;  AC_AttitudeControl: attitude position control of a drone using PID-control algorithms;  AC_WPNav: pre-defined trajectory flight using waypoints and PID-control.  APM_Control: stabilisation on the pitch, roll, yaw axes;  AP_Math: a module with internal mathematical routines;  AP_Techs: combined energy, speed and altitude control;  AP_Arming: check the preconditions of equipment performance before starting drone control;  AP_Compas: a module to work with compass hardware;  AP_Baro: a module to work with barometer hardware;  AP_BattMonitor: a module of work with the battery controller, including the detection of its discharge;  AP_GPS: a module to work with GPS hardware;  AP_Motors: a module to work with drone's motors, supporting statuses, control and their testing;  AP_Frsky_Telem: a module to work with the radio telemetry;  GCC_MAVLink: support for MAVLink telemetry transmission protocol. These libraries allow to develop a custom software solution for a drone based on hardware described above. Consider the main working procedure in the flight controller in Ardupilot software. It has to get current hardware state using HAL-abstraction and libraries to work with devices, then construct a high-level state of the drone (for example, the orientation of it in the space), run algorithms of control based on the current mode, and after then apply some commands to hardware. Due to various types of devices and different protocols of communication (for example, SPI or UART), the code should use a different speed for devices polling or priorities. Fig. 4 shows an evolution of Ardupilot software depending of properties of corresponding hardware: up to branch 3.1 [17], Ardupilot used loops with different frequencies in the main loop code (some of them executed at each iteration, some -at each two iterations, etc.), then the code was upgraded to use the concept of tasks with priorities (depending on hardware platform it can be executed like loops of early versions or run inside processes of a real-time OS).  The difference of controllers is based on their purposes: for amateur or commercial use, operate with slow or high speed, the necessity of having additional logic that implies using special sensors. Modern flight controllers act like ECU (Electronic Control Unit) for cars and even contain CAN (Controller Area Network) bus for the periphery. Some controllers also include a «safety coprocessor» [18] to ensure the robustness of the flight state. Note that when we move from the simple loop with device polling to real-time scheduling algorithms, we should take in account that process switching can add some delays to normal handling of real physical process control data, so such algorithms must be formally verified. The APM controller was built in 2011-2012 [18] as a result of initial Ardupilot project development by 3D Robotics company. Later, the non-profit organisation ardupilot.org was established. Today the controller is slightly outdated but it is cheap and available on market. The components of the controller are shown in fig.6:  ATMEGA 2560 processor (8bit);  barometer MS5611, SPI connection;  3-axes magnetometer (compass) HMC5843, I2C connection;  6-axes gyroscope and accelerometer MPU-6000, SPI connection;  GPS: UART external interface;  FrSky telemetry: UART external interface;  external SPI interface. In our current research work, we learned to work with this hardware and provided a transfer of necessary data to another controller to execute control algorithms. For us following control algorithms are most interesting:  altitude (position) control;  waypoint flight or curve-based flight;  smoothing pilot's commands. All algorithms are based on the PID-controller approach based on the Control Theory.

PID control
The PID (Proportional, Integral, Differential) controller is a feedback system for correcting the state of the control object ( fig. 7). When controlling the object we calculate an error between current and desired state (for example, between current and set drone altitude), then based on current error we calculate the impact based on three parts with given coefficients.


The proportional part (P) is responsible for the proportional reduction of the error (present).  The integral part (I) is a statistical change of the error (past).  The differential part (D) is the change of the error, its tendency to 0 (future). PID-control is some kind of abstraction when the control process is primarily based on the difference (error) but not on attempts to describe the exact physical model of the system, because during flight a variable wind can blow, the rotation of the propellers may be unstable, the center of mass is shifted and so on, but in such situations PID controller will detect the deviation and will try to make an impact to change it. The analytic equation for the PID-control scheme: where , and are the PID coefficients. Presently, the coefficients are set up in the user interface of ground control software, for example, using Mission Planner [20]. Some guidance on coefficients' choice exists, and their values are known for standard drone assemblies but for custom quadcopter (for example, a heavyweight one) they should be identified as a result of experiments. If a value of some coefficient is zero the controlled system may lose stability or smoothness of behaviour and the controller can be called P-controller, PD-controller or PI-controller.

PID control implementation in Ardupilot
According to [21], the current implementation of Ardupilot/Arducopter for altitude control uses a combined scheme of P-and PID-controller. The orientation for each axis is controlled with a special P-controller to convert the angle error (the difference between the specified angle and the actual one) to the desired rotational speed. Then a PID-controller converts the rotational speed error to a high-level motor command. A special part of the P-controller -«square root controller» -at first represents the angle function linearly and then uses its square root approximation. [22] provides a discussion of the overall control scheme. This scheme and its current refactoring are shown in fig. 8. The scheme demonstrates that all the axes have an influence on each other and the construction of the whole analytical equation like (1) is a very challenging task. Also, it shows some input transformation blocks that help to control smoothly [22].  User's actions to control the drone (for example, commands to move it) are not translated to drone motors directly because they are not regular, may be conflicting and have different  To provide flight along a given trajectory it is necessary to carry out maneuvers in advance, otherwise the drone will have to inefficiently turn in sharp corners. The approach of constructing smooth curves for unmanned air vehicles is called L1 [23]. For drones, this method was changed because of other physical characteristics and implemented in the AC_WPNav library.

POK (Partitioned Operating System Kernel) is a name of OS created in France by Julien Delange during his PhD research.
The main features of this work are the following:  MDE (Model-Driven Engineering) approach: initial OS kernel configuration was defined with the AADL language, which allowed to generate code and represent the configuration graphically;  it is a good proof-of-concept of working models and examples;  the system partially conforms to the ARINC 653 standard for real-time onboard aviation systems;  the system uses protected partitions with time and memory space resources isolation;  two types of real-time processes schedulers with different strategies exist -the partition planner and the process planner in each partition;  controllable message exchange between processes or using BlackBoard concept. The use of OS designed according to avionics standards and providing isolation of processes and verifiable interprocess communications increases the robustness of the solution at the system level. By browsing source code [5], we have created a scheme of internal POK architecture (see fig. 9). It consists of three layers: Arch with platform-dependent code (open-source repository includes implementations for three platforms: x86-qemu, PowerPC, and Spark), Core as the internal code of kernel and syscalls, and libpok that can be used as an API. The ARINC 653-compatible API provides a possibility to work with partitions, processes, locks, ports, queries, and messages in a standardized way.  [24] provides system modeling engineers with following capabilities:  to develop a top-level system design;  to think in abstractions and then write implementations;  to see a graphical representation of the code;  to generate code using integrated tools such as Ocarina;  to validate properties of developed systems automatically;  to create certified solutions. In essence, AADL acts like «executable UML» but at the top level and it is designed not for expressing algorithms, but for describing systems with additional safety requirements. The language allows to describe systems and components as sets of extensible properties to model both hardware and software parts. For example, if we need to define a model for the APM board (already introduced in fig. 6) we may first define a model for ATMEGA 2560 processor as an extension of existing processor ATMEGA 328 ( fig. 10) with another frequency and memory sizes and then use this model in a board model definition ( fig. 11) additionally specifying connections by ports with use of SPI buses. In our work, AADL is used to model the whole structure of the partitioned OS for the flight controller with the possibility to generate and validate its kernel configuration.

Flight controller system in a POK way
In this subsection, we define a structure of real-time OS for the flight controller with increased reliability requirements using POK way. In [25], POK authors give some tips on such structure definition (see fig. 12). Linking a process with variables and ports to a thread and a compiled C-code [25] The scheme is generated from AADL code and represents the partitioning: four partitions and four memory segments for GPS interoperation, runtime support for throttle servo control, and runtime support for yaw and flight management to provide a PID-style control. Initial AADL code is shown in fig. 13 where demo_four_partitions defines a processor with four partitions, a major time frame, time slices for the partitions, and scheduling policy; partitions 1..4 define partitions with given individual schedulers and additional user libraries; segments 1..4 define memory segments of given types and sizes; connections section defines ports to support interprocess communication between parts of the system; prs_gps, prs_mgmt, prs_throttle and prs_yaw define actually working threads within partitions. Fig. 14 illustrates the AADL approach to forwarding system variables to processes through ports and then to features in threads inside these processes, as well as to binding those to external object code that will run in these threads. We see that the stabilizing PID controller gets a tuple (altitude, latitude, longitude) and adjusts speed and angle of a quadcopter. So, configuring OS using this approach provides a Model-Driving approach to design software for the flight controller. The process interoperations are clear and the configuration is verifiable, therefore this increases the reliability of the solution.

Current state of our solution
To obtain a model for developing OS and testing PID controllers we propose an architecture shown in fig. 15. We took the 3.2.1 branch of Ardupilot software and modified its code to send current state data of a quadcopter through SPI from the APM controller to a different controller that executes a partitioned OS and provides a flight control based a stabilizing PID controller. Fig.16 shows the current hardware connection. This solution is the first step to migrate the whole flight controller logic to a fully-partitioned code -we start from using the APM controller as a gateway to quadcopter hardware. The patched code of the APM transfers input data through SPI to a partitioned process (prc_gps in fig.12 and 13) that provides flight-control and sends control data through SPI back to APM. The CRC (cyclic redundancy check) algorithm is used to ensure the correctness of the transaction. We plan to add partitions with additional monitoring processes to ensure dynamic properties of safety and stability.  Fig.17 shows two windows of USB-Com port devices monitoring the APM and the new controller with partitioned OS that provides PID-control based on real sensors data. We used the ARM M3-based board STM32f103 as the controller hardware. The source code of FreeRTOS was used to study some platform-related stuff. The ARM M7-based board STM32F746 was used to work with ARM MPU regions [26] with debugging process based on OpenOCD and STM HAL library to deal with periphery. We are working to deploy the solution on the Raspberry Pi board as some open source programs for it [27] allow to work with internal Broadcom hardware.
We are planning to describe POK porting issues in further papers. 1 Verification at the cyber-physical system level Cyber-physical system is a computer science abstraction of controllable physical process. It consists of two parts:  a Cyber part -discrete controller;  a Physical part -continuous model of the system usually expressed in ordinary differential equations. These systems can be modeled as Hybrid automata with discrete-time and continuous-time transitions. Such models are known as Hybrid ones and are specified using the Dynamic Differential Logic. The approach is a kind of sliding state changing [28]. According to A. Platzer [29], the syntax of hybrid programs is defined as follows: : : = : = |? | = ( ) | ∪ | ; | * (2) where is a meta-variable for a hybrid program; is a meta-variable for the program variables; is a meta-variable for first-order real-valued terms; is a meta-variable for continuous real functions; and is a meta-variable for first-order formulas over real numbers. The construct «;» means sequential composition, «∪» is non-deterministic choice, «?» is the condition operator, and « * » is non-deterministic iteration (like Kleene-star) [30].
Here we discuss a formal verification of a simple PD-controller (the simplification of PIDcontroller) given from example [31]. The model of the system is represented as a Hoare's triple: ⟹ [ ]( ) (3) where init -a precondition; controller -a hybrid model; req -requirements that are invariants. Then, we decompose the system into precondition, continuous PD-controller and requirements. Precondition: where v is the velocity; -a number greater than zero; -a proportional part coefficient; -a differential part coefficient; ( , , ) -is a Lyapunov function. The continuous state: where is a current position; -a resulting position. For the requirement, it is proposed to try a stability check using the Lyapunov method in the form: ≔= ( , , ) < . (6) The stability means here that the UAV during control will be stabilized around a given point in space. The Lyapunov function is defined in a quadratic form as follows: ( , , ) = 5/4 ⋅ ( − ) + ( − ) ⋅ /2 + /4 (7) Using KeYmaera tool (see fig.18 for the system (2)-(7) representation in code in the form of Hybrid program) it is possible to automatically verify the stability of the CPS that modeling the PDcontroller. For the real PID-controller of the drone (see fig. 8) it is hard to obtain an analytical form of the whole model and to find a Lyapunov function to prove the stability. Possibly, a special kind of linearisation is required here. So it is a very challenging task and a subject of further research. Moreover, additional research is required to find ways to generate proof obligations with preconditions, postconditions and invariants in hybrid automaton states to help automatically prove stability of a system (our initial results are desrcribed in [32]).

Verification at the code level
Let discuss a verification technique for a PID controller using the Weakest Precondition (WP) method and adding ACSL annotations [33] into C code. The WP approach as an extension of the Hoare's logic was proposed by Dijkstra. It requires a precondition to be as simple as possible to surely reach the corresponding postcondition. In this case, the further program verification will be as follows: first, calculate = ( , ), go from the end of Q to the start of the function, and then post a task to prove => to a theorem prover (we use Frama-C tool with WP plugin and its internal Alt-Ergo prover). For example, below we deductively prove several functions from the code that performs the PID control based on the Ardupilot code. In this code, the intermediate values are not calculated every time but are stored in the PID structure ( fig. 19). To prove the code, we write annotations for postconditions, preconditions, and side effects of functions in ISO-standardized ACSL language. Consider first the simplest code with annotations for the function float get_p (PID * pid, float error) ( fig. 20). This specification is fairly obvious: \valid defines the requirement of a non-NULL pointer to the PID structure, \result -the return value, requires means the precondition, ensures -the post-condition. However, even such a simple function cannot be proven because multiplying of two real numbers can cause overflow with an unexpected result. Therefore. the verification tool cannot guarantee the correctness of this code without explicitly using «infinite» Real logical type. To do this, we run the proof tool with the parameter "-wp-model typed+real" and (for this moment) we abandon possible floating-point errors with loss of precision. To prove the code of function float get_i (PID * pid, float error, float dt), it is necessary to construct lemmas describing the verifying code in terms of logic, similar to the examples in [34]. Firstly, we note that the function can change the value of pid->integrator and there are three cases:  pid-> integrator <-pid->imax: it is limited to -pid-> imax;  pid-> integrator> pid->imax: it is limited to pid-> imax;  otherwise, that is, (integrator> = -max) and (integrator <= max): no change of pid-> integrator. At the same time, there must first be a change of pid-> integrator to (error * pid-> ki) * dt. Therefore, the solution is to create a set of lemmas in ACSL terminology and a logic that will be used as a function in the ensures section. Secondly, we note that the function returns 0 if the first condition does not hold and it does not change the value of pid->integrator. To describe the postcondition, we provide a description of the guard conditions in a form of implications. In fig. 22 we show a specification for the function in fig.  21. Here \old is the memory state before calling the function and \at(…, Post) -after calling it. Fig 23 shows that the specification often takes even more space than the code itself, and writing it significantly changes the way of development; it ensures the quality of the code by coding the algorithms twice: in programming and logic languages.

Validation of OS config
Thanks to AADL, a language with formal semantics, it is possible to analyze the code in it, create a formal model and then validate it. Some ideas of AADL code checking are given in [4] and [24]. In fig. 23 we demonstrate the result of automatic code validation for the model presented in Section 5 at the phase of the code generation process.

Conclusion
During the research, we studied information on modern drones with open-source software and commodity hardware. We did a detailed analysis of the Ardupilot software and the APM board. We touched some modern approaches to the organization of operating systems for such devices using partitions, AADL language and MDE applied to the OS configuration, code generation and validation. We have developed a demo system, in which a quadcopter state is transferred from the APM board to a different ARM-based board with the control logic implemented in parallel partitioned processes using ports for interprocess communication.
As a result, we propose a design of software solution for UAVs with enhanced reliability requirements. This solution should ensure robustness at the following five levels.  OS Level. Using a partitioned real-time OS will provide low-level scheduling and process isolation.  Validation level. The level of interaction between the processes through ports and messages will be described in AADL. Additional model checking is available.  Code level. Source code annotations and its deductive proof.  Level of processes-monitors (dynamic testing). Monitoring processes can ensure that the safety conditions of the running system are maintained.  Level of cyber-physical system (static verification). Proof of correctness of mathematical models of physical processes (safety and stability).