Skip to content

Instantly share code, notes, and snippets.

@deliastephens
Created July 15, 2019 21:21
Show Gist options
  • Save deliastephens/fb2cfeb348b4ac89e1acd20d751836a9 to your computer and use it in GitHub Desktop.
Save deliastephens/fb2cfeb348b4ac89e1acd20d751836a9 to your computer and use it in GitHub Desktop.
SITL Testing Environment

Robust Testing and Debugging with SITL

Desired Features

  • Simple UI
  • Run multiple different missions with home point at the starting location.
  • Change conditions
  • Inject failures
  • Interface with MissionPlanner, etc.
  • Robust test suite - run multiple misson in sequence
  • Change the exit condition.
  • Check that vehicle is fully initialized before uploading waypoints.

Quick Code

Run SITL: sim_vehicle.py --console --out 192.168.5.32:14550 -L MEX -v ArduPilot Run Fault Injector (in folder): python FaultInjector.py

DroneKit and Python

I quickly realized the best way to write testing scripts would not be with bash scripts or anything archaic and Windows-y, but with Python instead. My ultimate goal would quickly become a Python simulation UI - one where it is easy to load missions, add complicating factors, etc.

I found a UAV Fault Injector project which seemed like a great place to start. I ended up deciding to modify this script with an ability to load and run custom missions via DroneKit to build a fully-featured, all-in-one platform.

Installing DroneKit

My first tragedy arrived when I realized the entire python-dronekit website was down. Luckily, some fans had created another host, so I was in business.

Basic Modifications and Compatibility

My first order of business was to modify this Python script to get it to work with my particular Python setup. This involved changing capitalization, package names, spaces, tabs, etc.

Modifications Changelogs below, and available on my GitHub commit history:

  • Spelling mistakes
  • Renamed packages
  • Changed FS_BATT_MAH to BATT_CRT_MAH to reflect ArduPilot development.
  • Added ability to load custom Waypoint files.
  • Added ability to run custom WP files
  • Worked on documentation (res images, etc.)

Loading and Modifying Missions

My first task would be to load a suite of missions and start them from the FaultInjector.

I ended up adding this toolbar: mission loader The thing that I first noticed was the absolute lat/long coordinates for missions. I thought it would be quite helpful to write a Python script that would generate new Waypoint files based on the drone's current home position. This ended up being the mission_converter script.

Missions must be in the format specified in the mission-converter documentation; that is, the file should be a .txt file that looks something like this:

WP File Format

In order to get the plane to take off, you must reset the home position with this command:

vehicle.commands.next=0

Otherwise, the plane will not fly.

Running Multiple Missions

The next thing I wanted to do was run multiple missions in succession. However, I discovered that there was no good way to do this---the drone's state attributes were read-only, making it somewhat difficult to reset the position, battery, etc. of the drone after "completing" a mission.

Instead of resetting the drone, I eventually realized it would be easier to kick off multiple instances of the sim_vehicle.py script. This was certainly more confusing than I expected it to be, but this ended up being the code I needed to start a script:

import os
import subprocess
global sitl
os.chdir(r"C:\cygwin64\bin")
cmd = ["bash.exe", "-c", '. /etc/profile;  sim_vehicle.py --console --out 192.168.5.32:14550 -L MEX -v ArduPlane']
sitl = subprocess.Popen(cmd)

To make my script stop running, I went through and killed all of the processes on my computer named mavproxy.exe.

To do so, I had to reuse some of this code. To kill a process on Windows, simply call .kill() on the process.

The next thing I needed to do was create a way to kick off all these scripts with the push of one button. I also needed a way to figure out how to stop these scripts.

Currently, the current mission stops when the mode becomes 'RTL'. Obviously, this is not the best way to do it, so tomorrow's work will be to think of a better exit condition.

Generally, the workflow is as follows:

  1. Get a list of all the files in the missions folder.
  2. Pop the first file off the files remaining.
  3. Start the simulation.
  4. After waiting for a bit, connect to the simulation.
  5. Wait for the vehicle to initialize.
  6. Load the mission onto the vehicle.
  7. Start the mission.
  8. If at any time the exit condition is reached, disconnect from and stop the simulation.
  9. If there are files left to load, return to step 2.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment