Ejemplo n.º 1
0
    def start_accelerometer(self):
        """
        Creates Phidget22 accelerometer and polls it at a fixed rate using a QTimer.
        """
        # set up the target image
        self.setup_target()

        # create the accelerometer, and wait 1 sec for connection
        # TODO does the open wait for attachment throw an error
        try:
            self.accelerometer = Accelerometer()
            self.accelerometer.openWaitForAttachment(1000)
            log.info("Created accelerometer")
        except:
            log.warning("There is no accelerometer connected")
            self.accelerometer = None
            return

        # create QTimer to periodically monitor the acceleration
        self.accelerometer_timer = QtCore.QTimer()
        self.accelerometer_timer.setTimerType(QtCore.Qt.PreciseTimer)
        self.accelerometer_timer.timeout.connect(self.update_target)
        self.accelerometer_timer.setInterval(ACCELEROMETER_PERIOD_MS)
        self.accelerometer_timer.start()
        log.debug("Timer limiting accelerometer update frequency to %f Hz" %
                  (1000.0 / ACCELEROMETER_PERIOD_MS))
Ejemplo n.º 2
0
def main():
    try:
        #Create your Phidget channels
        accelerometer0 = Accelerometer()
        gyroscope0 = Gyroscope()
        magnetometer0 = Magnetometer()

        #Set addressing parameters to specify which channel to open (if any)

        #Assign any event handlers you need before calling open so that no events are missed.
        accelerometer0.setOnAccelerationChangeHandler(onAccelerationChange)
        gyroscope0.setOnAngularRateUpdateHandler(onAngularRateUpdate)
        magnetometer0.setOnMagneticFieldChangeHandler(onMagneticFieldChange)

        #Open your Phidgets and wait for attachment
        accelerometer0.openWaitForAttachment(5000)
        gyroscope0.openWaitForAttachment(5000)
        magnetometer0.openWaitForAttachment(5000)

        #Do stuff with your Phidgets here or in your event handlers.

        time.sleep(5)

        #Close your Phidgets once the program is done.
        accelerometer0.close()
        gyroscope0.close()
        magnetometer0.close()

    except PhidgetException as ex:
        #We will catch Phidget Exceptions here, and print the error informaiton.
        traceback.print_exc()
        print("")
        print("PhidgetException " + str(ex.code) + " (" + ex.description +
              "): " + ex.details)
    def __init__(self):
        self.kalmanX = KalmanAngle()
        self.kalmanY = KalmanAngle()

        self.RestrictPitch = True  #Comment out to restrict roll to ±90deg instead - please read: http://www.freescale.com/files/sensors/doc/app_note/AN3461.pdf
        self.radToDeg = 57.2957786
        self.kalAngleX = 0
        self.kalAngleY = 0
        try:
            self.accel = Accelerometer()  #ch.getAcceleration()
            self.gyro = Gyroscope()  #ch.getAngularRate()
        except Exception as e:
            print(
                "Cannot initalize, try checking you have the Phidget22 library installed."
            )
            print("Error:", e)
            sys.exit()
Ejemplo n.º 4
0
def imu_talker():

    # Create new phidget22 accelerometer object
    accelerometer = Accelerometer()

    # Check if imu can be found by OS
    accelerometer.openWaitForAttachment(1000)

    try:
        pub = rospy.Publisher('crashed', Bool, queue_size=10)
        rospy.init_node('crash_detector', anonymous=True)
        rate = rospy.Rate(10)

        while not rospy.is_shutdown():

            # Get current acceleration
            acceleration = accelerometer.getAcceleration()

            # Check if y acceleration has a large negative value in gs
            if acceleration[1] < -0.2:

                # In this case we have probably crashed
                crashed = True

            else:

                # In this case we probably didn't crash
                crashed = False

            pub.publish(crashed)
            rate.sleep()
    except rospy.ROSInterruptException:
        accelerometer.close()
Ejemplo n.º 5
0
def initialize_sensors():
    print("\n--- Sensors initializing...")
    try:
        #For a raspberry pi, for example, to set up pins 4 and 5, you would add
        #GPIO.setmode(GPIO.BCM)
        #GPIO.setup(4, GPIO.IN)
        #GPIO.setup(5, GPIO.IN)
        print("--- Waiting 10 seconds for sensors to warm up...")
        time.sleep(10)

        # Activate the accelerometer
        global ch
        ch = Accelerometer()

        # Assign event handlers
        ch.setOnAttachHandler(AccelerometerAttached)
        ch.setOnDetachHandler(AccelerometerDetached)
        ch.setOnErrorHandler(ErrorEvent)

        # Wait for the sensor to be attached
        print(
            "--- Waiting for the Phidget Accelerometer Object to be attached..."
        )
        ch.openWaitForAttachment(5000)
        print("--- Sensors initialized!")

        # Sync the time on this device to an internet time server
        try:
            print('\n--- Syncing time...')
            os.system('sudo service ntpd stop')
            time.sleep(1)
            os.system('sudo ntpd -gq')
            time.sleep(1)
            os.system('sudo service ntpd start')
            print('--- Success! Time is ' + str(datetime.datetime.now()))
        except:
            print('Error syncing time!')

    except Exception as ex:
        # Log any error, if it occurs
        print(
            str(datetime.datetime.now()) +
            " Error when initializing sensors: " + str(ex))
def main():
    accelerometer0 = Accelerometer()

    accelerometer0.setOnAccelerationChangeHandler(onAccelerationChange)

    accelerometer0.openWaitForAttachment(5000)

    try:
        input("Press Enter to Stop\n")
    except (Exception, KeyboardInterrupt):
        pass

    accelerometer0.close()
