Esempio n. 1
0
    def smooth_orientations_internal(self, times, orientation_list):

        alpha = 1
        smooth = self.get_user_option_value("smoothness")
        if smooth > 0:
            alpha = 1 - np.exp(-(1 / self.gyro_sample_rate) / smooth)

            smoothed_orientation = np.zeros(orientation_list.shape)

            value = orientation_list[0, :]

            for i in range(self.num_data_points):
                value = quat.single_slerp(value, orientation_list[i, :], alpha)
                smoothed_orientation[i] = value

            # reverse pass
            start_orientations = np.zeros(orientation_list.shape)

            value2 = smoothed_orientation[-1, :]

            for i in range(self.num_data_points - 1, -1, -1):
                value2 = quat.single_slerp(value2, smoothed_orientation[i, :],
                                           alpha)
                start_orientations[i] = value2

        else:
            start_orientations = np.array(orientation_list)

        # swap around
        start_orientations[:, [0, 1, 2, 3]] = start_orientations[:,
                                                                 [1, 2, 3, 0]]

        eul = Rotation(start_orientations).as_euler("zxy")
        #plt.figure()
        #plt.plot(eul[:,0])
        #plt.plot(eul[:,1])
        #plt.plot(eul[:,2])
        #plt.show()
        eul[:, 0] = self.get_user_option_value("horizon_angle") * np.pi / 180

        #new_quat = Rotation.from_euler(["xyz", "zxy", "yzx", "xzy", "zyx", "yxz"][self.get_user_option_value("eul")], eul).as_quat()
        new_quat = Rotation.from_euler("zxy", eul).as_quat()

        new_quat[:, [0, 1, 2, 3]] = new_quat[:, [3, 0, 1, 2]]

        return times, new_quat
Esempio n. 2
0
    def smooth_orientations_internal(self, times, orientation_list):
        # To be overloaded

        # https://en.wikipedia.org/wiki/Exponential_smoothing
        # the smooth value corresponds to the time constant

        alpha = 1
        smooth = self.get_user_option_value("smoothness")
        if smooth > 0:
            alpha = 1 - np.exp(-(1 / self.gyro_sample_rate) / smooth)

        smoothed_orientation = np.zeros(orientation_list.shape)

        value = orientation_list[0, :]

        for i in range(self.num_data_points):
            value = quat.single_slerp(value, orientation_list[i, :], alpha)
            smoothed_orientation[i] = value

        # reverse pass
        smoothed_orientation2 = np.zeros(orientation_list.shape)

        value2 = smoothed_orientation[-1, :]

        for i in range(self.num_data_points - 1, -1, -1):
            value2 = quat.single_slerp(value2, smoothed_orientation[i, :],
                                       alpha)
            smoothed_orientation2[i] = value2

        # Test rotation lock (doesn't work)
        #if test:
        #    from scipy.spatial.transform import Rotation
        #    for i in range(self.num_data_points):
        #        quat = smoothed_orientation2[i,:]
        #        eul = Rotation([quat[1], quat[2], quat[3], quat[0]]).as_euler("xyz")
        #        new_quat = Rotation.from_euler('xyz', [eul[0], eul[1], np.pi]).as_quat()
        #        smoothed_orientation2[i,:] = [new_quat[3], new_quat[0], new_quat[1], new_quat[2]]

        return times, smoothed_orientation2
Esempio n. 3
0
    def get_interpolated_stab_transform_old(self, start=0, interval=1 / 29.97):

        if self.smoothing_algo:
            if self.smoothing_algo.bypass_external_processing:
                print("Bypassing quaternion orientation integration")
                time_list, smoothed_orientation = self.smoothing_algo.get_stabilize_transform(
                    self.gyro)
            else:
                time_list, smoothed_orientation = self.get_stabilize_transform(
                )
        else:
            time_list, smoothed_orientation = self.get_stabilize_transform()

        time = start

        out_times = []
        slerped_rotations = []

        while time < 0:
            slerped_rotations.append(smoothed_orientation[0])
            out_times.append(time)
            time += interval

        while time_list[0] >= time:
            slerped_rotations.append(smoothed_orientation[0])
            out_times.append(time)
            time += interval

        for i in range(len(time_list) - 1):
            while time_list[i] <= time < time_list[i + 1]:

                # interpolate between two quaternions
                weight = (time - time_list[i]) / (time_list[i + 1] -
                                                  time_list[i])
                slerped_rotations.append(
                    quat.single_slerp(smoothed_orientation[i],
                                      smoothed_orientation[i + 1], weight))
                out_times.append(time)

                time += interval

            if time < time_list[i]:
                # continue even if missing gyro data
                slerped_rotations.append(smoothed_orientation[i])
                out_times.append(time)
                time += interval

        return (out_times, slerped_rotations)
