class NeblinaAPI(object): """ Neblina Application Programming Interface. This is used to communicate with Neblina. """ def __init__(self, interface): """ Constructor :param interface: Neblina communication interface. See Neblina.Interface. """ self.core = NeblinaCore(interface) def close(self): """ Close communication with Neblina. """ self.core.close() def open(self, address): """ Open communication with Neblina. :param address: Neblina address to reach. It can be UART """ self.core.open(address) def isOpened(self): """ Is communication opened ? :return: True, if communication opened. False, otherwise. """ return self.core.isOpened() def getBatteryLevel(self): """ Retrieve battery level. :return: Battery Level (0-100%) """ return self.core.getBatteryLevel() def getTemperature(self): """ Retrieve internal temperature :return: Temperature (in Celsius) """ self.core.sendCommand(SubSystem.Power, Commands.Power.GetTemperature, True) packet = self.core.waitForAck(SubSystem.Power, Commands.Power.GetTemperature) packet = self.core.waitForPacket(PacketType.RegularResponse, SubSystem.Power, Commands.Power.GetTemperature) return packet.data.temperature def setDataPortState(self, interface, state): """ Set data port state :param interface: Neblina.Interface to set. :param state: True, to open data port. False, to close data port. """ assert(type(state) is bool) self.core.sendCommand(SubSystem.Debug, Commands.Debug.InterfaceState, state, interface=interface) logging.debug('Waiting for the module to set data port state...') packet = self.core.waitForAck(SubSystem.Debug, Commands.Debug.InterfaceState) logging.debug('Module has change its data port state') def setInterface(self, interface=Interface.BLE): """ Set communication interface. :param interface: Neblina.Interface to used. """ self.core.sendCommand(SubSystem.Debug, Commands.Debug.SetInterface, interface) logging.debug('Waiting for the module to switch its interface...') packet = self.core.waitForAck(SubSystem.Debug, Commands.Debug.SetInterface) logging.debug("Module has switched its interface.") numTries = 0 while (packet == None): numTries += 1 if numTries > 5: logging.error('The unit is not responding. Exiting...') exit() logging.warning('Trying again...') self.core.sendCommand(SubSystem.Debug, Commands.Debug.SetInterface, interface) packet = self.core.waitForAck(SubSystem.Debug, Commands.Debug.SetInterface) def getMotionStatus(self): """ Retrieve current motion streaming status. :return: MotionStatusData instance. """ self.core.sendCommand(SubSystem.Debug, Commands.Debug.MotAndFlashRecState) self.core.waitForAck(SubSystem.Debug, Commands.Debug.MotAndFlashRecState) packet = self.core.waitForPacket(PacketType.RegularResponse, SubSystem.Debug, Commands.Debug.MotAndFlashRecState) return packet.data.motionStatus def getRecorderStatus(self): """ Retrieve current recording status :return: RecorderStatusData instance. """ self.core.sendCommand(SubSystem.Debug, Commands.Debug.MotAndFlashRecState) self.core.waitForAck(SubSystem.Debug, Commands.Debug.MotAndFlashRecState) packet = self.core.waitForPacket(PacketType.RegularResponse, SubSystem.Debug, Commands.Debug.MotAndFlashRecState) return packet.data.recorderStatus def setDownsample(self, factor): """ Set motion streaming downsampling. Downsampling must be between 20 and 1000, and a multiple of 20. This represent the time in ms between each packet. :param factor: Downsampling factor to use. """ # Limit to factor of 20 and between 20 and 1000. assert factor % 20 == 0 and 20 <= factor <= 1000 self.core.sendCommand(SubSystem.Motion, Commands.Motion.Downsample, factor) logging.debug('Sending downsample command. Waiting for acknowledge.') self.core.waitForAck(SubSystem.Motion, Commands.Motion.Downsample) logging.debug('Acknowledgment received.') def setAccelerometerRange(self, factor): """ Set accelerometer range. Must be 2, 4, 8 or 16. :param factor: Accelerometer range to use. """ # Limit factor to 2, 4, 8 and 16 assert factor == 2 or factor == 4 or factor == 8 or factor == 16 self.core.sendCommand(SubSystem.Motion, Commands.Motion.AccRange, factor) self.core.waitForAck(SubSystem.Motion, Commands.Motion.AccRange) def resetTimestamp(self): """ Reset timestamp """ self.core.sendCommand(SubSystem.Motion, Commands.Motion.ResetTimeStamp, True) self.core.waitForAck(SubSystem.Motion, Commands.Motion.ResetTimeStamp) def streamDisableAll(self): """ Disable all streaming. """ self.core.sendCommand(SubSystem.Motion, Commands.Motion.DisableStreaming, True) logging.debug("Sending disable streaming command. Waiting for acknowledge.") self.core.waitForAck(SubSystem.Motion, Commands.Motion.DisableStreaming) logging.debug("Acknowledgment received.") def getEulerAngle(self): """ Retrieve Euler Angle. This is a blocking function until an Euler Angle is retrieve. Requires that Euler Angle streaming is activated, otherwise will hang forever. :return: EulerAngleData instance. """ packet = self.core.waitForPacket(PacketType.RegularResponse, SubSystem.Motion, Commands.Motion.EulerAngle) logging.debug("Received EulerAngle.") return packet.data def getExternalForce(self): """ Retrieve External Force. This is a blocking function until an External Force is retrieve. Requires that External Force streaming is activated, otherwise will hang forever. :return: ExternalForceData instance. """ packet = self.core.waitForPacket(PacketType.RegularResponse, SubSystem.Motion, Commands.Motion.ExtForce) logging.debug("Received ExternalForce.") return packet.data def getFingerGesture(self): """ Retrieve Finger Gesture. This is a blocking function until a Finger Gesture is retrieve. Requires that Finger Gesture streaming is activated, otherwise will hang forever. :return: FingerGestureData instance. """ packet = self.core.waitForPacket(PacketType.RegularResponse, SubSystem.Motion, Commands.Motion.FingerGesture) logging.debug("Received FingerGesture.") return packet.data def getIMU(self): """ Retrieve IMU (Inertial Motion Unit). This is a blocking function until an IMU is retrieve. Requires that IMU streaming is activated, otherwise will hang forever. :return: IMUData instance. """ packet = self.core.waitForPacket(PacketType.RegularResponse, SubSystem.Motion, Commands.Motion.IMU) logging.debug("Received IMU.") return packet.data def getMAG(self): """ Retrieve MAG (Magnetometer). This is a blocking function until a MAG is retrieve. Requires that MAG streaming is activated, otherwise will hang forever. :return: MAGData instance. """ packet = self.core.waitForPacket(PacketType.RegularResponse, SubSystem.Motion, Commands.Motion.MAG) logging.debug("Received MAG.") return packet.data def getMotionState(self): """ Retrieve Motion State. This is a blocking function until a Motion State is retrieve. Requires that Motion State streaming is activated, otherwise will hang forever. :return: MotionStateData instance. """ packet = self.core.waitForPacket(PacketType.RegularResponse, SubSystem.Motion, Commands.Motion.MotionState) logging.debug("Received MotionState.") return packet.data def getPedometer(self): """ Retrieve Pedometer. This is a blocking function until a Pedometer is retrieve. Requires that Pedometer streaming is activated, otherwise will hang forever. :return: PedometerData instance. """ packet = self.core.waitForPacket(PacketType.RegularResponse, SubSystem.Motion, Commands.Motion.Pedometer) logging.debug("Received Pedometer.") return packet.data def getQuaternion(self): """ Retrieve Quaternion. This is a blocking function until a Quaternion is retrieve. Requires that Quaternion streaming is activated, otherwise will hang forever. :return: QuaternionData instance. """ packet = self.core.waitForPacket(PacketType.RegularResponse, SubSystem.Motion, Commands.Motion.Quaternion) logging.debug("Received Quaternion.") return packet.data def getRotationInfo(self): """ Retrieve Rotation Information. This is a blocking function until a Rotation Information is retrieve. Requires that Rotation Information streaming is activated, otherwise will hang forever. :return: RotationData instance. """ packet = self.core.waitForPacket(PacketType.RegularResponse, SubSystem.Motion, Commands.Motion.RotationInfo) logging.debug("Received RotationInfo.") return packet.data def getSittingStanding(self): """ Retrieve Sitting/Standing. This is a blocking function until a Sitting/Standing is retrieve. Requires that Sitting/Standing streaming is activated, otherwise will hang forever. :return: """ packet = self.core.waitForPacket(PacketType.RegularResponse, SubSystem.Motion, Commands.Motion.SittingStanding) logging.debug("Received SittingStanding.") return packet.data def getTrajectoryInfo(self): """ Retrieve Trajectory Information. This is a blocking function until a Trajectory Information is retrieve. Requires that Trajectory Information is recording and streaming, otherwise will hang forever. :return: EulerAngleData instance. """ packet = self.core.waitForPacket(PacketType.RegularResponse, SubSystem.Motion, Commands.Motion.TrajectoryInfo) logging.debug("Received TrajectoryInfo.") return packet.data def recordTrajectory(self, state): """ Record trajectory information. :param state: True, to start recording. False, to stop recording. :return: """ self.core.sendCommand(SubSystem.Motion, Commands.Motion.TrajectoryRecStartStop, state) logging.debug("Sending recordTrajectory. Waiting for aknowledge.") self.core.waitForAck(SubSystem.Motion, Commands.Motion.TrajectoryRecStartStop) logging.debug("Acknowledgment received.") def streamEulerAngle(self, state): """ Start/Stop Euler Angle streaming. :param state: True, to start streaming. False, to stop streaming. """ self.core.sendCommand(SubSystem.Motion, Commands.Motion.EulerAngle, state) logging.debug("Sending streamEulerAngle. Waiting for acknowledge.") self.core.waitForAck(SubSystem.Motion, Commands.Motion.EulerAngle) logging.debug("Acknowledgment received.") def streamExternalForce(self, state): """ Start/Stop External Force streaming. :param state: True, to start streaming. False, to stop streaming. """ self.core.sendCommand(SubSystem.Motion, Commands.Motion.ExtForce, state) logging.debug("Sending streamExternalForce. Waiting for acknowledge.") self.core.waitForAck(SubSystem.Motion, Commands.Motion.ExtForce) logging.debug("Acknowledgment received.") def streamFingerGesture(self, state): """ Start/Stop Finger Gesture streaming. :param state: True, to start streaming. False, to stop streaming. """ self.core.sendCommand(SubSystem.Motion, Commands.Motion.FingerGesture, state) logging.debug("Sending streamFingerGesture. Waiting for acknowledge.") self.core.waitForAck(SubSystem.Motion, Commands.Motion.FingerGesture) logging.debug("Acknowledgment received.") def streamIMU(self, state): """ Start/Stop IMU streaming. :param state: True, to start streaming. False, to stop streaming. """ self.core.sendCommand(SubSystem.Motion, Commands.Motion.IMU, state) logging.debug("Sending streamIMU. Waiting for acknowledge.") self.core.waitForAck(SubSystem.Motion, Commands.Motion.IMU) logging.debug("Acknowledgment received.") def streamMAG(self, state): """ Start/Stop MAG streaming. :param state: True, to start streaming. False, to stop streaming. """ self.core.sendCommand(SubSystem.Motion, Commands.Motion.MAG, state) logging.debug("Sending streamMAG. Waiting for acknowledge.") self.core.waitForAck(SubSystem.Motion, Commands.Motion.MAG) logging.debug("Acknowledgment received.") def streamMotionState(self, state): """ Start/Stop Motion State streaming. :param state: True, to start streaming. False, to stop streaming. """ self.core.sendCommand(SubSystem.Motion, Commands.Motion.MotionState, state) logging.debug("Sending streamMotionState. Waiting for acknowledge.") self.core.waitForAck(SubSystem.Motion, Commands.Motion.MotionState) logging.debug("Acknowledgment received.") def streamPedometer(self, state): """ Start/Stop Pedometer streaming. :param state: True, to start streaming. False, to stop streaming. """ self.core.sendCommand(SubSystem.Motion, Commands.Motion.Pedometer, state) logging.debug("Sending streamPedometer. Waiting for acknowledge.") self.core.waitForAck(SubSystem.Motion, Commands.Motion.Pedometer) logging.debug("Acknowledgment received.") def streamQuaternion(self, state): """ Start/Stop Quaternion streaming. :param state: True, to start streaming. False, to stop streaming. """ self.core.sendCommand(SubSystem.Motion, Commands.Motion.Quaternion, state) logging.debug("Sending streamQuaternion. Waiting for acknowledge.") self.core.waitForAck(SubSystem.Motion, Commands.Motion.Quaternion) logging.debug("Acknowledgment received.") def streamRotationInfo(self, state): """ Start/Stop Rotation Information streaming. :param state: True, to start streaming. False, to stop streaming. """ self.core.sendCommand(SubSystem.Motion, Commands.Motion.RotationInfo, state) logging.debug("Sending streamRotationInfo. Waiting for acknowledge.") self.core.waitForAck(SubSystem.Motion, Commands.Motion.RotationInfo) logging.debug("Acknowledgment received.") def streamSittingStanding(self, state): """ Start/Stop Sitting/Standing streaming. :param state: True, to start streaming. False, to stop streaming. """ self.core.sendCommand(SubSystem.Motion, Commands.Motion.SittingStanding, state) logging.debug("Sending streamSittingStanding. Waiting for acknowledge.") self.core.waitForAck(SubSystem.Motion, Commands.Motion.SittingStanding) logging.debug("Acknowledgment received.") def streamTrajectoryInfo(self, state): """ Start/Stop Trajectory Information streaming. :param state: True, to start streaming. False, to stop streaming. """ self.core.sendCommand(SubSystem.Motion, Commands.Motion.TrajectoryInfo, state) logging.debug("Sending streamTrajectoryInfo. Waiting for acknowledge.") self.core.waitForAck(SubSystem.Motion, Commands.Motion.TrajectoryInfo) logging.debug("Acknowledgment received.") def eepromRead(self, readPageNumber): """ Read a page from EEPROM :param readPageNumber: EEPROM page number to read. :return: EEPROMReadData instance. """ assert 0 <= readPageNumber <= 255 self.core.sendCommand(SubSystem.EEPROM, Commands.EEPROM.Read, pageNumber=readPageNumber) logging.debug("Sending EEPROM Read command. Waiting for acknowledgment.") packet = self.core.waitForAck(SubSystem.EEPROM, Commands.EEPROM.Read) logging.debug("Acknowledge received.") packet = self.core.waitForPacket(PacketType.RegularResponse, SubSystem.EEPROM, Commands.EEPROM.Read) logging.debug("EEPROM Read packet received.") return packet.data.dataBytes def eepromWrite(self, writePageNumber, dataString): """ Write a page to EEPROM. :param writePageNumber: EEPROM page number to write. :param dataString: 8-byte data string to write. """ assert 0 <= writePageNumber <= 255 self.core.sendCommand(SubSystem.EEPROM, Commands.EEPROM.Write, \ pageNumber=writePageNumber, dataBytes=dataString) packet = self.core.waitForAck(SubSystem.EEPROM, Commands.EEPROM.Write) def getLED(self, index): """ Retrieve LED state. :param index: LED index to retrieve. :return: LEDGetValData instance. """ assert 0 <= index <= 7 self.core.sendCommand(SubSystem.LED, Commands.LED.GetVal, ledIndices=[index]) packet = self.core.waitForPacket(PacketType.RegularResponse, SubSystem.LED, Commands.LED.GetVal) if not packet: return 0xF # Return anything but 0x0 or 0x1 return packet.data.ledState[index] def setLED(self, ledIndex, ledValue): """ Set LED state. :param ledIndex: LED index to use. :param ledValue: LED state. True, open. False, close. """ assert 0 <= ledIndex <= 7 ledValues = [(ledIndex, ledValue)] self.core.sendCommand(SubSystem.LED, Commands.LED.SetVal, ledValueTupleList=ledValues) self.core.waitForAck(SubSystem.LED, Commands.LED.SetVal) self.core.waitForPacket(PacketType.RegularResponse, SubSystem.LED, Commands.LED.GetVal) def eraseStorage(self, eraseType=Erase.Quick): """ Erase storage. Full erase can take up to 3 minute to complete. :param eraseType: Erase Type. Quick or Full. """ assert eraseType==Erase.Mass or eraseType==Erase.Quick # Step 1 - Initialization self.core.sendCommand(SubSystem.Motion, Commands.Motion.DisableStreaming, True) logging.debug('Sending the DisableAllStreaming command, and waiting for a response...') # Step 2 - wait for ack self.core.waitForAck(SubSystem.Motion, Commands.Motion.DisableStreaming) logging.debug('Acknowledge packet was received!') # Step 3 - erase the flash command self.core.sendCommand(SubSystem.Storage, Commands.Storage.EraseAll, eraseType) logging.debug('Sent the EraseAll command, and waiting for a response...') # Step 4 - wait for ack self.core.waitForAck(SubSystem.Storage, Commands.Storage.EraseAll) logging.debug("Acknowledge packet was received!") logging.info("Started erasing... This takes up to around 3 minutes...") # Step 5 - wait for the completion notice self.core.waitForPacket(PacketType.RegularResponse, SubSystem.Storage, Commands.Storage.EraseAll, 300) logging.info('Flash erase has completed successfully!') def sessionRecord(self, state): """ Start/Stop recording a session. :param state: True, to start recording. False, to stop recording. :return: Recording session identifier. """ # Step 1 - Start recording self.core.sendCommand(SubSystem.Storage, Commands.Storage.Record, state) if state: logging.debug('Sending the command to start the flash recorder, and waiting for a response...') else: logging.debug('Sending the command to stop the flash recorder, and waiting for a response...') # Step 2 - wait for ack and the session number self.core.waitForAck(SubSystem.Storage, Commands.Storage.Record) logging.debug("Acknowledge received.") packet = self.core.waitForPacket(PacketType.RegularResponse, SubSystem.Storage, Commands.Storage.Record) if packet.header.packetType == PacketType.ErrorLogResp: logging.warn("Flash is full, not recording.") else: logging.debug('Acknowledge packet was received with the session number {0}!'.format(packet.data.sessionID)) sessionID = packet.data.sessionID return sessionID def sessionPlayback(self, pbSessionID, dump=False): """ Playback a recorded session. :param pbSessionID: Recorded session identifier. :param dump: True, to dump recorded data to file. False, to skip. :return: Number of data retrieved. """ self.core.sendCommand(SubSystem.Storage, Commands.Storage.Playback, True, sessionID=pbSessionID) logging.debug('Sent the start playback command, waiting for response...') # wait for confirmation self.core.waitForAck(SubSystem.Storage, Commands.Storage.Playback) packet = self.core.waitForPacket(PacketType.RegularResponse, SubSystem.Storage, Commands.Storage.Playback) if packet.header.packetType == PacketType.ErrorLogResp: logging.error('Playback failed due to an invalid session number request!') return 0 else: pbSessionID = packet.data.sessionID logging.info('Playback routine started from session number {0}'.format(pbSessionID)) packetList = self.core.storePacketsUntil(PacketType.RegularResponse, SubSystem.Storage, Commands.Storage.Playback) logging.info('Finished playback from session number {0}!'.format(pbSessionID)) if dump: logging.info('Saving dump file. Waiting for completion...') NebUtilities.saveFlashPlayback(pbSessionID, packetList) logging.info('Dump file saving completed.') return len(packetList) def getSessionCount(self): """ Retrieve number of session recording :return: Recorded session count. """ self.core.sendCommand(SubSystem.Storage, Commands.Storage.NumSessions) packet = self.core.waitForAck(SubSystem.Storage, Commands.Storage.NumSessions) packet = self.core.waitForPacket(PacketType.RegularResponse, SubSystem.Storage, Commands.Storage.NumSessions) return packet.data.numSessions def getSessionInfo(self, sessionID): """ Retrieve a session information. :param sessionID: Recorded session identifier :return: FlashSessionInfo instance. """ self.core.sendCommand(SubSystem.Storage, Commands.Storage.SessionInfo, sessionID=sessionID) self.core.waitForAck(SubSystem.Storage, Commands.Storage.SessionInfo) packet = self.core.waitForPacket(PacketType.RegularResponse, SubSystem.Storage, Commands.Storage.SessionInfo) if packet.data.sessionLength == 0xFFFFFFFF: return None else: return packet.data def getFirmwareVersions(self): """ Retrieve firmware versions. :return: FirmwareVersionsData instance. """ self.core.sendCommand(SubSystem.Debug, Commands.Debug.FWVersions) packet = self.core.waitForPacket(PacketType.RegularResponse, SubSystem.Debug, Commands.Debug.FWVersions) return packet.data def debugUnitTestEnable(self, enable=True): """ Debugging/Testing function only. """ self.core.sendCommand(SubSystem.Debug, Commands.Debug.StartUnitTestMotion, enable) logging.debug("Sending Start UnitTest Motion. Waiting for acknowledgment.") self.core.waitForAck(SubSystem.Debug, Commands.Debug.StartUnitTestMotion) logging.debug("Acknowledgment received") def debugUnitTestSendBytes(self, bytes): """ Debugging/Testing function only. """ self.core.sendCommandBytes(bytes) logging.debug("Sending UnitTest Motion Bytes. Waiting for packet.") packet = self.core.waitForPacket(PacketType.RegularResponse, SubSystem.Debug, Commands.Debug.UnitTestMotionData) logging.debug("Packet received.") return packet
class NeblinaAPI(object): """ Neblina Application Programming Interface. This is used to communicate with Neblina. """ def __init__(self, interface): """ Constructor :param interface: Neblina communication interface. See Neblina.Interface. """ self.core = NeblinaCore(interface) def close(self): """ Close communication with Neblina. """ self.core.close() def open(self, address): """ Open communication with Neblina. :param address: Neblina address to reach. It can be UART """ self.core.open(address) def isOpened(self): """ Is communication opened ? :return: True, if communication opened. False, otherwise. """ return self.core.isOpened() def getBatteryLevel(self): """ Retrieve battery level. :return: Battery Level (0-100%) """ return self.core.getBatteryLevel() def getTemperature(self): """ Retrieve internal temperature :return: Temperature (in Celsius) """ self.core.sendCommand(SubSystem.Power, Commands.Power.GetTemperature, True) packet = self.core.waitForAck(SubSystem.Power, Commands.Power.GetTemperature) packet = self.core.waitForPacket(PacketType.RegularResponse, SubSystem.Power, Commands.Power.GetTemperature) return packet.data.temperature def setDataPortState(self, interface, state): """ Set data port state :param interface: Neblina.Interface to set. :param state: True, to open data port. False, to close data port. """ assert (type(state) is bool) self.core.sendCommand(SubSystem.Debug, Commands.Debug.InterfaceState, state, interface=interface) logging.debug('Waiting for the module to set data port state...') packet = self.core.waitForAck(SubSystem.Debug, Commands.Debug.InterfaceState) logging.debug('Module has change its data port state') def setInterface(self, interface=Interface.BLE): """ Set communication interface. :param interface: Neblina.Interface to used. """ self.core.sendCommand(SubSystem.Debug, Commands.Debug.SetInterface, interface) logging.debug('Waiting for the module to switch its interface...') packet = self.core.waitForAck(SubSystem.Debug, Commands.Debug.SetInterface) logging.debug("Module has switched its interface.") numTries = 0 while (packet == None): numTries += 1 if numTries > 5: logging.error('The unit is not responding. Exiting...') exit() logging.warning('Trying again...') self.core.sendCommand(SubSystem.Debug, Commands.Debug.SetInterface, interface) packet = self.core.waitForAck(SubSystem.Debug, Commands.Debug.SetInterface) def getMotionStatus(self): """ Retrieve current motion streaming status. :return: MotionStatusData instance. """ self.core.sendCommand(SubSystem.Debug, Commands.Debug.MotAndFlashRecState) self.core.waitForAck(SubSystem.Debug, Commands.Debug.MotAndFlashRecState) packet = self.core.waitForPacket(PacketType.RegularResponse, SubSystem.Debug, Commands.Debug.MotAndFlashRecState) return packet.data.motionStatus def getRecorderStatus(self): """ Retrieve current recording status :return: RecorderStatusData instance. """ self.core.sendCommand(SubSystem.Debug, Commands.Debug.MotAndFlashRecState) self.core.waitForAck(SubSystem.Debug, Commands.Debug.MotAndFlashRecState) packet = self.core.waitForPacket(PacketType.RegularResponse, SubSystem.Debug, Commands.Debug.MotAndFlashRecState) return packet.data.recorderStatus def setDownsample(self, factor): """ Set motion streaming downsampling. Downsampling must be between 20 and 1000, and a multiple of 20. This represent the time in ms between each packet. :param factor: Downsampling factor to use. """ # Limit to factor of 20 and between 20 and 1000. assert factor % 20 == 0 and 20 <= factor <= 1000 self.core.sendCommand(SubSystem.Motion, Commands.Motion.Downsample, factor) logging.debug('Sending downsample command. Waiting for acknowledge.') self.core.waitForAck(SubSystem.Motion, Commands.Motion.Downsample) logging.debug('Acknowledgment received.') def setAccelerometerRange(self, factor): """ Set accelerometer range. Must be 2, 4, 8 or 16. :param factor: Accelerometer range to use. """ # Limit factor to 2, 4, 8 and 16 assert factor == 2 or factor == 4 or factor == 8 or factor == 16 self.core.sendCommand(SubSystem.Motion, Commands.Motion.AccRange, factor) self.core.waitForAck(SubSystem.Motion, Commands.Motion.AccRange) def resetTimestamp(self): """ Reset timestamp """ self.core.sendCommand(SubSystem.Motion, Commands.Motion.ResetTimeStamp, True) self.core.waitForAck(SubSystem.Motion, Commands.Motion.ResetTimeStamp) def streamDisableAll(self): """ Disable all streaming. """ self.core.sendCommand(SubSystem.Motion, Commands.Motion.DisableStreaming, True) logging.debug( "Sending disable streaming command. Waiting for acknowledge.") self.core.waitForAck(SubSystem.Motion, Commands.Motion.DisableStreaming) logging.debug("Acknowledgment received.") def getEulerAngle(self): """ Retrieve Euler Angle. This is a blocking function until an Euler Angle is retrieve. Requires that Euler Angle streaming is activated, otherwise will hang forever. :return: EulerAngleData instance. """ packet = self.core.waitForPacket(PacketType.RegularResponse, SubSystem.Motion, Commands.Motion.EulerAngle) logging.debug("Received EulerAngle.") return packet.data def getExternalForce(self): """ Retrieve External Force. This is a blocking function until an External Force is retrieve. Requires that External Force streaming is activated, otherwise will hang forever. :return: ExternalForceData instance. """ packet = self.core.waitForPacket(PacketType.RegularResponse, SubSystem.Motion, Commands.Motion.ExtForce) logging.debug("Received ExternalForce.") return packet.data def getFingerGesture(self): """ Retrieve Finger Gesture. This is a blocking function until a Finger Gesture is retrieve. Requires that Finger Gesture streaming is activated, otherwise will hang forever. :return: FingerGestureData instance. """ packet = self.core.waitForPacket(PacketType.RegularResponse, SubSystem.Motion, Commands.Motion.FingerGesture) logging.debug("Received FingerGesture.") return packet.data def getIMU(self): """ Retrieve IMU (Inertial Motion Unit). This is a blocking function until an IMU is retrieve. Requires that IMU streaming is activated, otherwise will hang forever. :return: IMUData instance. """ packet = self.core.waitForPacket(PacketType.RegularResponse, SubSystem.Motion, Commands.Motion.IMU) logging.debug("Received IMU.") return packet.data def getMAG(self): """ Retrieve MAG (Magnetometer). This is a blocking function until a MAG is retrieve. Requires that MAG streaming is activated, otherwise will hang forever. :return: MAGData instance. """ packet = self.core.waitForPacket(PacketType.RegularResponse, SubSystem.Motion, Commands.Motion.MAG) logging.debug("Received MAG.") return packet.data def getMotionState(self): """ Retrieve Motion State. This is a blocking function until a Motion State is retrieve. Requires that Motion State streaming is activated, otherwise will hang forever. :return: MotionStateData instance. """ packet = self.core.waitForPacket(PacketType.RegularResponse, SubSystem.Motion, Commands.Motion.MotionState) logging.debug("Received MotionState.") return packet.data def getPedometer(self): """ Retrieve Pedometer. This is a blocking function until a Pedometer is retrieve. Requires that Pedometer streaming is activated, otherwise will hang forever. :return: PedometerData instance. """ packet = self.core.waitForPacket(PacketType.RegularResponse, SubSystem.Motion, Commands.Motion.Pedometer) logging.debug("Received Pedometer.") return packet.data def getQuaternion(self): """ Retrieve Quaternion. This is a blocking function until a Quaternion is retrieve. Requires that Quaternion streaming is activated, otherwise will hang forever. :return: QuaternionData instance. """ packet = self.core.waitForPacket(PacketType.RegularResponse, SubSystem.Motion, Commands.Motion.Quaternion) logging.debug("Received Quaternion.") return packet.data def getRotationInfo(self): """ Retrieve Rotation Information. This is a blocking function until a Rotation Information is retrieve. Requires that Rotation Information streaming is activated, otherwise will hang forever. :return: RotationData instance. """ packet = self.core.waitForPacket(PacketType.RegularResponse, SubSystem.Motion, Commands.Motion.RotationInfo) logging.debug("Received RotationInfo.") return packet.data def getSittingStanding(self): """ Retrieve Sitting/Standing. This is a blocking function until a Sitting/Standing is retrieve. Requires that Sitting/Standing streaming is activated, otherwise will hang forever. :return: """ packet = self.core.waitForPacket(PacketType.RegularResponse, SubSystem.Motion, Commands.Motion.SittingStanding) logging.debug("Received SittingStanding.") return packet.data def getTrajectoryInfo(self): """ Retrieve Trajectory Information. This is a blocking function until a Trajectory Information is retrieve. Requires that Trajectory Information is recording and streaming, otherwise will hang forever. :return: EulerAngleData instance. """ packet = self.core.waitForPacket(PacketType.RegularResponse, SubSystem.Motion, Commands.Motion.TrajectoryInfo) logging.debug("Received TrajectoryInfo.") return packet.data def recordTrajectory(self, state): """ Record trajectory information. :param state: True, to start recording. False, to stop recording. :return: """ self.core.sendCommand(SubSystem.Motion, Commands.Motion.TrajectoryRecStartStop, state) logging.debug("Sending recordTrajectory. Waiting for aknowledge.") self.core.waitForAck(SubSystem.Motion, Commands.Motion.TrajectoryRecStartStop) logging.debug("Acknowledgment received.") def streamEulerAngle(self, state): """ Start/Stop Euler Angle streaming. :param state: True, to start streaming. False, to stop streaming. """ self.core.sendCommand(SubSystem.Motion, Commands.Motion.EulerAngle, state) logging.debug("Sending streamEulerAngle. Waiting for acknowledge.") self.core.waitForAck(SubSystem.Motion, Commands.Motion.EulerAngle) logging.debug("Acknowledgment received.") def streamExternalForce(self, state): """ Start/Stop External Force streaming. :param state: True, to start streaming. False, to stop streaming. """ self.core.sendCommand(SubSystem.Motion, Commands.Motion.ExtForce, state) logging.debug("Sending streamExternalForce. Waiting for acknowledge.") self.core.waitForAck(SubSystem.Motion, Commands.Motion.ExtForce) logging.debug("Acknowledgment received.") def streamFingerGesture(self, state): """ Start/Stop Finger Gesture streaming. :param state: True, to start streaming. False, to stop streaming. """ self.core.sendCommand(SubSystem.Motion, Commands.Motion.FingerGesture, state) logging.debug("Sending streamFingerGesture. Waiting for acknowledge.") self.core.waitForAck(SubSystem.Motion, Commands.Motion.FingerGesture) logging.debug("Acknowledgment received.") def streamIMU(self, state): """ Start/Stop IMU streaming. :param state: True, to start streaming. False, to stop streaming. """ self.core.sendCommand(SubSystem.Motion, Commands.Motion.IMU, state) logging.debug("Sending streamIMU. Waiting for acknowledge.") self.core.waitForAck(SubSystem.Motion, Commands.Motion.IMU) logging.debug("Acknowledgment received.") def streamMAG(self, state): """ Start/Stop MAG streaming. :param state: True, to start streaming. False, to stop streaming. """ self.core.sendCommand(SubSystem.Motion, Commands.Motion.MAG, state) logging.debug("Sending streamMAG. Waiting for acknowledge.") self.core.waitForAck(SubSystem.Motion, Commands.Motion.MAG) logging.debug("Acknowledgment received.") def streamMotionState(self, state): """ Start/Stop Motion State streaming. :param state: True, to start streaming. False, to stop streaming. """ self.core.sendCommand(SubSystem.Motion, Commands.Motion.MotionState, state) logging.debug("Sending streamMotionState. Waiting for acknowledge.") self.core.waitForAck(SubSystem.Motion, Commands.Motion.MotionState) logging.debug("Acknowledgment received.") def streamPedometer(self, state): """ Start/Stop Pedometer streaming. :param state: True, to start streaming. False, to stop streaming. """ self.core.sendCommand(SubSystem.Motion, Commands.Motion.Pedometer, state) logging.debug("Sending streamPedometer. Waiting for acknowledge.") self.core.waitForAck(SubSystem.Motion, Commands.Motion.Pedometer) logging.debug("Acknowledgment received.") def streamQuaternion(self, state): """ Start/Stop Quaternion streaming. :param state: True, to start streaming. False, to stop streaming. """ self.core.sendCommand(SubSystem.Motion, Commands.Motion.Quaternion, state) logging.debug("Sending streamQuaternion. Waiting for acknowledge.") self.core.waitForAck(SubSystem.Motion, Commands.Motion.Quaternion) logging.debug("Acknowledgment received.") def streamRotationInfo(self, state): """ Start/Stop Rotation Information streaming. :param state: True, to start streaming. False, to stop streaming. """ self.core.sendCommand(SubSystem.Motion, Commands.Motion.RotationInfo, state) logging.debug("Sending streamRotationInfo. Waiting for acknowledge.") self.core.waitForAck(SubSystem.Motion, Commands.Motion.RotationInfo) logging.debug("Acknowledgment received.") def streamSittingStanding(self, state): """ Start/Stop Sitting/Standing streaming. :param state: True, to start streaming. False, to stop streaming. """ self.core.sendCommand(SubSystem.Motion, Commands.Motion.SittingStanding, state) logging.debug( "Sending streamSittingStanding. Waiting for acknowledge.") self.core.waitForAck(SubSystem.Motion, Commands.Motion.SittingStanding) logging.debug("Acknowledgment received.") def streamTrajectoryInfo(self, state): """ Start/Stop Trajectory Information streaming. :param state: True, to start streaming. False, to stop streaming. """ self.core.sendCommand(SubSystem.Motion, Commands.Motion.TrajectoryInfo, state) logging.debug("Sending streamTrajectoryInfo. Waiting for acknowledge.") self.core.waitForAck(SubSystem.Motion, Commands.Motion.TrajectoryInfo) logging.debug("Acknowledgment received.") def eepromRead(self, readPageNumber): """ Read a page from EEPROM :param readPageNumber: EEPROM page number to read. :return: EEPROMReadData instance. """ assert 0 <= readPageNumber <= 255 self.core.sendCommand(SubSystem.EEPROM, Commands.EEPROM.Read, pageNumber=readPageNumber) logging.debug( "Sending EEPROM Read command. Waiting for acknowledgment.") packet = self.core.waitForAck(SubSystem.EEPROM, Commands.EEPROM.Read) logging.debug("Acknowledge received.") packet = self.core.waitForPacket(PacketType.RegularResponse, SubSystem.EEPROM, Commands.EEPROM.Read) logging.debug("EEPROM Read packet received.") return packet.data.dataBytes def eepromWrite(self, writePageNumber, dataString): """ Write a page to EEPROM. :param writePageNumber: EEPROM page number to write. :param dataString: 8-byte data string to write. """ assert 0 <= writePageNumber <= 255 self.core.sendCommand(SubSystem.EEPROM, Commands.EEPROM.Write, \ pageNumber=writePageNumber, dataBytes=dataString) packet = self.core.waitForAck(SubSystem.EEPROM, Commands.EEPROM.Write) def getLED(self, index): """ Retrieve LED state. :param index: LED index to retrieve. :return: LEDGetValData instance. """ assert 0 <= index <= 7 self.core.sendCommand(SubSystem.LED, Commands.LED.GetVal, ledIndices=[index]) packet = self.core.waitForPacket(PacketType.RegularResponse, SubSystem.LED, Commands.LED.GetVal) if not packet: return 0xF # Return anything but 0x0 or 0x1 return packet.data.ledState[index] def setLED(self, ledIndex, ledValue): """ Set LED state. :param ledIndex: LED index to use. :param ledValue: LED state. True, open. False, close. """ assert 0 <= ledIndex <= 7 ledValues = [(ledIndex, ledValue)] self.core.sendCommand(SubSystem.LED, Commands.LED.SetVal, ledValueTupleList=ledValues) self.core.waitForAck(SubSystem.LED, Commands.LED.SetVal) self.core.waitForPacket(PacketType.RegularResponse, SubSystem.LED, Commands.LED.GetVal) def eraseStorage(self, eraseType=Erase.Quick): """ Erase storage. Full erase can take up to 3 minute to complete. :param eraseType: Erase Type. Quick or Full. """ assert eraseType == Erase.Mass or eraseType == Erase.Quick # Step 1 - Initialization self.core.sendCommand(SubSystem.Motion, Commands.Motion.DisableStreaming, True) logging.debug( 'Sending the DisableAllStreaming command, and waiting for a response...' ) # Step 2 - wait for ack self.core.waitForAck(SubSystem.Motion, Commands.Motion.DisableStreaming) logging.debug('Acknowledge packet was received!') # Step 3 - erase the flash command self.core.sendCommand(SubSystem.Storage, Commands.Storage.EraseAll, eraseType) logging.debug( 'Sent the EraseAll command, and waiting for a response...') # Step 4 - wait for ack self.core.waitForAck(SubSystem.Storage, Commands.Storage.EraseAll) logging.debug("Acknowledge packet was received!") logging.info("Started erasing... This takes up to around 3 minutes...") # Step 5 - wait for the completion notice self.core.waitForPacket(PacketType.RegularResponse, SubSystem.Storage, Commands.Storage.EraseAll, 300) logging.info('Flash erase has completed successfully!') def sessionRecord(self, state): """ Start/Stop recording a session. :param state: True, to start recording. False, to stop recording. :return: Recording session identifier. """ # Step 1 - Start recording self.core.sendCommand(SubSystem.Storage, Commands.Storage.Record, state) if state: logging.debug( 'Sending the command to start the flash recorder, and waiting for a response...' ) else: logging.debug( 'Sending the command to stop the flash recorder, and waiting for a response...' ) # Step 2 - wait for ack and the session number self.core.waitForAck(SubSystem.Storage, Commands.Storage.Record) logging.debug("Acknowledge received.") packet = self.core.waitForPacket(PacketType.RegularResponse, SubSystem.Storage, Commands.Storage.Record) if packet.header.packetType == PacketType.ErrorLogResp: logging.warn("Flash is full, not recording.") else: logging.debug( 'Acknowledge packet was received with the session number {0}!'. format(packet.data.sessionID)) sessionID = packet.data.sessionID return sessionID def sessionPlayback(self, pbSessionID, dump=False): """ Playback a recorded session. :param pbSessionID: Recorded session identifier. :param dump: True, to dump recorded data to file. False, to skip. :return: Number of data retrieved. """ self.core.sendCommand(SubSystem.Storage, Commands.Storage.Playback, True, sessionID=pbSessionID) logging.debug( 'Sent the start playback command, waiting for response...') # wait for confirmation self.core.waitForAck(SubSystem.Storage, Commands.Storage.Playback) packet = self.core.waitForPacket(PacketType.RegularResponse, SubSystem.Storage, Commands.Storage.Playback) if packet.header.packetType == PacketType.ErrorLogResp: logging.error( 'Playback failed due to an invalid session number request!') return 0 else: pbSessionID = packet.data.sessionID logging.info( 'Playback routine started from session number {0}'.format( pbSessionID)) packetList = self.core.storePacketsUntil( PacketType.RegularResponse, SubSystem.Storage, Commands.Storage.Playback) logging.info('Finished playback from session number {0}!'.format( pbSessionID)) if dump: logging.info('Saving dump file. Waiting for completion...') NebUtilities.saveFlashPlayback(pbSessionID, packetList) logging.info('Dump file saving completed.') return len(packetList) def getSessionCount(self): """ Retrieve number of session recording :return: Recorded session count. """ self.core.sendCommand(SubSystem.Storage, Commands.Storage.NumSessions) packet = self.core.waitForAck(SubSystem.Storage, Commands.Storage.NumSessions) packet = self.core.waitForPacket(PacketType.RegularResponse, SubSystem.Storage, Commands.Storage.NumSessions) return packet.data.numSessions def getSessionInfo(self, sessionID): """ Retrieve a session information. :param sessionID: Recorded session identifier :return: FlashSessionInfo instance. """ self.core.sendCommand(SubSystem.Storage, Commands.Storage.SessionInfo, sessionID=sessionID) self.core.waitForAck(SubSystem.Storage, Commands.Storage.SessionInfo) packet = self.core.waitForPacket(PacketType.RegularResponse, SubSystem.Storage, Commands.Storage.SessionInfo) if packet.data.sessionLength == 0xFFFFFFFF: return None else: return packet.data def getFirmwareVersions(self): """ Retrieve firmware versions. :return: FirmwareVersionsData instance. """ self.core.sendCommand(SubSystem.Debug, Commands.Debug.FWVersions) packet = self.core.waitForPacket(PacketType.RegularResponse, SubSystem.Debug, Commands.Debug.FWVersions) return packet.data def debugUnitTestEnable(self, enable=True): """ Debugging/Testing function only. """ self.core.sendCommand(SubSystem.Debug, Commands.Debug.StartUnitTestMotion, enable) logging.debug( "Sending Start UnitTest Motion. Waiting for acknowledgment.") self.core.waitForAck(SubSystem.Debug, Commands.Debug.StartUnitTestMotion) logging.debug("Acknowledgment received") def debugUnitTestSendBytes(self, bytes): """ Debugging/Testing function only. """ self.core.sendCommandBytes(bytes) logging.debug("Sending UnitTest Motion Bytes. Waiting for packet.") packet = self.core.waitForPacket(PacketType.RegularResponse, SubSystem.Debug, Commands.Debug.UnitTestMotionData) logging.debug("Packet received.") return packet