示例#1
0
class wicedsense:

    # frequency of data
    delta_t = .0125  # in seconds (preset to 12.5 ms)
    # total duration
    endtime = 5.0  # in seconds
    garbageiterations = 10

    inittime = 0
    starttimer = 0  # wait for garbageiterations before the timer starts

    calibrate = False
    calibrateMagnet = False
    accelCal = [0.0, 0.0, 0.0]
    gyroCal = [0.0, 0.0, 0.0]
    magCal = [0, 0, 0, 0, 0, 0]

    vx = 0.0
    ax = []
    dx = 0.0
    # y
    vy = 0.0
    ay = []
    dy = 0.0
    # z
    vz = 0.0
    az = []
    dz = 0.0

    gyroX = []
    gyroY = []
    gyroZ = []

    magX = []
    magY = []
    magZ = []

    magnitude = []
    timestamp = []

    def pushToCloud(self, frames, gyrodata, accel):
        #print frames[1]
        connection = httplib.HTTPSConnection("api.parse.com", 443)
        connection.connect()
        connection.request(
            'PUT', '/1/classes/Putt/12fz4AHTDK',
            json.dumps({
                "frames": frames,
                "gyro": gyrodata,
                "accel": accel
            }), {
                "X-Parse-Application-Id":
                "iAFEw9XwderX692l0DGIwoDDHcLTGMGtcBFbgMqb",
                "X-Parse-REST-API-Key":
                "I0xfoOS0nDqaHxfSBTgLNMuXGtsStl7zO0XZVDZX",
                "Content-Type": "application/json"
            })

    # Init function to connect to wiced sense using mac address
    # Blue tooth address is obtained from blescan.py
    def __init__(self, bluetooth_adr, calibrate, calibrateMagnet):
        self.con = pexpect.spawn('gatttool -b ' + bluetooth_adr +
                                 ' --interactive')
        #self.con.logfile = sys.stdout
        self.con.expect('\[LE\]>', timeout=600)
        print "Preparing to connect. You might need to press the side button..."
        self.con.sendline('connect')
        # test for success of connect
        self.con.expect('Connection successful.*\[LE\]>')
        print "Connection successful"
        self.calibrate = calibrate
        self.calibrateMagnet = calibrateMagnet
        self.cb = {}
        return

    # Function to write a value to a particular handle
    def char_write_cmd(self, handle, value):
        cmd = 'char-write-req 0x%02x 0%x' % (handle, value)
        #print cmd
        self.con.sendline(cmd)
        return

    def writeToFile(self, filename, text):
        file = open(filename, 'w')
        file.write(text)
        file.close

    def readFromFile(self, filename):
        file = open(filename, 'r')
        return file.read()

        # Notification handle = 0x002b
    def notification_loop(self):
        if (self.calibrate == False):
            calText = self.readFromFile("calibration.txt")
            calArray = calText.split(",")
            self.gyroCal = calArray[0:3]
            self.accelCal = calArray[3:]
            calText = self.readFromFile("magnetCalibration.txt")
            self.magCal = calText.split(",")
            print self.gyroCal
            print self.accelCal
            print self.magCal
            total = math.ceil(self.endtime / self.delta_t)

        # LOOP UNTIL TIME EXPIRES
        else:
            total = math.ceil(30.0 / self.delta_t)
            print "set time to 30s for calibration"

        iters = 0
        while total > iters:
            try:
                pnum = self.con.expect('Notification handle = .*? \r',
                                       timeout=4)

                # wait for the BT to settle -> wait for program to cycle through garbage iterations
                if self.starttimer == 1:
                    iters += 1

            except pexpect.TIMEOUT:
                print "TIMEOUT exception!"
                break

            try:
                if pnum == 0:
                    after = self.con.after
                    hxstr = after.split()[3:]
                    handle = long(float.fromhex(hxstr[0]))
                    self.cb[handle](
                        [long(float.fromhex(n)) for n in hxstr[2:]])
                else:
                    print "pnum not equal to 0"

            except Exception, e:
                print str(e)
                '''else:
          print "TIMEOUT!!"
          pass'''

        # After the while loop has broken...
        gyroAvg = [0, 0, 0]
        accelAvg = [0, 0, 0]
        if (self.calibrate == True):
            calText = ""
            if (self.calibrateMagnet == True):
                xOff = -(max(self.magX) + min(self.magX)) / 2
                yOff = -(max(self.magY) + min(self.magY)) / 2
                zOff = -(max(self.magZ) + min(self.magZ)) / 2
                calText += str(xOff) + "," + str(yOff) + "," + str(zOff)
                print calText
                self.writeToFile("magnetCalibration.txt", calText)
            else:
                calText = ""
                gyroAvg[0] = math.fsum(self.gyroX) / len(self.gyroX)
                gyroAvg[1] = math.fsum(self.gyroY) / len(self.gyroY)
                gyroAvg[2] = math.fsum(self.gyroZ) / len(self.gyroZ)
                accelAvg[0] = math.fsum(self.ax) / len(self.ax)
                accelAvg[1] = math.fsum(self.ay) / len(self.ay)
                accelAvg[2] = math.fsum(self.az) / len(self.az)
                calText += str(0 - gyroAvg[0]) + "," + str(
                    0 - gyroAvg[1]) + "," + str(0 - gyroAvg[2]) + ","
                calText += str(0 - accelAvg[0]) + "," + str(
                    0 - accelAvg[1]) + "," + str(8192 - accelAvg[2])
                self.writeToFile("calibration.txt", calText)

        else:
            # FILTER OUT INITIAL ACCELERATION VALUES --------------
            thresh = 9.9  # accel treshold must be exceeded to indicate putt has begun (m/s^2)
            axnew = []  # new acceleration list in the x direction
            aynew = []  # ... y direction
            aznew = []  # ... z direction
            accelNew = []
            gyroXnew = []
            gyroYnew = []
            gyroZnew = []
            magnew = []

            for x in range(len(self.magnitude)):
                print self.magnitude[x]
                #if self.magnitude[x] > thresh:
                if True:
                    print "PUTTING................."
                    axnew = self.ax[x:]
                    aynew = self.ay[x:]
                    aznew = self.az[x:]
                    magnew = self.magnitude[x:]
                    gyroXnew = self.gyroX[x:]
                    gyroYnew = self.gyroY[x:]
                    gyroZnew = self.gyroZ[x:]
                    #self.magX = self.magX[x:]
                    #self.magY = self.magY[x:]
                    #self.magZ = self.magZ[x:]
                    break

            # ========================
            # GET DISPLACEMENT FRAMES
            # ========================

            for x in range(len(axnew)):
                accelNew.append([axnew[x], aynew[x], aznew[x], magnew[x]])

            roll = []
            pitch = []
            yaw = []
            roll.append(MathUtil.roll(axnew[0], aynew[0], aznew[0]))
            pitch.append(MathUtil.pitch(axnew[0], aynew[0], aznew[0]))
            #yaw.append(MathUtil.yaw(roll[0], pitch[0], self.magX[0], self.magY[0], self.magZ[0]))
            for x in range(1, len(axnew)):
                roll.append(MathUtil.roll(axnew[x], aynew[x], aznew[x]))
                pitch.append(MathUtil.pitch(axnew[x], aynew[x], aznew[x]))
                #yaw.append(MathUtil.yaw(roll[x], pitch[x], self.magX[x], self.magY[x], self.magZ[x]))

            # OUTPUT TO SCREEN ------------------
            '''
      print "axnew:"
      for x in range(0,len(axnew)): print axnew[x]
      print

      print "axnew length"
      print len(axnew)
      print

      print "xyzframes (frame indicates the x displacement in meters at a given time):"
      for x in range(0,len(xyzframes)): print xyzframes[x]
      print
      
      print "total duration (in s) "
      print (float(len(axnew)))*delta_t
      print

      print "total samples"
      print int (len(axnew)) + 1 # add one for time 0
      print

      '''

            #Kalman filtering
            gyrodata = []
            kalmanX = kalman.Kalman(roll[0])
            kalmanY = kalman.Kalman(pitch[0])

            gyrodata.append([roll[0], pitch[0], 0.0])
            zAngle = [0.0]
            xAngle = [0.0]
            yAngle = [0.0]
            time = [0.0]
            data = [0.0]
            angle = [0.0]
            for x in range(1, len(gyroXnew)):
                time.append(time[-1] + self.delta_t)
                data.append(MathUtil.getAngle(gyroZnew[x], self.delta_t))
                xAngle.append(xAngle[-1] +
                              MathUtil.getAngle(gyroXnew[x], self.delta_t))
                yAngle.append(yAngle[-1] +
                              MathUtil.getAngle(gyroYnew[x], self.delta_t))
                zAngle.append(zAngle[-1] + data[-1])
                gyrodata.append([
                    kalmanX.updateAngle(roll[x], gyroXnew[x], self.delta_t),
                    kalmanY.updateAngle(pitch[x], gyroYnew[x], self.delta_t),
                    zAngle[x]
                ])

            accelRot = MathUtil.rotateAcceleration(
                [axnew, aynew, aznew],
                [[i[0] for i in gyrodata[:]], [i[1] for i in gyrodata[:]],
                 [i[2] for i in gyrodata[:]]])

            #displacement calculations
            xframes = [
                MathUtil.displacement(self.dx, self.vx, accelRot[0][0],
                                      self.delta_t)[0]
            ]
            yframes = [
                MathUtil.displacement(self.dy, self.vy, accelRot[1][0],
                                      self.delta_t)[0]
            ]
            zframes = [
                MathUtil.displacement(self.dz, self.vz, accelRot[2][0],
                                      self.delta_t)[0]
            ]
            xyzframes = [[xframes[-1], yframes[-1], zframes[-1]]]
            for x in range(1, len(gyroXnew)):
                self.dx, self.vx = MathUtil.displacement(
                    self.dx, self.vx, accelRot[0][x], self.delta_t)
                xframes.append(float(xframes[-1] + self.dx))
                self.dy, self.vy = MathUtil.displacement(
                    self.dy, self.vy, accelRot[1][x], self.delta_t)
                yframes.append(float(yframes[-1] + self.dy))
                self.dz, self.vz = MathUtil.displacement(
                    self.dz, self.vz, accelRot[2][x], self.delta_t)
                zframes.append(float(zframes[-1] + self.dz))
                xyzframes.append([xframes[-1], yframes[-1], zframes[-1]])
                accelNew[x] = [
                    accelRot[0][x], accelRot[1][x], accelRot[2][x],
                    accelNew[x][3]
                ]

            # =======================
            # PUSH FRAMES TO PARSE
            # =======================
            self.pushToCloud(xyzframes, gyrodata, accelNew)

        self.resetVars()