Exemplo n.º 1
0
def example1():
    """
    Test Kalman Filter implementation
    :return:
    """
    dt = 1.0 / 60
    F = np.array([[1, dt, 0], [0, 1, dt], [0, 0, 1]])
    H = np.array([1, 0, 0]).reshape(1, 3)
    Q = np.array([[0.05, 0.05, 0.0], [0.05, 0.05, 0.0], [0.0, 0.0, 0.0]])
    R = np.array([0.5]).reshape(1, 1)

    x = np.linspace(-10, 10, 100)
    measurements = -(x**2 + 2 * x - 2) + np.random.normal(0, 2, 100)
    kf = KalmanFilter(F=F, H=H, Q=Q, R=R)
    predictions = []

    for z in measurements:
        predictions.append(np.dot(H, kf.predict())[0])
        kf.update(z)

    plt.plot(range(len(measurements)), measurements, label='Measurements')
    plt.plot(range(len(predictions)),
             np.array(predictions),
             label='Kalman Filter Prediction')
    plt.legend()
    plt.show()
Exemplo n.º 2
0
def main():

    # Create opencv video capture object
    VideoCap = cv2.VideoCapture('video/randomball.avi')

    #Variable used to control the speed of reading the video
    ControlSpeedVar = 100  #Lowest: 1 - Highest:100

    HiSpeed = 100

    #Create KalmanFilter object KF
    #KalmanFilter(dt, u_x, u_y, std_acc, x_std_meas, y_std_meas)

    KF = KalmanFilter(0.1, 1, 1, 1, 0.1, 0.1)

    debugMode = 1

    while (True):
        # Read frame
        ret, frame = VideoCap.read()

        # Detect object
        centers = detect(frame, debugMode)

        # If centroids are detected then track them
        if (len(centers) > 0):

            # Draw the detected circle
            cv2.circle(frame, (int(centers[0][0]), int(centers[0][1])), 10,
                       (0, 191, 255), 2)

            # Predict
            (x, y) = KF.predict()
            # Draw a rectangle as the predicted object position
            cv2.rectangle(frame, (int(x) - 15, int(y) - 15),
                          (int(x) + 15, int(y) + 15), (255, 0, 0), 2)

            # Update
            (x1, y1) = KF.update(centers[0])

            # Draw a rectangle as the estimated object position
            cv2.rectangle(frame, (int(x1) - 15, int(y1) - 15),
                          (int(x1) + 15, int(y1) + 15), (0, 0, 255), 2)

            cv2.putText(frame, "Estimated Position",
                        (int(x1) + 15, int(y1) + 10), 0, 0.5, (0, 0, 255), 2)
            cv2.putText(frame, "Predicted Position", (int(x) + 15, int(y)), 0,
                        0.5, (255, 0, 0), 2)
            cv2.putText(frame, "Measured Position",
                        (int(centers[0][0]) + 15, int(centers[0][1]) - 15), 0,
                        0.5, (0, 191, 255), 2)

        cv2.imshow('image', frame)

        if cv2.waitKey(2) & 0xFF == ord('q'):
            VideoCap.release()
            cv2.destroyAllWindows()
            break

        cv2.waitKey(HiSpeed - ControlSpeedVar + 1)
Exemplo n.º 3
0
class VelocityFilter:
    def __init__(self, dt):
        self.filter = KalmanFilter()

        self.filter.F = np.kron(np.array([[1., dt], [0., 1.]]), np.eye(2))
        self.filter.H = np.kron(np.array([1., 0.]), np.eye(2))

        self.filter.P = np.diag([1., 1., 1e-9, 1e-9])
        self.filter.Q = np.kron(np.diag([1e-9] * 2), np.eye(2))
        self.filter.R = np.diag([5.0] * 2)

        self.filter.xhat = np.array([0., 0., 0., 0.])

    def predict(self):
        return self.filter.predict()

    def update(self, meas):
        return self.filter.update(meas)

    def run(self, meas):
        self.update(meas)
        return self.predict()
Exemplo n.º 4
0
    pos = (i, i)
    ra, rb = d.range_of(pos)
    rx, ry = d.range_of((i + f1.x[0, 0], i + f1.x[2, 0]))

    print('range =', ra, rb)

    z = np.mat([[ra - rx], [rb - ry]])
    print('z =', z)

    f1.H = H_of(pos, pos_a, pos_b)
    print('H =', f1.H)

    ##f1.update (z)

    print(f1.x)
    xs.append(f1.x[0, 0] + i)
    ys.append(f1.x[2, 0] + i)
    pxs.append(pos[0])
    pys.append(pos[1])
    f1.predict()
    print(f1.H * f1.x)
    print(z)
    print(f1.x)
    f1.update(z)
    print(f1.x)

p1, = plt.plot(xs, ys, 'r--')
p2, = plt.plot(pxs, pys)
plt.legend([p1, p2], ['filter', 'ideal'], 2)
plt.show()
    pos = (i, i)
    ra, rb = d.range_of(pos)
    rx, ry = d.range_of((i + f1.x[0, 0], i + f1.x[2, 0]))

    print('range =', ra, rb)

    z = np.mat([[ra - rx], [rb - ry]])
    print('z =', z)

    f1.H = H_of(pos, pos_a, pos_b)
    print('H =', f1.H)

    ##f1.update (z)

    print(f1.x)
    xs.append(f1.x[0, 0] + i)
    ys.append(f1.x[2, 0] + i)
    pxs.append(pos[0])
    pys.append(pos[1])
    f1.predict()
    print(f1.H * f1.x)
    print(z)
    print(f1.x)
    f1.update(z)
    print(f1.x)

p1, = plt.plot(xs, ys, 'r--')
p2, = plt.plot(pxs, pys)
plt.legend([p1, p2], ['filter', 'ideal'], 2)
plt.show()
Exemplo n.º 6
0
from KalmanFilter import KalmanFilter
import time
kf = KalmanFilter()
kf.update(5)
print kf.predict()
time.sleep(.2)
kf.update(5.5)
print kf.predict()

time.sleep(.2)
kf.update(6)
print kf.predict()

time.sleep(.2)
kf.update(6.5)
print kf.predict()

time.sleep(.2)
kf.update(7)
print kf.predict()

time.sleep(.2)
kf.update(15)
print kf.predict()

time.sleep(.2)
kf.update(8.5)
print kf.predict()

