I have run into an issue while setting up the headless client on a raspberry pi - the althold function engages but afterwards the crazyflie slowly descends. The behavior is as if the "zero thrust" stick position decreases the target altitude rather than keeping it constant. With althold engaged, the target altitude does increase when the stick is pushed to max thrust. It seems as if it needs about 50% thrust on the joystick for the altitude setpoint to remain constant.
The althold function works correctly when running cfclient on the same raspberry pi so the behavior seems related to the headless client only. I have used the pre-configured RPi SD image provided on the wiki and have also built my own per the instructions on the wiki on top of the latest Raspbian distribution. I have tried PS3 and Xbox360 controllers (with xboxdrv and with the kernel drivers). In all scenarios I get the same result - althold works running cfclient but not when running cfheadless.
Any suggestions would be greatly appreciated!
[SOLVED] althold issue with cfheadless
[SOLVED] althold issue with cfheadless
Last edited by rmcnish on Thu Aug 21, 2014 12:40 am, edited 1 time in total.
Re: althold issue with cfheadless
This problem has been discussed, it turns out that you have to constantly, 100Hz, have to set the thrust to 32767 to maintain a constant target altitude. This is because in althold-mode you are able to either decrease or increase the target altitude by increasing or decreasing thrust.
Re: althold issue with cfheadless
Thanks for the reply. I have spent some time looking through the code but am still a bit lost.
In an attempt to remedy the issue I tried modifying line 268 in lib/cfclient/utils/input.py but this seems to have no effect:
[267] if althold and self._has_pressure_sensor:
[268] thrust = int(round(JoystickReader.deadband(thrust,0.2)*32767 + 32767)) #Convert to uint16
Can you help me understand why this works in the GUI client but not with the headless? My understanding is that the headless client runs the cfclient code, just without the GUI on top. Is that not correct? Is the issue that the thrust is not being set at 100Hz? What controls this update rate?
In an attempt to remedy the issue I tried modifying line 268 in lib/cfclient/utils/input.py but this seems to have no effect:
[267] if althold and self._has_pressure_sensor:
[268] thrust = int(round(JoystickReader.deadband(thrust,0.2)*32767 + 32767)) #Convert to uint16
Can you help me understand why this works in the GUI client but not with the headless? My understanding is that the headless client runs the cfclient code, just without the GUI on top. Is that not correct? Is the issue that the thrust is not being set at 100Hz? What controls this update rate?
Re: althold issue with cfheadless
Hi again. I am really not sure lets hope one of the mods or more experienced users gets involved in this thread. I am not very well-versed in programming and Im not familiar with the headless client, Ive been writing my programs/functions importing cflib libraries and sending thrust using the already existing functions defined there. However you could try to change the firmware? If you check out crazyflie-firmware/modules/src/stabilize.c you will find the stabilize algorithms runned on the crazyflie. If you scroll down you'll find the function:
static void stabilizerAltHoldUpdate(void)
This, among other things, updates the targetAltitude. If you simply wants the targetAltitude to remain constant once its "set" you could remove the part that updates the value based on the joystick thrust:
// In altitude hold mode
if (altHold)
{
//Update target altitude from joy controller input
altHoldTarget += altHoldChange / altHoldChange_SENS; //remove this part?
pidSetDesired(&altHoldPID, altHoldTarget);
*******
I don't think I really understand your problem, let's wait and see what the mods say. Good luck
static void stabilizerAltHoldUpdate(void)
This, among other things, updates the targetAltitude. If you simply wants the targetAltitude to remain constant once its "set" you could remove the part that updates the value based on the joystick thrust:
// In altitude hold mode
if (altHold)
{
//Update target altitude from joy controller input
altHoldTarget += altHoldChange / altHoldChange_SENS; //remove this part?
pidSetDesired(&altHoldPID, altHoldTarget);
*******
I don't think I really understand your problem, let's wait and see what the mods say. Good luck

Re: althold issue with cfheadless
This is a bug. I managed to bypass it by making this change:
The problem is that when activating altitude hold the thrust data in the commander packets changes role and changes scaling, so there is a code in the joystick input driver that is checking if altitude hold is activated. There is some code in the GUI client that tells the joystick driver that altitude hold is possible (ie. we are connected to a 10DOF) and this is not done in headless client hence the line I added.
The change fixes the problem but it still need to be done properly to be pushed in git (ie. detecting if the connected copter is a 10DOF or a 6DOF).
Code: Select all
diff --git a/lib/cfheadless.py b/lib/cfheadless.py
index af05193..11711e2 100644
--- a/lib/cfheadless.py
+++ b/lib/cfheadless.py
@@ -97,6 +97,7 @@ class HeadlessClient():
self._cf.open_link(link_uri)
self._jr.input_updated.add_callback(self._cf.commander.send_setpoint)
+ self._jr.setAltHoldAvailable(True)
def _connection_failed(self, link, message):
"""Callback for a failed Crazyflie connection"""
The change fixes the problem but it still need to be done properly to be pushed in git (ie. detecting if the connected copter is a 10DOF or a 6DOF).
Re: althold issue with cfheadless
That did the trick. Thank you very much for the support!