def initialize_sensors():
    print("\n--- Sensors initializing...")
    try:
	#For a raspberry pi, for example, to set up pins 4 and 5, you would add
        #GPIO.setmode(GPIO.BCM)
	#GPIO.setup(4, GPIO.IN)
	#GPIO.setup(5, GPIO.IN)
        print("--- Waiting 10 seconds for sensors to warm up...")
        time.sleep(10)

        # Activate the accelerometer
        global ch
        ch = Accelerometer()
        
        # Assign event handlers
        ch.setOnAttachHandler(AccelerometerAttached)
        ch.setOnDetachHandler(AccelerometerDetached)
        ch.setOnErrorHandler(ErrorEvent)

        # Wait for the sensor to be attached
        print("--- Waiting for the Phidget Accelerometer Object to be attached...")
        ch.openWaitForAttachment(5000)
        print("--- Sensors initialized!")
		
        # Sync the time on this device to an internet time server
        try:
            print('\n--- Syncing time...')
            os.system('sudo service ntpd stop')
            time.sleep(1)
            os.system('sudo ntpd -gq')
            time.sleep(1)
            os.system('sudo service ntpd start')
            print('--- Success! Time is ' + str(datetime.datetime.now()))
        except:
            print('Error syncing time!')

    except Exception as ex:
		# Log any error, if it occurs
        print(str(datetime.datetime.now()) + " Error when initializing sensors: " + str(ex))
Ejemplo n.º 8
0
class TiltData:
    _all = set()
    _logger = None
    _accelerometer = Accelerometer()
    _waitTimeForConnect = 5000

    def __init__(self,
                 config={},
                 positionChange=0,
                 elapsedtime=0.0,
                 position=0):
        TiltData._all.add(self)
        self.gestureProcessor = TiltGestureProcessor(self, config)
        self.queueLength = config['accelerometerQueueLength']
        self.components = [
            Queue(self.queueLength),
            Queue(self.queueLength),
            Queue(self.queueLength)
        ]
        self.variances = [
            Queue(self.queueLength),
            Queue(self.queueLength),
            Queue(self.queueLength)
        ]
        self.magnitude = 0.0
        self.zeros = [0.0, 0.0, 0.0]
        self.serialNumber = ''

        if (TiltData._logger == None):
            TiltData._logger = logging.getLogger('tiltsensorserver')

        try:
            TiltData._accelerometer.setOnAttachHandler(
                TiltData._accelerometerAttached)
            TiltData._accelerometer.setOnDetachHandler(
                TiltData._accelerometerDetached)
            TiltData._accelerometer.setOnErrorHandler(
                TiltData._accelerometerError)
            TiltData._accelerometer.setOnAccelerationChangeHandler(
                TiltData._accelerometerAccelerationChanged)
        except PhidgetException as e:
            _accelerometer = None
            d = {'clientip': "tilter", 'user': "******"}
            TiltData._logger.critical('Tilter init failed: %s',
                                      e.details,
                                      extra=d)
        try:
            TiltData._accelerometer.openWaitForAttachment(
                TiltData._waitTimeForConnect)
        except PhidgetException as e:
            d = {'clientip': "tilter", 'user': "******"}
            TiltData._logger.critical('Tilter connect failed: %s',
                                      e.details,
                                      extra=d)
            TiltData._accelerometer = None

    def setZeros(self, x0, y0, z0):
        self.zeros = [x0, y0, z0]

    def set_accelerometerZero(self, index, newZero):
        self.zeros[index] = newZero

    def level_table(self):
        self.components = [
            Queue(self.queueLength),
            Queue(self.queueLength),
            Queue(self.queueLength)
        ]
        self.variances = [
            Queue(self.queueLength),
            Queue(self.queueLength),
            Queue(self.queueLength)
        ]

    def ingestSpatialData(self, sensorData):
        if self.components[0].size() == 0:
            self.setZeros(sensorData.Acceleration[0],
                          sensorData.Acceleration[1],
                          sensorData.Acceleration[2])
        newX = config['flipX'] * (sensorData.Acceleration[0] - self.zeros[0])
        newY = config['flipY'] * (sensorData.Acceleration[1] - self.zeros[1])
        newZ = sensorData.Acceleration[2] - self.zeros[2]
        self.variances[0].enqueue(newX - self.components[0].head())
        self.variances[1].enqueue(newY - self.components[1].head())
        self.variances[2].enqueue(newZ - self.components[2].head())
        self.components[0].enqueue(newX)
        self.components[1].enqueue(newY)
        self.components[2].enqueue(newZ)

    def ingest_accelerometerData(self, sensorData):
        for index in range(3):
            if self.components[index].size() == 0:
                self.set_accelerometerZero(index, sensorData[index])
            newX = sensorData[index] - self.zeros[index]
            self.variances[index].enqueue(newX - self.components[index].head())
            self.components[index].enqueue(newX)

    def getJSON(self):
        jsonBundle = {
            'type': 'tilt',
            'packet': {
                'sensorID': '',
                'tiltX': 0.0,
                'tiltY': 0.0
            }
        }
        return (JSON.dumps(jsonBundle))

    def _accelerometerAttached(e):
        attached = e
        for tilter in TiltData._all:
            tilter.serialNumber = attached.getDeviceSerialNumber()

        d = {
            'clientip': "tilter",
            'user': "******",
            'foo': "accelerometer attached"
        }
        TiltData._logger.info('accelerometer Attached! %s', 'yay', extra=d)

    def _accelerometerDetached(e):
        detached = e
        d = {
            'clientip':
            "tilter",
            'user':
            "******",
            'foo':
            "accelerometer Detached! %s" % (detached.getDeviceSerialNumber())
        }
        TiltData._logger.warning('accelerometer  Detached! %s',
                                 'connection reset',
                                 extra=d)

    def _accelerometerError(e, eCode, description):

        d = {'clientip': "tilter", 'user': "******"}
        TiltData._logger.error('_accelerometerError %s', description, extra=d)

    def _accelerometerAccelerationChanged(e, acceleration, timestamp):
        # print("Acceleration: %f  %f  %f" % (acceleration[0], acceleration[1], acceleration[2]))
        # print("Timestamp: %f\n" % timestamp)
        #TiltData._logger.info('accelerometer data %s', "checking", extra=d)
        for tilter in TiltData._all:
            #print(tilter.serialNumber, e.getDeviceSerialNumber(), len(TiltData._all ))
            if tilter.serialNumber == e.getDeviceSerialNumber():
                #print(repr(tilter), len(TiltData._all ))
                if tilter:
                    tilter.ingest_accelerometerData(acceleration)
