diff --git a/cflib/crtp/radiodriver.py b/cflib/crtp/radiodriver.py index 1aa9cad6342cf8b51ab075db7cf13cbd6929ed54..a0a86a8d42c80d6236fa150edd549057bf74df59 100644 --- a/cflib/crtp/radiodriver.py +++ b/cflib/crtp/radiodriver.py @@ -153,6 +153,41 @@ class RadioDriver(CRTPDriver): an error message. """ + devid, channel, datarate, address = self.parse_uri(uri) + self.uri = uri + + if self._radio_manager is None: + self._radio_manager = _RadioManager(devid, + channel, + datarate, + address) + else: + raise Exception('Link already open!') + + with self._radio_manager as cradio: + if cradio.version >= 0.4: + cradio.set_arc(_nr_of_arc_retries) + else: + logger.warning('Radio version <0.4 will be obsoleted soon!') + + # Prepare the inter-thread communication queue + self.in_queue = queue.Queue() + # Limited size out queue to avoid "ReadBack" effect + self.out_queue = queue.Queue(1) + + # Launch the comm thread + self._thread = _RadioDriverThread(self._radio_manager, + self.in_queue, + self.out_queue, + link_quality_callback, + link_error_callback, + self) + self._thread.start() + + self.link_error_callback = link_error_callback + + @staticmethod + def parse_uri(uri): # check if the URI is a radio URI if not re.search('^radio://', uri): raise WrongUriType('Not a radio URI') @@ -165,8 +200,6 @@ class RadioDriver(CRTPDriver): uri_data = re.search('^radio://([0-9a-fA-F]+)((/([0-9]+))' '((/(250K|1M|2M))?(/([A-F0-9]+))?)?)?$', uri) - self.uri = uri - if len(uri_data.group(1)) < 10 and uri_data.group(1).isdigit(): devid = int(uri_data.group(1)) else: @@ -195,35 +228,7 @@ class RadioDriver(CRTPDriver): new_addr = struct.unpack('<BBBBB', binascii.unhexlify(addr)) address = new_addr - if self._radio_manager is None: - self._radio_manager = _RadioManager(devid, - channel, - datarate, - address) - else: - raise Exception('Link already open!') - - with self._radio_manager as cradio: - if cradio.version >= 0.4: - cradio.set_arc(_nr_of_arc_retries) - else: - logger.warning('Radio version <0.4 will be obsoleted soon!') - - # Prepare the inter-thread communication queue - self.in_queue = queue.Queue() - # Limited size out queue to avoid "ReadBack" effect - self.out_queue = queue.Queue(1) - - # Launch the comm thread - self._thread = _RadioDriverThread(self._radio_manager, - self.in_queue, - self.out_queue, - link_quality_callback, - link_error_callback, - self) - self._thread.start() - - self.link_error_callback = link_error_callback + return devid, channel, datarate, address def receive_packet(self, time=0): """ diff --git a/sys-test/__init__.py b/sys-test/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/sys-test/swarm_test_rig/__init__.py b/sys-test/swarm_test_rig/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7dc36c6a406d6eee3cf820aa19b66589f28f78f8 --- /dev/null +++ b/sys-test/swarm_test_rig/__init__.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +# +# || ____ _ __ +# +------+ / __ )(_) /_______________ _____ ___ +# | 0xBC | / __ / / __/ ___/ ___/ __ `/_ / / _ \ +# +------+ / /_/ / / /_/ /__/ / / /_/ / / /_/ __/ +# || || /_____/_/\__/\___/_/ \__,_/ /___/\___/ +# +# Copyright (C) 2019 Bitcraze AB +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301, USA. + diff --git a/sys-test/swarm_test_rig/cload_all_nrf.sh b/sys-test/swarm_test_rig/cload_all_nrf.sh new file mode 100755 index 0000000000000000000000000000000000000000..7da86e8f3e4f9b45264c9e662294837885eaabeb --- /dev/null +++ b/sys-test/swarm_test_rig/cload_all_nrf.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +file=$1 + +python3 -m cfloader flash $file nrf51-fw -w radio://0/42/2M/E7E7E74201 +python3 -m cfloader flash $file nrf51-fw -w radio://0/42/2M/E7E7E74202 +python3 -m cfloader flash $file nrf51-fw -w radio://0/42/2M/E7E7E74203 +python3 -m cfloader flash $file nrf51-fw -w radio://0/42/2M/E7E7E74204 +python3 -m cfloader flash $file nrf51-fw -w radio://0/42/2M/E7E7E74205 +python3 -m cfloader flash $file nrf51-fw -w radio://0/42/2M/E7E7E74206 +python3 -m cfloader flash $file nrf51-fw -w radio://0/42/2M/E7E7E74207 +python3 -m cfloader flash $file nrf51-fw -w radio://0/42/2M/E7E7E74208 diff --git a/sys-test/swarm_test_rig/cload_all_stm.sh b/sys-test/swarm_test_rig/cload_all_stm.sh new file mode 100755 index 0000000000000000000000000000000000000000..630a1b29c487d63fa8ac171ee5b13b079d03824c --- /dev/null +++ b/sys-test/swarm_test_rig/cload_all_stm.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +file=$1 + +python3 -m cfloader flash $file stm32-fw -w radio://0/42/2M/E7E7E74201 +python3 -m cfloader flash $file stm32-fw -w radio://0/42/2M/E7E7E74202 +python3 -m cfloader flash $file stm32-fw -w radio://0/42/2M/E7E7E74203 +python3 -m cfloader flash $file stm32-fw -w radio://0/42/2M/E7E7E74204 +python3 -m cfloader flash $file stm32-fw -w radio://0/42/2M/E7E7E74205 +python3 -m cfloader flash $file stm32-fw -w radio://0/42/2M/E7E7E74206 +python3 -m cfloader flash $file stm32-fw -w radio://0/42/2M/E7E7E74207 +python3 -m cfloader flash $file stm32-fw -w radio://0/42/2M/E7E7E74208 diff --git a/sys-test/swarm_test_rig/test_connection.py b/sys-test/swarm_test_rig/test_connection.py new file mode 100644 index 0000000000000000000000000000000000000000..e89ad03cae0bd66afafbe0e89ddb5d00d6b30788 --- /dev/null +++ b/sys-test/swarm_test_rig/test_connection.py @@ -0,0 +1,95 @@ +# -*- coding: utf-8 -*- +# +# || ____ _ __ +# +------+ / __ )(_) /_______________ _____ ___ +# | 0xBC | / __ / / __/ ___/ ___/ __ `/_ / / _ \ +# +------+ / /_/ / / /_/ /__/ / / /_/ / / /_/ __/ +# || || /_____/_/\__/\___/_/ \__,_/ /___/\___/ +# +# Copyright (C) 2019 Bitcraze AB +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301, USA. + +import unittest +import time + +import cflib.crtp +from cflib.crazyflie.swarm import Swarm +from cflib.crtp import RadioDriver +from cflib.drivers.crazyradio import Crazyradio + + +class TestSwarmConnection(unittest.TestCase): + def setUp(self): + + self.all_uris = [ + 'radio://0/42/2M/E7E7E74201', + 'radio://0/42/2M/E7E7E74202', + 'radio://0/42/2M/E7E7E74203', + 'radio://0/42/2M/E7E7E74204', + 'radio://0/42/2M/E7E7E74205', + 'radio://0/42/2M/E7E7E74206', + 'radio://0/42/2M/E7E7E74207', + 'radio://0/42/2M/E7E7E74208', + 'radio://0/42/2M/E7E7E74209', + 'radio://0/42/2M/E7E7E7420A', + ] + + def test_that_connection_time_scales_with_more_devices(self): + cflib.crtp.init_drivers(enable_debug_driver=False) + + self.restart_devices(self.all_uris) + + EXPECTED_CONNECTION_TIME = 5 + + for nr_of_devices in range(1, len(self.all_uris)): + uris = self.all_uris[:nr_of_devices] + + start_time = time.time() + with Swarm(uris): + connected_time = time.time() + + actual = connected_time - start_time + max_expected = EXPECTED_CONNECTION_TIME * nr_of_devices + print('Connection time for', nr_of_devices, ':', actual, + ', per device:', actual / nr_of_devices) + self.assertLess(actual, max_expected) + + def restart_devices(self, uris): + def send_packets(uris, value): + for uri in uris: + devid, channel, datarate, address = RadioDriver.parse_uri(uri) + radio.set_channel(channel) + radio.set_data_rate(datarate) + radio.set_address(address) + + received_packet = False + for i in range(100): + result = radio.send_packet((0xf3, 0xfe, value)) + if result.ack: + received_packet = True + break + + self.assertTrue(received_packet) + + BOOTLOADER_CMD_SYSOFF = 0x02 + BOOTLOADER_CMD_SYSON = 0x03 + + radio = Crazyradio() + send_packets(uris, BOOTLOADER_CMD_SYSOFF) + time.sleep(0.1) + send_packets(uris, BOOTLOADER_CMD_SYSON) + radio.close() + time.sleep(5)