This is a toolchain which implements your MATLAB/Simulink controller in ArduPilot.
Currently supported: ArduCopter and ArduPlane.
Note that the ArduPlane patch also contains a custom interface to ArduPilot SITL with UDP connection (see ArduPilot SITL interface of LADAC).
If you design your controllers for an existing vehicle, you have to implement your controller on the electronic control unit of your vehicle. Since the controller is only a (small) part of the software running on the electronic control unit, it might be beneficial to implement the controller in an existing software like ArduPilot. ArduPilot supports different boards and sensors, it allows communication via MAVLink and also provides a state estimator (EKF) if needed. Moreover, you can perform software in the loop (SITL) simulations and keep standard ArduPilot flight modes if you want. Here, the implementation of your MATLAB/Simulink controller in ArduPilot is described.
- You must install LADAC (you need the MATLAB Coder and Simulink Embedded Coder).
- You must install the ArduPilot SITL.
- Clone the following ArduPilot fork and check out one of the following branches:
- ArduCopter 4.2.0
git clone -b Copter-Matlab-4.2.0-dev https://github.com/ybeyer/ardupilot cd ardupilot git submodule update --init --recursive
- ArduPlane 4.3.0
git clone -b Plane-Matlab-4.3 https://github.com/ybeyer/ardupilot cd ardupilot git submodule update --init --recursive
- ArduCopter 4.2.0
- These instructions assume that you have a basic understanding of ArduPilot and the ArduPilot SITL. Please also note the ArduPilot SITL interface of LADAC.
This unit test shows you how it works and it can be used for verification. Therefore, a dummy controller from MATLAB/Simulink is already implemented in the ArduPilot fork. The dummy controller runs in an additional ArduPilot flight mode (mode 29 in ArduCopter and mode 26 in ArduPlane).
Note that the steps are slightly different for ArduCopter and ArduPlane.
- Test the code in ArduPilot software in the loop (SITL).
- Compile the code and start the ArduCopter SITL:
sim_vehicle.py -v ArduCopter
- Switch to the MATLAB/Simulink flight mode via the MAVProxy command prompt (same console that runs
sim_vehicle.py
):mode 29
- Arm the vehicle:
arm throttle
- Terminate the simulation with
Cntrl+C
. - You can now review the logs. The actuator commands should be equal to the outputs of the MATLAB/Simulink dummy controller.
Moreover, there should be a
ML1
struct which contains the custom logs of the MATLAB/Simulink dummy controller.
- Compile the code and start the ArduCopter SITL:
- Upload the code to your board.
- You can build the code for supported boards and upload it according to the Building ArduPilot documentation.
- For example, if your board is a Pixhawk 1, use the following commands:
(Note that you have to replace
./waf configure --board Pixhawk1 ./waf copter ./waf --upload copter
copter
withplane
if you want to build ArduPlane.)
- Test the MATLAB/Simulink controller in flight tests (CAUTION: THIS MIGHT BE DANGEROUS, PLEASE ASSURE SAFETY ARRANGEMENTS!).
- Only do flight tests after careful and comprehensive SITL tests.
- Only do flight tests at dedicated terrain.
- Only do flight tests if you are sure that you can deactivate the MATLAB/Simulink controller at all times.
- Only do flight tests if you have implemented a radio failsafe action that will cause acceptable reactions of the quadcopter in case of transmitter/receiver connection loss.
Step 1 must be adjusted as follows.
- Test the code in ArduPilot software in the loop (SITL).
- Compile the code and start the ArduPlane SITL:
sim_vehicle.py -v ArduPlane
- Switch to the MATLAB/Simulink flight mode via the MAVProxy command prompt (same console that runs
sim_vehicle.py
):mode 26
- follow ArduCopter procedure.
- Compile the code and start the ArduPlane SITL:
Take a look at the Simulink models ArduCopter_TemplateController
and ArduPlane_TemplateController
in this folder.
They contain the dummy controller in the middle.
On the left and on the right, there are interfaces to the ArduPilot fork.
In this case, the dummy controller sends constant values to the actuators and it logs some signals.
To get your MATLAB/Simulink controller to run in ArduPilot you need to generate C++ code from your Simulink model and copy it into the ArduPilot fork.
- Make a copy of one of the
Ardu<Copter/Plane>_TemplateController
Simulink files, replace the dummy test controller with your own controller block and connect the inputs and outputs with the interface blocks to ArduPilot (Actuator muxer, log muxer etc.). The interface blocks are provided by the Simulink libraryardupilot_custom_controller_lib
. You must first initialise the Simulink bus objects in MATLAB:ardupilotCreateInputBuses
- Generate C++ code from the Simulink file (click top right button "Build Model"): https://de.mathworks.com/help/dsp/ug/generate-c-code-from-simulink-model.html
Note that floating points should be 32-bit. This is assured in the Simulink template files because the following parameters were set:set_param(gcs, 'DefaultUnderspecifiedDataType', 'single')
andset_param(gcs, 'DataTypeOverride', 'Single','DataTypeOverrideAppliesTo','Floating-point')
- You only need four files of the generated code:
MatlabController.cpp
,MatlabController.h
,MatlabController_data.cpp
andrtwtypes.h
. Store these files in one folder and copy the content into your local ArduPilot repository.
ArduCopter:ArduPlane:cp -rf <your_source_folder>/. <path_to_ardupilot>/libraries/AC_AttitudeControl/
cp -rf <your_source_folder>/. <path_to_ardupilot>/libraries/AP_Common/
- You should now be able to compile the modified ArduPilot project and use flight mode 29 (ArduCopter) or mode 26 (ArduPlane).
Note that it is probably required to delete thebuild
folder in your local ArduPilot repository or to perform a./waf clean
.
If you want to understand in general how the interface works, or if you want to use a different ArduPilot commit, you may need to look into the ArduPilot code. This is a guide of how to adjust the code.
For each step there is a git commit in the ArduPilot fork. Please study the git commits. The diff and the commit message should be comprehensible. In general, it is recommended to learn the ArduPilot code and to use an IDE with debugger (e.g. VS Code with GDB).
Originally the interfaces were created based on Copter 4.0.0
(tag Copter-Matlab-4.0.0-dev
which is based on commit f69be707
) and based on Plane 4.1
(tag Plane-Matlab-4.1.0
which is based on commit 6711c479
).
However, this has not been further developed for a long time.
Instead, the ArduPilot version was updated to Copter 4.2.0
(branch Copter-Matlab-4.2.0-dev
which is based on commit 999c2692
), Copter 4.4.0 beta
(branch Copter-Matlab-4.4.0-beta2
which is based on commit 07f11531
) and Plane 4.3.0
(branch Copter-Matlab-4.3
which is based on commit 033266f9
).
Several improvements have been implemented in these branches.
For understanding it is very helpful to use a Git GUI which shows the history well.
The basic functionality of the interface can be understood from the original history.
The original history consists of the following steps:
ArduCopter:
- Create new custom flight mode (see commit
284a3e8f
). - Change a compiler flag to avoid errors (see commit
16fc4968
). - Get measured values and commanded values in the new custom flight mode (see commit
1f9633bb
). - Integrate the MATLAB/Simulink controller (C/C++ code) (see commit
84ea9cd0
). - Send motor commands (This is somewhat complicated because no way was found without modifying the ArduCopter main loop. Two soluations are presented.).
- Send motor commands directly and deactivate all standard ArduCopter flight modes (easy) (see commit
f1378e72
). - Send motor command maintaining all standard ArduCopter flight modes (more difficult) (see commit
ea316281
).
- Send motor commands directly and deactivate all standard ArduCopter flight modes (easy) (see commit
ArduPlane:
Take a look at the commits 540b1a7a
, 090fd2d1
, 458fb653
, e06e0f57
, 50b83360
, 05e8e5f4
.