def __init__(self, intrinsics_file):
        self.intrinsics = CameraIntrinsics(intrinsics_file)

        # Chessboard
        self.chessboard = Chessboard(t_G=np.array([0.3, 0.1, 0.1]),
                                     nb_rows=11,
                                     nb_cols=11,
                                     square_size=0.02)
        self.plot_chessboard = PlotChessboard(chessboard=self.chessboard)

        # Gimbal
        self.gimbal = GimbalModel()
        self.gimbal.set_attitude([0.0, 0.0, 0.0])
        self.plot_gimbal = PlotGimbal(gimbal=self.gimbal)

        # Cameras
        self.static_camera = self.setup_static_camera()
        self.gimbal_camera = self.setup_gimbal_camera()
Exemple #2
0
    def __init__(self, **kwargs):
        self.origin = np.array([0.0, 0.0, 0.0])
        self.gimbal = kwargs.get("gimbal", GimbalModel())

        self.link0 = None
        self.link1 = None
        self.link2 = None
        self.link3 = None

        self.show_static_frame = kwargs.get("show_static_frame", True)
        self.show_base_frame = kwargs.get("show_base_frame", True)
        self.show_end_frame = kwargs.get("show_end_frame", True)
        self.show_dynamic_frame = kwargs.get("show_dynamic_frame", True)
    def __init__(self, **kwargs):
        self.gimbal_model = kwargs.get("gimbal_model", GimbalModel())

        if kwargs.get("sim_mode", False):
            self.ec_data = kwargs["ec_data"]
            self.joint_data = kwargs["joint_data"]
        else:
            self.loader = GECDataLoader(**kwargs)

        if kwargs.get("preprocessed", False) is False:
            # Calibration and joint data
            self.ec_data, self.joint_data = self.loader.load()

            # Camera intrinsics matrix
            self.K_s = self.ec_data[0].intrinsics.K_new
            self.K_d = self.ec_data[1].intrinsics.K_new

            # Number of measurement set
            self.K = len(self.ec_data[0].corners2d_ud)

            # Number of links - 2 for a 2-axis gimbal
            self.L = 2

            # Setup measurement sets
            self.Z = []
            for i in range(self.K):
                # Corners 3d observed in both the static and dynamic cam
                P_s = self.ec_data[0].corners3d_ud[i]
                P_d = self.ec_data[1].corners3d_ud[i]
                # Corners 2d observed in both the static and dynamic cam
                Q_s = self.ec_data[0].corners2d_ud[i]
                Q_d = self.ec_data[1].corners2d_ud[i]
                Z_i = [P_s, P_d, Q_s, Q_d]
                self.Z.append(Z_i)

        else:
            # Measurement set and joint data
            self.Z, self.K_s, self.K_d, self.joint_data = self.loader.load()

            # Number of measurement set
            self.K = len(self.Z)

            # Number of links - 2 for a 2-axis gimbal
            self.L = 2
Exemple #4
0
    def __init__(self, **kwargs):
        self.gimbal_model = kwargs.get("gimbal_model", GimbalModel())

        if kwargs.get("sim_mode", False):
            # Load sim data
            self.Z = kwargs["Z"]
            self.K_s = kwargs["K_s"]
            self.K_d = kwargs["K_d"]
            self.D_s = kwargs["D_s"]
            self.D_d = kwargs["D_d"]
            self.joint_data = kwargs["joint_data"]
            self.K = len(self.Z)

        else:
            # Load data
            self.loader = DataLoader(**kwargs)
            # -- Measurement set and joint data
            data = self.loader.load()
            self.Z, self.K_s, self.K_d, self.D_s, self.D_d, self.joint_data = data
            # -- Number of measurement set
            self.K = len(self.Z)
Exemple #5
0
    def test_optimize_preprocessed(self):
        gimbal_model = GimbalModel(
            tau_s=np.array([0.045, 0.075, -0.085, 0.0, 0.0, pi / 2.0]),
            tau_d=np.array([0.0, 0.015, 0.0, 0.0, 0.0, -pi / 2.0]),
            w1=np.array([0.0, 0.0, 0.075]),
            w2=np.array([0.0, 0.0, 0.0])
        )
        # gimbal_model.set_attitude([deg2rad(0), deg2rad(0)])
        # plot_gimbal = PlotGimbal(gimbal=gimbal_model)
        # plot_gimbal.plot()
        # plt.show()

        data_path = "/home/chutsu/Dropbox/calib_data"
        calib = GimbalCalibrator(
            preprocessed=True,
            gimbal_model=gimbal_model,
            data_path=data_path,
            data_dirs=["cam0", "cam1"],
            intrinsic_files=["static_camera.yaml", "gimbal_camera.yaml"],
            joint_file="joint.csv"
        )
        calib.optimize()