time.sleep(.2)
kf.update(7)
def main():
   params = check_params(parse_args(sys.argv[1:]))
   kf = KalmanFilter()

   if params['file']:
      template = read_template(params)

   surf, flann = init_surf()
   kp, des = surf.detectAndCompute(template, None)

   #Start up Video processing thread
   vs = PiVideoStream(resolution=(params['xRes'], params['yRes'])).start()

   #Wait for camera to warm up
   time.sleep(3.0)

   #Used for calculating FPS
   startTime = time.time()
   if params['capTime'] == 0:
      endTime = startTime + 1000000000
   else:
      endTime = startTime + params['capTime']
   frames = 0

   # Open up serial port with Pixhawk
   if params['sendToPX4']:
      port = serial.Serial('/dev/ttyAMA0', 57600)
      mav = mavlink.MAVLink(port)

   # Typically only need to search within a small Y-range
   yRes = params['yRes']
   (cropYmin, cropYmax) = (yRes * .25, yRes * .70)

   #Take weighted average of last # of distances to filter out noise
   notFoundCount = 1000

   while time.time() < endTime:
      frames += 1
      frame = vs.read()
      frame = frame[cropYmin : cropYmax, 0:params['xRes']]

      found, [x,y], frame = FindingFuncs.findPatternSURF(frame, surf, kp, des, template, flann, params['preview'])

      # Count how many frames it has been since the RPi has not found anything
      if not found:
         notFoundCount += 1
      else:
         notFoundCount = 0
         kf.update(x)

      # How many frames until you assume to keep going straight.
      if notFoundCount > 100:
         kf.reset()
         x = params['xRes'] / 2
      else:      
         x = kf.predict()

      loc = boundFloat(2.0 * x / params['xRes'] - 1, -1., 1.)

      if params['sendToPX4']:
         message = mavlink.MAVLink_duck_leader_loc_message(loc, 5.0)
         mav.send(message)

      if params['debug'] :
         print str(time.time() - startTime) + ", " + str(loc)

      if params['preview']:
         # Draw a circle on frame where the Kalman filter predicts.
         cv2.circle(frame, (int(x), 10), 4, (0, 0, 255), 6)

         frame = imutils.resize(frame, width=1000)
         cv2.imshow("Preview", frame)

      #Check for keypress, ending if Q is entered
      key = cv2.waitKey(1) & 0xFF
      if (key == ord("q")):
         break;
      
   totalTime = time.time() - startTime
   cv2.destroyAllWindows()

   vs.stop()

   print "Average main FPS: " + str(float(frames) / totalTime) + "fps"
def main():
    # Create opencv video capture object
    # VideoCap = cv2.VideoCapture('./video/randomball.avi')
    VideoCap = cv2.VideoCapture('./video/multi.mp4')
    # VideoCap = cv2.VideoCapture('./video/cars2.mp4')
    frame_width = int(VideoCap.get(3))
    frame_height = int(VideoCap.get(4))
    fps = VideoCap.get(cv2.CAP_PROP_FPS)
    outVid = cv2.VideoWriter('trackedObjects.avi',
                             cv2.VideoWriter_fourcc('M', 'J', 'P', 'G'), fps,
                             (frame_width, frame_height))
    largestDistance = math.sqrt(frame_width**2 + frame_height**2)
    # Variable used to control the speed of reading the video
    ControlSpeedVar = 100  # Lowest: 1 - Highest:100

    HiSpeed = 100

    # Create KalmanFilter object KF
    #KalmanFilter(dt, u_x, u_y, std_acc, x_std_meas, y_std_meas)

    # debugMode = 1
    debugMode = 0

    KFs = []
    KFs_used = []
    j = 0
    while (True):
        j += 1
        # Read frame
        ret, frame = VideoCap.read()
        if not ret and cv2.waitKey(2) & 0xFF == ord('q'):
            outVid.release()
            VideoCap.release()
            cv2.destroyAllWindows()
            break

        # Detect object
        try:
            centers = detect(frame, debugMode)
        except:
            outVid.release()
            VideoCap.release()
            cv2.destroyAllWindows()
            break

        # If centroids are detected then track them
        if (len(centers) > 0):
            # getting rid of unused Kalman Filters
            temp = KFs.copy()
            KFs = []
            for i in range(len(temp)):
                if (KFs_used[i]):
                    KFs.append(temp[i])
            gc.collect()
            # predict all KFs
            predicted_x, predicted_y = predictKFs(KFs)
            KFs_used = [False] * len(KFs)
            for i in range(len(centers)):
                # Draw the detected circle
                cv2.circle(frame, (int(centers[i][0]), int(centers[i][1])), 10,
                           (0, 191, 255), 2)

                curr_KF = getClosestKF(centers[i][0], centers[i][1],
                                       predicted_x, predicted_y,
                                       largestDistance / 24)
                if (curr_KF < 0):
                    KF = KalmanFilter(1.0 / fps, 1, 1, 1, 0.1, 0.1)
                    x, y = KF.predict()
                    KFs.append(KF)
                    KFs_used.append(True)
                else:
                    KF = KFs[curr_KF]
                    KFs_used[curr_KF] = True
                    x, y = predicted_x[curr_KF], predicted_y[curr_KF]

                # Draw a rectangle as the predicted object position
                x, y = int(x), int(y)
                cv2.rectangle(frame, (x - 15, y - 15), (x + 15, y + 15), (
                    255,
                    0,
                ), 2)

                # Update
                (x1, y1) = KF.update(centers[i])
                x1, y1 = int(x1), int(y1)
                # Draw a rectangle as the estimated object position
                cv2.rectangle(frame, (x1 - 15, y1 - 15), (x1 + 15, y1 + 15),
                              (0, 0, 255), 2)

                cv2.putText(frame, "Estimated Position" + str(i),
                            (x1 + 15, y1 + 10), 0, 0.5, (0, 0, 255), 2)
                cv2.putText(frame, "Predicted Position" + str(i), (x + 15, y),
                            0, 0.5, (255, 0, 0), 2)
                cv2.putText(frame, "Measured Position" + str(i),
                            (int(centers[i][0] + 15), int(centers[i][1] - 15)),
                            0, 0.5, (0, 191, 255), 2)

        cv2.imshow('image', frame)
        outVid.write(frame)

        cv2.waitKey(HiSpeed - ControlSpeedVar + 1)
class KalmanAgent(Agents.Agent):

    def __init__(self, tank_index, target_color, state):
        self.state = state
        self.target_color = target_color
        self.tank_index = tank_index
        self.pdc = PDController()
        self.timer_id = Timer.add_task(self.update)
        self.kvis = KalmanVisualizer(800, 800)
        self.kfilter = KalmanFilter()

    def update(self):
        # update state
        self.state.update_mytanks()
        self.state.update_othertanks()

        tank = self.state.mytanks['0']
        angvel = self.getAngvelToTarget(tank)

        tank.set_angvel(angvel)

    def getAngvelToTarget(self, tank):
        """
        Calculates the vector that we should be facing to kill the target, then uses the PDController to find the
        angular velocity required to face the target.
        This calculation is performed like this:
        1. Use the Kalman Filter to get the predicted location of the target.
        2. Add to that vector the distance that the target will travel while the bullet fires.
        3. Pass the vector into the PDController to find the angular velocity that we need to face the right way
        :return float: the angular velocity that we need in order to correctly face the target.
        """
        # get newest data about target
        target = self.state.othertanks[self.target_color][0]

        # get the angle to the target

        # step 1: Kalman Filter
        ut, width, height = self.kfilter.update(npy.array([[target.x], [target.y]]))
        xpos, xvel, xacc, ypos, yvel, yacc = ut

        # step 2: bullet travel time
        t = math.sqrt((tank.x - target.x) ** 2 + (tank.y - target.y) ** 2) / 100
        hitzone_x = xpos + xvel*t + 0.5  # * xacc * t**2 + 100 * math.cos(tank.x) * t
        hitzone_y = ypos + yvel*t + 0.5  # * yacc * t**2 + 100 * math.sin(tank.y) * t
        self.kvis.update(xpos, ypos, width, target.x, target.y, hitzone_x, hitzone_y)


        # step 3: PDController to find angular velocity
        ang = self.ang(hitzone_x, hitzone_y)
        # print ang
        if abs(math.pi + tank.angle - ang) < 0.1:
            tank.shoot()
        target_vec = [-math.cos(ang), -math.sin(ang)]
        next_action = self.pdc.get_next_action(self.state.mytanks[self.tank_index], target_vec)
        return next_action['angvel']

    def ang(self, x, y):
        tank = self.state.mytanks['0']
        angle = math.atan2(tank.y - y, tank.x - x)
        '''Make any angle be between +/- pi.'''
        angle -= 2 * math.pi * int(angle / (2 * math.pi))
        if angle <= -math.pi:
            angle += 2 * math.pi
        elif angle > math.pi:
            angle -= 2 * math.pi
        return angle
