Skip to main content

Command Palette

Search for a command to run...

Code coverage collection for ArduPilot in real flight mode and software-in-the-loop (SITL) mode

Updated
8 min read

Ardupilot compilation steps

1.Set the board subtype

./waf configure --board CUAVv5

2.Compile fixed wing

./waf plane

After compiling, compile_commands.json compilation database will be generated in build/CUAVv5/ directory.

Generate the bootable arduplane.apj firmware under build/CUAVv5/bin/.

Ardupilot instrumentation

1.Modify ZoaInstru.c

a.Change all the parameters to 1

b.change the parameter to 1 to open

c.Comment out the original code and modify it to

#define ZOA_IS_NORMAL(head)(((head)→type & 0×1f) == ZoaTypeNornmal)d. Add name to the structure

2. Change line 128 #define ZOA_CONST const to #define ZOA_CONST

3.Change the variable to 0

4.Put ZoaInstru.h in the shell/include directory

Put ZoaInstru.c in the ardupilot/ArduPlane directory

5.Create a project and associate

(default username: user, password: user)

a.A new project is being built here.

b.Click the red box to create a virtual project. Enter the name of the virtual project in the green box and the identifier of the virtual project in the blue box. Then click the purple box to save.

c.After adding, it will look like the following picture. Click "Add Real Project" on the right.

d.Add the real project name, select the project type, and click Confirm.

e.After successful creation, it will be displayed as shown in the following figure.

6.Instrumentation the compile_commands.json compilation database generated under the board subtype directory at compile time

a. Change the ip, etc. configuration at shlle/bin/Server.cfg

b.shlle/bin/Server.cfg modify configuration such as instrumentation black and white list

c.Create version./shell -c real project name Round name version name

d.Instrumentation./shell -p ../compile_commands.json

7. Copy the generated zoa_opt.c

After installing the shell/bin directory generate zoa_opt.c, this file will be put in the ardupilot/ArduPlane directory

Collect coverage data

To collect the coverage data, you need to write the coverage data to the ardupilot's file system, which is the SD card.

1.Modify ArduPlane/Plane.h

find the one_second_loop method definition, and add the write_to_sd_card(void) method definition in the figure in the next line

2. Modify ArduPlane/ Arduplane.cpp,

find the ahrs_update method implementation, and add the following code in the method

static int zoai = 0;

if (zoai == 0) {

        hal.scheduler->register_timer_process(FUNCTOR_BIND_MEMBER(&Plane::write_to_sd_card, void));

    zoai++;

}

3. modify ArduPlane/ arduplane.cpp

implement write_to_sd_card method, in AP_HAL_MAIN_CALLBACKS(&plane); Add the following before. This code will write the coverage of the entire file every 5 seconds. It's generated in the file system /APM/ZOA/ directory, called zoa_data, and it overwrites every time.

static int zoa_i = 0;

static int Zoafile;

static void save_to_file(struct __zoa_linker *linker) {

    void *data;

    int bytes;

    struct zoa_data_info info;

    info = zoa_get_data_info(linker);

    data = info.datas[0];

    bytes = info.bytes[0];

    // Write data

    AP::FS().write(Zoafile, data, bytes);

    if (info.parts > 1) {

        data = info.datas[1];

        bytes = info.bytes[1];

        AP::FS().write(Zoafile, data, bytes);

    } 

}

static void dump_all(void) {

    char buf[256];

    if (zoa_i < ZOA_FILE_MAX) {

        // Open the file, only once

        snprintf(buf, sizeof(buf), "/APM/ZOA/zoa_data");

        //Zoafile = AP::FS().open(buf, O_RDWR | O_CREAT | O_APPEND);

        Zoafile = AP::FS().open(buf, O_RDWR | O_CREAT);

        if (Zoafile == -1) {

            hal.console->println("Failed to open file.");

            return;

        }

        // write data in a loop

        while (zoa_i < ZOA_FILE_MAX) {

            save_to_file(__zoa_list[zoa_i]);

            zoa_i++;

        }

        // Write all the data before closing the file

        AP::FS().close(Zoafile);

        zoa_i = 0;

    }

}

static int num = 1;

void Plane::write_to_sd_card(void) {

    if (num % 5000 == 0) {

        dump_all();

    }

    num++;

}

Compile the instrumented code

When compiling the instrumented code, since the build tool waf for this project has many strict compilation parameters configured, we need to comment out these configurations and also add configurations to include the ZoaInstru.h header file.

1. Modify ardupilot/wscript

Add the path where shell/include is located at line 519.

Line 628 also adds the path of shell/include

2. Modify the compilation parameters

Some configurations of -Werror need to be annotated; otherwise, it will be too strict and fail to compile. There are many changes. It is recommended to directly replace the modified file, or you can manually annotate based on the error messages after compilation.