class GimbalDataGenerator:
    def __init__(self, intrinsics_file):
        self.intrinsics = CameraIntrinsics(intrinsics_file)

        # Chessboard
        self.chessboard = Chessboard(t_G=np.array([0.3, 0.1, 0.1]),
                                     nb_rows=11,
                                     nb_cols=11,
                                     square_size=0.02)
        self.plot_chessboard = PlotChessboard(chessboard=self.chessboard)

        # Gimbal
        self.gimbal = GimbalModel()
        self.gimbal.set_attitude([0.0, 0.0, 0.0])
        self.plot_gimbal = PlotGimbal(gimbal=self.gimbal)

        # Cameras
        self.static_camera = self.setup_static_camera()
        self.gimbal_camera = self.setup_gimbal_camera()

    def setup_static_camera(self):
        image_width = 640
        image_height = 480
        fov = 120
        fx, fy = focal_length(image_width, image_height, fov)
        cx, cy = (image_width / 2.0, image_height / 2.0)
        K = camera_intrinsics(fx, fy, cx, cy)
        cam_model = PinholeCameraModel(image_width, image_height, K)

        return cam_model

    def setup_gimbal_camera(self):
        image_width = 640
        image_height = 480
        fov = 120
        fx, fy = focal_length(image_width, image_height, fov)
        cx, cy = (image_width / 2.0, image_height / 2.0)
        K = camera_intrinsics(fx, fy, cx, cy)
        cam_model = PinholeCameraModel(image_width, image_height, K)

        return cam_model

    def calc_static_camera_view(self):
        # Transforming chessboard grid points in global to camera frame
        R = np.eye(3)
        t = np.zeros(3)
        R_CG = euler2rot([-pi / 2.0, 0.0, -pi / 2.0], 123)
        X = dot(R_CG, self.chessboard.grid_points3d.T)
        x = self.static_camera.project(X, R, t).T[:, 0:2]

        return x

    def calc_gimbal_camera_view(self):
        # Create transform from global to static camera frame
        t_g_sg = np.array([0.0, 0.0, 0.0])
        R_sg = euler2rot([-pi / 2.0, 0.0, -pi / 2.0], 321)
        T_gs = np.array([[R_sg[0, 0], R_sg[0, 1], R_sg[0, 2], t_g_sg[0]],
                         [R_sg[1, 0], R_sg[1, 1], R_sg[1, 2], t_g_sg[1]],
                         [R_sg[2, 0], R_sg[2, 1], R_sg[2, 2], t_g_sg[2]],
                         [0.0, 0.0, 0.0, 1.0]])

        # Calculate transform from global to dynamic camera frame
        links = self.gimbal.calc_transforms()
        T_sd = links[-1]
        T_gd = dot(T_gs, T_sd)

        # Project chessboard grid points in global to dynamic camera frame
        # -- Convert 3D points to homogeneous coordinates
        X = self.chessboard.grid_points3d.T
        X = np.block([[X], [np.ones(X.shape[1])]])
        # -- Project to dynamica camera image frame
        X = dot(np.linalg.inv(T_gd), X)[0:3, :]
        x = dot(self.gimbal_camera.K, X)
        # -- Normalize points
        x[0, :] = x[0, :] / x[2, :]
        x[1, :] = x[1, :] / x[2, :]
        x = x[0:2, :].T

        return x, X.T

    def plot_static_camera_view(self, ax):
        x = self.calc_static_camera_view()
        ax.scatter(x[:, 0], x[:, 1], marker="o", color="red")

    def plot_gimbal_camera_view(self, ax):
        x, X = self.calc_gimbal_camera_view()
        ax.scatter(x[:, 0], x[:, 1], marker="o", color="red")

    def plot_camera_views(self):
        # Plot static camera view
        ax = plt.subplot(211)
        ax.axis('square')
        self.plot_static_camera_view(ax)
        ax.set_title("Static Camera View", y=1.08)
        ax.set_xlim((0, self.static_camera.image_width))
        ax.set_ylim((0, self.static_camera.image_height))
        ax.invert_yaxis()
        ax.xaxis.tick_top()

        # Plot gimbal camera view
        ax = plt.subplot(212)
        ax.axis('square')
        self.plot_gimbal_camera_view(ax)
        ax.set_title("Gimbal Camera View", y=1.08)
        ax.set_xlim((0, self.gimbal_camera.image_width))
        ax.set_ylim((0, self.gimbal_camera.image_height))
        ax.invert_yaxis()
        ax.xaxis.tick_top()

        # Overall plot settings
        plt.tight_layout()

    def plot(self):
        # Plot camera views
        self.plot_camera_views()

        # Plot gimbal and chessboard
        fig = plt.figure()
        ax = fig.gca(projection='3d')
        self.plot_gimbal.plot(ax)
        self.plot_chessboard.plot(ax)
        axis_equal_3dplot(ax)
        ax.set_xlabel("x")
        ax.set_ylabel("y")
        ax.set_zlabel("z")
        plt.show()

    def calc_roll_pitch_combo(self, nb_images):
        nb_combo = int(sqrt(nb_images))

        roll_lim = [radians(-10), radians(10)]
        pitch_lim = [radians(-10), radians(10)]

        roll_vals = np.linspace(roll_lim[0], roll_lim[1], num=nb_combo)
        pitch_vals = np.linspace(pitch_lim[0], pitch_lim[1], num=nb_combo)

        return roll_vals, pitch_vals

    def generate(self):
        # Setup
        nb_images = 100
        R_CG = euler2rot([-pi / 2.0, 0.0, -pi / 2.0], 123)

        # Generate static camera data
        self.intrinsics.K_new = self.intrinsics.K()
        static_cam_data = ECData(None, self.intrinsics, self.chessboard)
        x = self.calc_static_camera_view()
        X = dot(R_CG, self.chessboard.grid_points3d.T).T
        for i in range(nb_images):
            static_cam_data.corners2d_ud.append(x)
            static_cam_data.corners3d_ud.append(X)
        static_cam_data.corners2d_ud = np.array(static_cam_data.corners2d_ud)
        static_cam_data.corners3d_ud = np.array(static_cam_data.corners3d_ud)

        # Generate gimbal data
        roll_vals, pitch_vals = self.calc_roll_pitch_combo(nb_images)
        gimbal_cam_data = ECData(None, self.intrinsics, self.chessboard)
        joint_data = []

        for roll in roll_vals:
            for pitch in pitch_vals:
                self.gimbal.set_attitude([roll, pitch])
                x, X = self.calc_gimbal_camera_view()
                gimbal_cam_data.corners2d_ud.append(x)
                gimbal_cam_data.corners3d_ud.append(X)
                joint_data.append([roll, pitch])

        gimbal_cam_data.corners2d_ud = np.array(gimbal_cam_data.corners2d_ud)
        gimbal_cam_data.corners3d_ud = np.array(gimbal_cam_data.corners3d_ud)
        joint_data = np.array(joint_data)

        return [static_cam_data, gimbal_cam_data], joint_data
    def test_plot(self):
        # Gimbal initial guess
        # # -- tau (x, y, z, roll, pitch, yaw)
        # tau_s = np.array([-0.045, -0.085, 0.08, 0.0, 0.0, 0.0])
        # tau_d = np.array([0.01, 0.0, -0.03, pi / 2.0, 0.0, -pi / 2.0])
        # # -- link (theta, alpha, a, d)
        # alpha = pi / 2.0
        # offset = -pi / 2.0
        # roll = 0.0
        # pitch = 0.1
        # link1 = np.array([offset + roll, alpha, 0.0, 0.045])
        # link2 = np.array([pitch, 0.0, 0.0, 0.0])

        # # Optimized gimbal params
        # offset = -pi / 2.0
        # roll = 0.0
        # pitch = 0.0
        #
        # tau_s = np.array([-0.0419, -0.0908, 0.0843, 0.0189, -0.0317, -0.0368])
        # tau_d = np.array([0.0032, 0.0007, -0.0302, 1.5800, 0.0123, -1.5695])
        # link1 = np.array([offset + roll, 1.5731, -0.0012, 0.0404])
        # link2 = np.array([pitch, 0.0, 0.0, 0.0])

        # Real 2 initial guess
        # offset = -pi / 2.0
        # roll = 0.0
        # pitch = 0.0
        # tau_s = np.array([0.0, -0.08, 0.1143, 0.0, 0.0, 0.0])
        # tau_d = np.array([0.0, 0.0, 0.0, pi / 2.0, 0.0, -pi / 2.0])
        # link1 = np.array([offset + roll,  # theta
        #                   pi / 2.0,       # alpha
        #                   0.0,            # a
        #                   0.0])           # d
        # link2 = np.array([pitch, 0.0, 0.0, 0.0])

        # Real 2 optimized params
        offset = -pi / 2.0
        roll = 0.0
        pitch = 0.0
        tau_s = np.array([
            0.01519, -0.036509, 0.096354,
            deg2rad(2.15041521),
            deg2rad(1.41060977),
            deg2rad(18.52822371)
        ])
        link1 = np.array([
            offset + roll,  # theta
            deg2rad(83.57483),  # alpha
            -0.0050,  # a
            0.01683
        ])  # d
        link2 = np.array([pitch, 0.0, 0.0, 0.0])
        tau_d = np.array([
            -0.00029, 0.00138, -0.03656,
            deg2rad(84.14281),
            deg2rad(0.28527),
            deg2rad(-91.17418)
        ])

        # -- Gimbal model
        gimbal_model = GimbalModel(tau_s=tau_s,
                                   tau_d=tau_d,
                                   link1=link1,
                                   link2=link2)
        # T_ds = gimbal_model.T_ds()
        # p_s = np.array([1.0, 0.0, 0.0, 1.0])

        # Plot gimbal model
        plot = PlotGimbal(gimbal=gimbal_model,
                          show_static_frame=True,
                          show_base_frame=True,
                          show_end_frame=True,
                          show_dynamic_frame=True)
        plot.set_attitude([0.0, 0.0])
        plot.plot()

        # Plot
        debug = True
        # debug = False
        if debug:
            plt.show()