bitcraze / crazyflie-lib-python

Python library to communicate with Crazyflie
Other
250 stars 889 forks source link

Investigate TOC retrieval crazyflies #466

Closed knmcguire closed 1 week ago

knmcguire commented 1 week ago

Currently it takes some time (5ish secs per crazyflie) to receive the TOC of both parameters and logging variables, which is pretty long especially with Swarms. This is a bit too long apparently so we need to investigate exactly how long it takes per Crazyflie (and if it is linear).

The cache functionality is supposed to solve it partially, but it probably also has been hiding any potential problems with the TOC retrieval. So let's investigate 😄.

whoenig commented 1 week ago

It might take long to query the actual parameter values. In Crazyswarm2, Cpp backend, we made this optional (with the default being to not query it), which made the connection much faster.

knmcguire commented 1 week ago

hi @whoenig. Ah yes we are very aware, but we do consider the TOC retrieval and value download differently, so this issue is just about the TOC retrieval for both logs and params.

But I did made an issue for Crazyswarm2 to implement what you mentioned for the cflib, since that should be reasonable easy by seperating connected (only toc)/fully_connected (toc and values) in https://github.com/IMRCLab/crazyswarm2/issues/560. I hope to have made a PR on this soon.

gemenerik commented 1 week ago

Simple Python script that measures total time to connect:

import cflib.crtp
from cflib.crazyflie.swarm import CachedCfFactory
from cflib.crazyflie.swarm import Swarm
import time

uris = {
    """
    Use a different channel for each radio dongle and unique addresses for each Crazyflie.
    Sharing channels between radios can cause packet loss. Limit to 3-4 Crazyflies per radio.
    """
}

if __name__ == '__main__':
    cflib.crtp.init_drivers()
    factory = CachedCfFactory(rw_cache='./cache')

    start_time = time.time()
    with Swarm(uris, factory=factory) as swarm:
        end_time = time.time()
        print('Connection took: {0} seconds'.format(end_time - start_time))
        print('Connected to Crazyflies!')
Number of Crazyflies   Time to fully connect (s)  
Radio 1 Radio 2 Pre-cached Uncached
1 0 0.7 3.8
2 0 1.4 8.3
3 0 2.2 12.4
4 0 2.7 16.3
4 1 2.7 16.7
4 2 3 16.5
4 3 3 16.5
1 1 1 4
2 2 1.7 8.4
3 3 2.4 12.9

The caching system works as expected with the recommended radio setup for swarms. The connection time scales linearly with the number of Crazyflies per radio. When using multiple radios, the connection time is determined by the radio with the most connections. There is a small, consistent time increase when using multiple radios, regardless of the number of connected Crazyflies.

One thing to note is that the cache location in our examples is set as a relative path to the active working directory. While this might lead to some user errors, it should work fine as long as the active working directory remains consistent.

While the uncached connection time for 4 Crazyflies per radio is long, it seems workable, especially since this process theoretically only needs to be done once. To speed up uncached connection times, we could optimize the process by first checking the ToC CRC for each Crazyflie and then only downloading each unique ToC once. This would prevent writing the same cache multiple times for Crazyflies that share identical ToC CRCs.

gemenerik commented 1 week ago

The recommended radio setup is to;