Exemplo n.º 10
0
class KalmanBoxTracker(object):
    """
  This class represents the internel state of individual tracked objects observed as bbox.
  """
    count = 0

    def __init__(self, bbox):
        """
    Initialises a tracker using initial bounding box.
    """
        #define constant velocity model
        self.kf = KalmanFilter(dim_x=7, dim_z=4)
        self.kf.F = np.array([[1, 0, 0, 0, 1, 0, 0], [0, 1, 0, 0, 0, 1, 0],
                              [0, 0, 1, 0, 0, 0, 1], [0, 0, 0, 1, 0, 0, 0],
                              [0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 1, 0],
                              [0, 0, 0, 0, 0, 0, 1]])
        self.kf.H = np.array([[1, 0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0],
                              [0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0]])

        self.kf.R[2:, 2:] *= 10.
        self.kf.P[
            4:,
            4:] *= 1000.  #give high uncertainty to the unobservable initial velocities
        self.kf.P *= 10.
        self.kf.Q[-1, -1] *= 0.01
        self.kf.Q[4:, 4:] *= 0.01

        self.kf.x[:4] = convert_bbox_to_z(bbox)
        self.time_since_update = 0
        self.id = KalmanBoxTracker.count
        KalmanBoxTracker.count += 1
        self.history = []
        self.hits = 0
        self.hit_streak = 0
        self.age = 0

    def update(self, bbox):
        """
    Updates the state vector with observed bbox.
    """
        self.time_since_update = 0
        self.history = []
        self.hits += 1
        self.hit_streak += 1
        self.kf.update(convert_bbox_to_z(bbox))

    def predict(self):
        """
    Advances the state vector and returns the predicted bounding box estimate.
    """
        if ((self.kf.x[6] + self.kf.x[2]) <= 0):
            self.kf.x[6] *= 0.0
        self.kf.predict()
        self.age += 1
        if (self.time_since_update > 0):
            self.hit_streak = 0
        self.time_since_update += 1
        self.history.append(convert_x_to_bbox(self.kf.x))
        return self.history[-1]

    def get_state(self):
        """
    Returns the current bounding box estimate.
    """
        return convert_x_to_bbox(self.kf.x)
