whoenig / crazyflie_cpp

C++ Library to communicate with Bitcraze Crazyflie
MIT License
21 stars 38 forks source link

broadcast support for setpoint message (?) #20

Open ajshank opened 1 year ago

ajshank commented 1 year ago

Hello,

When connected to multiple Crazyflies (2.0) on the same radio, sending setpoints (Commander, port 3, crtpSetpointRequest) to more than one CF results in very poor performance in flight. I suspect this is because by default this packet is ack'd and is sent on a unicast-type link, so switching between each of the CFs causes a bottleneck. The CrazyflieBroadcaster class doesn't have an appropriate method for sending these packets; they don't have an id field associated with them.

What would be the appropriate way to send crtpSetpointRequest packets to multiple connected CFs? I have tried sending these via sendPacketNoAck() methods (with arc set to zero, and forcing setAckEnable to false after initialisation), however, I can't definitively say that this has improved anything much.

This may be an unusual use-case, so, apologies if there's a better/recommended way of achieving this that I haven't found.

Thanks for all the work on the cpp libraries!

whoenig commented 1 year ago

Which branch are you using and do you exchange any other packets apart from the setpoints? How do you measure "very poor performance"?

ajshank commented 1 year ago

This is with the master branch, and no other packets are being sent.

The measure of performance here is flight stability* -- if 2 CFs are being sent these packets, then one of them flies poorly (and this varies by time and relative distance from the PA radio). If one of them is forcibly removed**, then the other one returns to a stable flight.

Adding a few more helpful notes: individually, either CFs will fly perfectly fine; as noted above, removing either one mid-flight will also make the other fly ok; these packets are being sent at ~30Hz.


*The poor stability is highly reminiscent of lost/missed commands or poor link quality. If there's a tool to analyse crtp link utilisation on the fly, I can try to post some comms stats here.

** I've tried to "remove" a CF in a way that prevents it from acknowledging these packets. One way to do it is to dislodge it mid-flight so that it enters a 'crash' state. The user-code is still sending packets to both regardless of this.

whoenig commented 1 year ago

I mostly work with https://github.com/whoenig/crazyflie_cpp/tree/dev-crazyflie-link-cpp, which uses an entirely different way of communicating. Would be great if you could try and report back if that solves your problem.

I assume both CFs have the same channel, but different addresses? I have seen weird issues if different channels but same addresses are being used.

Your broadcast idea is what I had implemented a while locally in dev-crazyflie-link-cpp, similar to what you described; it mostly helped with getting lower latency responses (but requires a custom firmware of the Crazyradio PA, since the firmware that ships with it doesn't support broadcasts). It's not merged in there yet, but would be easy to do so.

It's strange that you get different behavior in a "crash" state. As you said, this doesn't affect the host-code at all.

ajshank commented 1 year ago

Ok, I can try that branch and repeat this particular test.

I'm certain that I've tried combinations of same vs different channels/addresses, without too many noticeable differences. This is unsurprising, perhaps, when they are on different channels, because I didn't think that the radio is physically capable of switching in/out of multi-channel links in this fashion. I will take a look at the dev branch and see if it addresses the problem. Happy to help with any PRs if its speeds up the process. EDIT: I guess https://github.com/bitcraze/crazyflie-link-cpp/issues/24 is the relevant discussion?

I thought the different behaviour in "crash" state was explainable, but maybe I'm wrong. My interpretation was that it affected the host in its handling of acks or waiting on them (either on the radio firmware level, or somewhere downstream). That is, consequently, if the setpoint packets had no acks associated with them anywhere, I could expect the problem to be resolved.

since the firmware that ships with it doesn't support broadcasts

Just to clarify, does this mean none of the broadcast packets would work (essentially anything from the CrazyflieBroadcaster class) with the stock firmware? I'm afraid I've not tested broadcast functionality at all.

whoenig commented 1 year ago

Yes, the link you found is correct.

I don't think the lack of acks should really break the system - it will just repeat that particular packet for that particular drone.

Broadcast: That is correct. If you install the latest official firmware it works. In the dev branch, there is also proper error checking for this, which is only triggered if you try to use broadcasts, but your radio firmware doesn't support it. In the main branch there is no such warning...