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",
"BootloaderStatus",
"FPSStatus",
]
[docs]
class Maskbit(enum.IntFlag):
"""A maskbit enumeration. Intended for subclassing."""
__version__ = None
def __str__(self):
members, _ = enum._decompose(self.__class__, self._value_) # type: ignore
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] # type: ignore
[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
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
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
- 15: Halls sensors have been disabled
"""
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
[docs]
class FPSStatus(enum.Flag):
"""Status of the FPS."""
IDLE = 0x01
MOVING = 0x02
COLLIDED = 0x04
ERRORED = 0x08
TEMPERATURE_NORMAL = 0x10
TEMPERATURE_COLD = 0x20
TEMPERATURE_VERY_COLD = 0x40
TEMPERATURE_UNKNOWN = 0x80
TEMPERATURE_BITS = (
TEMPERATURE_NORMAL
| TEMPERATURE_COLD
| TEMPERATURE_VERY_COLD
| TEMPERATURE_UNKNOWN
)
STATUS_BITS = IDLE | ERRORED | MOVING | COLLIDED