class PhidgetKalman(object):
    #Read the gyro and acceleromater values from MPU6050
    def __init__(self):
        self.kalmanX = KalmanAngle()
        self.kalmanY = KalmanAngle()

        self.RestrictPitch = True  #Comment out to restrict roll to ±90deg instead - please read: http://www.freescale.com/files/sensors/doc/app_note/AN3461.pdf
        self.radToDeg = 57.2957786
        self.kalAngleX = 0
        self.kalAngleY = 0
        try:
            self.accel = Accelerometer()  #ch.getAcceleration()
            self.gyro = Gyroscope()  #ch.getAngularRate()
        except Exception as e:
            print(
                "Cannot initalize, try checking you have the Phidget22 library installed."
            )
            print("Error:", e)
            sys.exit()
        # return self.accel, self.gyro

    def start(self):
        try:
            self.accel.openWaitForAttachment(1000)
            self.gyro.openWaitForAttachment(1000)
        except Exception as e:
            print(
                "Issue with attaching to IMU. The IMU maybe connected to something else right now.."
            )
            print("Error:", e)
            sys.exit()

    def stop(self):
        self.accel.close()
        self.gyro.close()
        print("Stopping")

    def get_angles(self, measure_time=5):
        #Keep going
        time.sleep(1)
        accX, accY, accZ = self.accel.getAcceleration()
        if (self.RestrictPitch):
            roll = math.atan2(accY, accZ) * self.radToDeg
            pitch = math.atan(-accX / math.sqrt((accY**2) +
                                                (accZ**2))) * self.radToDeg
        else:
            roll = math.atan(accY / math.sqrt((accX**2) +
                                              (accZ**2))) * self.radToDeg
            pitch = math.atan2(-accX, accZ) * self.radToDeg
        # print(roll)
        self.kalmanX.setAngle(roll)
        self.kalmanX.setAngle(pitch)
        gyroXAngle = roll
        gyroYAngle = pitch
        compAngleX = roll
        compAngleY = pitch

        timer = time.time()
        compare_timer = time.time()
        flag = 0
        try:
            while int(time.time()) < int(measure_time) + int(
                    compare_timer
            ):  #Should only run for about 5 seconds <- Could make lower

                #Read Accelerometer raw value
                accX, accY, accZ = self.accel.getAcceleration()

                #Read Gyroscope raw value
                gyroX, gyroY, gyroZ = self.gyro.getAngularRate()

                dt = time.time() - timer
                timer = time.time()

                if (self.RestrictPitch):
                    roll = math.atan2(accY, accZ) * self.radToDeg
                    pitch = math.atan(
                        -accX / math.sqrt((accY**2) +
                                          (accZ**2))) * self.radToDeg
                else:
                    roll = math.atan(
                        accY / math.sqrt((accX**2) +
                                         (accZ**2))) * self.radToDeg
                    pitch = math.atan2(-accX, accZ) * self.radToDeg

                gyroXRate = gyroX / 131
                gyroYRate = gyroY / 131

                if (self.RestrictPitch):

                    if ((roll < -90 and self.kalAngleX > 90)
                            or (roll > 90 and self.kalAngleX < -90)):
                        self.kalmanX.setAngle(roll)
                        complAngleX = roll
                        self.kalAngleX = roll
                        gyroXAngle = roll
                    else:
                        self.kalAngleX = self.kalmanX.getAngle(
                            roll, gyroXRate, dt)

                    if (abs(self.kalAngleX) > 90):
                        gyroYRate = -gyroYRate
                        self.kalAngleY = self.kalmanX.getAngle(
                            pitch, gyroYRate, dt)
                else:

                    if ((pitch < -90 and self.kalAngleY > 90)
                            or (pitch > 90 and self.kalAngleY < -90)):
                        self.kalmanX.setAngle(pitch)
                        complAngleY = pitch
                        self.kalAngleY = pitch
                        gyroYAngle = pitch
                    else:
                        self.kalAngleY = self.kalmanX.getAngle(
                            pitch, gyroYRate, dt)

                    if (abs(self.kalAngleY) > 90):
                        gyroXRate = -gyroXRate
                        self.kalAngleX = self.kalmanX.getAngle(
                            roll, gyroXRate, dt)

                #angle = (rate of change of angle) * change in time
                gyroXAngle = gyroXRate * dt
                gyroYAngle = gyroYAngle * dt

                #compAngle = constant * (old_compAngle + angle_obtained_from_gyro) + constant * angle_obtained from accelerometer
                compAngleX = 0.93 * (compAngleX + gyroXRate * dt) + 0.07 * roll
                compAngleY = 0.93 * (compAngleY +
                                     gyroYRate * dt) + 0.07 * pitch

                if ((gyroXAngle < -180) or (gyroXAngle > 180)):
                    gyroXAngle = self.kalAngleX
                if ((gyroYAngle < -180) or (gyroYAngle > 180)):
                    gyroYAngle = self.kalAngleY

                self.X_angle = self.kalAngleX
                self.Y_angle = self.kalAngleY
                #print("Angle X: " + str(self.kalAngleX)+"   " +"Angle Y: " + str(self.kalAngleY))
                #print(str(roll)+"  "+str(gyroXAngle)+"  "+str(compAngleX)+"  "+str(self.kalAngleX)+"  "+str(pitch)+"  "+str(gyroYAngle)+"  "+str(compAngleY)+"  "+str(self.kalAngleY))
                time.sleep(0.005)

        except KeyboardInterrupt:
            print("test")
        return self.X_angle, self.Y_angle
