From bd3ced9812823f8218d676e11f39b7cc97b1d466 Mon Sep 17 00:00:00 2001
From: ziminlu <ziminlu@umich.edu>
Date: Sun, 27 Mar 2022 18:18:51 +0000
Subject: [PATCH] Upload New File

---
 main_system_measurement.py | 244 +++++++++++++++++++++++++++++++++++++
 1 file changed, 244 insertions(+)
 create mode 100644 main_system_measurement.py

diff --git a/main_system_measurement.py b/main_system_measurement.py
new file mode 100644
index 0000000..9ca0a71
--- /dev/null
+++ b/main_system_measurement.py
@@ -0,0 +1,244 @@
+import numpy as np
+from numpy.random import randn
+from particle_filter import particle_filter
+import matplotlib.pyplot as plt
+import math
+
+
+
+class myStruct:
+    pass
+
+def projection_matrix_left(fx, fy, cx, cy):
+    '''return the projection_matrix_left
+
+    Parameters
+    ----------
+    fx: float
+        fx = f/k, where k is the pixel density, pixels/m, f is the focus length
+        Similarly, fy = f/l
+
+    Returns
+    -------
+    3*4 matrix
+        projection_matrix_left
+
+    '''
+    P_left = np.array([[fx, 0, cx, 0],[0, fy, cy, 0],[0, 0, 1, 0]])
+    return P_left
+
+def projection_matrix_right(fx, fy, cx, cy, R, T):
+    '''return the projection_matrix_right
+
+    Parameters
+    ----------
+    fx: float
+        fx = f/k, where k is the pixel density, pixels/m, f is the focus length
+        Similarly, fy = f/l
+
+    Returns
+    -------
+    3*4 matrix
+        projection_matrix_right
+
+    '''
+    # construct the trasformation matrix, which transforms poses from the frame of camera1 to that of camera2
+    T = T.reshape((3,1))
+    RT = np.vstack((R, T))
+    last_row = np.array([0,0,0,1])
+    RT = np.hstack((RT, last_row))
+    # transform the points from the frame of camera1 to that of camera2, so we can build the Pr
+    P_right = np.array([[fx, 0, cx, 0],[0, fy, cy, 0],[0, 0, 1, 0]])
+    P_right = P_right @ RT
+
+    return P_right
+
+def linear_triangulation(x_left, x_right, P_left, P_right):
+    '''return the 3D and 2D coordinate of the point in the left camera frame
+
+    Parameters
+    ----------
+    x_left, x_right: pixel coordinate in the left image
+        can either be 2*1 or 3*1 homogeneous form
+    P_left, P_right: projection matrices of the left and right cameras
+
+    Returns
+    -------
+    3*1 matrix
+        Z: the 3D coordinate of the point in the left camera frame
+    2*1 matrix
+        Z_2D: the 2D projection coordinate
+
+    '''
+    x_left = x_left.reshape((-1,1))
+    x_right = x_right.reshape((-1,1))
+    # check if they are in homogeneous form, if not, then transform them
+    if x_left.shape == (3,1):
+        pass
+    else:
+        x_left = np.array([x_left[0,0], x_left[1,0], 1]).reshape((3,1))
+
+    if x_right.shape == (3,1):
+        pass
+    else:
+        x_right = np.array([x_right[0,0], x_right[1,0], 1]).reshape((3,1))
+
+
+    A = np.array([[x_left[0,:]*P_left[2,:]-P_left[0,:]],
+                  [x_left[1,:]*P_left[2,:]-P_left[1,:]],
+                  [x_right[0,:]*P_right[2,:]-P_right[0,:]],
+                  [x_right[1,:]*P_right[2,:]-P_right[1,:]]])
+
+    U, S_vector, V_transpose = np.linalg.svd(A, full_matrices=True)
+    V = V_transpose.T
+
+    X = V[:,3].reshape((-1,1))
+    X = X * (1/X[3,:])
+    X = X[0:3,:].reshape((3,1))
+    Z_2D = np.array([X[2,:], X[0,:]]).reshape((2,1))  # (z,x) = (mx, my), check
+    Z = X
+    return Z, Z_2D
+
+def measurement(x_left, x_right, P_left, P_right):
+    # use this function to transform the pixel position measurement to the 2D bearing and range measurement
+    Z, Z_2D = linear_triangulation(x_left, x_right, P_left, P_right)
+    mx = Z_2D[0, 0]
+    my = Z_2D[1, 0]
+    z_br = np.array([[math.atan2(my, mx)],[np.sqrt(my ** 2 + mx ** 2)]])  # z_bearing_range
+    return z_br.reshape([2, 1])
+
+def measurement_model(x_hat, mx_t_minus_1, my_t_minus_1):
+    x_hat = x_hat.reshape((-1,1))
+    mx = mx_t_minus_1
+    my = my_t_minus_1
+    h = np.array([[math.atan2(my - x_hat[1,0], mx - x_hat[0,0]) - x_hat[2,0]], [np.sqrt((my - x_hat[1,0]) ** 2 + (mx - x_hat[0,0]) ** 2)]])
+    return h.reshape([2, 1])
+
+
+
+
+def process_model(x, w):
+    """
+    Think this makes sense because we don't move at all
+    :param x: actually point with respect to frame 1
+    :param w: noise vector sampled as part of the motion model (the vibes )
+    :return:
+    """
+    f = np.array([x[0], x[1], x[2]], dtype=float).reshape([3,1]) + w
+    return f.reshape([3, 1])
+
+def measurement_model_1(K_f, p, c_1):
+    """
+    :param K_f:  intrinisic Camera 1 Matrix
+    :param p: point in frame 1
+    :param c_1: optical center of image camera 1
+    :return: process model camera 1
+    """
+    proj_func= np.array([p[0]/p[2], p[1]/p[2]], dtype=float).reshape((-1,1))
+    return np.dot(K_f, proj_func) + c_1
+
+def measurement_model_2(K_f, p, c_2):
+    """
+    :param K_f: intrinisic Camera 2 Matrix
+    :param p: point in frame 1
+    :param c_1:
+    :return:
+    """
+    p = p.reshape([3,1])
+    q = np.dot(R.T, p) - np.dot(R.T, t)
+    proj_func= np.array([q[0]/q[2], q[1]/q[2]], dtype=float).reshape((-1,1))
+    return np.dot(K_f, proj_func) + c_2
+
+
+if __name__=="__main__":
+
+    C_1 = np.loadtxt(open('data/C_1.csv'), delimiter=",").reshape(-1, 1)
+    C_2 = np.loadtxt(open('data/C_2.csv'), delimiter=",").reshape(-1, 1)
+    Kf_1 = np.loadtxt(open('data/Kf_1.csv'), delimiter=",")
+    Kf_2 = np.loadtxt(open('data/Kf_2.csv'), delimiter=",")
+    R = np.loadtxt(open('data/R.csv'), delimiter=",")
+    t = np.loadtxt(open('data/t.csv'), delimiter=",").reshape(-1, 1)
+    z_1 = np.loadtxt(open('data/z_1.csv'), delimiter=",")
+    z_2 = np.loadtxt(open('data/z_2.csv'), delimiter=",")
+
+    given_data = myStruct()
+    given_data.C_1 = C_1
+    given_data.C_2 =C_2
+    given_data.Kf_1 = Kf_1
+    given_data.Kf_2 = Kf_2
+    given_data.R = R
+    given_data.t = t
+
+
+    # initialize the state using the first measurement
+    init = myStruct()
+    init.x = np.zeros([3,1])
+    init.x[0, 0] = 0.12
+    init.x[1, 0] = 0.09
+    init.x[2, 0] = 1.5
+    init.n = 1000
+    init.Sigma = 0.01*np.eye(3) #Tune
+
+
+    # Build the system
+    sys = myStruct()
+    sys.f = process_model
+    sys.R1 = np.cov(z_1, rowvar=False)  # double check 2by 2
+    sys.R2 = np.cov(z_2, rowvar=False)  # double check 2 by 2
+    sys.h1 = measurement_model_1
+    sys.h2 = measurement_model_2
+    sys.Q1 = np.array([[0.03,0.02,0.01],
+                       [0.02,0.04, 0.01],
+                       [0.01,0.01, 0.05]]).reshape((3,3)) # vibrations
+
+
+    filter = particle_filter(sys, init, given_data)
+    x = np.empty([3, np.shape(z_1)[0]+1]) # used since picked a random init
+    x[:, 0] = [init.x[0, 0], init.x[1, 0], init.x[2, 0]]  # don't need since picked random point
+
+
+    green = np.array([0.2980, .6, 0])
+
+    # started from 0 instead cuz picked random init
+    for i in range(0, np.shape(z_1)[0], 1):
+        filter.sample_motion()
+
+        #####################################################
+        # First measurement
+        z = np.append(z_1[i, :], z_2[i, :]).reshape((-1,1))
+
+        filter.importance_mesurement_batch(z)
+        if filter.Neff < filter.n/5:   # Note sampling threshold is hidden in there
+            filter.resampling() # does this work correctly terms of shapes
+        wtot = np.sum(filter.p.w)
+
+        if wtot  > 0:
+            # a = filter.p.x
+            # b = filter.p.w
+            x[0, i+1] = np.sum(filter.p.x[: , 0] * filter.p.w.reshape(-1)) / wtot
+            x[1 ,i+1] = np.sum(filter.p.x[: , 1] * filter.p.w.reshape(-1))/ wtot
+            x[2, i+1] = np.sum(filter.p.x[:, 2] * filter.p.w.reshape(-1)) / wtot
+        else:
+            print('\033[91mWarning: Total weight is zero or nan!\033[0m')
+            x[:, i+1] = [np.nan, np.nan, np.nan]
+        ############################################################################
+
+
+    # Final Label
+    print('Final x: %.4f, y: %.4f, z: %.4f' % (x[0,-1], x[1,-1], x[2,-1]))
+
+    # quit()
+    fig = plt.figure()
+    # axis = np.linspace()
+    plt.plot(x[0,:], label='px' )
+    plt.plot(x[1,:], label='py')
+    plt.plot(x[2,:], label ='pz')
+    plt.title('Particle Filter Batch ')
+    plt.xlabel(r'time Step')
+    plt.ylabel(r'Position')
+    plt.legend()
+    plt.show()
+
+
+
+    print('here')
-- 
GitLab