ardupilot/Tools/ardupilotwaf/boards.py

ardupilot/Tools/ardupilotwaf/ar/dupilotwaf.py

3. Recompile again

Filter empty files uninstrumented because of macros

In some code of this project, there are some macros after preprocessing the condition is false, resulting in an empty file, but the instrumentation succeeds. But when you link zoa_opt.c, you can't link to the symbol. So you need to filter it out.

1.Single-thread instrumentation

Multi-threaded data is not allowed as it will be incomplete and disordered. Generate files_map.json in the shell/bin directory. This file records the correspondence between source code and link symbols.

2.Error resolution

After instrumentation, compiling will give an error when linking, for example, symbolic link __zoa_data_123 could not be found.At this time, the file with id 123 is found in files_map.json, and it is configured to the instrumentation blacklist. Generally, there will be multiple symbolic links that cannot be found. Restore all the files again and instrumentalize and compile them again.

SITL software simulates flight control

Software simulation can run the firmware on the computer without the board.

It is important to note that during the compilation of plane (fixed wing), our database is ardupilot instrumentation used to compile/build/CUAVv5/compile_commands json, and we use SITL software simulation, Instrumentation used to compile the database should be for ardupilot/build/sitl/compile_commands json

1.Compile the code and generate the compilation database.

../Tools/autotest/sim_vehicle.py -v ArduPlane --console --map

2.Use the current compiled database instrumentation after

ls .. /build/sitl/compile_commands.json

.. /build/sitl/compile_commands.json

3.Put the zoa_opt.c generated from the shell/bin directory after instrumentation into the project directory

cp .. /zoa_opt.c ./

4.Use software simulation again

.. /Tools/autotest/sim_vehicle.py -v ArduPlane --console --map

a. Enter the unlock command

arm throttle

b.Push the throttle above median and take off

rc 3 1700

c.Switch auto mode

mode auto

d.Set the simulation starting position and initial heading

Open locations.txt under the ardupilot\Tools\autotest folder and add a new location point in the second line. Add a location point named "NFCY_Home", latitude "66.66666", longitude "77.77777", elevation 20 meters, initial heading 30 degrees (latitude: north latitude is positive, south latitude is negative; Longitude: east longitude is positive, west longitude is negative);

Simulation script file, at the end of that line of command add a command: "-L your location name", in our example, after adding the script command is as follows:

Coverage data parsing

Earlier we added code to collect coverage, which is automatically written to the directory /APM/ZOA/zoa_data file every 5 seconds when the firmware starts.

1.Software emulation

a.The APM/ZOA directory needs to be prepared in the current directory of the simulation command

mkdir -p APM/ZOA

b.Simulation run

.. /Tools/autotest/sim_vehicle.py -v ArduPlane --console –map

After emulation, you can see that zoa_data has been generated.

2.Burn to the board for test use

Connect the board to the flight control and connect it to the sd card of the board via MAVFtp in the mission planner after creating the APM/ZOA directory. Connect the board again, and as you can see, zoa_data has been generated. Directly right click to download it locally.

Once you have the data, you need to send it to the server via zoa-server and zoa-sync.

3.Start zoa-server

specify the interface for the server to receive coverage data, and receive the data sent by zoa-sync

zoa-server.exe -dd_url="tcp://ip:15555" -mcdc_url="tcp://ip:15557" -cond_url "tcp://ip:15556" -enable_log -user_id 7

4.Start zoa-sync

zoa-sync.exe -cov_root ..\zoa_data

-cov_root specifies the directory where zoa_data is located

The following figure parses successfully

5.Wait for the zoa-server to finish sending

You can check the coverage in ttweb, ZoaInstru.h is configured with only statement block coverage before, so it is normal.

Code visualization

Points to note when using the code association tool TTSupport for code visualization in this project.

The file in the compiled data of the project is a relative path. If we directly instrumentate, it is very messy in ttweb, and it cannot be visualized after testing. We can use a script to change it to an absolute path.

For example my absolute path is /home/jianglei/ardupilot, I use the following script to process this file

sed -i 's#"file": ".. /.. #"file": "/home/jianglei/ardupilot#g' compile_commands.json

The compiled database after processing is as follows.

We again modify zoa_setting to filter out path prefixes

At this point it is very convenient to configure the visualization and it is also very simple to view on ttweb

Display of the basic functions of the platform

1.Forward and reverse traceability

Forward traceback, test cases are automatically associated with source code

Backward traceback, tracing the corresponding test case through the function

2.Regression testing

New version instrumentation testing, source code changes or additions, the system calculates the set of test cases to regression

3.Coverage View

a.Package coverage view

b.File coverage view

c.Function coverage view

d.Code visualization, block, condition, MC/DC coverage views

e.Function call graph

f.Function control flow chart