Ejemplo n.º 10
0
def plugin_reconfigure(handle, new_config):
    """ Reconfigures the plugin

    Args:
        handle: handle returned by the plugin initialisation call
        new_config: JSON object representing the new configuration category for the category
    Returns:
        new_handle: new handle to be used in the future calls
    """
    _LOGGER.info("Old config for wind_turbine plugin {} \n new config {}".format(handle, new_config))
    # Shutdown sensors 
    try: 
        handle['humidity'].close() 
        handle['temperature'].close()
        handle['current'].close() 
        handle['encoder'].close() 
        handle['accelerometer'].close()  
        handle['gyroscope'].close() 
        handle['magnetometer'].close() 
    except Exception as ex:
        _LOGGER.exception("wind_turbine exception: {}".format(str(ex)))
        raise ex
    time.sleep(5) 
    new_handle = copy.deepcopy(new_config)
    try: 
        # check if temp/humidity sensor is enabled. If so restart it 
        if new_handle['tempHumEnable']['value'] == 'true': 
            new_handle['humidity'] = HumiditySensor()
            new_handle['humidity'].setDeviceSerialNumber(int(new_handle['hubSN']['value']))
            new_handle['humidity'].setHubPort(int(new_handle['tempHumPort']['value']))
            new_handle['humidity'].setIsHubPortDevice(False)
            new_handle['humidity'].setChannel(0)
            new_handle['humidity'].openWaitForAttachment(5000)
            try:
                new_handle['humidity'].getHumidity()
            except Exception:
                pass

            new_handle['temperature'] = TemperatureSensor()
            new_handle['temperature'].setDeviceSerialNumber(int(new_handle['hubSN']['value']))
            new_handle['temperature'].setHubPort(int(new_handle['tempHumPort']['value']))
            new_handle['temperature'].setIsHubPortDevice(False)
            new_handle['temperature'].setChannel(0)
            new_handle['temperature'].openWaitForAttachment(5000)
            try:
                new_handle['temperature'].getTemperature()
            except Exception:
                pass

        # check if current sensor is enabled, if so restart it 
        if new_handle['currentEnable']['value'] == 'true':
            new_handle['current'] = CurrentInput()
            new_handle['current'].setDeviceSerialNumber(int(new_handle['hubSN']['value']))
            new_handle['current'].setHubPort(int(new_handle['currentPort']['value']))
            new_handle['current'].setIsHubPortDevice(False)
            new_handle['current'].setChannel(0)
            new_handle['current'].openWaitForAttachment(5000)
            try:
                new_handle['current'].getCurrent()
            except Exception:
                pass

        # check if encoder sensor is enabled  
        if new_handle['encoderEnable']['value'] == 'true':
            new_handle['encoder'] = Encoder()
            new_handle['encoder'].setDeviceSerialNumber(int(new_handle['hubSN']['value']))
            new_handle['encoder'].setHubPort(int(new_handle['encoderPort']['value']))
            new_handle['encoder'].setIsHubPortDevice(False)
            new_handle['encoder'].setChannel(0)
            new_handle['encoder'].openWaitForAttachment(5000)
            new_handle['encoder'].setDataInterval(20)
            i = 0
            while i < 120:
                try:
                    new_handle['encoder'].getPosition()
                except Exception:
                    time.sleep(1)
                    i += 1
                else:
                    break

        # check if accelerometer is enabled
        if new_handle['accelerometerEnable']['value'] == 'true':
            new_handle['accelerometer'] = Accelerometer()
            new_handle['accelerometer'].setDeviceSerialNumber(int(new_handle['hubSN']['value']))
            new_handle['accelerometer'].setHubPort(int(new_handle['spatialPort']['value']))
            new_handle['accelerometer'].setIsHubPortDevice(False)
            new_handle['accelerometer'].setChannel(0)
            new_handle['accelerometer'].openWaitForAttachment(5000)
            new_handle['accelerometer'].setDataInterval(20)
            i = 0
            while i < 120:
                try:
                    new_handle['accelerometer'].getAcceleration()
                except Exception:
                    time.sleep(1)
                    i += 1
                else:
                    break
        # check if gyroscope is enabled 
        if new_handle['gyroscopeEnable']['value'] == 'true':
            new_handle['gyroscope'] = Gyroscope()
            new_handle['gyroscope'].setDeviceSerialNumber(int(new_handle['hubSN']['value']))
            new_handle['gyroscope'].setHubPort(int(new_handle['spatialPort']['value']))
            new_handle['gyroscope'].setIsHubPortDevice(False)
            new_handle['gyroscope'].setChannel(0)
            new_handle['gyroscope'].openWaitForAttachment(5000)
            new_handle['gyroscope'].setDataInterval(20)
            i = 0
            while i < 120:
                try:
                    new_handle['gyroscope'].getAngularRate()
                except Exception:
                    time.sleep(1)
                    i += 1
                else:
                    break
        # check if magnetometer enable is enabled 
        if new_handle['magnetometerEnable']['value'] == 'true':
            new_handle['magnetometer'] = Magnetometer()
            new_handle['magnetometer'].setDeviceSerialNumber(int(new_handle['hubSN']['value']))
            new_handle['magnetometer'].setHubPort(int(new_handle['spatialPort']['value']))
            new_handle['magnetometer'].setIsHubPortDevice(False)
            new_handle['magnetometer'].setChannel(0)
            new_handle['magnetometer'].openWaitForAttachment(5000)
            new_handle['magnetometer'].setDataInterval(20)
            i = 0
            while i < 120:
                try:
                    new_handle['magnetometer'].getMagneticField()
                except Exception:
                    time.sleep(1)
                    i += 1
                else:
                    break

        # check if hub has changed, if so init restart 
        if new_handle['hubSN']['value'] != handle['hubSN']['value']:
            new_handle['restart'] = 'yes'
        else:
            new_handle['restart'] = 'no'
    except Exception as ex:
        _LOGGER.exception("wind_turbine exception: {}".format(str(ex)))
        raise ex

    # counter to know when to run process
    new_handle['tempHumCount'] = 0
    new_handle['currentCount'] = 0
    new_handle['encoderCount'] = 0
    new_handle['accelerometerCount'] = 0
    new_handle['gyroscopeCount'] = 0
    new_handle['magnetometerCount'] = 0

    # counter of last encoder value
    new_handle['encoderPreviousValue'] = handle['encoderPreviousValue']

    return new_handle