Esempio n. 4
0
    def get_interpolated_orientations(self, start=0, interval=1 / 29.97):

        time_list, smoothed_orientation = self.get_orientations()

        time = start

        out_times = []
        slerped_rotations = []

        while time < 0:
            slerped_rotations.append(smoothed_orientation[0])
            out_times.append(time)
            time += interval

        while time_list[0] >= time:
            slerped_rotations.append(smoothed_orientation[0])
            out_times.append(time)
            time += interval

        for i in range(len(time_list) - 1):
            while time_list[i] <= time < time_list[i + 1]:

                # interpolate between two quaternions
                weight = (time - time_list[i]) / (time_list[i + 1] -
                                                  time_list[i])
                slerped_rotations.append(
                    quat.single_slerp(smoothed_orientation[i],
                                      smoothed_orientation[i + 1], weight))
                out_times.append(time)

                time += interval

            if time < time_list[i]:
                # continue even if missing gyro data
                slerped_rotations.append(smoothed_orientation[i])
                out_times.append(time)
                time += interval

        self.interp_times = np.array(out_times)
        self.interp_orientations = np.array(slerped_rotations)

        return (self.interp_times, self.interp_orientations)
Esempio n. 5
0
    def smooth_orientations_internal(self, times, orientation_list):
        # To be overloaded

        # https://en.wikipedia.org/wiki/Exponential_smoothing
        # the smooth value corresponds to the time constant

        alpha = 1
        smooth = self.get_user_option_value("smoothness")
        print(f"Smoothing orientation with smoothness={smooth}")
        smooth2 = min(smooth * 0.1, 0.1)  # When outside zone
        alpha2 = 1 - np.exp(-(1 / self.gyro_sample_rate) / smooth2)

        if smooth > 0:
            alpha = 1 - np.exp(-(1 / self.gyro_sample_rate) / smooth)

        smoothed_orientation = np.zeros(orientation_list.shape)

        value = orientation_list[0, :]

        rotlimit = self.get_user_option_value("rotlimit") * np.pi / 180

        begin_curve = rotlimit * 0.6

        # Forward pass
        for i in range(self.num_data_points):
            temp_value = quat.single_slerp(value, orientation_list[i, :],
                                           alpha)
            anglebetween = abs(
                quat.angle_between(temp_value, orientation_list[i, :]))
            if begin_curve < anglebetween <= rotlimit:
                smoothinterp = smooth + (anglebetween - begin_curve) * (
                    smooth2 - smooth) / (rotlimit - begin_curve)

                alphainterp = 1 - np.exp(
                    -(1 / self.gyro_sample_rate) / smoothinterp)
                temp_value = quat.single_slerp(value, orientation_list[i, :],
                                               alphainterp)

            elif anglebetween > rotlimit:  # new smoothed orientation over angle limit
                temp_value = quat.single_slerp(value, orientation_list[i, :],
                                               alpha2)

            value = temp_value
            smoothed_orientation[i] = value

        # reverse pass
        smoothed_orientation2 = np.zeros(orientation_list.shape)

        value2 = smoothed_orientation[-1, :]

        for i in range(self.num_data_points - 1, -1, -1):
            temp_value2 = quat.single_slerp(value2, smoothed_orientation[i, :],
                                            alpha)
            anglebetween = abs(
                quat.angle_between(temp_value2, orientation_list[i, :]))
            #print(anglebetween, rotlimit)
            if begin_curve < anglebetween <= rotlimit:
                smoothinterp = smooth + (anglebetween - begin_curve) * (
                    smooth2 - smooth) / (rotlimit - begin_curve)
                alphainterp = 1 - np.exp(
                    -(1 / self.gyro_sample_rate) / smoothinterp)
                temp_value2 = quat.single_slerp(value2,
                                                smoothed_orientation[i, :],
                                                alphainterp)

            elif anglebetween > rotlimit:  # new smoothed orientation over angle limit
                temp_value2 = quat.single_slerp(value2,
                                                smoothed_orientation[i, :],
                                                alpha2)

            value2 = temp_value2
            smoothed_orientation2[i] = value2

        return times, smoothed_orientation2