Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

crazyflie_py: fix flake8 and pep256 issues #321

Merged
merged 4 commits into from
Oct 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion .github/workflows/ci-ros2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,21 @@ jobs:
sudo apt update
sudo apt install -y libusb-1.0-0-dev

- name: install pip dependencies
# TODO: would be better to follow https://answers.ros.org/question/370666/how-to-declare-an-external-python-dependency-in-ros2/
# but this requires some upstream changes
run: |
pip install rowan

- uses: actions/checkout@v2
- name: build and test ROS 2
uses: ros-tooling/action-ros-ci@v0.3
with:
# TODO: removed crazyflie_interfaces since it causes some test failures
package-name: |
crazyflie
crazyflie_examples
crazyflie_interfaces
crazyflie_py
crazyflie_sim
target-ros2-distro: ${{ matrix.ros_distribution }}
vcs-repo-file-url: rosinstall
2 changes: 1 addition & 1 deletion crazyflie_py/crazyflie_py/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
from .crazyswarm_py import Crazyswarm

__all__ = ["Crazyswarm"]
__all__ = ['Crazyswarm']
344 changes: 207 additions & 137 deletions crazyflie_py/crazyflie_py/crazyflie.py

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions crazyflie_py/crazyflie_py/crazyswarm_py.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import rclpy

from . import genericJoystick
from .crazyflie import TimeHelper, CrazyflieServer
from .crazyflie import CrazyflieServer, TimeHelper


class Crazyswarm:

def __init__(self):
rclpy.init()

self.allcfs = CrazyflieServer()
self.timeHelper = TimeHelper(self.allcfs)

Expand Down
13 changes: 7 additions & 6 deletions crazyflie_py/crazyflie_py/genericJoystick.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import time
import copy
# import pyglet

from . import keyboard

# class JoyStickHandler:
Expand All @@ -20,7 +20,9 @@
# def on_joyhat_motion(joystick, hat_x, hat_y):
# pass


class Joystick:

def __init__(self, timeHelper):
# joysticks = pyglet.input.get_joysticks()
# joystick = joysticks[0]
Expand All @@ -35,14 +37,14 @@ def __init__(self, timeHelper):
self.js = linuxjsdev.Joystick()
devices = self.js.devices()
if len(devices) == 0:
print("Warning: No joystick found!")
print('Warning: No joystick found!')
else:
ids = [dev["id"] for dev in devices]
ids = [dev['id'] for dev in devices]
# For backwards compatibility, always choose device 0 if available.
self.joyID = 0 if 0 in ids else devices[0]["id"]
self.joyID = 0 if 0 in ids else devices[0]['id']
self.js.open(self.joyID)
except ImportError:
print("Warning: Joystick only supported on Linux.")
print('Warning: Joystick only supported on Linux.')

# def on_joybutton_press(joystick, button):
# print(button)
Expand Down Expand Up @@ -77,7 +79,6 @@ def waitUntilButtonPressed(self):
while keyPoller.poll() is not None:
self.timeHelper.sleep(0.01)


def checkIfAnyButtonIsPressed(self):
if self.joyID is not None:
state = self.js.read(self.joyID)
Expand Down
9 changes: 6 additions & 3 deletions crazyflie_py/crazyflie_py/joystick.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
import time

import rospy
from sensor_msgs.msg import Joy


class Joystick:

def __init__(self):
self.lastButtonState = 0
self.buttonWasPressed = False
rospy.Subscriber("/joy", Joy, self.joyChanged)
rospy.Subscriber('/joy', Joy, self.joyChanged)

def joyChanged(self, data):
if (not self.buttonWasPressed and
data.buttons[5] == 1 and
self.lastButtonState == 0):
data.buttons[5] == 1 and
self.lastButtonState == 0):
self.buttonWasPressed = True
self.lastButtonState = data.buttons[5]

Expand Down
7 changes: 4 additions & 3 deletions crazyflie_py/crazyflie_py/keyboard.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import sys
import select
import sys
import termios


