00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <gtest/gtest.h>
00031
00032 #include <mcl_3dl/motion_prediction_models/motion_prediction_model_differential_drive.h>
00033
00034 static const double EPS = 1.0e-6;
00035
00036 TEST(TestMotionPredictionModelDifferentialDrive, predictWithoutNoise)
00037 {
00038 const mcl_3dl::Vec3 relative_trans(0.5, -0.1, 0.1);
00039 const mcl_3dl::Quat relative_quat(mcl_3dl::Vec3(0.1, -0.1, 0.3));
00040
00041 const mcl_3dl::State6DOF odom_prev(mcl_3dl::Vec3(1.0, 1.1, 1.2), mcl_3dl::Vec3(0.3, 0.2, 0.1));
00042 const mcl_3dl::State6DOF odom_current(odom_prev.pos_ + odom_prev.rot_ * relative_trans,
00043 odom_prev.rot_ * relative_quat);
00044
00045 const mcl_3dl::Vec3 state_trans(1.5, 1.2, 1.3);
00046 const mcl_3dl::Quat state_quat(mcl_3dl::Vec3(-0.3, -0.2, -0.1));
00047 mcl_3dl::State6DOF state(state_trans, state_quat);
00048 state.noise_ll_ = 0.0;
00049 state.noise_la_ = 0.0;
00050 state.noise_al_ = 0.0;
00051 state.noise_aa_ = 0.0;
00052
00053 mcl_3dl::MotionPredictionModelDifferentialDrive predictor(10.0, 10.0);
00054 predictor.setOdoms(odom_prev, odom_current, 1.0);
00055 predictor.predict(state);
00056
00057 const auto expected_state_pos = state_trans + state_quat * relative_trans;
00058 EXPECT_NEAR(state.pos_.x_, expected_state_pos.x_, EPS);
00059 EXPECT_NEAR(state.pos_.y_, expected_state_pos.y_, EPS);
00060 EXPECT_NEAR(state.pos_.z_, expected_state_pos.z_, EPS);
00061
00062 const mcl_3dl::Quat expected_state_rot = state_quat * relative_quat;
00063 EXPECT_NEAR(state.rot_.x_, expected_state_rot.x_, EPS);
00064 EXPECT_NEAR(state.rot_.y_, expected_state_rot.y_, EPS);
00065 EXPECT_NEAR(state.rot_.z_, expected_state_rot.z_, EPS);
00066 EXPECT_NEAR(state.rot_.w_, expected_state_rot.w_, EPS);
00067
00068
00069 EXPECT_NEAR(state.odom_err_integ_lin_.x_, 0.0, EPS);
00070 EXPECT_NEAR(state.odom_err_integ_lin_.y_, 0.0, EPS);
00071 EXPECT_NEAR(state.odom_err_integ_lin_.z_, 0.0, EPS);
00072 EXPECT_NEAR(state.odom_err_integ_ang_.x_, 0.0, EPS);
00073 EXPECT_NEAR(state.odom_err_integ_ang_.y_, 0.0, EPS);
00074 EXPECT_NEAR(state.odom_err_integ_ang_.z_, 0.0, EPS);
00075 }
00076
00077 TEST(TestMotionPredictionModelDifferentialDrive, predictWithoutRotation)
00078 {
00079 const mcl_3dl::Vec3 relative_trans(-0.5, 0.1, 0.05);
00080 const float relative_trans_norm = relative_trans.norm();
00081
00082 const mcl_3dl::State6DOF odom_prev(mcl_3dl::Vec3(5.0, 4.0, 3.0), mcl_3dl::Vec3(0.5, 0.4, 0.3));
00083 const mcl_3dl::State6DOF odom_current(odom_prev.pos_ + odom_prev.rot_ * relative_trans, odom_prev.rot_);
00084
00085 const mcl_3dl::Vec3 state_trans(4.0, 3.0, 2.0);
00086 const float state_yaw_angle = 0.3;
00087 const mcl_3dl::Quat state_quat(mcl_3dl::Vec3(0.0, 0.0, state_yaw_angle));
00088 mcl_3dl::State6DOF state(state_trans, state_quat);
00089 state.noise_ll_ = 0.1;
00090 state.noise_al_ = 0.2;
00091 state.noise_la_ = 0.3;
00092 state.noise_aa_ = 0.4;
00093
00094 const float err_integ_multiply = 0.9;
00095 mcl_3dl::MotionPredictionModelDifferentialDrive predictor(10.0, 10.0);
00096 predictor.setOdoms(odom_prev, odom_current, 1.0);
00097 predictor.predict(state);
00098
00099 const auto expected_state_pos = state_trans + state_quat * relative_trans * (1.0 + state.noise_ll_);
00100 EXPECT_NEAR(state.pos_.x_, expected_state_pos.x_, EPS);
00101 EXPECT_NEAR(state.pos_.y_, expected_state_pos.y_, EPS);
00102 EXPECT_NEAR(state.pos_.z_, expected_state_pos.z_, EPS);
00103
00104 const float yaw_diff = state.noise_la_ * relative_trans_norm;
00105 const mcl_3dl::Quat expected_state_quat(mcl_3dl::Vec3(0.0, 0.0, state_yaw_angle + yaw_diff));
00106 EXPECT_NEAR(state.rot_.x_, expected_state_quat.x_, EPS);
00107 EXPECT_NEAR(state.rot_.y_, expected_state_quat.y_, EPS);
00108 EXPECT_NEAR(state.rot_.z_, expected_state_quat.z_, EPS);
00109 EXPECT_NEAR(state.rot_.w_, expected_state_quat.w_, EPS);
00110
00111 const auto expected_odom_err_integ_lin = (relative_trans * state.noise_ll_) * err_integ_multiply;
00112 EXPECT_NEAR(state.odom_err_integ_lin_.x_, expected_odom_err_integ_lin.x_, EPS);
00113 EXPECT_NEAR(state.odom_err_integ_lin_.y_, expected_odom_err_integ_lin.y_, EPS);
00114 EXPECT_NEAR(state.odom_err_integ_lin_.z_, expected_odom_err_integ_lin.z_, EPS);
00115
00116 const float expected_odom_err_integ_acc_z = yaw_diff * err_integ_multiply;
00117 EXPECT_NEAR(state.odom_err_integ_ang_.x_, 0.0, EPS);
00118 EXPECT_NEAR(state.odom_err_integ_ang_.y_, 0.0, EPS);
00119 EXPECT_NEAR(state.odom_err_integ_ang_.z_, expected_odom_err_integ_acc_z, EPS);
00120 }
00121
00122 TEST(TestMotionPredictionModelDifferentialDrive, predictWithoutTranslationAndRollPitch)
00123 {
00124 const float relative_yaw_angle = 0.2;
00125 const mcl_3dl::Quat relative_quat(mcl_3dl::Vec3(0.0, 0.0, relative_yaw_angle));
00126
00127 const mcl_3dl::State6DOF odom_prev(mcl_3dl::Vec3(-5.0, -2.0, -3.0), mcl_3dl::Vec3(0.5, 1.0, 2.0));
00128 const mcl_3dl::State6DOF odom_current(odom_prev.pos_, odom_prev.rot_ * relative_quat);
00129
00130 const mcl_3dl::Vec3 state_trans(-5.5, -3.0, -2.0);
00131 const float state_yaw_angle = 0.3;
00132 const mcl_3dl::Quat state_quat(mcl_3dl::Vec3(0.0, 0.0, state_yaw_angle));
00133 mcl_3dl::State6DOF state(state_trans, state_quat);
00134 state.noise_ll_ = 0.1;
00135 state.noise_al_ = 0.2;
00136 state.noise_la_ = 0.3;
00137 state.noise_aa_ = 0.4;
00138
00139 const float err_integ_multiply = 1.0 - (1.0 / 10.0);
00140 mcl_3dl::MotionPredictionModelDifferentialDrive predictor(10.0, 10.0);
00141 predictor.setOdoms(odom_prev, odom_current, 1.0);
00142 predictor.predict(state);
00143
00144 const auto expected_state_pos =
00145 state_trans + state_quat * mcl_3dl::Vec3(state.noise_al_ * relative_yaw_angle, 0.0, 0.0);
00146 EXPECT_NEAR(state.pos_.x_, expected_state_pos.x_, EPS);
00147 EXPECT_NEAR(state.pos_.y_, expected_state_pos.y_, EPS);
00148 EXPECT_NEAR(state.pos_.z_, expected_state_pos.z_, EPS);
00149
00150 const float yaw_diff = state.noise_aa_ * relative_yaw_angle;
00151 const mcl_3dl::Quat expected_state_quat(mcl_3dl::Vec3(0.0, 0.0, relative_yaw_angle + state_yaw_angle + yaw_diff));
00152 EXPECT_NEAR(state.rot_.x_, expected_state_quat.x_, EPS);
00153 EXPECT_NEAR(state.rot_.y_, expected_state_quat.y_, EPS);
00154 EXPECT_NEAR(state.rot_.z_, expected_state_quat.z_, EPS);
00155 EXPECT_NEAR(state.rot_.w_, expected_state_quat.w_, EPS);
00156
00157 const auto expected_odom_err_integ_lin =
00158 mcl_3dl::Vec3(state.noise_al_ * relative_yaw_angle, 0.0, 0.0) * err_integ_multiply;
00159 EXPECT_NEAR(state.odom_err_integ_lin_.x_, expected_odom_err_integ_lin.x_, EPS);
00160 EXPECT_NEAR(state.odom_err_integ_lin_.y_, expected_odom_err_integ_lin.y_, EPS);
00161 EXPECT_NEAR(state.odom_err_integ_lin_.z_, expected_odom_err_integ_lin.z_, EPS);
00162
00163 const float expected_odom_err_integ_acc_z = yaw_diff * err_integ_multiply;
00164 EXPECT_NEAR(state.odom_err_integ_ang_.x_, 0.0, EPS);
00165 EXPECT_NEAR(state.odom_err_integ_ang_.y_, 0.0, EPS);
00166 EXPECT_NEAR(state.odom_err_integ_ang_.z_, expected_odom_err_integ_acc_z, EPS);
00167 }
00168
00169 TEST(TestMotionPredictionModelDifferentialDrive, predictWithoutRollPitch)
00170 {
00171 const mcl_3dl::Vec3 relative_trans(1.0, 0.2, 0.3);
00172 const float relative_trans_norm = relative_trans.norm();
00173 const float relative_yaw_angle = 0.2;
00174 const mcl_3dl::Quat relative_quat(mcl_3dl::Vec3(0.0, 0.0, relative_yaw_angle));
00175
00176 const mcl_3dl::State6DOF odom_prev(mcl_3dl::Vec3(10.0, -5.0, 0.5), mcl_3dl::Vec3(-2.0, -1.0, -0.5));
00177 const mcl_3dl::State6DOF odom_current(odom_prev.pos_ + odom_prev.rot_ * relative_trans,
00178 odom_prev.rot_ * relative_quat);
00179
00180 const mcl_3dl::Vec3 state_trans(11.0, -5.0, 1.0);
00181 const float state_yaw_angle = 0.3;
00182 const mcl_3dl::Quat state_quat(mcl_3dl::Vec3(0.0, 0.0, state_yaw_angle));
00183 mcl_3dl::State6DOF state(state_trans, state_quat);
00184 state.noise_ll_ = 0.1;
00185 state.noise_al_ = 0.2;
00186 state.noise_la_ = 0.3;
00187 state.noise_aa_ = 0.4;
00188
00189 const float err_integ_multiply = 1.0 - (1.0 / 10.0);
00190 mcl_3dl::MotionPredictionModelDifferentialDrive predictor(10.0, 10.0);
00191 predictor.setOdoms(odom_prev, odom_current, 1.0);
00192 predictor.predict(state);
00193
00194 const auto expected_state_pos = state_trans +
00195 state_quat * (relative_trans * (1.0 + state.noise_ll_) +
00196 mcl_3dl::Vec3(state.noise_al_ * relative_yaw_angle, 0.0, 0.0));
00197 EXPECT_NEAR(state.pos_.x_, expected_state_pos.x_, EPS);
00198 EXPECT_NEAR(state.pos_.y_, expected_state_pos.y_, EPS);
00199 EXPECT_NEAR(state.pos_.z_, expected_state_pos.z_, EPS);
00200
00201 const double yaw_diff = state.noise_la_ * relative_trans_norm + state.noise_aa_ * relative_yaw_angle;
00202 const mcl_3dl::Quat expected_state_quat(mcl_3dl::Vec3(0.0, 0.0, relative_yaw_angle + state_yaw_angle + yaw_diff));
00203 EXPECT_NEAR(state.rot_.x_, expected_state_quat.x_, EPS);
00204 EXPECT_NEAR(state.rot_.y_, expected_state_quat.y_, EPS);
00205 EXPECT_NEAR(state.rot_.z_, expected_state_quat.z_, EPS);
00206 EXPECT_NEAR(state.rot_.w_, expected_state_quat.w_, EPS);
00207
00208 const auto expected_odom_err_integ_lin =
00209 (relative_trans * state.noise_ll_ + mcl_3dl::Vec3(state.noise_al_ * relative_yaw_angle, 0.0, 0.0)) *
00210 err_integ_multiply;
00211 EXPECT_NEAR(state.odom_err_integ_lin_.x_, expected_odom_err_integ_lin.x_, EPS);
00212 EXPECT_NEAR(state.odom_err_integ_lin_.y_, expected_odom_err_integ_lin.y_, EPS);
00213 EXPECT_NEAR(state.odom_err_integ_lin_.z_, expected_odom_err_integ_lin.z_, EPS);
00214
00215 const float expected_odom_err_integ_acc_z = yaw_diff * err_integ_multiply;
00216 EXPECT_NEAR(state.odom_err_integ_ang_.x_, 0.0, EPS);
00217 EXPECT_NEAR(state.odom_err_integ_ang_.y_, 0.0, EPS);
00218 EXPECT_NEAR(state.odom_err_integ_ang_.z_, expected_odom_err_integ_acc_z, EPS);
00219 }
00220
00221 int main(int argc, char** argv)
00222 {
00223 testing::InitGoogleTest(&argc, argv);
00224
00225 return RUN_ALL_TESTS();
00226 }