Source code for jaeger.maskbits
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# @Author: José Sánchez-Gallego (gallegoj@uw.edu)
# @Date: 2018-09-11
# @Filename: maskbits.py
# @License: BSD 3-clause (http://www.opensource.org/licenses/BSD-3-Clause)
import enum
__ALL__ = ['Maskbit', 'PositionerStatus', 'CommandStatus' 'ResponseCode',
'RobotStatus', 'BootloaderStatus']
[docs]class Maskbit(enum.IntFlag):
"""A maskbit enumeration. Intended for subclassing."""
__version__ = None
def __str__(self):
members, uncovered = enum._decompose(self.__class__, self._value_)
return '|'.join([str(m._name_ or m._value_) for m in members])
@property
def version(self):
"""The version of the flags."""
return self.__version__
@property
def active_bits(self):
"""Returns a list of flags that match the value."""
return [bit for bit in self.__class__ if bit.value & self.value]
[docs]class CommandStatus(Maskbit):
"""Maskbits for command status."""
DONE = enum.auto()
CANCELLED = enum.auto()
FAILED = enum.auto()
READY = enum.auto()
RUNNING = enum.auto()
TIMEDOUT = enum.auto()
@property
def is_done(self):
"""Returns True if the command is done (completed or failed)."""
return True if (self in [self.DONE, self.TIMEDOUT] or self.failed) else False
@property
def is_running(self):
"""Returns True if the command is running."""
return True if self == CommandStatus.RUNNING else False
@property
def failed(self):
"""Returns True if the command failed (or got cancelled)."""
failed_states = self.CANCELLED | self.FAILED
return True if self in failed_states else False
@property
def timed_out(self):
"""Returns True if the command timed out."""
return True if self.TIMEDOUT in self else False
[docs]class PositionerStatusV4_1(Maskbit):
"""Maskbits for positioner status (firmware >=04.01.00)."""
__version__ = '4.1'
SYSTEM_INITIALIZED = 0x0000000000000001
CONFIG_CHANGED = 0x0000000000000002
BSETTINGS_CHANGED = 0x0000000000000004
DATA_STREAMING = 0x0000000000000008
RECEIVING_TRAJECTORY = 0x0000000000000010
TRAJECTORY_ALPHA_RECEIVED = 0x0000000000000020
TRAJECTORY_BETA_RECEIVED = 0x0000000000000040
LOW_POWER_AFTER_MOVE = 0x0000000000000080
DISPLACEMENT_COMPLETED = 0x0000000000000100
DISPLACEMENT_COMPLETED_ALPHA = 0x0000000000000200
DISPLACEMENT_COMPLETED_BETA = 0x0000000000000400
COLLISION_ALPHA = 0x0000000000000800
COLLISION_BETA = 0x0000000000001000
CLOSED_LOOP_ALPHA = 0x0000000000002000
CLOSED_LOOP_BETA = 0x0000000000004000
PRECISE_POSITIONING_ALPHA = 0x0000000000008000
PRECISE_POSITIONING_BETA = 0x0000000000010000
COLLISION_DETECT_ALPHA_DISABLE = 0x0000000000020000
COLLISION_DETECT_BETA_DISABLE = 0x0000000000040000
MOTOR_CALIBRATION = 0x0000000000080000
MOTOR_ALPHA_CALIBRATED = 0x0000000000100000
MOTOR_BETA_CALIBRATED = 0x0000000000200000
DATUM_CALIBRATION = 0x0000000000400000
DATUM_ALPHA_CALIBRATED = 0x0000000000800000
DATUM_BETA_CALIBRATED = 0x0000000001000000
DATUM_INITIALIZATION = 0x0000000002000000
DATUM_ALPHA_INITIALIZED = 0x0000000004000000
DATUM_BETA_INITIALIZED = 0x0000000008000000
HALL_ALPHA_DISABLE = 0x0000000010000000
HALL_BETA_DISABLE = 0x0000000020000000
COGGING_CALIBRATION = 0x0000000040000000
COGGING_ALPHA_CALIBRATED = 0x0000000080000000
COGGING_BETA_CALIBRATED = 0x0000000100000000
ESTIMATED_POSITION = 0x0000000200000000
POSITION_RESTORED = 0x0000000400000000
SWITCH_OFF_AFTER_MOVE = 0x0000000800000000
CALIBRATION_SAVED = 0x0000001000000000
PRECISE_MOVE_IN_OPEN_LOOP_ALPHA = 0x0000002000000000
PRECISE_MOVE_IN_OPEN_LOOP_BETA = 0x0000004000000000
SWITCH_OFF_HALL_AFTER_MOVE = 0x0000008000000000
UNKNOWN = 0x0000010000000000
@property
def collision(self):
"""Returns `True` if the positioner is collided."""
return True if (PositionerStatusV4_1.COLLISION_ALPHA & self or
PositionerStatusV4_1.COLLISION_BETA & self) else False
@property
def initialised(self):
"""Returns `True` if the positioner is initialised."""
return True if PositionerStatusV4_1.SYSTEM_INITIALIZED & self else False
[docs]class PositionerStatusV4_0(Maskbit):
"""Maskbits for positioner status (firmware <=04.00.04)."""
__version__ = '4.0'
SYSTEM_INITIALIZATION = 0x00000001
RECEIVING_TRAJECTORY = 0x00000100
TRAJECTORY_ALPHA_RECEIVED = 0x00000200
TRAJECTORY_BETA_RECEIVED = 0x00000400
DATUM_INITIALIZATION = 0x00200000
DATUM_ALPHA_INITIALIZED = 0x00400000
DATUM_BETA_INITIALIZED = 0x00800000
DISPLACEMENT_COMPLETED = 0x01000000
ALPHA_DISPLACEMENT_COMPLETED = 0x02000000
BETA_DISPLACEMENT_COMPLETED = 0x04000000
ALPHA_COLLISION = 0x08000000
BETA_COLLISION = 0x10000000
DATUM_INITIALIZED = 0x20000000
ESTIMATED_POSITION = 0x40000000
POSITION_RESTORED = 0x80000000
UNKNOWN = 0x100000000
@property
def initialised(self):
"""Returns `True` if the positioner is initialised."""
return True if PositionerStatusV4_0.SYSTEM_INITIALIZATION & self else False
@property
def collision(self):
"""Returns `True` if the positioner is collided."""
return True if (PositionerStatusV4_0.ALPHA_COLLISION & self or
PositionerStatusV4_0.BETA_COLLISION & self) else False
#: Alias to the default positioner status flags.
PositionerStatus = PositionerStatusV4_1
[docs]class BootloaderStatus(Maskbit):
"""Maskbits for positioner status when in bootloader mode."""
BOOTLOADER_INIT = 0x00000001
BOOTLOADER_TIMEOUT = 0x00000002
BSETTINGS_CHANGED = 0x00000200
RECEIVING_NEW_FIRMWARE = 0x00010000
NEW_FIRMWARE_RECEIVED = 0x01000000
NEW_FIRMWARE_CHECK_OK = 0x02000000
NEW_FIRMWARE_CHECK_BAD = 0x04000000
UNKNOWN = 0x40000000
[docs]class ResponseCode(enum.IntFlag):
"""Maskbit for the status of the bootloader.
0 All OK
1 Received parameter is out of range
2 Trajectory not accepted
3 Already in motion, cannot accept command
4 Datum not initialized
5 Incorrect amount of data in packet
6 One of the calibration modes is active: MOTOR_CALIBRATION,
COGGING_CALIBRATION, DATUM_CALIBRATION, DATUM _INITIALIZATION
7 The motors are not calibrated and therefore
the hall sensors can't be used
8 A collision is detected, the flag has to be first cleared
with stop trajectory
9 Hall sensors are disabled and can therefore not be used
10 Broadcast command not valid
11 Command not supported by bootloader
12 Invalid command
13 Unknown command
14 Datum not calibrated
"""
COMMAND_ACCEPTED = 0,
VALUE_OUT_OF_RANGE = 1,
INVALID_TRAJECTORY = 2,
ALREADY_IN_MOTION = 3,
DATUM_NOT_INITIALIZED = 4,
INCORRECT_AMOUNT_OF_DATA = 5,
CALIBRATION_MODE_ACTIVE = 6,
MOTOR_NOT_CALIBRATED = 7,
COLLISION_DETECTED = 8,
HALL_SENSOR_DISABLED = 9,
INVALID_BROADCAST_COMMAND = 10,
INVALID_BOOTLOADER_COMMAND = 11,
INVALID_COMMAND = 12,
UNKNOWN_COMMAND = 13,
DATUM_NOT_CALIBRATED = 14
HALL_SENSORS_DISABLED = 15