Package micromelon
Python module for connecting to and interacting with the Micromelon Rover
and simulated rovers in the Micromelon Robot Simulator.
Submodules can be accessed with either lower-case or upper case notation.
Expand source code
"""
Python module for connecting to and interacting with the Micromelon Rover
and simulated rovers in the Micromelon Robot Simulator.
Submodules can be accessed with either lower-case or upper case notation.
"""
from ._robot_comms import RoverController
from . import battery as Battery
from . import colour as Colour
from . import i2c as I2C
from . import imu as IMU
from . import ir as IR
from . import leds as LEDs
from . import motors as Motors
from . import robot as Robot
from . import servos as Servos
from . import sounds as Sounds
from . import ultrasonic as Ultrasonic
from .helper_math import _math as Math
from ._utils import delay
CS = Colour.CS
COLOURS = Colour.COLOURS
NOTES = Sounds.NOTES
TUNES = Sounds.TUNES
__all__ = [
"RoverController",
"Motors",
"Ultrasonic",
"IMU",
"IR",
"Battery",
"Math",
"Robot",
"Sounds",
"NOTES",
"TUNES",
"LEDs",
"Colour",
"CS",
"COLOURS",
"Servos",
"I2C",
"delay",
]
Sub-modules
micromelon.battery
-
Functions to read the state of the robot's internal battery
micromelon.colour
-
Collection of functions for manipulating colour representations.
Includes functions for reading from the robot's colour sensors. micromelon.helper_math
-
Collection of helpful maths functions and aliases
micromelon.i2c
-
Functions for communicating with I2C devices connected to the expansion header
If the rover controller is in uart operation then these functions are … micromelon.imu
-
Collection of functions to read information from the robot's Inertial Measurement Unit (IMU)
The robot's IMU has an accelerometer and gyroscope micromelon.ir
-
Functions for reading from the robot's IR time of flight distance sensors.
These sensors read the distance in cm to the nearest object on each side of … micromelon.leds
-
Functions for controlling the RGB LEDs on the corners of the robot
Top and bottom LEDs are coupled so you can only control 4
Bottom LEDs mirror … micromelon.motors
-
Collection of functions to control the movement of the robot
micromelon.robot
-
Collection of functions to set and get robot attributes and use the onboard screen …
micromelon.servos
-
Collection of functions for controlling servo motors connected to
the three pin headers on the back of the robot. micromelon.sounds
-
Functions to control the onboard buzzer to play tunes or specific frequencies.
Also helpful definitions for musical notes to their frequency and … micromelon.ultrasonic
-
Functions to read from the robot's ultrasonic sensor.
Functions
def delay(seconds) ‑> None
-
Alias to Python time.sleep(seconds)
Args
seconds
:number
- see Python time.sleep documentation
Returns
None
Expand source code
def delay(seconds) -> None: """ Alias to Python time.sleep(seconds) Args: seconds (number): see Python time.sleep documentation Returns: None """ sleep(seconds)
Classes
class COLOURS (value, names=None, *, module=None, qualname=None, type=None, start=1)
-
A collection of predefined colour names mapped to an RGB array
Expand source code
class COLOURS(Enum): """ A collection of predefined colour names mapped to an RGB array """ WHITE = [255, 255, 255] GREY = [128, 128, 128] BLACK = [0, 0, 0] LAVENDER = [220, 190, 255] MAGENTA = [240, 50, 230] PURPLE = [163, 53, 232] CYAN = [70, 240, 240] BLUE = [0, 128, 255] NAVY = [0, 0, 128] MINT = [170, 255, 195] GREEN = [0, 255, 0] TEAL = [0, 128, 128] LIME = [210, 245, 60] YELLOW = [255, 255, 0] OLIVE = [128, 128, 0] APRICOT = [255, 215, 180] ORANGE = [255, 128, 0] BROWN = [170, 110, 40] PINK = [250, 190, 212] RED = [255, 0, 34] MAROON = [128, 0, 0]
Ancestors
- enum.Enum
Class variables
var APRICOT
var BLACK
var BLUE
var BROWN
var CYAN
var GREEN
var GREY
var LAVENDER
var LIME
var MAGENTA
var MAROON
var MINT
var NAVY
var OLIVE
var ORANGE
var PINK
var PURPLE
var RED
var TEAL
var WHITE
var YELLOW
class CS (value, names=None, *, module=None, qualname=None, type=None, start=1)
-
A collection of attributes that can be read from the colour sensor
Values correspond to attribute position in the sensor read arrayCS.HUE = 0
CS.RED = 1
CS.GREEN = 2
CS.BLUE = 3
CS.BRIGHT = 4
CS.ALL = 5Expand source code
class CS(Enum): """ A collection of attributes that can be read from the colour sensor Values correspond to attribute position in the sensor read array CS.HUE = 0 CS.RED = 1 CS.GREEN = 2 CS.BLUE = 3 CS.BRIGHT = 4 CS.ALL = 5 """ HUE = 0 RED = 1 GREEN = 2 BLUE = 3 BRIGHT = 4 ALL = 5
Ancestors
- enum.Enum
Class variables
var ALL
var BLUE
var BRIGHT
var GREEN
var HUE
var RED
class NOTES (value, names=None, *, module=None, qualname=None, type=None, start=1)
-
A collection of standard musical note frequencies
As '#' is not valid in a variable name 's' is used instead
Example: F sharp in the 6th octave would be NOTES.Fs6
B flat in the 4th octave would be NOTES.Bb4Ancestors
- enum.Enum
Class variables
var A0
var A1
var A2
var A3
var A4
var A5
var A6
var A7
var A8
var AsBb0
var AsBb1
var AsBb2
var AsBb3
var AsBb4
var AsBb5
var AsBb6
var AsBb7
var AsBb8
var B0
var B1
var B2
var B3
var B4
var B5
var B6
var B7
var B8
var C0
var C1
var C2
var C3
var C4
var C5
var C6
var C7
var C8
var CsDb0
var CsDb1
var CsDb2
var CsDb3
var CsDb4
var CsDb5
var CsDb6
var CsDb7
var CsDb8
var D0
var D1
var D2
var D3
var D4
var D5
var D6
var D7
var D8
var DsEb0
var DsEb1
var DsEb2
var DsEb3
var DsEb4
var DsEb5
var DsEb6
var DsEb7
var DsEb8
var E0
var E1
var E2
var E3
var E4
var E5
var E6
var E7
var E8
var F0
var F1
var F2
var F3
var F4
var F5
var F6
var F7
var F8
var FsGb0
var FsGb1
var FsGb2
var FsGb3
var FsGb4
var FsGb5
var FsGb6
var FsGb7
var FsGb8
var G0
var G1
var G2
var G3
var G4
var G5
var G6
var G7
var G8
var GsAb0
var GsAb1
var GsAb2
var GsAb3
var GsAb4
var GsAb5
var GsAb6
var GsAb7
var GsAb8
class RoverController (defaultTimeout=3.0)
-
Manages connection and packet level communication with the robot
Is a singleton - get a reference to the instance with constructorstandard usage
rc = RoverController()Then connect using one of the three methods below
rc.connectSerial('COM port name')
rc.connectIP(address, port)
rc.connectBLE(botID)Expand source code
class RoverController(metaclass=Singleton): """ Manages connection and packet level communication with the robot Is a singleton - get a reference to the instance with constructor standard usage rc = RoverController() Then connect using one of the three methods below rc.connectSerial('COM port name') rc.connectIP(address, port) rc.connectBLE(botID) """ def __init__(self, defaultTimeout=3.0) -> None: signal.signal(signal.SIGINT, _sigint_handler) self._roverSimInfo = 0 self._roverCharge = None self._roverErrorMask = None self._defaultCommunicationTimeout = defaultTimeout self._robotCommunicator = RobotCommunicatorThread() self._robotCommunicator.start() def setDefaultCommunicationTimeout(self, newDefaultTimeout: float) -> None: """ This default timeout (in seconds) is used as a fallback for any communication that happens with the robot. Can be overridden for individual function calls. Set a longer timeout if you expect slow communcation. Args: newDefaultTimeout (float): time in seconds to timeout on a communication command Returns: None """ self._defaultCommunicationTimeout = newDefaultTimeout def isConnected(self) -> bool: return self._robotCommunicator.isConnected() def connectedRobotIsSimulated(self) -> bool: return self.isConnected() and self._roverSimInfo != 0 def startRover(self, overrideSensorSpamMode: bool = None) -> None: """ Start sequence depending on robot mode: Serial UART: Set rover to Expansion mode to respond to packets from UART on header Serial TCP: Write the running state for program start Bluetooth: Write the running state for program start and start sensor spam iff not overridden to False Args: overrideSensorSpamMode (bool): - Defaults to None - Sensor Spam mode will be activated by default for a Bluetooth connection to improve sensor read speeds - It is not activated by default for serial and TCP connections Returns: None """ if ( self._robotCommunicator.isInBluetoothMode() and overrideSensorSpamMode is None ) or overrideSensorSpamMode: self._robotCommunicator.startSensorSpam() if not self._robotCommunicator.isInSerialMode(): self.writeAttribute(OPTYPE.BUTTON_PRESS, [RUNNING_STATES.RUNNING.value]) def _postConnectionSetup(self) -> None: """ Check whether the connected robot is simulated Read battery percentage and sensor error mask Returns: None """ self._roverSimInfo = None self._roverCharge = None self._roverErrorMask = None try: self._roverSimInfo = self.readAttribute(OPTYPE.SIMULATOR_INFO)[0] logger.debug("Rover siminfo: " + str(self._roverSimInfo)) except Exception as e: # couldn't read simulator info - assume not simulated logger.info("Rover siminfo read failed") logger.info(e) self._roverSimInfo = 0 try: self._roverCharge = self.readAttribute(OPTYPE.STATE_OF_CHARGE)[0] logger.info("Rover battery at " + str(self._roverCharge) + "%") self._roverErrorMask = bytesToIntArray( self.readAttribute(OPTYPE.SENSOR_ERRORS), 2, False )[0] if self._roverErrorMask == 0: logger.info("No sensor errors detected") else: logger.warning("Sensor errors detected") logger.warning("Error mask: " + str(self._roverErrorMask)) except Exception as e: logger.error("Failed to read battery and error mask") logger.error(e) def connectSerial(self, port="/dev/ttyS0"): """ Connects to the desired port and attempts to set the rover to UART mode The default port is the miniUART on a Raspberry Pi (primary UART on Zero W, 3, and 4) Other Raspberry Pi models have "/dev/ttyAMA0" as primary UART Note: You will need to disable serial console on the UART you choose to use for it to function correctly Args: port (string): Name of serial COM port Returns: None """ self._robotCommunicator.connectSerial(port) self.setRoverToUART(True) self._postConnectionSetup() def connectIP(self, address="127.0.0.1", port=9000): """ Connects over TCP to the address and port provided. To connect to a simulated robot choose the port to match the BotID shown in the robot controls on the top left of the simulator window. Args: address (string): IP address - defaults to IPv4 loopback (127.0.0.1) port (int): TCP port number - defaults to 9000 Returns: None """ self._robotCommunicator.connectIP(address, port) self._postConnectionSetup() def connectBLE(self, botID): """ Connects over Bluetooth LE to a robot displaying the given ID on its screen. Args: botID (int): Robot ID number (shown on robot screen) Returns: None """ self._robotCommunicator.connectBLE(botID) self._postConnectionSetup() def disconnect(self) -> None: self._robotCommunicator.disconnect() def getTransmitAverageMS(self) -> int: """ Returns: The approximate (moving average) time in ms it takes to transmit a packet to the robot. """ stats = self._robotCommunicator.getCommsTimingStats() return stats[0] def getTransactionAverageMS(self) -> int: """ Returns: The approximate (moving average) time in ms it takes to complete a transaction with the robot. A transaction is an attribute write or non-cached attribute read """ stats = self._robotCommunicator.getCommsTimingStats() return stats[2] def stopRover(self): """ Attempts to stop the rover by setting motor speeds to 0, turning off the buzzer, turning sensor spam off, and taking it out of running mode. Returns: None """ waitForAck = False timeout = 0.5 try: self.writePacket(OPCODE.WRITE, OPTYPE.SPAM_MODE, [0], waitForAck, timeout) self.writePacket( OPCODE.WRITE, OPTYPE.MOTOR_SET, [0] * 7, waitForAck, timeout ) self.writePacket( OPCODE.WRITE, OPTYPE.BUZZER_FREQ, [0, 0], waitForAck, timeout ) if not self._robotCommunicator.isInSerialMode(): self.writePacket( OPCODE.WRITE, OPTYPE.BUTTON_PRESS, [RUNNING_STATES.CLOSED.value], waitForAck, timeout, ) except Exception as e: logger.debug("Not all robot stop commands completed") logger.debug(e) def end(self): """ Stops all communication threads and ends the entire Python program. """ self._robotCommunicator.stop() self._robotCommunicator.join() try: sys.exit(0) except Exception: # Sometimes threading module has a shutdown exception # TODO: investigate further os._exit(0) def writeAttribute(self, opType, data, timeout=None): """ Blocking Write - writes an attribute and returns once the ACK packet is received from the robot. Args: opType (int or MicromelonOpType): Attribute to write to. data (list of bytes): data to write. timeout (number): time in seconds to wait for completion. Uses the default timeout of this controller if not provided Raises: TimeoutError on timeout. Exception on comms failure. Returns: True on success, False otherwise. """ if timeout is None: timeout = self._defaultCommunicationTimeout return self._robotCommunicator.writeAttribute(opType, data, timeout) def readAttribute(self, opType, data=None, timeout=None): """ Blocking read - returns the raw data from robot response Args: opType (int or MicromelonOpType): Attribute to write to. data (list of bytes): extra read configuration data. timeout (number): time in seconds to wait for result. Uses the default timeout of this controller if not provided Raises: TimeoutError on timeout. Exception on comms failure. Returns: List of bytes on success, None otherwise. """ if data is None: data = [] if timeout is None: timeout = self._defaultCommunicationTimeout return self._robotCommunicator.readAttribute(opType, data, timeout) def writePacket(self, opCode, opType, data=None, waitForAck=True, timeout=None): """ Blocking write - Writes the packet over transport. Waits for ack by default. Args: opCode (int or MicromelonOpCode): Flag for type of operation. opType (int or MicromelonOpType): Attribute to write to. data (list of bytes): data for packet, defaults to None. waitForAck (bool): whether or not to wait for the robot to acknowledge the packet. Defaults to true. timeout (number): time in seconds to wait for result. Defaults to None (block indefinitely). Uses the default timeout of this controller if not provided Raises: TimeoutError on timeout. Exception on comms failure. Returns: True on success, False otherwise. """ if data is None: data = [] if timeout is None: timeout = self._defaultCommunicationTimeout return self._robotCommunicator.writePacket( opCode, opType, data, waitForAck, timeout ) def doMotorOperation(self, opType, data, timeout=120): """ Some motor operations that use encoders or IMU take an unknown amount of time to complete. In this case the robot acknowledges receipt of the command and then notifies completion at a later time. This function writes the motor command and waits for the completion notification. Only use this if you're sure you want to. Args: opType (int or MicromelonOpType): Attribute to write to. data (list of bytes): data for packet, defaults to None. timeout (number): time in seconds to wait for result. Defaults to 120. If your operation should take more than 2 minutes maybe the approach isn't ideal. Raises: TimeoutError on timeout. Exception on comms failure. Returns: None """ self._robotCommunicator.clearMotorNotificationWatchers() toWait = self._robotCommunicator.getNewMotorNotificationWatcherEvent() self.writeAttribute(opType, data) timedOut = not toWait.wait(timeout) if timedOut: raise TimeoutError("Motor Encoder operation timed out") def setRoverToUART(self, uartMode: bool) -> None: """ Sets the robot's UART control mode. If set to True, the robot will respond to packets over the UART connection on the expansion header and will not be available for Bluetooth connections. If set to false, the robot will be in normal Bluetooth operation mode Args: uartMode (bool): Whether or not to be in UART mode. Raises: TimeoutError on timeout. Exception on comms failure. Returns: None """ data = [0] if uartMode: data = [1] self.writePacket(OPCODE.WRITE, OPTYPE.CONTROL_MODE, data)
Methods
def connectBLE(self, botID)
-
Connects over Bluetooth LE to a robot displaying the given ID on its screen.
Args
botID
:int
- Robot ID number (shown on robot screen)
Returns
None
Expand source code
def connectBLE(self, botID): """ Connects over Bluetooth LE to a robot displaying the given ID on its screen. Args: botID (int): Robot ID number (shown on robot screen) Returns: None """ self._robotCommunicator.connectBLE(botID) self._postConnectionSetup()
def connectIP(self, address='127.0.0.1', port=9000)
-
Connects over TCP to the address and port provided.
To connect to a simulated robot choose the port to match the BotID shown in the robot
controls on the top left of the simulator window.Args
address
:string
- IP address - defaults to IPv4 loopback (127.0.0.1)
port
:int
- TCP port number - defaults to 9000
Returns
None
Expand source code
def connectIP(self, address="127.0.0.1", port=9000): """ Connects over TCP to the address and port provided. To connect to a simulated robot choose the port to match the BotID shown in the robot controls on the top left of the simulator window. Args: address (string): IP address - defaults to IPv4 loopback (127.0.0.1) port (int): TCP port number - defaults to 9000 Returns: None """ self._robotCommunicator.connectIP(address, port) self._postConnectionSetup()
def connectSerial(self, port='/dev/ttyS0')
-
Connects to the desired port and attempts to set the rover to UART mode
The default port is the miniUART on a Raspberry Pi (primary UART on Zero W, 3, and 4)
Other Raspberry Pi models have "/dev/ttyAMA0" as primary UART
Note: You will need to disable serial console on the UART you choose to use for it to function correctlyArgs
port
:string
- Name of serial COM port
Returns
None
Expand source code
def connectSerial(self, port="/dev/ttyS0"): """ Connects to the desired port and attempts to set the rover to UART mode The default port is the miniUART on a Raspberry Pi (primary UART on Zero W, 3, and 4) Other Raspberry Pi models have "/dev/ttyAMA0" as primary UART Note: You will need to disable serial console on the UART you choose to use for it to function correctly Args: port (string): Name of serial COM port Returns: None """ self._robotCommunicator.connectSerial(port) self.setRoverToUART(True) self._postConnectionSetup()
def connectedRobotIsSimulated(self) ‑> bool
-
Expand source code
def connectedRobotIsSimulated(self) -> bool: return self.isConnected() and self._roverSimInfo != 0
def disconnect(self) ‑> None
-
Expand source code
def disconnect(self) -> None: self._robotCommunicator.disconnect()
def doMotorOperation(self, opType, data, timeout=120)
-
Some motor operations that use encoders or IMU take an unknown amount of time to complete.
In this case the robot acknowledges receipt of the command and then notifies completion at
a later time.
This function writes the motor command and waits for the completion notification.
Only use this if you're sure you want to.Args
opType
:int
orMicromelonOpType
- Attribute to write to.
data
:list
ofbytes
- data for packet, defaults to None.
timeout
:number
- time in seconds to wait for result. Defaults to 120.
If your operation should take more than 2 minutes maybe the approach isn't ideal.
Raises
TimeoutError on timeout.
Exception on comms failure.Returns
None
Expand source code
def doMotorOperation(self, opType, data, timeout=120): """ Some motor operations that use encoders or IMU take an unknown amount of time to complete. In this case the robot acknowledges receipt of the command and then notifies completion at a later time. This function writes the motor command and waits for the completion notification. Only use this if you're sure you want to. Args: opType (int or MicromelonOpType): Attribute to write to. data (list of bytes): data for packet, defaults to None. timeout (number): time in seconds to wait for result. Defaults to 120. If your operation should take more than 2 minutes maybe the approach isn't ideal. Raises: TimeoutError on timeout. Exception on comms failure. Returns: None """ self._robotCommunicator.clearMotorNotificationWatchers() toWait = self._robotCommunicator.getNewMotorNotificationWatcherEvent() self.writeAttribute(opType, data) timedOut = not toWait.wait(timeout) if timedOut: raise TimeoutError("Motor Encoder operation timed out")
def end(self)
-
Stops all communication threads and ends the entire Python program.
Expand source code
def end(self): """ Stops all communication threads and ends the entire Python program. """ self._robotCommunicator.stop() self._robotCommunicator.join() try: sys.exit(0) except Exception: # Sometimes threading module has a shutdown exception # TODO: investigate further os._exit(0)
def getTransactionAverageMS(self) ‑> int
-
Returns
The approximate (moving average) time in ms it takes to complete a transaction with the robot.
A transaction is an attribute write or non-cached attribute readExpand source code
def getTransactionAverageMS(self) -> int: """ Returns: The approximate (moving average) time in ms it takes to complete a transaction with the robot. A transaction is an attribute write or non-cached attribute read """ stats = self._robotCommunicator.getCommsTimingStats() return stats[2]
def getTransmitAverageMS(self) ‑> int
-
Returns
The approximate (moving average) time in ms it takes to transmit a packet to the robot.
Expand source code
def getTransmitAverageMS(self) -> int: """ Returns: The approximate (moving average) time in ms it takes to transmit a packet to the robot. """ stats = self._robotCommunicator.getCommsTimingStats() return stats[0]
def isConnected(self) ‑> bool
-
Expand source code
def isConnected(self) -> bool: return self._robotCommunicator.isConnected()
def readAttribute(self, opType, data=None, timeout=None)
-
Blocking read - returns the raw data from robot response
Args
opType
:int
orMicromelonOpType
- Attribute to write to.
data
:list
ofbytes
- extra read configuration data.
timeout
:number
- time in seconds to wait for result.
Uses the default timeout of this controller if not provided
Raises
TimeoutError on timeout.
Exception on comms failure.Returns
List of bytes on success, None otherwise.
Expand source code
def readAttribute(self, opType, data=None, timeout=None): """ Blocking read - returns the raw data from robot response Args: opType (int or MicromelonOpType): Attribute to write to. data (list of bytes): extra read configuration data. timeout (number): time in seconds to wait for result. Uses the default timeout of this controller if not provided Raises: TimeoutError on timeout. Exception on comms failure. Returns: List of bytes on success, None otherwise. """ if data is None: data = [] if timeout is None: timeout = self._defaultCommunicationTimeout return self._robotCommunicator.readAttribute(opType, data, timeout)
def setDefaultCommunicationTimeout(self, newDefaultTimeout: float) ‑> None
-
This default timeout (in seconds) is used as a fallback for any communication
that happens with the robot.
Can be overridden for individual function calls.
Set a longer timeout if you expect slow communcation.Args
newDefaultTimeout
:float
- time in seconds to timeout on a communication command
Returns
None
Expand source code
def setDefaultCommunicationTimeout(self, newDefaultTimeout: float) -> None: """ This default timeout (in seconds) is used as a fallback for any communication that happens with the robot. Can be overridden for individual function calls. Set a longer timeout if you expect slow communcation. Args: newDefaultTimeout (float): time in seconds to timeout on a communication command Returns: None """ self._defaultCommunicationTimeout = newDefaultTimeout
def setRoverToUART(self, uartMode: bool) ‑> None
-
Sets the robot's UART control mode.
If set to True, the robot will respond to packets over the UART connection
on the expansion header and will not be available for Bluetooth connections.
If set to false, the robot will be in normal Bluetooth operation modeArgs
uartMode
:bool
- Whether or not to be in UART mode.
Raises
TimeoutError on timeout.
Exception on comms failure.Returns
None
Expand source code
def setRoverToUART(self, uartMode: bool) -> None: """ Sets the robot's UART control mode. If set to True, the robot will respond to packets over the UART connection on the expansion header and will not be available for Bluetooth connections. If set to false, the robot will be in normal Bluetooth operation mode Args: uartMode (bool): Whether or not to be in UART mode. Raises: TimeoutError on timeout. Exception on comms failure. Returns: None """ data = [0] if uartMode: data = [1] self.writePacket(OPCODE.WRITE, OPTYPE.CONTROL_MODE, data)
def startRover(self, overrideSensorSpamMode: bool = None) ‑> None
-
Start sequence depending on robot mode: Serial UART: Set rover to Expansion mode to respond to packets from UART on header
Serial TCP: Write the running state for program start
Bluetooth: Write the running state for program start and start sensor spam iff not overridden to FalseArgs
overrideSensorSpamMode (bool): - Defaults to None
- Sensor Spam mode will be activated by default for a Bluetooth connection to improve sensor read speeds
- It is not activated by default for serial and TCP connectionsReturns
None
Expand source code
def startRover(self, overrideSensorSpamMode: bool = None) -> None: """ Start sequence depending on robot mode: Serial UART: Set rover to Expansion mode to respond to packets from UART on header Serial TCP: Write the running state for program start Bluetooth: Write the running state for program start and start sensor spam iff not overridden to False Args: overrideSensorSpamMode (bool): - Defaults to None - Sensor Spam mode will be activated by default for a Bluetooth connection to improve sensor read speeds - It is not activated by default for serial and TCP connections Returns: None """ if ( self._robotCommunicator.isInBluetoothMode() and overrideSensorSpamMode is None ) or overrideSensorSpamMode: self._robotCommunicator.startSensorSpam() if not self._robotCommunicator.isInSerialMode(): self.writeAttribute(OPTYPE.BUTTON_PRESS, [RUNNING_STATES.RUNNING.value])
def stopRover(self)
-
Attempts to stop the rover by setting motor speeds to 0, turning off the buzzer,
turning sensor spam off, and taking it out of running mode.Returns
None
Expand source code
def stopRover(self): """ Attempts to stop the rover by setting motor speeds to 0, turning off the buzzer, turning sensor spam off, and taking it out of running mode. Returns: None """ waitForAck = False timeout = 0.5 try: self.writePacket(OPCODE.WRITE, OPTYPE.SPAM_MODE, [0], waitForAck, timeout) self.writePacket( OPCODE.WRITE, OPTYPE.MOTOR_SET, [0] * 7, waitForAck, timeout ) self.writePacket( OPCODE.WRITE, OPTYPE.BUZZER_FREQ, [0, 0], waitForAck, timeout ) if not self._robotCommunicator.isInSerialMode(): self.writePacket( OPCODE.WRITE, OPTYPE.BUTTON_PRESS, [RUNNING_STATES.CLOSED.value], waitForAck, timeout, ) except Exception as e: logger.debug("Not all robot stop commands completed") logger.debug(e)
def writeAttribute(self, opType, data, timeout=None)
-
Blocking Write - writes an attribute and returns once the ACK packet is received from the robot.
Args
opType
:int
orMicromelonOpType
- Attribute to write to.
data
:list
ofbytes
- data to write.
timeout
:number
- time in seconds to wait for completion.
Uses the default timeout of this controller if not provided
Raises
TimeoutError on timeout.
Exception on comms failure.Returns
True on success, False otherwise.
Expand source code
def writeAttribute(self, opType, data, timeout=None): """ Blocking Write - writes an attribute and returns once the ACK packet is received from the robot. Args: opType (int or MicromelonOpType): Attribute to write to. data (list of bytes): data to write. timeout (number): time in seconds to wait for completion. Uses the default timeout of this controller if not provided Raises: TimeoutError on timeout. Exception on comms failure. Returns: True on success, False otherwise. """ if timeout is None: timeout = self._defaultCommunicationTimeout return self._robotCommunicator.writeAttribute(opType, data, timeout)
def writePacket(self, opCode, opType, data=None, waitForAck=True, timeout=None)
-
Blocking write - Writes the packet over transport.
Waits for ack by default.Args
opCode
:int
orMicromelonOpCode
- Flag for type of operation.
opType
:int
orMicromelonOpType
- Attribute to write to.
data
:list
ofbytes
- data for packet, defaults to None.
waitForAck
:bool
- whether or not to wait for the robot to acknowledge the packet. Defaults to true.
timeout
:number
- time in seconds to wait for result. Defaults to None (block indefinitely).
Uses the default timeout of this controller if not provided
Raises
TimeoutError on timeout.
Exception on comms failure.Returns
True on success, False otherwise.
Expand source code
def writePacket(self, opCode, opType, data=None, waitForAck=True, timeout=None): """ Blocking write - Writes the packet over transport. Waits for ack by default. Args: opCode (int or MicromelonOpCode): Flag for type of operation. opType (int or MicromelonOpType): Attribute to write to. data (list of bytes): data for packet, defaults to None. waitForAck (bool): whether or not to wait for the robot to acknowledge the packet. Defaults to true. timeout (number): time in seconds to wait for result. Defaults to None (block indefinitely). Uses the default timeout of this controller if not provided Raises: TimeoutError on timeout. Exception on comms failure. Returns: True on success, False otherwise. """ if data is None: data = [] if timeout is None: timeout = self._defaultCommunicationTimeout return self._robotCommunicator.writePacket( opCode, opType, data, waitForAck, timeout )
class TUNES (value, names=None, *, module=None, qualname=None, type=None, start=1)
-
A collection of pre-programmed tunes the robot can play
TUNES.UP = 1
TUNES.DOWN = 2Expand source code
class TUNES(Enum): """ A collection of pre-programmed tunes the robot can play TUNES.UP = 1 TUNES.DOWN = 2 """ UP = 1 DOWN = 2
Ancestors
- enum.Enum
Class variables
var DOWN
var UP