class KeyPoller():

def __enter__(self):
# Save the terminal settings
self.fd = sys.stdin.fileno()
Expand All @@ -16,11 +17,11 @@ def __enter__(self):

return self

def __exit__(self, type, value, traceback):
def __exit__(self, type, value, traceback): # noqa A002
termios.tcsetattr(self.fd, termios.TCSAFLUSH, self.old_term)

def poll(self):
dr,dw,de = select.select([sys.stdin], [], [], 0)
dr, dw, de = select.select([sys.stdin], [], [], 0)
if not dr == []:
return sys.stdin.read(1)
return None
83 changes: 40 additions & 43 deletions crazyflie_py/crazyflie_py/linuxjsdev.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
"""
Linux joystick driver using the Linux input_joystick subsystem. Requires sysfs
to be mounted on /sys and /dev/input/js* to be readable.
Linux joystick driver using the Linux input_joystick subsystem.

Requires sysfs to be mounted on /sys and /dev/input/js* to be readable.

This module is very linux specific but should work on any CPU platform
"""
Expand All @@ -36,19 +37,19 @@
import sys

if not sys.platform.startswith('linux'):
raise ImportError("Only supported on Linux")
raise ImportError('Only supported on Linux')

try:
import fcntl
except ImportError as e:
raise Exception("fcntl library probably not installed ({})".format(e))
raise Exception('fcntl library probably not installed ({})'.format(e))

__author__ = 'Bitcraze AB'
__all__ = ['Joystick']

logger = logging.getLogger(__name__)

JS_EVENT_FMT = "@IhBB"
JS_EVENT_FMT = '@IhBB'
JE_TIME = 0
JE_VALUE = 1
JE_TYPE = 2
Expand All @@ -62,24 +63,23 @@
JSIOCGAXES = 0x80016a11
JSIOCGBUTTONS = 0x80016a12

MODULE_MAIN = "Joystick"
MODULE_NAME = "linuxjsdev"
MODULE_MAIN = 'Joystick'
MODULE_NAME = 'linuxjsdev'


class JEvent(object):
"""
Joystick event class. Encapsulate single joystick event.
"""
"""Joystick event class. Encapsulate single joystick event."""

def __init__(self, evt_type, number, value):
self.type = evt_type
self.number = number
self.value = value

