Documentation: Developing on the SkyController


Hi Developers !

As a follow-up to this message, I’ve wrote a documentation about developing an android application for the SkyController.

A little disclaimers about this topic:

  • There is no plan to allow third party developers to deploy a SkyController application for the public. This document will help you develop an application for your own SkyController only (or at least for SkyControllers you have physical access to).
  • Some of the modifications discussed in the documentation require you to run the SkyController with root access, and with the /system partition in read/write mode. Do not do these modifications if you are not comfortable with the Android internals, as a bad command CAN brick the device in this case !

You can find the documentation here:
Documentation: Developing on the SkyController
And the latex sources here.


Skycontroller copiloting
About SkyController

Hi Nicolas.
It does not talk about reading drone’s GPS position (see my post here: Bebop 1 GPS reading problem while using skycontroller).
May you help me please with it?


Hi @Nicolas,

What does AxisFilter do?

<class name="AxisFilters" id="16">
  Controls the axis filters of the SkyController

  <cmd name="getCurrentAxisFilters">
	Asks the SkyController to send its current axis filters

  <cmd name="getPresetAxisFilters">
	Asks the SkyController to send the preset filters

  <cmd name="setAxisFilter">
	Set an axis filter to the SkyController
	@note replaces previous filter for the given axis
	<arg name="axis_id" type="i32">
	  The axiscode to filter
	<arg name="filter_uid_or_builder" type="string">
	  The mapping preset to associate with the axis
	  (Or a string to build a new one)

  <cmd name="defaultAxisFilters">
	Asks the SkyController to reset the axis filters to the default value

<class name="AxisFiltersState" id="17">
  State of the axis filters of the SkyController

  <cmd name="currentAxisFilters" listtype="MAP">
	Sent by the SkyController each time a filter changes
	<arg name="axis_id" type="i32">
	  The axiscode filtered
	<arg name="filter_uid_or_builder" type="string">
	  The filter associated

  <cmd name="allCurrentFiltersSent">
	Sent by the SkyController after sending its last 'currentAxisFilters' command

  <cmd name="presetAxisFilters" listtype="MAP">
	Sent after a 'getPresetAxisFilters' request
	<arg name="filter_uid" type="string">
	  The filter UID (used in communication with the SkyController)
	<arg name="name" type="string">
	  Display name for the user

  <cmd name="allPresetFiltersSent">
	Sent by the SkyController after sending its last 'presetAxisFilters' command




The axis filters are used to change the response curve of each axis (you can see this in the FreeFlight settings).

As the filters are dynamic, we do not use a list of “available filters” (and the presets is empty, as you might have seen), but rather a syntax of “filter builder” (you can see this as a serialization of the filter object). This syntax is indeed undocumented now, but I’ll try to add it somewhere !



Oh I get it! It is a form of exponential. That explains why the preset list is empty too. I think I have what I need to proceed.

CORRECTION… will have what I need to proceed once I figure out the format of filter builder.


I’ll explain the format, nothing secret here :wink:
I’m just not currently at work (well … it’s saturday :smiley: ), so I don’t want to explain it “by head” and tell you something wrong :wink:

If you really want to see the format before the documentation is out, you can try setting different kind of exponential or multi-linear curves from FreeFlight, and look at what you get from the currentAxisFilters map.



Nicolas, you are a man of few words, but when spoken go a long way :slightly_smiling:

This is pretty neat stuff:

gamePadInfo id=103 type=BUTTON name=HOME
gamePadInfo id=100 type=BUTTON name=RIGHT_MINI_JS
gamePadInfo id=101 type=BUTTON name=TAKEOFF_LANDING
gamePadInfo id=98 type=BUTTON name=RECORD
gamePadInfo id=99 type=BUTTON name=EMERGENCY
gamePadInfo id=96 type=BUTTON name=LEFT_MINI_JS
gamePadInfo id=97 type=BUTTON name=RETURN_HOME
gamePadInfo id=104 type=BUTTON name=BACK

gamePadInfo id=0 type=AXIS name=TOP_LEFT_LEFT_RIGHT
gamePadInfo id=1 type=AXIS name=TOP_LEFT_UP_DOWN
gamePadInfo id=2 type=AXIS name=RIGHT_LEFT_RIGHT
gamePadInfo id=3 type=AXIS name=RIGHT_UP_DOWN
gamePadInfo id=4 type=AXIS name=LEFT_LEFT_RIGHT
gamePadInfo id=5 type=AXIS name=LEFT_UP_DOWN
gamePadInfo id=6 type=AXIS name=TOP_RIGHT_LEFT_RIGHT
gamePadInfo id=7 type=AXIS name=TOP_RIGHT_UP_DOWN

buttonMapping uid=Emergency name=Emergency
buttonMapping uid=Return Home name=Return Home
buttonMapping uid=Record name=Record
buttonMapping uid=Settings name=Settings
buttonMapping uid=Reset Camera name=Reset Camera
buttonMapping uid=Takeoff/Landing name=Takeoff/Landing
buttonMapping uid=Photo name=Photo
buttonMapping uid=No Action name=No Action
buttonMapping uid=Back name=Back

axisMapping uid=Camera Tilt name=Camera Tilt
axisMapping uid=Camera Pan name=Camera Pan
axisMapping uid=Gaz name=Gaz
axisMapping uid=Roll name=Roll
axisMapping uid=Yaw name=Yaw
axisMapping uid=No Action name=No Action
axisMapping uid=Pitch name=Pitch

currentButtonMapping id=103 uid=Reset Camera
currentButtonMapping id=100 uid=Photo
currentButtonMapping id=101 uid=Takeoff/Landing
currentButtonMapping id=98 uid=Record
currentButtonMapping id=99 uid=Emergency
currentButtonMapping id=96 uid=Settings
currentButtonMapping id=97 uid=Return Home
currentButtonMapping id=104 uid=Back

currentAxisMapping id=0 uid=No Action
currentAxisMapping id=1 uid=No Action
currentAxisMapping id=2 uid=Roll
currentAxisMapping id=3 uid=Pitch
currentAxisMapping id=4 uid=Yaw
currentAxisMapping id=5 uid=Gaz
currentAxisMapping id=6 uid=Camera Pan
currentAxisMapping id=7 uid=Camera Tilt

currentAxisFilter id=0 uid=ARMF;
currentAxisFilter id=1 uid=ARMF;
currentAxisFilter id=2 uid=ARMF;
currentAxisFilter id=3 uid=ARMF;
currentAxisFilter id=4 uid=ARMF;
currentAxisFilter id=5 uid=ARMF;
currentAxisFilter id=6 uid=ARMF;
currentAxisFilter id=7 uid=ARMF;


That did it, Nicolas. Thanks for the pointers.

ARMF; == Linear

ARXF;x;y == Exponential

x (0 to 1 float) x location of center
y (0 to 1 float) y location of center

I guess there is no way to populate the presets? Further guessing that this feature was cut at some point.

One last question, it looks like exponential can also be applied to the top left and top right hat axes?


Thats the idea, yeah, but the ARMF; syntax is actually more than that (it can have arguments).

The presets is a compile-time empty list, the functionnality was designed but actually never used because building your own filter is not that difficult (that’s what is done within FreeFlight ;)).

And yeah, filtering can be applied to any AXIS (as in the gamepadInfoState command) of the SkyController.


Regarding other parameters for ARMF — Something like dual rates maybe?



You’ll find all required informations on the new SkyController SDK documentation page, and specially the setAxisFilter command documentation.

It also includes a simple python script to validate and examine your filter strings (since I wrote it to draw the curve in the documentation, I thought it might be useful for some other people ;))