Ejemplo n.º 11
0
def plugin_init(config):
    """ Initialise the plugin.
    Args:
        config: JSON configuration document for the South plugin configuration category
    Returns:
        data: JSON object to be used in future calls to the plugin
    Raises:
    """
    try: 
        data = copy.deepcopy(config)
        if data['tempHumEnable']['value'] == 'true':
            data['humidity'] = HumiditySensor()
            data['humidity'].setDeviceSerialNumber(int(data['hubSN']['value']))
            data['humidity'].setHubPort(int(data['tempHumPort']['value']))
            data['humidity'].setIsHubPortDevice(False)
            data['humidity'].setChannel(0)
            data['humidity'].openWaitForAttachment(5000)
            try:
                data['humidity'].getHumidity()
            except Exception:
                pass

            data['temperature'] = TemperatureSensor()  
            data['temperature'].setDeviceSerialNumber(int(data['hubSN']['value']))
            data['temperature'].setHubPort(int(data['tempHumPort']['value']))
            data['temperature'].setIsHubPortDevice(False)
            data['temperature'].setChannel(0)
            data['temperature'].openWaitForAttachment(5000)
            try:
                data['temperature'].getTemperature()
            except Exception:
                pass

        if data['currentEnable']['value'] == 'true': 
            data['current'] = CurrentInput() 
            data['current'].setDeviceSerialNumber(int(data['hubSN']['value']))
            data['current'].setHubPort(int(data['currentPort']['value']))
            data['current'].setIsHubPortDevice(False)
            data['current'].setChannel(0)
            data['current'].openWaitForAttachment(5000)
            try:
                data['current'].getCurrent()
            except Exception:
                pass

        if data['encoderEnable']['value'] == 'true': 
            data['encoder'] = Encoder()
            data['encoder'].setDeviceSerialNumber(int(data['hubSN']['value']))
            data['encoder'].setHubPort(int(data['encoderPort']['value']))
            data['encoder'].setIsHubPortDevice(False)
            data['encoder'].setChannel(0)
            data['encoder'].openWaitForAttachment(5000)
            data['encoder'].setDataInterval(20)
            i = 0
            while i < 120:
                try:
                    data['encoder'].getPosition()
                except Exception:
                    time.sleep(1)
                    i += 1
                else:
                    break
    
        if data['accelerometerEnable']['value'] == 'true': 
            data['accelerometer'] = Accelerometer()
            data['accelerometer'].setDeviceSerialNumber(int(data['hubSN']['value']))
            data['accelerometer'].setHubPort(int(data['spatialPort']['value']))
            data['accelerometer'].setIsHubPortDevice(False)
            data['accelerometer'].setChannel(0)
            data['accelerometer'].openWaitForAttachment(5000)
            data['accelerometer'].setDataInterval(20)
            i = 0
            while i < 120:
                try:
                    data['accelerometer'].getAcceleration()
                except Exception:
                    time.sleep(1)
                    i += 1
                else:
                    break

        if data['gyroscopeEnable']['value'] == 'true': 
            data['gyroscope'] = Gyroscope()
            data['gyroscope'].setDeviceSerialNumber(int(data['hubSN']['value']))
            data['gyroscope'].setHubPort(int(data['spatialPort']['value']))
            data['gyroscope'].setIsHubPortDevice(False)
            data['gyroscope'].setChannel(0)
            data['gyroscope'].openWaitForAttachment(5000)
            data['gyroscope'].setDataInterval(20)
            i = 0
            while i < 120:
                try:
                    data['gyroscope'].getAngularRate()
                except Exception:
                    time.sleep(1)
                    i += 1
                else:
                    break

        if data['magnetometerEnable']['value'] == 'true': 
            data['magnetometer'] = Magnetometer()
            data['magnetometer'].setDeviceSerialNumber(int(data['hubSN']['value']))
            data['magnetometer'].setHubPort(int(data['spatialPort']['value']))
            data['magnetometer'].setIsHubPortDevice(False)
            data['magnetometer'].setChannel(0)
            data['magnetometer'].openWaitForAttachment(5000)
            data['magnetometer'].setDataInterval(20)
            i = 0 
            while i < 120: 
                try: 
                    data['magnetometer'].getMagneticField() 
                except Exception:
                    time.sleep(1)
                    i += 1
                else: 
                    break 

    except Exception as ex:
        _LOGGER.exception("wind_turbine exception: {}".format(str(ex)))
        raise ex

    # counter to know when to run process 
    data['tempHumCount'] = 0 
    data['currentCount'] = 0 
    data['encoderCount'] = 0 
    data['accelerometerCount'] = 0 
    data['gyroscopeCount'] = 0 
    data['magnetometerCount'] = 0 

    # counter of last encoder value 
    data['encoderPreviousValue'] = 0
    data['encoderPreviousTime'] = 0  
    return data
