The Crazyflie parameter framework provides a way to get, set and monitor parameters in the quadcopter. Examples of a parameter include which effect the LED ring will display as well as which controller to use for flight.
The parameters have default values and up until now have been reset to those default values on each restart of the Crazyflie. This has not been seen as much of a problem (Or has it? Let us know!) since most use of the Crazyflie platform has been session based and the need for persistent parameters has been low. Our work with getting the Crazyflie Bolt out of early access has however changed this need.
The Bolt will need different values for the tuning parameters for controllers and being forced to set these on each boot would be pretty annoying. And since we want the Crazyflie Bolt and the Crazyflie 2.1 to share the same firmware, persistent parameters would come in handy.
Fortunately the Crazyflie includes an EEPROM (Electronically Erasable Programmable Read-Only Memory) which we can use to store parameter values and have them survive restarts of the quad.
So this means, with the latest branches of the firmware and the python library, you can set values of a persistent parameter, store it to EEPROM, and the parameter will keep its values across reset and even across firmware upgrades.
Persistent Parameter API
Not all parameters will be able to be persistent and stored in the EEPROM. We have added a way to declare a parameter as persistent in the firmware:
PARAM_ADD_CORE(PARAM_UINT8 | PARAM_PERSISTENT, effect, &effect)
This will allow the new API added to our python library to be used with this parameter. The API consists of three actions:
- Getting the state of a persistent parameter
- Storing the current value of a persistent parameter
- Clearing the stored value of a persistent parameter
The state of a persistent parameter consist of three pieces of information:
- Is the value stored or not
- The default value of the parameter
- The stored value of the parameter
Setting a value, using the regular parameter API, is not enough to store the value to the EEPROM for a persistent parameter, you need to be explicit. A special API call is needed to store the current value to memory. And to stop storing the value you need to use the clear API action.
The above choices corresponds to three methods in our Python API:
def persistent_get_state(self, complete_name, callback)
Get the state of the specified persistent parameter. The state will be returned in the supplied callback. The state is represented as a named tuple with members:
stored_value. The state is
None if the parameter is not persistent or if something goes wrong.
def persistent_store(self, complete_name, callback=None)
Store the current value of the specified persistent parameter to EEPROM. The supplied callback will be called with
True as an argument on success, and with
False as an argument on failure.
def persistent_clear(self, complete_name, callback=None)
Clear the current value of the specified persistent parameter from EEPROM. The supplied callback will be called with
True as an argument on success and with
False as an argument on failure.
We have also added an example script that will showcase the functionality, it will list the state of all persisted parameters in the firmware, and will store and clear some of them. The output when run against current master is:
$ CFLIB_URI=radio://0/80/2M/E7E7E7E7E8 python3 examples/parameters/persistent_params.py -- All persistent parameters -- sound.effect: PersistentParamState(is_stored=False, default_value=0, stored_value=None) ring.effect: PersistentParamState(is_stored=True, default_value=6, stored_value=2) Set parameter ring.effect to 10 Store the new value in persistent memory Persisted ring.effect! The new state is: ring.effect: PersistentParamState(is_stored=True, default_value=6, stored_value=10) Clear the persisted parameter Cleared ring.effect! The new state is: ring.effect: PersistentParamState(is_stored=False, default_value=6, stored_value=None)
You can count on more parameters to be marked as persistent in the near future. Hopefully this will be useful for you! Please report any issues you find!