Exemplo n.º 11
0
class KalmanFilterSimulatorWindow(AnimationWindow):
    """
	The mouse motion tracking window and some GUI input widgets.
	"""
    def helperWidget(self):
        """
		GUI designer function, 
		The Canvas is the main window, Some helper Widget is added
		on the side of the canvas. 
		"""

        # Intall Pause button, default button, restart button and a check button
        # on the frame to better organise the interface.
        self.frameTop = tk.Frame()
        self.frameTop.pack(anchor=tk.NW, side=tk.TOP, pady=25)

        self.pauseButton = tk.Button(master=self.frameTop,
                                     text="Pause",
                                     width=8,
                                     command=self.pauseClick)
        self.pauseButton.pack(anchor=tk.NE, side=tk.LEFT, padx=5)

        self.defaultButton = tk.Button(master=self.frameTop,
                                       text="Restore Default Values",
                                       command=self.restoreClick)
        self.defaultButton.pack(anchor=tk.NW, side=tk.LEFT, padx=5)

        self.restartButton = tk.Button(master=self.frameTop,
                                       text="Restart",
                                       command=self.restartClick)
        self.restartButton.pack(anchor=tk.NW, side=tk.LEFT, padx=5)

        self.showMouseTraceButtonOn = tk.BooleanVar()
        self.showMouseTraceButton = tk.Checkbutton(
            master=self.frameTop,
            text="Show Mouse Trace",
            variable=self.showMouseTraceButtonOn,
            command=self.showMouseTrace)
        self.showMouseTraceButton.pack(anchor=tk.NW, side=tk.LEFT, padx=5)

        # setup the instance of Entry
        self.entries = OrderedDict()
        self.entries["A"] = [[0] * 4 for i in range(4)]
        self.entries["B"] = [[0] * 4 for i in range(4)]
        self.entries["H"] = [[0] * 4 for i in range(4)]
        self.entries["Q"] = [[0] * 4 for i in range(4)]
        self.entries["R"] = [[0] * 4 for i in range(4)]
        self.entries["N"] = [[0] * 4 for i in range(4)]
        self.code2entries = {0: "A", 1: "B", 2: "H", 3: "Q", 4: "R", 5: "N"}

        # Install Entries of Matrix A, B, H on the medium top frame beneath the top frame.

        self.frameMediumTop = tk.Frame()
        self.frameMediumTop.pack(anchor=tk.NW, side=tk.TOP, pady=10)

        for _ in range(3):
            # Frame1 hold entries of matrix A, B, H in each iteration
            self.frame1 = tk.Frame(master=self.frameMediumTop)
            self.frame1.pack(anchor=tk.NW, side=tk.LEFT, padx=10)

            for i in range(5):
                self.frame2 = tk.Frame(master=self.frame1)
                self.frame2.pack(anchor=tk.NW, side=tk.TOP)
                if i == 4:

                    if _ == 0:
                        label = tk.Label(master=self.frame1,
                                         text="A matrix\nState Transition")
                        label.pack(anchor=tk.NW, side=tk.LEFT, padx=2)
                    elif _ == 1:
                        label = tk.Label(master=self.frame1,
                                         text="B matrix\nInput Control")
                        label.pack(anchor=tk.NW, side=tk.LEFT, padx=2)
                    elif _ == 2:
                        label = tk.Label(master=self.frame1,
                                         text="H matrix\nMeasurement")
                        label.pack(anchor=tk.NW, side=tk.LEFT, padx=2)

                else:

                    for j in range(4):
                        self.entries[self.code2entries[_]][i][j] = tk.Entry(
                            master=self.frame2, width=3)
                        self.entries[self.code2entries[_]][i][j].pack(
                            anchor=tk.NW, side=tk.LEFT, padx=1)

        # Install Entries of Matrix Q, R, N on the medium top frame beneath the medium top frame.
        self.frameMediumBottom = tk.Frame()
        self.frameMediumBottom.pack(anchor=tk.NW, side=tk.TOP)

        for _ in range(3, 6):
            # Frame1 hold entries of matrix Q, R, N in each iteration
            self.frame1 = tk.Frame(master=self.frameMediumBottom)
            self.frame1.pack(anchor=tk.NW, side=tk.LEFT, padx=10)

            for i in range(5):
                self.frame2 = tk.Frame(master=self.frame1)
                self.frame2.pack(anchor=tk.NW, side=tk.TOP)
                if i == 4:

                    if _ == 3:
                        label = tk.Label(master=self.frame1,
                                         text="Q matrix\nAction Uncertainty")
                        label.pack(anchor=tk.NW, side=tk.LEFT, padx=2)
                    elif _ == 4:
                        label = tk.Label(master=self.frame1,
                                         text="R matrix\nSensor Noise")
                        label.pack(anchor=tk.NW, side=tk.LEFT, padx=2)
                    elif _ == 5:
                        label = tk.Label(master=self.frame1,
                                         text="N matrix\nDistrubation")
                        label.pack(anchor=tk.NW, side=tk.LEFT, padx=2)

                else:

                    for j in range(4):
                        self.entries[self.code2entries[_]][i][j] = tk.Entry(
                            master=self.frame2, width=3)
                        self.entries[self.code2entries[_]][i][j].pack(
                            anchor=tk.NW, side=tk.LEFT, padx=1)

        # Install a slider bar on the bottom frame
        self.frameBottom = tk.Frame()
        self.frameBottom.pack(anchor=tk.NW, side=tk.TOP, pady=50)

        label = tk.Label(master=self.frameBottom, text="Fade-Out Time (sec):")
        label.pack(anchor=tk.NW, side=tk.TOP, padx=10, pady=0)

        # Life time for the fading-out points
        self.lifetime = 4
        self.lifetimeScale = tk.Scale(self.frameBottom,
                                      from_=0.1,
                                      to=8,
                                      length=200,
                                      orient=tk.HORIZONTAL,
                                      resolution=0.1,
                                      command=self.onScale)
        # initialize the scale
        self.lifetimeScale.set(self.lifetime)
        self.lifetimeScale.pack(anchor=tk.NW, side=tk.TOP, padx=10, pady=0)

    def setup(self):
        """
		Setup the intial condition for the Kalman Filter, 
		"""

        self.mouseX, self.mouseY = 0, 0
        self.premouseX, self.premouseY = 0, 0

        # delta_t
        self.A = np.array([[1, 0, self.frame_time, 0],
                           [0, 1, 0, self.frame_time], [0, 0, 1, 0],
                           [0, 0, 0, 1]])

        # no control unit
        self.B = np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0],
                           [0, 0, 0, 1]])

        # measurement unit
        self.H = np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0],
                           [0, 0, 0, 1]])

        # model noise
        self.Q = np.array([[0.01, 0, 0, 0], [0, 0.01, 0, 0], [0, 0, 0.01, 0],
                           [0, 0, 0, 0.01]])

        # measurement noise
        self.R = np.array([[0.1, 0, 0, 0], [0, 0.1, 0, 0], [0, 0, 0.1, 0],
                           [0, 0, 0, 0.1]])

        # Noise to disturb the true position of the mouse
        self.N = np.array([[100, 0, 0, 0], [0, 100, 0, 0], [0, 0, 0, 0],
                           [0, 0, 0, 0]])

        # current state
        self.cur_x = np.array([self.mouseX, self.mouseY, 0, 0])

        # current error covariance matrix
        self.cur_P = np.array([[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0],
                               [0, 0, 0, 0]])

        # Record the default value.
        self.Adefault = self.A.copy()
        self.Bdefault = self.B.copy()
        self.Hdefault = self.H.copy()
        self.Qdefault = self.Q.copy()
        self.Rdefault = self.R.copy()
        self.Ndefault = self.N.copy()

        # control unit, For this case there is no control unit
        self.control = np.array([0, 0, 0, 0])

        # rPoint: record the measurement, the measurement is created
        #         by the true hidden state with Gaussian noise
        # kPoint: store the positions of points from estimation of the Kalman filter
        # tPoint: record true position of the mouse
        self.rPoints = deque()
        self.kPoints = deque()
        self.tPoints = deque()
        # self.pPoints = deque()

        self.running = True

        # I commented out the prediction line as it seems not very useful from my point of view.
        # But I add the true mouse position.
        # self.predictionOn = True

        self.mousepositionOn = self.showMouseTraceButtonOn.get()

        # Instance of the Kalman filter,
        self.kfmodel = KalmanFilter(self.A, self.B, self.H, self.Q, self.R,
                                    self.cur_x, self.cur_P)

        # Intialize the entries,
        # TO THINK: there is a better way? better to put it in a helperWidget() fucntion,
        #           as this function is used to design graphic interface...
        self.setMatrix("A", self.Adefault)
        self.setMatrix("B", self.Bdefault)
        self.setMatrix("H", self.Hdefault)
        self.setMatrix("Q", self.Qdefault)
        self.setMatrix("R", self.Rdefault)
        self.setMatrix("N", self.Ndefault)

    def draw(self):
        """
		Update the canvas in each frame per second.
		"""

        if not self.running:
            return

        # Clean the Canvas first.
        self.canvas.delete(tk.ALL)

        # Receive the values from the entries of each matrix.
        # Is there a better to do that? As if I don't modify the matrix,
        # I don't need to read the entries every time.
        # Is there a callback function of the Entry object? NO...,
        # https://stackoverflow.com/questions/6548837/how-do-i-get-an-event-callback-when-a-tkinter-entry-widget-is-modified
        # There is a solution, But it adds some complexities. I don't like it.
        self.modifyMatrix("A")
        self.modifyMatrix("B")
        self.modifyMatrix("H")
        self.modifyMatrix("Q")
        self.modifyMatrix("R")
        self.modifyMatrix("N")
        self.kfmodel.A = self.A
        self.kfmodel.B = self.B
        self.kfmodel.H = self.H
        self.kfmodel.Q = self.Q
        self.kfmodel.R = self.R

        # the core of this code... ....
        #**************** Kalman Filter *******************#
        # Hidden State
        self.curState = np.array([
            self.mouseX, self.mouseY,
            (self.mouseX - self.premouseX) / self.frame_time,
            (self.mouseY - self.premouseY) / self.frame_time
        ])
        # Gaussian Noise
        self.measureNoise = np.random.multivariate_normal([0, 0, 0, 0], self.N)
        # Apply measurement, z_k = H_k * x_k + V_k
        self.measureState = np.dot(self.H, self.curState) + self.measureNoise

        self.kfmodel.update(self.measureState, self.control)
        #***************       END       ******************#

        # Store the measured, estimated, and mouse position points
        # to the deque
        self.rPoints.append(
            Point(self, self.measureState[0], self.measureState[1],
                  [255, 255, 255], self.lifetime))

        self.kPoints.append(
            ConnectedPoint(self, self.kfmodel.cur_x[0], self.kfmodel.cur_x[1],
                           [0, 255, 0], self.lifetime, self.kfmodel.last_x[0],
                           self.kfmodel.last_x[1]))

        if self.mousepositionOn:
            self.tPoints.append(
                ConnectedPoint(self, self.mouseX, self.mouseY, [0, 0, 255],
                               self.lifetime, self.premouseX, self.premouseY))

        # Draw points in the deque, pop out those points which are dead
        def drawPoints(pointDeque):
            count_dead = 0
            for point in pointDeque:
                if point.isAlive():
                    point.draw()
                else:
                    count_dead += 1
            for _ in range(count_dead):
                pointDeque.popleft()

        drawPoints(self.rPoints)
        drawPoints(self.kPoints)
        if self.mousepositionOn:
            drawPoints(self.tPoints)
        ###############################

        # Not very useful... to show the status of state.
        #self.showStatus()

        # keep track of the current mouse position as previous mouse position
        self.premouseX, self.premouseY = self.mouseX, self.mouseY

    def mousemotion(self, mouseposition):
        """
		store the mouse position 
		"""
        self.mouseX, self.mouseY = mouseposition[0], mouseposition[1]

    def pauseClick(self):
        """
		pause or resume animation
		"""
        self.running = not self.running
        if self.running:
            self.pauseButton.config(relief=tk.RAISED, text="Pause")
        else:
            self.pauseButton.config(relief=tk.SUNKEN, text="Resume")

    def restartClick(self):
        """
		restart the animation
		"""
        self.setup()

    def restoreClick(self):
        """
		restore to the default value...
		"""
        self.lifetime = 4
        self.lifetimeScale.set(self.lifetime)

        self.setMatrix("A", self.Adefault)
        self.setMatrix("B", self.Bdefault)
        self.setMatrix("H", self.Hdefault)
        self.setMatrix("Q", self.Qdefault)
        self.setMatrix("R", self.Rdefault)
        self.setMatrix("N", self.Ndefault)

    def showMouseTrace(self):
        """
		toggle the trace of mouse
		"""
        if self.showMouseTraceButtonOn.get() == True:
            self.mousepositionOn = True
        else:
            self.mousepositionOn = False

    def onScale(self, value):
        """
		Fade out time
		"""
        self.lifetime = float(value)

    def setMatrix(self, id, vals):
        """
		set the values of the matrix
		"""
        for i in range(len(vals)):
            for j in range(len(vals[0])):
                self.entries[id][i][j].delete(0, tk.END)
                self.entries[id][i][j].insert(0, vals[i, j])

    def modifyMatrix(self, id):
        """
		modify the matrix according to the GUI input.
		"""
        switcher = {
            "A": self.A,
            "B": self.B,
            "H": self.H,
            "Q": self.Q,
            "R": self.R,
            "N": self.N
        }

        for i in range(4):
            for j in range(4):
                # The following state make sure even the entry is empty, it
                # can still work. Alphabic characters are not alowed.
                if self.entries[id][i][j].get() == "":
                    switcher[id][i, j] = 1.0
                else:
                    switcher[id][i, j] = float(self.entries[id][i][j].get())

    def showStatus(self):
        """
		Print the status of the mouse (position and velocity), 
		the Kalman filter estimation of the status of the mouse
		"""
        statustext = """Mouse status, (x, y, velx, vely) = ({0:7.0f}, {1:7.0f}, {2:7.2f}, {3:7.2f})\n
Kalman filter estimation            = ({4:7.0f}, {5:7.0f}, {6:7.2f}, {7:7.2f})\n""".format(
            self.curState[0], self.curState[1], self.curState[2],
            self.curState[3], self.kfmodel.cur_x[0], self.kfmodel.cur_x[1],
            self.kfmodel.cur_x[2], self.kfmodel.cur_x[3])

        self.canvas.create_text(0,
                                150,
                                text=statustext,
                                fill="green4",
                                anchor=tk.NW)