Ejemplo n.º 12
0
class PlotCamLiteWindow_Monitor(QMainWindow):
    def __init__(self):
        super().__init__()

        # init variables
        self.depth_cam_proc = None
        self.accelerometer = None
        self.metadata = None

        self.experiment_path = None
        self.is_streaming = multiprocessing.Value('i', False)

        self.current_plot_number = 0
        self.x = 0.0
        self.y = 0.0

        self.init_ui()
        self.title = "PlotCam Lite - %s and PyQt5" % PLATFORM

    def init_ui(self):
        """
        Initalizes the UI.
        Connects methods to the buttons and begins the background processes.
        """
        if not pcl_config["monitor"]:
            self.setFixedSize(850, 630)

        with disable_logging(logging.DEBUG):
            loadUi(pcl_config["main_window_ui_path"], self)

        # Set Window Title
        self.setWindowTitle(PROGRAM_TITLE)

        # Set Window Icon
        self.setWindowIcon(QIcon(ICON_IMAGE_PATH))

        # Add actions to menu bar
        self.add_actions()

        # Start the camera stream
        self.start_stream()

        # Start the accelerometer
        self.start_accelerometer()

        # Connect buttons to methods
        self.take_picture_button.clicked.connect(self.take_picture)
        self.exit_button.clicked.connect(self.close)
        self.new_file_button.clicked.connect(self.new_experiment_dialog)

        self.load_experiment_button.clicked.connect(self.browse_files)

        # disable the take pic btn until an experiment is set
        self.take_picture_button.setEnabled(False)

        self.alert = QSound(ALERT_AUDIO_PATH)

    def add_actions(self):
        """
        Connects the menu bar actions to their respective functions.
        """
        # File Menu
        self.actionClose.triggered.connect(self.close)

        # Edit Menu
        self.action640x480.triggered.connect(lambda: self.set_res(480, 640))
        self.action1280x720.triggered.connect(lambda: self.set_res(720, 1280))
        self.action15.triggered.connect(lambda: self.set_fps(15))
        self.action30.triggered.connect(lambda: self.set_fps(30))
        self.actionMonitor.triggered.connect(lambda: self.set_view("view"))
        self.actionVR.triggered.connect(lambda: self.set_fps(30))

        self.resGroup = QActionGroup(self)
        self.resGroup.addAction(self.action640x480)
        self.resGroup.addAction(self.action1280x720)
        self.resGroup.setExclusive(True)

        self.action640x480.setCheckable(True)
        self.action1280x720.setCheckable(True)

        if pcl_config["stream_height"] == 640:
            self.action640x480.setChecked(True)
        else:
            self.action1280x720.setChecked(True)

        self.fpsGroup = QActionGroup(self)
        self.fpsGroup.addAction(self.action15)
        self.fpsGroup.addAction(self.action30)
        self.fpsGroup.setExclusive(True)

        self.action15.setCheckable(True)
        self.action30.setCheckable(True)

        if pcl_config["stream_fps"] == 15:
            self.action15.setChecked(True)
        else:
            self.action30.setChecked(True)

        # Help Menu
        self.actionAbout.triggered.connect(self.about_dialog)
        self.actionDocumentation.triggered.connect(
            lambda: self.open_URL(HELP_DOCUMENTATION_URL))

    def open_URL(self, url):
        """
        Opens specified URL

        Args:
            url ([string]): [The URL to open, can be formatted using QUrl]
        """
        webbrowser.open(url)

    def set_res(self, width, height):
        """
        Set resolution of the stream

        Args:
            width (int): Width of the stream
            height (int): Height of the stream
        """
        self.configure_stream(width, height, pcl_config["stream_fps"])

    def set_fps(self, fps):
        """
        Set FPS of the stream

        Args:
            fps (int): Frames per Second of the stream
        """
        self.configure_stream(pcl_config["stream_width"],
                              pcl_config["stream_height"], fps)

    def set_view(self, view_type):
        """
        Set View Type of the window

        Args:
            view_type (string): View type of the window, monitor or vr
        """
        log.info("View Type Changed to " + view_type)

    def start_stream(self):
        """
        Start the camera stream.
        Creates a seperate process for the stream, and interacts with the frames through shared memory.
        Uses a QTimer to maintain a stable frame rate.
        """
        # grab config variables
        STREAM_HEIGHT = pcl_config["stream_height"]
        STREAM_WIDTH = pcl_config["stream_width"]
        STREAM_FPS = pcl_config["stream_fps"]

        # set up the label
        camera_size_policy = QSizePolicy(STREAM_WIDTH, STREAM_HEIGHT)
        self.camera_label.setSizePolicy(camera_size_policy)

        # create shared memory to hold a single frame for inter process communication,
        # wrap it in a numpy array
        nbyte_per_frame = STREAM_WIDTH * STREAM_HEIGHT * FRAME_NCHANNELS  # bytes in a frame
        log.debug("Allocating %i x %i bytes of shared memory" %
                  (SM_BUF_SIZE, nbyte_per_frame))
        self.frame_shm = shared_memory.SharedMemory(create=True,
                                                    size=nbyte_per_frame *
                                                    SM_BUF_SIZE)
        shm_shape = (SM_BUF_SIZE, STREAM_HEIGHT, STREAM_WIDTH, FRAME_NCHANNELS)
        self.frame_buffer = np.ndarray(shm_shape,
                                       dtype=np.uint8,
                                       buffer=self.frame_shm.buf)

        # spawn the child depth cam process
        self.frame_in_use = Value("i", False)
        self.pending_frame = Value("i", False)
        read_pipe, write_pipe = multiprocessing.Pipe()
        self.camera_communication_pipe = write_pipe
        self.depth_cam_proc = Process(
            target=generate_frames,
            args=(self.frame_shm.name, shm_shape, STREAM_HEIGHT, STREAM_WIDTH,
                  STREAM_FPS, self.frame_in_use, self.pending_frame, read_pipe,
                  self.is_streaming),
        )
        self.depth_cam_proc.start()
        log.info("Created depth camera process, pId = %i" %
                 self.depth_cam_proc.pid)

        # create a QTimer to manage frame updates
        self.fps_timer = QtCore.QTimer()
        self.fps_timer.setTimerType(QtCore.Qt.PreciseTimer)
        self.fps_timer.timeout.connect(self.update_stream)
        self.fps_timer.setInterval(round(1000.0 / STREAM_FPS))
        self.fps_timer.start()
        log.debug("Timer limiting FPS to %i" % STREAM_FPS)

        # just for some stats
        self.frameUpdateCount = 0
        self.stream_start_time = time.time()

        # for camera depending on accelerometer
        self.waitingForLevel = False

    def configure_stream(self, width, height, fps):
        # End exisiting stream
        pcl_config["stream_height"] = height
        pcl_config["stream_width"] = width
        pcl_config["stream_fps"] = fps

        # Tear down camera process
        self.end_stream()

        # Start stream with new values
        self.start_stream()

        log.info("The stream configuration is as follows:\n Resolution: " +
                 str(height) + "x" + str(width) + "\nFPS: " + str(fps))

    def update_stream(self):
        """
        Updates the GUI to display the current video frame.
        """
        self.frame_in_use.value = True
        pix = frame_to_pixmap(self.frame_buffer[0])
        self.camera_label.setPixmap(pix)
        self.frame_in_use.value = False
        self.frameUpdateCount += 1

    def take_picture(self):
        """
        Notifies camera process to save the next frame.
        Disables the take picture button & posts the image name and experiment path onto the shared pipe.
        (SUS) Waits till image is saved to enable the button again.
        """

        if not self.is_streaming.value:
            log.info("Cant save pic - no stream !!")
            return

        # disable take pic btn until its done
        self.take_picture_button.setEnabled(False)

        if not within_tolerance(self.x, self.y, LEVEL_TOLERANCE):
            log.info("Waiting till camera is level to take the picture")
            self.waitingForLevel = True
            return

        # write save image info to pipe
        plot_num_str = str(self.current_plot_number).zfill(PLOT_NUMBER_PADDING)
        img_name = "%s_%s" % (self.experiment_name, plot_num_str)
        log.debug("Queueing image <%s> to be saved..." % img_name)
        self.pending_frame.value = True
        self.camera_communication_pipe.send((self.experiment_path, img_name))

        # wait for image to be saved
        while (self.pending_frame.value):
            pass

        self.update_metadata()
        self.save_metadata()
        # resume normal operations
        log.debug("Image <%s> successfully saved" % img_name)
        self.update_plot_number(self.current_plot_number + 1)
        self.take_picture_button.setEnabled(True)

        self.alert.play()

        self.waitingForLevel = False

    def start_accelerometer(self):
        """
        Creates Phidget22 accelerometer and polls it at a fixed rate using a QTimer.
        """
        # set up the target image
        self.setup_target()

        # create the accelerometer, and wait 1 sec for connection
        # TODO does the open wait for attachment throw an error
        try:
            self.accelerometer = Accelerometer()
            self.accelerometer.openWaitForAttachment(1000)
            log.info("Created accelerometer")
        except:
            log.warning("There is no accelerometer connected")
            self.accelerometer = None
            return

        # create QTimer to periodically monitor the acceleration
        self.accelerometer_timer = QtCore.QTimer()
        self.accelerometer_timer.setTimerType(QtCore.Qt.PreciseTimer)
        self.accelerometer_timer.timeout.connect(self.update_target)
        self.accelerometer_timer.setInterval(ACCELEROMETER_PERIOD_MS)
        self.accelerometer_timer.start()
        log.debug("Timer limiting accelerometer update frequency to %f Hz" %
                  (1000.0 / ACCELEROMETER_PERIOD_MS))

    def setup_target(self):
        """
        Sets up the target graphic of the GUI.
        """
        self.wrapper = QWidget()
        self.target_layout = QGridLayout()
        self.target_layout.addWidget(self.wrapper)
        self.target_widget.setLayout(self.target_layout)
        self.target = Target()
        self.target.pixmap = QPixmap(TARGET_ICON_PATH)
        self.target.setGeometry(40, 0, 150, 150)
        self.target.setParent(self.wrapper)
        self.target.show()

    def update_target(self):
        """
        Update the coordinate on the GUI's target.
        """
        # TODO try-catch error
        acceleration = self.accelerometer.getAcceleration()

        self.x = acceleration[0]
        self.y = acceleration[1]

        self.target.coordinate = QPointF(self.x, self.y)
        if within_tolerance(self.x, self.y, LEVEL_TOLERANCE):
            if self.waitingForLevel:
                self.take_picture()
            self.camera_level_label.setText("Camera is Level")
            self.camera_level_label.setStyleSheet("color: green;")
        else:
            self.camera_level_label.setText("Camera is not Level")
            self.camera_level_label.setStyleSheet("color: red;")

    def about_dialog(self):
        """
        Open the "New Experiment" Dialog and connect methods to update file name and plot number labels.
        """
        about_page = AboutPage()
        about_page.exec_()
        about_page.show()

    def new_experiment_dialog(self):
        """
        Open the "New Experiment" Dialog and connect methods to update file name and plot number labels.
        """
        new_exp_page = NewExperimentPage()
        new_exp_page.expirementCreated.connect(self.update_experiment)
        new_exp_page.changePlotNumber.connect(self.update_plot_number)
        new_exp_page.exec_()
        new_exp_page.show()

    def browse_files(self):
        """
        Opens up experiment folder directory so that an existing experiment can be chosen
        """
        loaded_filename = QFileDialog.getExistingDirectory(
            self, 'Select Experiment Folder', PCL_EXP_PATH)
        self.update_experiment(basename(loaded_filename))

    @pyqtSlot(str)
    def update_experiment(self, new_exp_name):
        """
        Updates the working experiment.
        Modifys all relevant variables and paths. 
        Sets up metadata to be periodically saved to file.
        Enables button if experiment is set.
        Args:
            new_exp_name (str): The new experiment name
        """

        # make sure this is a valid experiment before updating
        new_exp_path = os.path.join(PCL_EXP_PATH, new_exp_name)
        if not self.validate_experiment(new_exp_path):
            return

        self.experiment_name = new_exp_name
        self.file_name_label.setText(self.experiment_name)
        self.experiment_path = new_exp_path

        # save old metadata before opening new experiment
        self.save_metadata()
        metadata_path = os.path.join(self.experiment_path, "Metadata",
                                     "%s.json" % self.experiment_name)
        self.metadata = Metadata(metadata_path)
        last_index = self.metadata.get_last_index()

        if last_index != -1:
            self.update_plot_number(last_index + 1)

        self.take_picture_button.setEnabled(True)

        log.info("Opened experiment %s" % self.experiment_name)

    def validate_experiment(self, exp_path):
        """
        Validates experiment at the given path.
        If no experiment exists or the experiment structure is faulty,
        Displays an error message dialog.

        Args:
            exp_path (path): path to a plotcam experiment
        Returns:
            bool: true if experiment is valid
        """
        # TODO would u want to create RGB and depth folders if they r missing
        valid = True
        errorMsg = ""
        if not os.path.exists(exp_path):
            valid = False
            errorMsg = "No experiment at %s" % exp_path
        elif not os.path.exists(os.path.join(exp_path, "Depth")):
            valid = False
            errorMsg = "Experiment missing depth data directory"
        elif not os.path.exists(os.path.join(exp_path, "RGB")):
            valid = False
            errorMsg = "Experiment missing rgb data directory"

        # dont need to validate metadata, the path will be created if it doenst exist on update exp
        if not valid:
            # error pop up
            log.info(errorMsg)
            pass

        return valid

    @pyqtSlot(int)
    def update_plot_number(self, new_plot_number):
        """ 
        Updates plot number.

        Args:
            new_plot_number (int): The new plot number
        """
        self.plot_number_label.setText(
            "Plot #: " + str(new_plot_number).zfill(PLOT_NUMBER_PADDING))
        self.current_plot_number = new_plot_number

    def update_metadata(self):
        """ 
        Updates metadata with new entry.
        """
        num = str(self.current_plot_number).zfill(PLOT_NUMBER_PADDING)
        t = datetime.now().strftime('%H:%M:%S')
        date = datetime.now().strftime('%d/%m/%Y')
        name = self.experiment_name
        self.metadata.add_entry(num, t, date, self.x, self.y, name)

    def save_metadata(self):
        """
        Saves the metadata file to disk.
        """
        if self.metadata is None:
            return

        log.info("Saving metadata")
        self.metadata.save()

    def end_stream(self):
        if self.depth_cam_proc:
            log.debug("Stream's Average FPS: %.2f" %
                      (self.frameUpdateCount /
                       (time.time() - self.stream_start_time)))

            # end depth cam process and wait for it to complete
            # TODO end the fps Qtimer
            self.is_streaming.value = False
            self.frame_in_use.value = False
            self.depth_cam_proc.join()

            # free shared memory
            self.frame_shm.close()
            self.frame_shm.unlink()
            log.info("Terminated camera process")

    def closeEvent(self, event):
        """ 
        Overrides systems "self.close" method so that the program can terminate properly.
        Teardown all running threads and processes.
        """
        # tear down accelerometer
        if self.accelerometer:
            pass

        # tear down camera process
        self.end_stream()

        log.info("PlotCamLite says goodbye :[")
from Phidget22.Devices.Accelerometer import *
from Phidget22.PhidgetException import *
from Phidget22.Phidget import *
from Phidget22.Net import *

#########################################################################
# Event Managers Definitions
#########################################################################

t = []
ac0 = []
ac1 = []
ac2 = []

try:
    ch = Accelerometer()
except RuntimeError as e:
    print("Runtime Exception %s" % e.details)
    print("Press Enter to Exit...\n")
    readin = sys.stdin.read(1)
    exit(1)


def AccelerometerAttached(e):
    try:
        attached = e
        print("\nAttach Event Detected (Information Below)")
        print("===========================================")
        print("Library Version: %s" % attached.getLibraryVersion())
        print("Serial Number: %d" % attached.getDeviceSerialNumber())
        print("Channel: %d" % attached.getChannel())