Hacking the Potensic Atom drone to fly pre-generated waypoint missions
1. Overview: Drone Tasking Manager (DroneTM)
About a year ago, a joint initiative between the Humanitarian OpenStreetMap Team (HOT) and NAXA began the development of the Drone Tasking Manager (DroneTM).
What is DroneTM?
- DroneTM is a tool to collaboratively generate base imagery as an alternative to traditional satellite sources. It enables subdivision of an area into ‘tasks’ and then generation of flight plans for teams of local drone operators to fly simultaneously.
- Niraj, the lead dev for DroneTM at NAXA already wrote a good blog explaining the idea, so there is no need for me to reiterate here.
Extra Links
Hardware Support
- The project initially focused on the DJI Mini 4 Pro—a highly capable, sub-250g drone that supports precise waypoint missions (~$1000).
- Long-term, HOT aims to build an open-source cheap drone optimised for photo capture only, and using open-source ArduPilot as the flight controller.
- In the short term, expanding drone support with similar cheap drones is critical for adoption.
2. The Potensic Atom Series
-
Potensic’s Atom 1 and Atom 2 offer affordable alternatives (~1/3 the cost of DJI), with promising hardware.
Here we have the Potensic Atom v1. You can clearly see the scuffed blades where I crashed it into a plant pot on landing 😂
Comparison
-
Atom 1: Supports waypoint missions with the current firmware.
-
Atom 2: Technically superior hardware (we suspect is uses the same photo sensor as the DJI Mini 4 Pro), but as of 2025-05-11, it does not yet support waypoint missions. Firmware update is expected later this year.
Note
Potensic currently imposes a 30 waypoint limit per mission in it’s apps. This needs further testing to assess if it’s a hard or soft limit.
3. Technical Exploration
Existing Attempts
An excellent community project by @koen-aerts reverse-engineered the proprietary flight log format for Potensic drones:
- Can visualise flight logs via a Kivy app, replaying the flight parameters and drone location as an interactive movie.
- Offers alpha support for waypoint mission loading/saving, primarily by clicking on a map, so it’s not overly sophisticated (yet).
- See more details on his blog here
Waypoint Planning in DroneTM
- DroneTM already contains a flight plan generation module flight plan generation module, that is used to generate waypoint and wayline missions.
- The primary output candidate is DJI Waypoint Markup Language, however, the remainder of this blog will look into the potential for outputting to a format supported by the Potensic drones.
Storing Waypoints In The Atom
The map.db
Waypoint File
- The flow to consider here is: PotensicPro Android app (phone) --> Flight controller
- –> Atom Drone.
- It looks like the PotensicPro stores the waypoint missions in a
map.db
SQLite database. - Upon further exploration, this is a pretty half-baked / unsophisticated approach, but it works! And you will see no complaints from me, because they could very well have added no waypoint support at all!
- The file is located on the phone, reading an writing to it as needed:
/data/data/com.ipotensic.potensicpro/databases/map.db
Note
Android File Access: A Quick Primer
An aside on how Android sanboxed filesystem works per-app since Android 14.
There are two storage options for apps:
- Each app gets it own sandboxed storage to work with, to prevent
privileged access to the entire filesystem:
/data/data/<package.name>/
. - Shared storage is also available if permission is granted, under:
/storage/emulated/0/Android/data/<package.name>/
.
However:
- In order to copy the
map.db
file across to a place on the phone that the PotensicPro app can read, we need to copy to this sandboxed filesystem. - The sandboxed filesystem is only accessible directly from the app code, unless
the device is rooted, or the app uses a
debuggable
flag in it’s manifest (see more info below).
We have two options:
- Mod the PotensicPro app further, to read
map.db
from shared storage instead. - Use ADB to interact with the sandboxed storage, via ‘run-as’ the required user.
An Existing Modded App
- Option 2 above is probably not a maintainable solution into the future.
- There are already modded versions of PotensicPro floating around, with one
of the best coming from ‘e443mods’ telegram community:
- Changes the height, waypoint & distance limits to 10000m.
- Removes unnecessary trackers.
- Changes the transmission mode to the maximum possible.
- I also modded the modded APK 😆 to add the
debuggable flag to
AndroidManifest.xml, as described above.
- I’m not sure I can legally host and distribute this, but suffice to say it’s out there.
The process to make an existing APK ‘debuggable’:
# Gen a new signing key
docker run -it --rm -v $PWD:/home/makedebuggable -u makedebuggable ghcr.io/spwoodcock/make-debuggable:2025-05-11 /scripts/keygen.sh
# Mod the APK to be debuggable
docker run -it --rm -v $PWD:/home/makedebuggable -u makedebuggable ghcr.io/spwoodcock/make-debuggable:2025-05-11 /scripts/makeDebuggable.py apk PotensicPro-V6.6.1
-E443.apk PotensicPro-V6.6.1-E443-debug.apk debuggable.keystore debuggable pwpwpw
- This allows us to access the sandboxed PotensicPro app files, including the waypoint database.
- Android USB debugging must be enabled via the phone developer options.
- This isn’t overly user friendly, so I will probably look into ADB In The Browser for DroneTM going forward.
4. Implementing Waypoint Generation
Inspecting The Waypoint Database
- The first step was to fly a waypoint mission manually via PotensicPro.
- Some important info before we attempt to get the file:
- When using
run-as com.ipotensic.potensicpro
in ADB we cannot access anything other than the sandboxed filesystem (no shared storage access…). - When using the standard user, we cannot access the sandboxed PotensicPro storage… a catch-22.
- When using
- So, to copy the generated
map.db
file from the sandbox onto our filesystem, instead of copying to an intermediary location then usingadb pull
, we can pipe the file content directly to our machine via terminal:
# First ensure the db is not being accessed
./adb shell am force-stop com.ipotensic.potensicpro
# This approach doesn't work due to permission issues
#./adb shell run-as com.ipotensic.potensicpro cp /data/data/com.ipotensic.potensicpro/databases/map.db /sdcard/Android/data/com.ipotensic.potensicpro/files/
# This works (we use base64 encode to avoid encoding issues between shells, e.g. powershell vs bash, see below)
./adb exec-out run-as com.ipotensic.potensicpro base64 /data/data/com.ipotensic.potensicpro/databases/map.db > map.db.b64
# I then copied this across to WSL decoding base64
dos2unix map.db.b64
base64 -d map.db.b64 > map.db
# For a Linux-only workflow, it would be simpler to just:
cat map.db | ./adb exec-in run-as com.ipotensic.potensicpro /data/data/com.ipotensic.potensicpro/databases/map.db
Note
A note about shell encoding… how I wasted 2hrs of my life.
Originally I was using:
./adb exec-out run-as com.ipotensic.potensicpro cat /data/data/com.ipotensic.potensicpro/databases/map.db > map.db
This failed as I was testing using Powershell instead of bourne / bash. After some hex inspection I noticed the encoding was wrong in the copied file headers.
In PowerShell, using redirection (>) causes the new files to be encoded in Windows UTF-16LE encoding, while Unix-like filesystems require UTF-8. Making the file not a valid SQLite file.
So I swapped to the base64 encoding approach above, that should be cross compatible between different terminals!
Creating A Waypoint File
-
For now I implemented this as a test only, with hardcoded coordinates.
-
In the long run I will tie this into the existing code in drone-flightplan:
- Generate the waypoint flight.
- Generate the file format consumed by the drone / controller (WPML for DJI, SQLite for Potensic).
-
I made a start on this, replicating the SQLite database table structure, and inserting a dummy waypoint flight plus hardcoded coordinates for my flight in London today.
Out of interest, here is a crappy orthophoto I generated by simply flying around my area and taking some test photos. The output will no doubt be much better using a regular interval consistent bearing of a waypoint flight, but it gives you an idea!
See Stay Tuned below to follow up on the progress here.
Limitations
The SQLite format used isn’t particularly sophisticated. Basically we have:
- A simple table to reference a mission, with a set height and other metadata.
- A linked table storing lat/lon pairs for each waypoint in the mission.
As a result, three major limitations has been identified:
- The mission altitude is set at a single level for the entire flight.
- Photos must be taken using the interval timer feature, as taking a photo at each waypoint cannot be programmed.
- The gimbal angle also cannot be adjusted automatically, meaning two runs of the mission would be required for both nadir (~85°) and oblique (~45°) imagery capture.
DJI obviously have an advantage here and clearly have a big team of software engineers at their disposal. The Waypoint Markup Language (WPML) is a very professional and infinitely configurable spec in comparison.
Importing The Generated File To A Phone
- Copying back to the correct place on a phone:
# Cleanup old journal files
./adb shell run-as com.ipotensic.potensicpro rm -f databases/map.db-journal
# Overwrite db
base64 map.db > map.db.b64
# Linux
./adb shell run-as com.ipotensic.potensicpro sh -c "'base64 -d > databases/map.db'" < map.db.b64
# Powershell
Get-Content -Raw "map.db.b64" | ./adb shell run-as com.ipotensic.potensicpro sh -c "'base64 -d > databases/map.db'"
- Next, PotensicPro should be opened, the waypoint map opened, then on the right there should be an option to view ‘previously flown’ waypoint missions.
- Click on the generated flight, then opt to ‘fly it again’ (in reality, for the first time).
- Note that before starting the mission, the interval timer should be set to an interval of ~2 - 3 second shots, else you will get no imagery!
ADB In The Browser
- Requiring the user to install and use
adb
isn’t user friendly / accessible. - Asking users to also enable USB debugging also isn’t ideal… but I think this will still be required in any environment we use. It’s not a huge dealbreaker, as it’s a one time only action.
- There is a very interesting ADB implementation in JavaScript called Tango.
- I will definitely be exploring this further and implementing a simple workflow to:
- Generate flightplans in the DroneTM web app.
- Click ‘transfer to device’.
- Have the flightplan automatically copied to the necessary place to be picked up.
- If Potensic released an SDK then this wouldn’t be necessary. But I would say that is highly unlikely.
- DJI actually recently released an SDK for the Mini 4 Pro, that we will be integrating into our DroneTM workflow soon!
Stay Tuned
- The creating a waypoint file section doesn’t include all the info for brevity, and because the work is ongoing 😄
- Follow progress on the implementation in this linked pull request
- I will be testing the generated waypoint files work on probably the weekend 17th May.
- From there, it will be a simple matter of hooking up the waypoint generation logic, and adding it as a drone option in DroneTM.