Hello all,
My team and I have had quite the adventure trying to make flight plans work with the Anafi, both within Sphinx and in the real world. Below is a write-up of the issues we encountered and how we were able to solve/work around them (or not). I’m not sure if this would be more useful as a bug report on Github and whether it would be better as one large report or broken out into its components. It could be the basis of some new documentation, or at the very least, hopefully it helps anyone reading on the forum. Happy to provide more information on any of the topics!
QGroundControl
First, I should start by mentioning that we primarily relied on QGroundControl to make our flight plans. We realize this likely goes against the recommended best practices, but since we are trying to fly a grid pattern of an area at a consistent altitude with the camera facing nadir, it was the tool that made the most sense for the job. QGroundControl outputs its data in JSON format with a .plan extension, so we wrote a parser to convert it to QGC WPL 120 format (it was unclear whether 110 or 120 was preferred, but we had success with 120). We are happy to share the code once we have documented/cleaned it up a bit.
MAVLink Discrepancies
It is important to note a few discrepancies between standard MAVLink and the customized Parrot commands. For anyone following along at home, the Parrot command documentation is available here: https://developer.parrot.com/docs/mavlink-flightplan/messages.html. Parrot does not support a null/NaN option in the parameters – everything must be a float. This means that command 16 (waypoint)has no functionality to direct the yaw angle (for parameter 4) automatically.
The MAVLink documentation states that we should set parameter 4 to “NaN to use the current system yaw heading mode (e.g. yaw towards next waypoint, yaw to home, etc.).” (source: https://github.com/mavlink/mavlink/blob/master/message_definitions/v1.0/common.xml#1260).
We also discovered that it is not possible to generate a flight plan that has no flying actions. We wanted to generate a flight plan that only controlled the gimbal and took images to help reduce the risk of flying in a lab environment, but found that the flight plan parser in the drone expects valid waypoints before it will run the plan. Additionally, we found that issuing an explicit 22 (launch) command did not seem to be required. We were unsure whether this was intentional on Parrot’s part, but we preferred to add one anyways. We also had issues making the 20 (return to home) command work – perhaps the home location needs to be explicitly set within Freeflight?
Capturing Images
We noticed a lot of inconsistent behavior in our initial image capture tests in sphinx – sometimes all of the images were available, sometimes none were, and sometimes only some of the images were available. There were a number of reasons we experienced these issues.
We ended up using a real Anafi to help understand how to properly take images with consistent results flying flight plans in real life. First, we issued a 50001 (capture mode) command with parameters 1&2 set at 1.0 and 2.0, then issued 2000 (image) commands with the parameters 1-3 set at 0.0, 1.0, and 12.0, respectively. This wasn’t documented anywhere (or its location was unclear) and took some trial and error to discover.
Once we were able to take pictures properly in the real world, we found using this method plus setting the timestamp properly in Sphinx allowed us to consistently take images within Sphinx. The timestamp and the related Sphinx issues are detailed in the next section. However, we’ve had issues getting the simple front cam to work, and the images that it does capture are different dimensions (1280 x 720) than the images captured by the real drone (4608 x 3456).
Setting the Timestamp in Sphinx
Not having the timestamp set properly seemed to create a cascade of problems within Sphinx. Even when issuing image commands properly (mentioned in the above section), we had issues with the virtual SD card showing up as full and not writing images. This likely contributed to the inconsistent image capture behavior.
To set the simulation timestamp, we passed “–time=date +%s
” as a command line argument when running Sphinx. This seemed to solve a number of our problems related to image capture, we also found that disconnecting and reconnecting the Freeflight app caused the SD card to show as full in Sphinx.
With the timestamp fix applied, the SD card still shows as full in Freeflight, but the images are captured anyways.
No Logs Available
Per our understanding, Sphinx and the Anafi’s operating system was initially based on Android. However Parrot’s logging system (ulog) differs heavily from Android. Sphinx ships with a full VM of a Parrot drone, but relies on some host services being present to make logging work. It would seem that the simulated Anafi drone is trying to write logs to /dev/ulog_main
which is not a valid device in the simulator (we receive errors like “cannot write to /dev/ulog_main, invalid argument”). We also notice some issues with firmwared not setting up the virtual PTY for init-time logging. As such, boxinit sends all logs to /dev/null
, and we have no way to access them. We developed a workaround by strace-ing the PID that would have been writing them and looking for any write() calls to FD #2 (stderr). This allowed us to understand some of the other issues we were facing. However, having easy access to the logs would have made things much easier and saved us a lot of time.
Closing Remarks
While there were some issues getting off the ground (lol), we found Sphinx to be an immensely useful tool, particularly since we didn’t have to crash any of our real drones to figure out how the flight plans worked. It can be a bit difficult to work with, but is definitely worth the learning curve. Here is a flight plan that we used to test image capture working within Sphinx in the world file called “outdoor_1.world”:
QGC WPL 120
0 0 3 178 0.0 3.0 -1.0 0.0 0.0 0.0 0.0 1
1 0 3 93 20.0 0.0 0.0 0.0 0.0 0.0 0.0 1
2 0 3 50001 1.0 10.0 0.0 0.0 0.0 0.0 0.0 1
3 0 3 205 -90.0 0.0 0.0 0.0 0.0 0.0 2.0 1
4 0 3 22 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1
5 0 3 16 1.0 2.0 0.0 0.0 48.87884073471497 2.367869801697479 20.0 1
6 0 3 16 1.0 2.0 0.0 45.0 48.87895889061195 2.367690138640655 20.0 1
7 0 3 2000 0.0 1.0 12.0 0.0 0.0 0.0 0.0 1
8 0 3 16 1.0 2.0 0.0 90.0 48.87895889061195 2.367869801697479 25.0 1
9 0 3 2000 0.0 1.0 12.0 0.0 0.0 0.0 0.0 1
10 0 3 16 1.0 2.0 0.0 180.0 48.87884073471497 2.367690138640655 30.0 1
11 0 3 2000 0.0 1.0 12.0 0.0 0.0 0.0 0.0 1
12 0 3 16 1.0 2.0 0.0 270.0 48.87884073471497 2.367869801697479 35.0 1
13 0 3 2000 0.0 1.0 12.0 0.0 0.0 0.0 0.0 1
14 0 3 16 1.0 2.0 0.0 0.0 48.87884073471497 2.367869801697479 35.0 1
15 0 3 21 0.0 10.0 0.0 0.0 0.0 0.0 0.0 1
To any Parrot devs, we are more than happy to help with writing bug reports or documentation, just let us know how we can best get this information out to the right people!