Exemplo n.º 12
0
VideoCap=cv2.VideoCapture(0)

KF=KalmanFilter(0.1, [0, 0])

while(True):
    ret, frame=VideoCap.read()

    points, mask=detect_inrange(frame, 800)
    #points, mask=detect_visage(frame)

    etat=KF.predict().astype(np.int32)

    cv2.circle(frame, (int(etat[0]), int(etat[1])), 2, (0, 255, 0), 5)
    cv2.arrowedLine(frame,
                    (etat[0], etat[1]), (etat[0]+etat[2], etat[1]+etat[3]),
                    color=(0, 255, 0),
                    thickness=3,
                    tipLength=0.2)
    if (len(points)>0):
        cv2.circle(frame, (points[0][0], points[0][1]), 10, (0, 0, 255), 2)
        KF.update(np.expand_dims(points[0], axis=-1))

    cv2.imshow('image', frame)
    if mask is not None:
        cv2.imshow('mask', mask)

    if cv2.waitKey(1)&0xFF==ord('q'):
        VideoCap.release()
        cv2.destroyAllWindows()
        break
               [0,  0, 1, dt],
               [0,  0, 0,  1]])

f.H = np.mat ([[1, 0, 0, 0],
               [0, 0, 1, 0]])



f.Q *= 4.
f.R = np.mat([[50,0],
              [0, 50]])

f.x = np.mat([0,0,0,0]).T
f.P *= 100.


xs = []
ys = []
count = 200
for i in range(count):
    z = np.mat([[i+random.randn()*1],[i+random.randn()*1]])
    f.predict ()
    f.update (z)
    xs.append (f.x[0,0])
    ys.append (f.x[2,0])


plt.plot (xs, ys)
plt.show()

Exemplo n.º 14
0
class speedEstimator():
    def __init__(self):
        self.validSpeedUpdated = False
        self.lastPoint = 0.
        self.distanceThreshold = 0.05
        self.speedUpdateTime = []
        self.speedWindowSize = 10
        self.keyMeasPairs = deque(maxlen=80)
        self.speedWindow = []
        self.filtedRange = []
        self.curSpeed = 0.0
        self.speedRecord = []
        self.rangeKF = KalmanFilter(dim_x=1, dim_z=1)
        self.rangeKF.x = np.array([0.])
        self.rangeKF.F = np.array([[1.]])
        self.rangeKF.H = np.array([[1.]])
        self.rangeKF.P *= 100.
        self.rangeKF.R = 0.1
        self.rangeKF.Q = 0.001
        self.rangeKF.initialized = False

    def vel_from_dis(self, l_0, l_1, l_2, t0, t1, t2):
        t_1 = t1 - t0
        t_2 = t2 - t1
        if (l_2 - l_1) * (l_1 - l_0) > 0:
            d = abs(l_2 * l_2 - l_1 * l_1 -
                    (l_1 * l_1 - l_0 * l_0) * t_2 / t_1)
            tl = t_1 * t_2 + t_2 * t_2
            return math.sqrt(d / tl)
        else:
            return False

    def range_key_pairs_maintaince(self, range, time):
        if abs(range - self.lastPoint) > self.distanceThreshold:
            self.lastPoint = range
            self.keyMeasPairs.append([range, time])
            return True
        else:
            return False

    def estimate_speed(self, range, time, interval):
        fdragne = self.filter_range(range)
        self.speedWindowSize = 5 + 0.1 * range

        if self.range_key_pairs_maintaince(
                fdragne, time) and len(self.keyMeasPairs) >= 2 * interval:
            tempresult = self.vel_from_dis(self.keyMeasPairs[-2 * interval][0],
                                           self.keyMeasPairs[-interval][0],
                                           self.keyMeasPairs[-1][0],
                                           self.keyMeasPairs[-2 * interval][1],
                                           self.keyMeasPairs[-interval][1],
                                           self.keyMeasPairs[-1][1])
            if tempresult:
                self.speedWindow.append(tempresult)
                if len(self.speedWindow) > (self.speedWindowSize - 1):
                    self.curSpeed = np.median(
                        self.speedWindow
                    )  # Estimation of this linear motion speed
                    self.speedRecord.append(self.curSpeed)
                    self.speedUpdateTime.append(time)
                    self.validSpeedUpdated = True
                    while (len(self.speedWindow) > (self.speedWindowSize - 1)):
                        self.speedWindow.pop(0)

        else:
            self.validSpeedUpdated = False

    def filter_range(self, range):
        if self.rangeKF.initialized == False:
            self.rangeKF.x = np.array([range])
            self.filtedRange.append(range)
            self.rangeKF.initialized = True
        else:
            self.rangeKF.predict()
            self.rangeKF.update(range)
            self.filtedRange.append(self.rangeKF.x)
        return self.filtedRange[-1]

    def get_vel(self):
        return self.curSpeed
