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 APRICOTvar BLACKvar BLUEvar BROWNvar CYANvar GREENvar GREYvar LAVENDERvar LIMEvar MAGENTAvar MAROONvar MINTvar NAVYvar OLIVEvar ORANGEvar PINKvar PURPLEvar REDvar TEALvar WHITEvar 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 = 5Ancestors
- enum.Enum
Class variables
var ALLvar BLUEvar BRIGHTvar GREENvar HUEvar 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 A0var A1var A2var A3var A4var A5var A6var A7var A8var AsBb0var AsBb1var AsBb2var AsBb3var AsBb4var AsBb5var AsBb6var AsBb7var AsBb8var B0var B1var B2var B3var B4var B5var B6var B7var B8var C0var C1var C2var C3var C4var C5var C6var C7var C8var CsDb0var CsDb1var CsDb2var CsDb3var CsDb4var CsDb5var CsDb6var CsDb7var CsDb8var D0var D1var D2var D3var D4var D5var D6var D7var D8var DsEb0var DsEb1var DsEb2var DsEb3var DsEb4var DsEb5var DsEb6var DsEb7var DsEb8var E0var E1var E2var E3var E4var E5var E6var E7var E8var F0var F1var F2var F3var F4var F5var F6var F7var F8var FsGb0var FsGb1var FsGb2var FsGb3var FsGb4var FsGb5var FsGb6var FsGb7var FsGb8var G0var G1var G2var G3var G4var G5var G6var G7var G8var GsAb0var GsAb1var GsAb2var GsAb3var GsAb4var GsAb5var GsAb6var GsAb7var 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:intorMicromelonOpType- Attribute to write to.
data:listofbytes- 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:intorMicromelonOpType- Attribute to write to.
data:listofbytes- 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:intorMicromelonOpType- Attribute to write to.
data:listofbytes- 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:intorMicromelonOpCode- Flag for type of operation.
opType:intorMicromelonOpType- Attribute to write to.
data:listofbytes- 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 = 2Ancestors
- enum.Enum
Class variables
var DOWNvar UP