rpng / open_vins

An open source platform for visual-inertial navigation research.
https://docs.openvins.com
GNU General Public License v3.0
2.13k stars 630 forks source link

The problem about Eval toolbox #151

Closed NEU-LC closed 3 years ago

NEU-LC commented 3 years ago

https://github.com/rpng/open_vins/blob/e516f7c564c2159b7edfb42a8230b732bf6aebc2/ov_eval/src/calc/ResultTrajectory.cpp#L203 Hello, I have a question about the code in the void ResultTrajectory::calculate_rpe(const std::vector<double> &segment_lengths, std::map<double,std::pair<Statistics,Statistics>> &error_rpe) . Is the groundtruth format: "qx qy qz qw ..."? And the rotation is world to body? So if I want to use the toolbox, do I need to save the groundtruth as the format of world to bodt.

            // Get T I1 to world GT at beginning of subtrajectory (at state idx)
            Eigen::Matrix4d T_m1 = Eigen::Matrix4d::Identity();
            T_m1.block(0, 0, 3, 3) = Math::quat_2_Rot(gt_poses.at(id_start).block(3,0,4,1)).transpose();
            T_m1.block(0, 3, 3, 1) = gt_poses.at(id_start).block(0,0,3,1);

            // Get T I2 to world GT at end of subtrajectory starting (at state comparisons[idx])
            Eigen::Matrix4d T_m2 = Eigen::Matrix4d::Identity();
            T_m2.block(0, 0, 3, 3) = Math::quat_2_Rot(gt_poses.at(id_end).block(3,0,4,1)).transpose();
            T_m2.block(0, 3, 3, 1) = gt_poses.at(id_end).block(0,0,3,1);

            // Get T I2 to I1 GT
            Eigen::Matrix4d T_m1_m2 = Math::Inv_se3(T_m1) * T_m2;

But According this code Eigen::Matrix4d T_m1_m2 = Math::Inv_se3(T_m1) * T_m2; The T_m1 or T_m2 should be the body to world. But why transpose the rotation matrix in the GroundTruth. But in general, the format of the Groundtruth should be body to world, such as ASL.

nmerrill67 commented 3 years ago

The quaternion is world to body in JPL format, or equivalently body to world in Hamilton format. The quat_2_Rot function and the rest of OpenVINS uses the JPL format, but if it was Hamilton then the quaternion would create a body to world rotation matrix. This is also explained in this comment.

NEU-LC commented 3 years ago

The quaternion is world to body in JPL format, or equivalently body to world in Hamilton format. The quat_2_Rot function and the rest of OpenVINS uses the JPL format, but if it was Hamilton then the quaternion would create a body to world rotation matrix. This is also explained in this comment.

Thanks for your reply. My understanding is that the Groundtruth format of the EUROC dataset is w, x, y, z, Body to World. Openvins uses a quaternion in the format of JPL to convert the quaternion into a rotation matrix

    inline Eigen::Matrix<double, 3, 3> quat_2_Rot(const Eigen::Matrix<double, 4, 1> &q) {
        Eigen::Matrix<double, 3, 3> q_x = skew_x(q.block(0, 0, 3, 1));
        Eigen::MatrixXd Rot = (2 * std::pow(q(3, 0), 2) - 1) * Eigen::MatrixXd::Identity(3, 3)
                              - 2 * q(3, 0) * q_x +
                              2 * q.block(0, 0, 3, 1) * (q.block(0, 0, 3, 1).transpose());
        return Rot;
    }

But the return value is equivalent to world to body in the Euroc Groundtruth. Because transpose() in the code.

goldbattle commented 3 years ago

This work by Joan Sola can provide a bit more detail if you want to investigate more: https://arxiv.org/pdf/1711.02508.pdf image

Feel free to close the issue if this clarifies how we read in orientations. Once they are loaded, you can always reference the variable naming conventions which should exactly describe what any variable is.