class DroneVideoDisplay(QtGui.QMainWindow):
	StatusMessages = {
		DroneStatus.Emergency : 'Emergency',
		DroneStatus.Inited    : 'Initialized',
		DroneStatus.Landed    : 'Landed',
		DroneStatus.Flying    : 'Flying',
		DroneStatus.Hovering  : 'Hovering',
		DroneStatus.Test      : 'Test (?)',
		DroneStatus.TakingOff : 'Taking Off',
		DroneStatus.GotoHover : 'Going to Hover Mode',
		DroneStatus.Landing   : 'Landing',
		DroneStatus.Looping   : 'Looping (?)'
		}
	DisconnectedMessage = 'Disconnected'
	UnknownMessage = 'Unknown Status'
	
	def __init__(self):
		# Construct the parent class
		super(DroneVideoDisplay, self).__init__()

		# Setup our very basic GUI - a label which fills the whole window and holds our image
		self.setWindowTitle('AR.Drone Video Feed')
		self.imageBox = QtGui.QLabel(self)
		self.setCentralWidget(self.imageBox)

		self.controller = BasicDroneController()
		self.counter = 0
		# Subscribe to the /ardrone/navdata topic, of message type navdata, and call self.ReceiveNavdata when a message is received
		self.subNavdata = rospy.Subscriber('/ardrone/navdata',Navdata,self.ReceiveNavdata) 
		
		# Subscribe to the drone's video feed, calling self.ReceiveImage when a new frame is received
		self.subVideo   = rospy.Subscriber('/ardrone/image_raw',Image,self.ReceiveImage)

		'''BEGIN CHANGES'''
		#Define Kalman Filter constants
		time = GUI_UPDATE_PERIOD
		time2 = time*time

		#1D case for velocity in the x-direction
		dimension = 1
		A = np.identity(dimension)
		B = np.matrix(time)
		H = np.identity(dimension)
		P = np.identity(dimension)
		Q = np.identity(dimension)
		R = np.identity(dimension)

		#tweak covariance matrices
		Q = np.dot(1,Q)
		R = np.dot(0.1, R)

		#create the Kalman Filter instance
		self.kfilter = KalmanFilter(A, P, R, Q, H, B, dimension)
		#rospy.loginfo("INIT")

		#create empty array to house our estimates
		self.state_estimate = []
		self.state_real = []


		#### Computer vision code

		self.x_pix = 320
		self.y_pix = 240

		self.x_ang = np.radians(54.4)
		self.y_ang = np.radians(37.8)

		self.prev_frame = None
		self.prev_points = None
		self.prev_time = None
		self.vel = []

		plt.ion()

		'''END CHANGES'''
		
		# Holds the image frame received from the drone and later processed by the GUI
		self.image = None
		self.imageLock = Lock()

		self.tags = []
		self.tagLock = Lock()
		
		# Holds the status message to be displayed on the next GUI update
		self.statusMessage = ''

		# Tracks whether we have received data since the last connection check
		# This works because data comes in at 50Hz but we're checking for a connection at 4Hz
		self.communicationSinceTimer = False
		self.connected = False

		# A timer to check whether we're still connected
		self.connectionTimer = QtCore.QTimer(self)
		self.connectionTimer.timeout.connect(self.ConnectionCallback)
		self.connectionTimer.start(CONNECTION_CHECK_PERIOD)
		
		# A timer to redraw the GUI
		self.redrawTimer = QtCore.QTimer(self)
		self.redrawTimer.timeout.connect(self.RedrawCallback)
		self.redrawTimer.start(GUI_UPDATE_PERIOD)

	# Called every CONNECTION_CHECK_PERIOD ms, if we haven't received anything since the last callback, will assume we are having network troubles and display a message in the status bar
	def ConnectionCallback(self):
		self.connected = self.communicationSinceTimer
		self.communicationSinceTimer = False

	def RedrawCallback(self):
		if self.image is not None:
			# We have some issues with locking between the display thread and the ros messaging thread due to the size of the image, so we need to lock the resources
			self.imageLock.acquire()
			try:			

					''' 
					TODO:

					1. Create Kalman Filter instance in constructor.         DONE 
					2. Create optical flow instance in constructor. 	     DONE
					3. Retrieve controller navdata here.                     DONE 
					4. Retrieve image matrix here. Conver to cv matrix.      DONE
					5. Run optical flow alg. on image. 						 DONE
					6. Make prediction with controller data.                 DONE
					7. Update prediction with image data.                    DONE
					8. Plot estimate vs real continuously					 DONE
					9. GetHeight() function in drone_controller.py 			 INCOMPLETE
					10. GetTime() function in here						     INCOMPLETE
					'''

					'''BEGIN CHANGES'''
					#convert the ROS image to OpenCV and apply some processing. then convert back to ROS
					openimage = ToOpenCV(self.image)

					# make picture 2D
					frame = cv2.cvtColor(openimage, cv2.COLOR_BGR2GRAY)

					''' TODO: Implement GetHeight in drone_controller.py '''

					feature_params = dict( maxCorners = 100,
	                       qualityLevel = 0.3,
	                       minDistance = 7,
	                       blockSize = 7 )

					if self.prev_frame is None:
						self.prev_frame = frame 
						self.prev_points = cv2.goodFeaturesToTrack(self.prev_frame, mask=None, **feature_params)
						self.prev_time = GUI_UPDATE_PERIOD #self.GetTime() is set to a constant for now
					else:

						h = self.controller.GetHeight()
						xdist = (h * np.tan(self.x_ang / 2.0))
						ydist = (h * np.tan(self.y_ang / 2.0)) 

						pix2mx = self.x_pix / xdist
						pix2my = self.y_pix / ydist

						curr_frame = frame

						''' Implement GetTime() '''
						curr_time = GUI_UPDATE_PERIOD #self.GetTime() is set to constant for now
						new_points, status, error = cv2.calcOpticalFlowPyrLK(self.prev_frame, curr_frame, self.prev_points)

						good_new = new_points[status==1]
						good_old = self.prev_points[status==1]
						assert good_new.shape == good_old.shape


						### Calculate velocity components
						sum_x = 0.0
						sum_y = 0.0
						ptslen = len(good_new)
						xcomp = 0
						ycomp = 0
						for x in range(ptslen):
							xcomp = ((good_new[x][1] - good_old[x][1]) / self.x_pix) / (curr_time / 1000.0) #- self.prev_time
							ycomp = ((good_new[x][0] - good_old[x][0]) / self.y_pix) / (curr_time / 1000.0)
							sum_y += ycomp
							sum_x += xcomp

						avg_x = np.divide(xcomp, ptslen)
						avg_y = np.divide(ycomp, ptslen)

						self.vel.append(avg_x) #only x for now

						# iterate next frames
						self.prev_frame = curr_frame
						self.prev_points = new_points
						self.prev_time = curr_time


					#Convert to ROS
					ROSimage = ToRos(openimage)

					##############################################
					### Change velocity to get correct one here ## 
					##############################################
					estimated_velocity = self.vel[-1:] ######
					##############################################
					if estimated_velocity == []:
						estimated_velocity = 0
					#rospy.loginfo("estimated_velocity")
					#rospy.loginfo(estimated_velocity)

					u_k = 0
					real_velocity = 0
					#update the measured accelerations and velocities
					real_velocity = self.controller.GetVelocity()
					rospy.loginfo("real_velocity")
					rospy.loginfo(real_velocity)
					u_k = self.controller.GetAcceleration()
					z_k = estimated_velocity
					rospy.loginfo("z_k")
					rospy.loginfo(estimated_velocity)

					#Kalman Filter step
					self.kfilter.predictState(u_k)
					self.kfilter.getKalmanGain()
					#rospy.loginfo("kalman_gain")
					#rospy.loginfo(self.kfilter.kalmanGain)
					self.kfilter.update(estimated_velocity)

					self.state_estimate.append(self.kfilter.x_k.item(0))
					self.state_real.append(real_velocity)
					#plot everything here, estimates not plotting atm
					if self.counter > 100:
						plt.plot(self.state_estimate[-90:], label = "estimated velocity", color = 'black')
						plt.plot(self.state_real[-90], color = 'yellow')
					else: 
						plt.plot(self.state_estimate, label = "estimated velocity", color = 'black')
						plt.plot(self.state_real, color = 'yellow')
					self.counter += 1
					#rospy.loginfo("estimate")
					#rospy.loginfo(self.state_estimate)
					#rospy.loginfo("real state")
					#rospy.loginfo(self.state_real)
					plt.draw()

					'''END CHANGES'''

					# Convert the ROS image into a QImage which we can display
					image = QtGui.QPixmap.fromImage(QtGui.QImage(ROSimage.data, ROSimage.width, ROSimage.height, QtGui.QImage.Format_RGB888))
					if len(self.tags) > 0:
						self.tagLock.acquire()
						try:
							painter = QtGui.QPainter()
							painter.begin(image)
							painter.setPen(QtGui.QColor(0,255,0))
							painter.setBrush(QtGui.QColor(0,255,0))
							for (x,y,d) in self.tags:
								r = QtCore.QRectF((x*image.width())/1000-DETECT_RADIUS,(y*image.height())/1000-DETECT_RADIUS,DETECT_RADIUS*2,DETECT_RADIUS*2)
								painter.drawEllipse(r)
								painter.drawText((x*image.width())/1000+DETECT_RADIUS,(y*image.height())/1000-DETECT_RADIUS,str(d/100)[0:4]+'m')
							painter.end()
						finally:
							self.tagLock.release()
			finally:
				self.imageLock.release()

			# display the window.
			self.resize(image.width(),image.height())
			self.imageBox.setPixmap(image)

		# Update the status bar to show the current drone status & battery level
		self.statusBar().showMessage(self.statusMessage if self.connected else self.DisconnectedMessage)

	def ReceiveImage(self,data):
		# Indicate that new data has been received (thus we are connected)
		self.communicationSinceTimer = True

		# We have some issues with locking between the GUI update thread and the ROS messaging thread due to the size of the image, so we need to lock the resources
		self.imageLock.acquire()
		try:
			self.image = data # Save the ros image for processing by the display thread
		finally:
			self.imageLock.release()

	def ReceiveNavdata(self,navdata):
		# Indicate that new data has been received (thus we are connected)
		self.communicationSinceTimer = True

		# Update the message to be displayed
		msg = self.StatusMessages[navdata.state] if navdata.state in self.StatusMessages else self.UnknownMessage
		self.statusMessage = '{} (Battery: {}%)'.format(msg,int(navdata.batteryPercent))

		self.tagLock.acquire()
		try:
			if navdata.tags_count > 0:
				self.tags = [(navdata.tags_xc[i],navdata.tags_yc[i],navdata.tags_distance[i]) for i in range(0,navdata.tags_count)]
			else:
				self.tags = []
		finally:
			self.tagLock.release()
