Set altHoldMode parameter from mobile application without using radio

Firmware/software/electronics/mechanics
Spordos
Beginner
Posts: 8
Joined: Mon May 17, 2021 11:15 am

Set altHoldMode parameter from mobile application without using radio

Post 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?
arnaud
Bitcraze
Posts: 2538
Joined: Tue Feb 06, 2007 12:36 pm

Re: Set altHoldMode parameter from mobile application without using radio

Post 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.
Spordos
Beginner
Posts: 8
Joined: Mon May 17, 2021 11:15 am

Re: Set altHoldMode parameter from mobile application without using radio

Post 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
arnaud
Bitcraze
Posts: 2538
Joined: Tue Feb 06, 2007 12:36 pm

Re: Set altHoldMode parameter from mobile application without using radio

Post 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.
Spordos
Beginner
Posts: 8
Joined: Mon May 17, 2021 11:15 am

Re: Set altHoldMode parameter from mobile application without using radio

Post 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.
Spordos
Beginner
Posts: 8
Joined: Mon May 17, 2021 11:15 am

Re: Set altHoldMode parameter from mobile application without using radio

Post 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
arnaud
Bitcraze
Posts: 2538
Joined: Tue Feb 06, 2007 12:36 pm

Re: Set altHoldMode parameter from mobile application without using radio

Post 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).
Spordos
Beginner
Posts: 8
Joined: Mon May 17, 2021 11:15 am

Re: Set altHoldMode parameter from mobile application without using radio

Post 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);
Spordos
Beginner
Posts: 8
Joined: Mon May 17, 2021 11:15 am

Re: Set altHoldMode parameter from mobile application without using radio

Post 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
Spordos
Beginner
Posts: 8
Joined: Mon May 17, 2021 11:15 am

Re: Set altHoldMode parameter from mobile application without using radio

Post 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
Post Reply