def __repr__(self):
return "JEvent(type={}, number={}, value={})".format(
return 'JEvent(type={}, number={}, value={})'.format(
self.type, self.number, self.value)


# Constants
TYPE_BUTTON = 1
TYPE_AXIS = 2
Expand All @@ -90,64 +90,64 @@ class _JS():
def __init__(self, num, name):
self.num = num
self.name = name
self._f_name = "/dev/input/js{}".format(num)
self._f_name = '/dev/input/js{}'.format(num)
self._f = None

self.opened = False
self.buttons = []
self.axes = []
self._prev_pressed = {}

def open(self):
def open(self): # noqa: A003
if self._f:
raise Exception("{} at {} is already "
"opened".format(self.name, self._f_name))
raise Exception('{} at {} is already '
'opened'.format(self.name, self._f_name))

self._f = open("/dev/input/js{}".format(self.num), "rb")
self._f = open('/dev/input/js{}'.format(self.num), 'rb')
fcntl.fcntl(self._f.fileno(), fcntl.F_SETFL, os.O_NONBLOCK)

# Get number of axis and button
val = ctypes.c_int()
if fcntl.ioctl(self._f.fileno(), JSIOCGAXES, val) != 0:
self._f.close()
self._f = None
raise Exception("Failed to read number of axes")
raise Exception('Failed to read number of axes')

self.axes = list(0 for i in range(val.value))
self.axes = [0 for i in range(val.value)]
if fcntl.ioctl(self._f.fileno(), JSIOCGBUTTONS, val) != 0:
self._f.close()
self._f = None
raise Exception("Failed to read number of axes")
raise Exception('Failed to read number of axes')

self.buttons = list(0 for i in range(val.value))
self.buttons = [0 for i in range(val.value)]
self.__initvalues()

def close(self):
"""Open the joystick device"""
"""Open the joystick device."""
if not self._f:
return

logger.info("Closed {} ({})".format(self.name, self.num))
logger.info('Closed {} ({})'.format(self.name, self.num))

self._f.close()
self._f = None

def __initvalues(self):
"""Read the buttons and axes initial values from the js device"""
"""Read the buttons and axes initial values from the js device."""
for _ in range(len(self.axes) + len(self.buttons)):
data = self._f.read(struct.calcsize(JS_EVENT_FMT))
jsdata = struct.unpack(JS_EVENT_FMT, data)
self.__updatestate(jsdata)

def __updatestate(self, jsdata):
"""Update the internal absolute state of buttons and axes"""
"""Update the internal absolute state of buttons and axes."""
if jsdata[JE_TYPE] & JS_EVENT_AXIS != 0:
self.axes[jsdata[JE_NUMBER]] = jsdata[JE_VALUE] / 32768.0
elif jsdata[JE_TYPE] & JS_EVENT_BUTTON != 0:
self.buttons[jsdata[JE_NUMBER]] = jsdata[JE_VALUE]

def __decode_event(self, jsdata):
""" Decode a jsdev event into a dict """
"""Decode a jsdev event into a dict."""
# TODO: Add timestamp?
if jsdata[JE_TYPE] & JS_EVENT_AXIS != 0:
return JEvent(evt_type=TYPE_AXIS,
Expand All @@ -159,7 +159,7 @@ def __decode_event(self, jsdata):
value=jsdata[JE_VALUE] / 32768.0)

def _read_all_events(self):
"""Consume all the events queued up in the JS device"""
"""Consume all the events queued up in the JS device."""
try:
while True:
data = self._f.read(struct.calcsize(JS_EVENT_FMT))
Expand All @@ -170,7 +170,7 @@ def _read_all_events(self):
logger.info(str(e))
self._f.close()
self._f = None
raise IOError("Device has been disconnected")
raise IOError('Device has been disconnected')
except TypeError:
pass
except ValueError:
Expand All @@ -182,19 +182,17 @@ def _read_all_events(self):
pass

def read(self):
""" Returns a list of all joystick event since the last call """
"""Return a list of all joystick event since the last call."""
if not self._f:
raise Exception("Joystick device not opened")
raise Exception('Joystick device not opened')

self._read_all_events()

return [self.axes, self.buttons]


class Joystick():
"""
Linux jsdev implementation of the Joystick class
"""
"""Linux jsdev implementation of the Joystick class."""

def __init__(self):
self.name = MODULE_NAME
Expand All @@ -203,31 +201,30 @@ def __init__(self):

def devices(self):
"""
Returns a list containing an {"id": id, "name": name} dict for each
detected device. Result is cached once one or more devices are found.
Return a list containing an {'id': id, 'name': name} dict for each detected device.

Result is cached once one or more devices are found.
"""
if len(self._devices) == 0:
syspaths = glob.glob("/sys/class/input/js*")
syspaths = glob.glob('/sys/class/input/js*')

for path in syspaths:
device_id = int(os.path.basename(path)[2:])
with open(path + "/device/name") as namefile:
with open(path + '/device/name') as namefile:
name = namefile.read().strip()
self._js[device_id] = _JS(device_id, name)
self._devices.append({"id": device_id, "name": name})
self._devices.append({'id': device_id, 'name': name})

return self._devices

def open(self, device_id):
"""
Open the joystick device. The device_id is given by available_devices
"""
def open(self, device_id): # noqa: A003
"""Open the joystick device. The device_id is given by available_devices."""
self._js[device_id].open()

def close(self, device_id):
"""Open the joystick device"""
"""Open the joystick device."""
self._js[device_id].close()

def read(self, device_id):
""" Returns a list of all joystick event since the last call """
"""Return a list of all joystick event since the last call."""
return self._js[device_id].read()
Loading
Loading