Page 1 of 2

Set altHoldMode parameter from mobile application without using radio

Posted: Mon Jun 14, 2021 9:05 am
by Spordos
Hello,

I am working on alternative features for the mobile crazyflie application and am currently trying to add the ablity to enable altitude hold modus through the mobile (android) application using the BleLink. I am currently running into the issue that writing this parameter currently only seems to work with the radio and a gamepad attached. I have also seen some comments about the writing of a parameter being very slow on Ble due to it sending the entire TOC.

Is there a way to read and write an indivudual parameter without having to make use of the TOC?

Re: Set altHoldMode parameter from mobile application without using radio

Posted: Tue Jun 15, 2021 9:02 am
by arnaud
There is a radio packet implemented exactly for this usecase: param set by name: https://www.bitcraze.io/documentation/r ... et-by-name. This allows to set a parameter by sending its group and name in the packet. So it would allow to enable altHoldMode without having to fetch the full param toc. There is no way to read a parameter by name though, this is something that could be added quite easily to the firmware (PR welcome ;-).

If I remember well, one of the reason altHold is not enabled on touch-screen was mostly due to a safety worry: with a gamepad altHold is enabled by holding a physical button and so if anything happens the motors of the Crazyflie can be stopped by releasing all buttons and joystick from the gamepad. On a touch screen, if a toggle button is used, it is much harder to hit a panic button. However this is definitly something that can be experimented with.

Re: Set altHoldMode parameter from mobile application without using radio

Posted: Tue Jun 15, 2021 3:19 pm
by Spordos
I have tried implementing "set by name", but the crazyflie still seems unresponsive to the packets I am sending out.

This is my code:
functioncall

Code: Select all

mCrazyflie.setParamValueBle("flightmode.althold", hover ? 1 : 0, VariableType.UINT8_T);
function

Code: Select all

public void setValueBle(String completeName, Number value, VariableType cType){
        byte[] groupBytes, nameBytes;
        byte bytevalue;
        Log.i("debug", "name: " + completeName + " value: " + value + " type: " + cType);
        Header header = new Header(MISC_CHANNEL, CrtpPort.PARAMETERS);
        String[] split = completeName.split("\\.");
        groupBytes = split[0].getBytes();
        nameBytes = split[1].getBytes();
        //byte[] parse = cType.parse(value);
        bytevalue = value.byteValue();
        ByteBuffer bb = ByteBuffer.allocate(1 + groupBytes.length + nameBytes.length + 4);
        bb.put((byte) 0x00);
        for (int i = 0; i < groupBytes.length; i++){
            bb.put(groupBytes[i]);
        }
        bb.put((byte) 0);
        for (int i = 0; i < nameBytes.length; i++){
            bb.put(nameBytes[i]);
        }
        bb.put((byte) 0);
        bb.put(cType.getTypeCode());
        bb.put(bytevalue);
        Log.i("debug", "data: " + bb.array());
        CrtpPacket packet = new CrtpPacket(header.getByte(), bb.array());
        //self.param_updater.request_param_setvalue(pk)
        Log.i("debug", "packet: " + packet);
        mPut.addParamRequest(packet);
    }
I have tried using the parse function aswell, but that also had no succes.

So my question is, is this implemented correctly, or am i doing it totally wrong/missing a function already in place?

Edited: a word

Re: Set altHoldMode parameter from mobile application without using radio

Posted: Wed Jun 16, 2021 9:22 am
by arnaud
I could not find anything wrong with your function. Have you looked for the answer from the Crazflie? The Crazyflie should set a packet back with an error code indicating success (0) or failure (non 0).

How are you testing the alt-hold? The way alt-hold is implemented in the Crazyflie, it should be activated when the Crazyflie is already flying, otherwise nothing will happen.

Re: Set altHoldMode parameter from mobile application without using radio

Posted: Wed Jun 16, 2021 9:45 am
by Spordos
One thing i just found while looking into the receiving end of the packages is that a part of the parameter name gets lost somewhere in the firmware. It receives flightmode as group (which is good), but name gets converted to althol instead of the complete name: althold.