Exemplo n.º 16
0
from KalmanFilter import KalmanFilter
import numpy as np
import matplotlib.pyplot as plt
import numpy.random as random

f = KalmanFilter(dim=4)

dt = 1
f.F = np.mat([[1, dt, 0, 0], [0, 1, 0, 0], [0, 0, 1, dt], [0, 0, 0, 1]])

f.H = np.mat([[1, 0, 0, 0], [0, 0, 1, 0]])

f.Q *= 4.
f.R = np.mat([[50, 0], [0, 50]])

f.x = np.mat([0, 0, 0, 0]).T
f.P *= 100.

xs = []
ys = []
count = 200
for i in range(count):
    z = np.mat([[i + random.randn() * 1], [i + random.randn() * 1]])
    f.predict()
    f.update(z)
    xs.append(f.x[0, 0])
    ys.append(f.x[2, 0])

plt.plot(xs, ys)
plt.show()
class RobotControl(object):
    """
    Class used to interface with the rover. Gets sensor measurements through ROS subscribers,
    and transforms them into the 2D plane, and publishes velocity commands.
    """
    def __init__(self, world_map,occupancy_map, pos_init, pos_goal, max_speed, max_omega, x_spacing, y_spacing, t_cam_to_body):
        """
        Initialize the class
        Inputs: (all loaded from the parameter YAML file)
        world_map - a P by 4 numpy array specifying the location, orientation,
            and identification of all the markers/AprilTags in the world. The
            format of each row is (x,y,theta,id) with x,y giving 2D position,
            theta giving orientation, and id being an integer specifying the
            unique identifier of the tag.
        occupancy_map - an N by M numpy array of boolean values (represented as
            integers of either 0 or 1). This represents the parts of the map
            that have obstacles. It is mapped to metric coordinates via
            x_spacing and y_spacing
        pos_init - a 3 by 1 array specifying the initial position of the robot,
            formatted as usual as (x,y,theta)
        pos_goal - a 3 by 1 array specifying the final position of the robot,
            also formatted as (x,y,theta)
        max_speed - a parameter specifying the maximum forward speed the robot
            can go (i.e. maximum control signal for v)
        max_omega - a parameter specifying the maximum angular speed the robot
            can go (i.e. maximum control signal for omega)
        x_spacing - a parameter specifying the spacing between adjacent columns
            of occupancy_map
        y_spacing - a parameter specifying the spacing between adjacent rows
            of occupancy_map
        t_cam_to_body - numpy transformation between the camera and the robot
            (not used in simulation)
        """

        # TODO for student: Comment this when running on the robot 
        self.robot_sim = RobotSim(world_map, occupancy_map, pos_init, pos_goal,
                                  max_speed, max_omega, x_spacing, y_spacing)
        # TODO for student: Use this when transferring code to robot
        # Handles all the ROS related items
        #self.ros_interface = ROSInterface(t_cam_to_body)

        # Uncomment as completed
        self.kalman_filter = KalmanFilter(world_map)
        self.diff_drive_controller = DiffDriveController(max_speed, max_omega)
        plan = dijkstras(occupancy_map, x_spacing, y_spacing, pos_init, pos_goal)
        self.state_tol = 0.1
        self.path = plan.tolist()
        print "Path: ", self.path, type(self.path)
        self.path.reverse()
        self.path.pop()
        self.state = pos_init
        self.goal = self.path.pop()
        self.x_offset = x_spacing
        self.vw = (0, 0, False)
        # self.goal[0] += self.x_offset/2
        # self.goal[1] += y_spacing
        print "INIT GOAL: ", self.goal

    #     def dijkstras(occupancy_map, x_spacing, y_spacing, start, goal):


    def process_measurements(self):
        """
        Main loop of the robot - where all measurements, control, and estimation
        are done. This function is called at 60Hz
        """

        meas = self.robot_sim.get_measurements()
        imu_meas = self.robot_sim.get_imu()

        self.vw = self.diff_drive_controller.compute_vel(self.state, self.goal)
        print "VW: ", self.vw
        print "Running Controller."

        if self.vw[2] == False:
            self.robot_sim.command_velocity(self.vw[0], self.vw[1])
        else:
            self.robot_sim.command_velocity(0, 0)
        
        est_x = self.kalman_filter.step_filter(self.vw, imu_meas, meas)
        print "EST X: ", est_x, est_x[2][0]
        if est_x[2][0] > 2.617991667:
            est_x[2][0] = 2.617991667
        if est_x[2][0] < 0.523598333:
            est_x[2][0] = 0.523598333
        self.state = est_x
        print "Get GT Pose: ", self.robot_sim.get_gt_pose()
        print "EKF Pose: ", est_x
        self.robot_sim.get_gt_pose()
        self.robot_sim.set_est_state(est_x)
        
        if imu_meas != None:
            self.kalman_filter.prediction(self.vw, imu_meas)

        if meas != None and meas != []:
            print("Measurements: ", meas)
            if imu_meas != None:
                # self.kalman_filter.prediction(self.vw, imu_meas)
                self.kalman_filter.update(meas)


        pos_x_check = ((self.goal[0] + self.state_tol) > est_x.item(0)) and \
                      ((self.goal[0] - self.state_tol) < est_x.item(0))

        pos_y_check = ((self.goal[1] + self.state_tol) > est_x.item(1)) and \
                      ((self.goal[1] - self.state_tol) < est_x.item(1))

        if pos_x_check and pos_y_check:
            if self.path != []:
                self.goal = self.path.pop()
                # self.goal[0] += self.x_offset/2
                # self.goal[1] += y_spacing
            else:
                self.goal = est_x
