Skip to content

Commit

Permalink
Merge branch 'master' into rik/latency
Browse files Browse the repository at this point in the history
  • Loading branch information
gemenerik committed Oct 22, 2024
2 parents 4136a69 + efbf417 commit 716071f
Show file tree
Hide file tree
Showing 17 changed files with 118 additions and 49 deletions.
30 changes: 15 additions & 15 deletions .github/workflows/dependency_check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,19 @@ on:
- cron: '0 2 * * *'

jobs:
# python-latest:
# runs-on: ubuntu-latest
# container:
# image: python:latest
#
# steps:
# - uses: actions/checkout@v4
#
# - name: python version
# run: python --version
#
# - name: install lib
# run: pip install -e .
python-latest:
runs-on: ubuntu-latest
container:
image: python:latest

steps:
- uses: actions/checkout@v4

- name: python version
run: python --version

- name: install lib
run: pip install -e .

python-python311:
runs-on: ubuntu-latest
Expand All @@ -34,10 +34,10 @@ jobs:
- name: install lib
run: pip install -e .

minimum-python37:
minimum-python310:
runs-on: ubuntu-latest
container:
image: python:3.7
image: python:3.10

steps:
- uses: actions/checkout@v4
Expand Down
12 changes: 9 additions & 3 deletions cflib/bootloader/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
from typing import Optional
from typing import Tuple

from packaging.version import Version

