test_motion_prediction_model_differential_drive.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2019, the mcl_3dl authors
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *
00008  *     * Redistributions of source code must retain the above copyright
00009  *       notice, this list of conditions and the following disclaimer.
00010  *     * Redistributions in binary form must reproduce the above copyright
00011  *       notice, this list of conditions and the following disclaimer in the
00012  *       documentation and/or other materials provided with the distribution.
00013  *     * Neither the name of the copyright holder nor the names of its
00014  *       contributors may be used to endorse or promote products derived from
00015  *       this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00021  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00027  * POSSIBILITY OF SUCH DAMAGE.
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   // odom_err_integ_lin_ and odom_err_integ_ang_ are zero vectors.
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);  // single step of the exponential smoother
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);  // single step of the exponential smoother
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 }


mcl_3dl
Author(s): Atsushi Watanabe
autogenerated on Thu Jun 20 2019 20:04:43