Re: Set altHoldMode parameter from mobile application without using radio

Posted: Wed Jun 16, 2021 10:00 am
by Spordos
Regarding how i'm testing it. From earlier tests with the PC client im sure the activation of the assisted mode also works if not already in flight (I tested it just now to be sure). I am testing whether my package was received using DEBUG_PRNT in the firmware, but I am noticing that either not all packages are succesfully received, or not all give a good response back to the android client.

EDIT: The fact the the packet is not as send when received seems to be a result of sendSplitPacket on the android app side. Since the lenght of this payload is 21, it does not pass the <20 for a normal packet and thus gets send as a split packed. I am not sure what, but something goes wrong in split packet

EDIT 2: I am getting the EINVAL response (paramater type mismatch). I dont understand what the reason for this is because I send type: UINT8_T and it is registered in the firmware as an UINT8_T

EDIT 3: it appears that the data after the name is all zeros (0x00), which is why to has the type mismatch and doesnt have a good value

Re: Set altHoldMode parameter from mobile application without using radio

Posted: Wed Jun 23, 2021 8:17 am
by arnaud
It may be that the split packet is bugged somehow. this is not impossible. One way to check would be to make a parameter with a smaller name that makes the packet fit in a single BLE packet (or rename the parameter you want to set) and seeing if this solves your problem. If it does, we have a bug in the BLE implementation in the Crazyflie and I can start looking at it (I was meaning to look a bit more at BLE during the summer anyway to test webBluetooth).

Re: Set altHoldMode parameter from mobile application without using radio

Posted: Thu Jun 24, 2021 10:29 am
by Spordos
I found the bug in split package:

Function:

Code: Select all

private void sendSplitPacket(CrtpPacket packet) {
        //send plain bytearrays with controlbyte header
        // controlbyte + crtpheader + payload (19bytes)
        byte[] firstPacket = new byte[20];
        firstPacket[0] = new ControlByte(true, pid, packet.toByteArray().length).toByte();
        firstPacket[1] = packet.getHeaderByte();
        System.arraycopy(packet.getPayload(),0, firstPacket, 2, 18);
        // send first packet
        mContext.runOnUiThread(new SendBlePacket(firstPacket, mCrtpUpChar));

        // controlbyte + payload (rest)
        byte[] secondPacket = new byte[20];
        secondPacket[0] = new ControlByte(false, pid, 0).toByte();
        System.arraycopy(packet.getPayload(),19, secondPacket, 1, packet.getPayload().length-19);
        // send second packet
        mContext.runOnUiThread(new SendBlePacket(secondPacket, mCrtpUpChar));
        pid = (pid+1)%4;
    }
On this line:

Code: Select all

 System.arraycopy(packet.getPayload(),19, secondPacket, 1, packet.getPayload().length-19);
Since the first package takes a portion of length 18 from the payload, it takes index 0-17. This line starts the second package at 19 however, thus skipping a byte. This line should be:

Code: Select all

 System.arraycopy(packet.getPayload(),18, secondPacket, 1, packet.getPayload().length-19);

Re: Set altHoldMode parameter from mobile application without using radio

Posted: Thu Jun 24, 2021 11:08 am
by Spordos
I also found the problem of the type mismatch. This problem is acutally introduced by Core Parametetes. Normally, the parameter has an bit value of 8, but in the PARAM ADD CORE, it is bitwise OR'd with bit value 32. This creates an 40 for typevalue for this variable, making it no longer lineup with the misc command of 8 for an UINT_8

Re: Set altHoldMode parameter from mobile application without using radio

Posted: Thu Jun 24, 2021 12:25 pm
by Spordos
Okey, I have it working now over bluetooth, but only over single packet, split packages seem to arrive correctly now, but only arrive/trigger the setting of the parameter less than 10% of my tries, while single packet always triggers correctly, So for split packets to work correctly it might be needed to take a look at the arrival of packets in the firmware