from .boottypes import BootVersion
from .boottypes import TargetTypes
from .cloader import Cloader
Expand Down Expand Up @@ -202,10 +204,12 @@ def flash(self, filename: str, targets: List[Target], cf=None, enable_console_lo
update_contains_nrf_sd = any(x.target.type == 'bootloader+softdevice' for x in flash_artifacts)
current_nrf_bl_version = None
if self._cload.targets[TargetTypes.NRF51].version is not None:
current_nrf_bl_version = str(self._cload.targets[TargetTypes.NRF51].version)
provided_nrf_bl_version = self._get_provided_nrf51_bl_version(flash_artifacts)
current_nrf_bl_version = Version(str(self._cload.targets[TargetTypes.NRF51].version))
provided_nrf_bl_version = None
if self._get_provided_nrf51_bl_version(flash_artifacts) is not None:
provided_nrf_bl_version = Version(self._get_provided_nrf51_bl_version(flash_artifacts))

print('nRF51 has: {} and requires {} and upgrade provides {}. Current bootloader version is [{}] but upgrade '
print('nRF51 has: {} and requires {} and upgrade provides {}. Current bootloader version is [{}] and upgrade '
'provides [{}]'.format(
current_nrf_sd_version, required_nrf_sd_version, provided_nrf_sd_version,
current_nrf_bl_version, provided_nrf_bl_version)
Expand Down Expand Up @@ -252,6 +256,8 @@ def flash(self, filename: str, targets: List[Target], cf=None, enable_console_lo
print('Reconnected to new bootloader')
self._cload.check_link_and_get_info()
self._cload.request_info_update(TargetTypes.NRF51)
else:
print('No need to flash nRF soft device')

# Remove the softdevice+bootloader from the list of artifacts to flash
flash_artifacts = [a for a in flash_artifacts if a.target.type !=
Expand Down
6 changes: 5 additions & 1 deletion cflib/crazyflie/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ def __init__(self, link=None, ro_cache=None, rw_cache=None):

# Called if establishing of the link fails (i.e times out)
self.connection_failed = Caller()
# Called if link driver has an error while state is DISCONNECTED
self.disconnected_link_error = Caller()
# Called for every packet received
self.packet_received = Caller()
# Called for every packet sent
Expand Down Expand Up @@ -205,10 +207,12 @@ def _link_error_cb(self, errmsg):
self.link = None
if (self.state == State.INITIALIZED):
self.connection_failed.call(self.link_uri, errmsg)
if (self.state == State.CONNECTED or
elif (self.state == State.CONNECTED or
self.state == State.SETUP_FINISHED):
self.disconnected.call(self.link_uri)
self.connection_lost.call(self.link_uri, errmsg)
elif (self.state == State.DISCONNECTED):
self.disconnected_link_error.call(self.link_uri, errmsg)
self.state = State.DISCONNECTED

def _link_quality_cb(self, percentage):
Expand Down
71 changes: 63 additions & 8 deletions cflib/crazyflie/high_level_commander.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"""
Used for sending high level setpoints to the Crazyflie
"""
import math
import struct

from cflib.crtp.crtpstack import CRTPPacket
Expand All @@ -46,6 +47,8 @@ class HighLevelCommander():
COMMAND_DEFINE_TRAJECTORY = 6
COMMAND_TAKEOFF_2 = 7
COMMAND_LAND_2 = 8
COMMAND_SPIRAL = 11
COMMAND_GO_TO_2 = 12

ALL_GROUPS = 0

Expand Down Expand Up @@ -131,7 +134,7 @@ def stop(self, group_mask=ALL_GROUPS):
self.COMMAND_STOP,
group_mask))

def go_to(self, x, y, z, yaw, duration_s, relative=False,
def go_to(self, x, y, z, yaw, duration_s, relative=False, linear=False,
group_mask=ALL_GROUPS):
"""
Go to an absolute or relative position
Expand All @@ -142,15 +145,67 @@ def go_to(self, x, y, z, yaw, duration_s, relative=False,
:param yaw: Yaw (radians)
:param duration_s: Time it should take to reach the position (s)
:param relative: True if x, y, z is relative to the current position
:param linear: True to use linear interpolation instead of a smooth polynomial
:param group_mask: Mask for which CFs this should apply to
"""
self._send_packet(struct.pack('<BBBfffff',
self.COMMAND_GO_TO,
group_mask,
relative,
x, y, z,
yaw,
duration_s))
if self._cf.platform.get_protocol_version() < 8:
if linear:
print('Warning: Linear mode not supported in protocol version < 8, update your crazyflie\'s firmware')
self._send_packet(struct.pack('<BBBfffff',
self.COMMAND_GO_TO,
group_mask,
relative,
x, y, z,
yaw,
duration_s))
else:
self._send_packet(struct.pack('<BBBBfffff',
self.COMMAND_GO_TO_2,
group_mask,
relative,
linear,
x, y, z,
yaw,
duration_s))

def spiral(self, angle, r0, rF, ascent, duration_s, sideways=False, clockwise=False,
group_mask=ALL_GROUPS):
"""
Follow a spiral-like segment (spline approximation of a spiral/arc for <= 90-degree segments)
:param angle: spiral angle (rad), limited to +/- 2pi
:param r0: initial radius (m), must be positive
:param rF: final radius (m), must be positive
:param ascent: altitude gain (m), positive to climb, negative to descent
:param duration_s: time it should take to reach the end of the spiral (s)
:param sideways: true if crazyflie should spiral sideways instead of forward
:param clockwise: true if crazyflie should spiral clockwise instead of counter-clockwise
:param group_mask: Mask for which CFs this should apply to
"""
if self._cf.platform.get_protocol_version() < 8:
print('Warning: Spiral command is not supported in protocol version < 8, update your crazyflie\'s firmware')
else:
if angle > 2*math.pi:
angle = 2*math.pi
print('Warning: Spiral angle saturated at 2pi as it was too large')
elif angle < -2*math.pi:
angle = -2*math.pi
print('Warning: Spiral angle saturated at -2pi as it was too small')
if r0 < 0:
r0 = 0
print('Warning: Initial radius set to 0 as it cannot be negative')
if rF < 0:
rF = 0
print('Warning: Final radius set to 0 as it cannot be negative')
self._send_packet(struct.pack('<BBBBfffff',
self.COMMAND_SPIRAL,
group_mask,
sideways,
clockwise,
angle,
r0, rF,
ascent,
duration_s))

def start_trajectory(self, trajectory_id, time_scale=1.0, relative=False,
reversed=False, group_mask=ALL_GROUPS):
Expand Down
3 changes: 1 addition & 2 deletions docs/development/matlab.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@ title: Using Matlab with the Crazyflie API
page_id: matlab
---

**Note that these are old instructions and they might not work anymore**

To use the Python cflib with matlab, you will need to install the python 'matlab engine' and then can access all matlab commands
directly from python.

*Note that these are old instructions and they might not work anymore**

Tried with
-------------

Expand Down
4 changes: 2 additions & 2 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
---
title: Home
page_id: home
page_id: home
---

cflib is an API written in Python that is used to communicate with the Crazyflie
and Crazyflie 2.0 quadcopters. It is intended to be used by client software to
and Crazyflie 2.x quadcopters. It is intended to be used by client software to
communicate with and control a Crazyflie quadcopter. For instance the [Crazyflie PC client](https://github.com/bitcraze/crazyflie-clients-python) uses the cflib.

## Contribute
Expand Down
8 changes: 4 additions & 4 deletions docs/installation/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ page_id: install

## Requirements

This project requires Python 3.8 - 3.12.
This project requires Python 3.10+.


See below sections for more platform-specific requirements.
Expand All @@ -28,7 +28,7 @@ pip uninstall cflib

Note: If you are developing for the cflib you must use python3. On Ubuntu (20.04+) use `pip3` instead of `pip`.

### Linux, OSX, Windows
### Linux, macOS, Windows

The following should be executed in the root of the crazyflie-lib-python file tree.

Expand All @@ -44,8 +44,8 @@ you can skip this section.

* To deactivate the virtualenv when you are done using it `deactivate`

### Pre commit hooks (Ubuntu)
If you want some extra help with keeping to the mandated python coding style you can install hooks that verify your style at commit time. This is done by running:
### Pre-commit hooks (Ubuntu)
If you want some extra help with keeping to the mandated Python coding style you can install hooks that verify your style at commit time. This is done by running:
```
$ pip3 install pre-commit
```
Expand Down
2 changes: 1 addition & 1 deletion examples/aideck/fpv.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
except ImportError:
pass

from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt6 import QtCore, QtWidgets, QtGui

logging.basicConfig(level=logging.INFO)

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
9 changes: 7 additions & 2 deletions examples/memory/erase-ow.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,11 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
Warning: you will have to write new data to the memory to make it
usable again. Use with caution.
Simple example that connects to the first Crazyflie found, looks for
EEPROM memories and lists its contents.
EEPROM memories and erases its contents.
"""
import logging
import sys
Expand All @@ -42,7 +45,7 @@

class EEPROMExample:
"""
Simple example listing the EEPROMs found and lists its contents.
Simple example listing the EEPROMs found and erases its contents.
"""

def __init__(self, link_uri):
Expand Down Expand Up @@ -122,6 +125,8 @@ def _disconnected(self, link_uri):


if __name__ == '__main__':
input('Warning, this will erase EEPROM memory, press enter to continue...')

# Initialize the low-level drivers
cflib.crtp.init_drivers()

Expand Down
2 changes: 1 addition & 1 deletion examples/memory/write-eeprom.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def _connected(self, link_uri):
elems['roll_trim'] = 0.0
elems['radio_channel'] = 80
elems['radio_speed'] = 2
elems['radio_address'] = 0xDEADBEEF
elems['radio_address'] = 0xE7E7E7E7E7

mems[0].write_data(self._data_written)

Expand Down
6 changes: 3 additions & 3 deletions examples/mocap/qualisys_hl_commander.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
import xml.etree.cElementTree as ET
from threading import Thread

import qtm
import qtm_rt
from scipy.spatial.transform import Rotation

import cflib.crtp
Expand Down Expand Up @@ -106,7 +106,7 @@ async def _connect(self):
qtm_instance = await self._discover()
host = qtm_instance.host
print('Connecting to QTM on ' + host)
self.connection = await qtm.connect(host)
self.connection = await qtm_rt.connect(host)

params = await self.connection.get_parameters(parameters=['6d'])
xml = ET.fromstring(params)
Expand All @@ -117,7 +117,7 @@ async def _connect(self):
on_packet=self._on_packet)

async def _discover(self):
async for qtm_instance in qtm.Discover('0.0.0.0'):
async for qtm_instance in qtm_rt.Discover('0.0.0.0'):
return qtm_instance

def _on_packet(self, packet):
Expand Down
9 changes: 4 additions & 5 deletions examples/radio/radio-test.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,10 @@
This script should be used on a Crazyflie with bluetooth disabled and RSSI
ack packet enabled to get RSSI feedback. To configure the Crazyflie in this
mode build the crazyflie2-nrf-firmware with
```make BLE=0 CONFIG=-DRSSI_ACK_PACKET```.
Additionally, the Crazyflie must be using the default address 0xE7E7E7E7E7.
See https://github.com/bitcraze/crazyflie-lib-python/issues/131 for more
informations.
mode build the crazyflie2-nrf-firmware with `CFLAGS += -DRSSI_ACK_PACKET=1`
in `config.mk`. Additionally, the Crazyflie must be using the default address
0xE7E7E7E7E7. See https://github.com/bitcraze/crazyflie-lib-python/issues/131
for more information.
'''
import argparse

Expand Down
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

setup(
name='cflib',
version='0.1.26',
version='0.1.27',
packages=find_packages(exclude=['examples', 'test']),

description='Crazyflie python driver',
Expand Down Expand Up @@ -41,6 +41,7 @@
'libusb-package~=1.0',
'scipy~=1.7',
'numpy~=1.20',
'packaging~=24.0',
],

# $ pip install -e .[dev]
Expand Down
2 changes: 1 addition & 1 deletion sys_test/single_cf_grounded/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Tests for a single Crazyflie 2.X (USB & Crazyradio) without flight
# Tests for a single Crazyflie 2.x (USB & Crazyradio) without flight

## Preparation

Expand Down

0 comments on commit 716071f

Please sign in to comment.