Exemplo n.º 18
0
class SensorSimulator:
    def __init__(self, theta, emax, cachelen):
        self.cache = []
        self.readings = []
        self.totaltrans = 0
        self.cacheLen = cachelen
        self.theta = theta
        self.emax = emax
        self.counter = 0
        self.correcteddata = []
        self.totalTransferredData = 0
        r_std, q_std = 1., 0.003
        self.kf = KalmanFilter(dim_x=2, dim_z=1)
        self.kf.x = np.array([[19], [0]])  # position, velocity
        self.kf.F = np.array([[1, 1], [0, 1]])
        self.kf.R = np.array([[r_std**2]])  # input noise
        self.kf.H = np.array([[1., 0.]])
        self.kf.P = np.diag([0.001**2, 0])
        self.kf.Q = Q_discrete_white_noise(2, 1, q_std**2)
        self.est_list = []
        self.counter = 0
        self.batCap = 3.6
        self.variance = 0
        self.V = 3.6
        self.Itx = ((17.4 + 18.8 + 0.5 + 0.426) / 32768)
        self.DetaT = 5

    def getSensorReadings(self, sensor_id, dataSize):
        self.readings = getData(sensor_id, dataSize)
        return self.readings

    def RDR(self, sensorReading):
        distance = sum = 0.0
        transmitted_counter = 0
        corr = 0.0
        list_1 = []
        est_list = []

        s = 0
        if len(self.cache) <= self.cacheLen:
            self.cache.append(sensorReading)
            SensorSimulator.findEnergyConsumption(self)
            self.correcteddata.append(sensorReading)

            self.totaltrans += 1
            #print(sensorReading)
            self.kf.predict()
            self.kf.update([sensorReading])
            return sensorReading
        else:
            if sensorReading == self.cache[self.cacheLen - 1]:
                self.correcteddata.append(sensorReading)
                return
            else:
                for i in range(0, self.cacheLen):
                    distance += pow(sensorReading - self.cache[i], 2)
                    sum += self.cache[i]
                distance = math.sqrt(distance)
                corr = 1 - distance / sum
                est = self.kf.predict()
                self.est_list.append(est[0])

                estval = est[0][0]
                self.kf.update(est[0][0])
                #print(sensorReading - estval, ", ", corr)
                if corr < self.theta:
                    sensorReading = est[0][0]
                    self.cache.pop(0)
                    self.cache.append(sensorReading)
                    self.counter += 1
                    SensorSimulator.findEnergyConsumption(self)
                    self.correcteddata.append(
                        sensorReading)  ####################

                    self.totaltrans += 1
                    #print(sensorReading)
                    return sensorReading
                else:
                    #print(sensorReading - estval)
                    if abs(sensorReading - estval) < self.emax:
                        self.correcteddata.append(sensorReading)
                        exit
                    else:
                        self.cache.pop(0)
                        self.cache.append(sensorReading)
                        self.counter += 1
                        SensorSimulator.findEnergyConsumption(self)
                        self.correcteddata.append(sensorReading)

                        self.totaltrans += 1
                        #print(sensorReading)
                        return sensorReading

    def findVariance(self):
        self.variance = np.var(self.readings)
        return self.variance

    def findEnergyEfficiency(self):
        # print(self.totalTransferredData)
        #print(3.6-self.batCap, 0)
        # print("Energy Efficiency:", self.totalTransferredData/(3.6-self.batCap))
        return 1  #self.totalTransferredData/(3.6-self.batCap)

    def findEnergyConsumption(self):

        #charge= self.Itx*(0.426+15)/32768
        charge = 17.4 / 32768
        Etx = self.V * charge
        self.batCap = self.batCap - Etx