diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index efb89ade080ff6f322fca52d4476587f1578f894..fe61ea7930cdf1b12aeaf23c806774ac4c3b8364 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -148,6 +148,13 @@ ENDIF(vision_utils_FOUND) wolf_add_gtest(gtest_constraint_gnss_fix_2D gtest_constraint_gnss_fix_2D.cpp) target_link_libraries(gtest_constraint_gnss_fix_2D ${PROJECT_NAME}) +# ConstraintGnssFix2D test +wolf_add_gtest(gtest_constraint_gnss_fix_2D_1 gtest_constraint_gnss_fix_2D_1.cpp) +target_link_libraries(gtest_constraint_gnss_fix_2D_1 ${PROJECT_NAME}) +# ConstraintGnssFix2D test +wolf_add_gtest(gtest_constraint_gnss_fix_2D_2 gtest_constraint_gnss_fix_2D_2.cpp) +target_link_libraries(gtest_constraint_gnss_fix_2D_2 ${PROJECT_NAME}) + # ConstraintGnssFix2D test wolf_add_gtest(gtest_constraint_gnss_fix_2D_simple gtest_constraint_gnss_fix_2D_simple.cpp) target_link_libraries(gtest_constraint_gnss_fix_2D_simple ${PROJECT_NAME}) diff --git a/test/gtest_constraint_gnss_fix_2D_1.cpp b/test/gtest_constraint_gnss_fix_2D_1.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3eac818ce578912b00e2461d5b8b37eb2afcafb5 --- /dev/null +++ b/test/gtest_constraint_gnss_fix_2D_1.cpp @@ -0,0 +1,155 @@ +/** + * \file gtest_constraint_gnss_fix_2D.cpp + * + * Created on: Aug 1, 2018 + * \author: jvallve + */ + + +#include "base/constraint/constraint_gnss_fix_2D.h" +#include "utils_gtest.h" + +#include "base/capture/capture_motion.h" +#include "base/problem.h" +#include "base/sensor/sensor_gnss.h" +#include "base/processor/processor_gnss_fix.h" + +#include "base/ceres_wrapper/ceres_manager.h" + + +using namespace Eigen; +using namespace wolf; +using std::cout; +using std::endl; + + +class ConstraintGnssFix2DTest : public testing::Test +{ + public: + + // groundtruth transformations + Vector3s t_ecef_enu; + Matrix3s R_ecef_enu, R_enu_map, R_map_base; + Vector3s t_base_antena, t_ecef_antena; + Vector1s o_enu_map; + Vector3s t_enu_map; + Vector3s t_map_base; + Vector1s o_map_base; + + // WOLF + ProblemPtr problem_ptr; + CeresManagerPtr ceres_mgr_ptr; + SensorGnssPtr gnss_sensor_ptr; + + ConstraintGnssFix2DTest() + { + o_enu_map << 2.6; + t_enu_map << 12, -34, 4; + t_map_base << 32, -34, 0; // z=0 + o_map_base << -0.4; + t_base_antena << 3,-2,8;// Antena extrinsics + t_ecef_enu << 100,30,50; + R_ecef_enu = (AngleAxis<Scalar>(1.3, Vector3s::UnitX()) + *AngleAxis<Scalar>(-2.2, Vector3s::UnitY()) + *AngleAxis<Scalar>(-1.8, Vector3s::UnitZ())).toRotationMatrix(); + R_enu_map = AngleAxis<Scalar>(o_enu_map(0), Vector3s::UnitZ()).toRotationMatrix(); + R_map_base = Matrix3s::Identity(); + R_map_base.topLeftCorner(2,2) = Rotation2D<Scalar>(o_map_base(0)).matrix(); + t_ecef_antena = R_ecef_enu * R_enu_map * (R_map_base * t_base_antena + t_map_base) + t_ecef_enu; + + // ---------------------------------------------------- + // Problem and solver + problem_ptr = Problem::create("PO 2D"); + ceres_mgr_ptr = std::make_shared<CeresManager>(problem_ptr); + ceres_mgr_ptr->getSolverOptions().max_num_iterations = 100; + + // gnss sensor & processor + gnss_sensor_ptr = std::static_pointer_cast<SensorGnss>(problem_ptr->installSensor("GNSS", "gnss", t_base_antena, std::make_shared<IntrinsicsBase>())); + gnss_sensor_ptr->getEnuMapTranslationStatePtr()->setState(t_enu_map); + gnss_sensor_ptr->getEnuMapYawStatePtr()->setState(o_enu_map); + gnss_sensor_ptr->getEnuMapRollStatePtr()->fix(); + gnss_sensor_ptr->getEnuMapPitchStatePtr()->fix(); + gnss_sensor_ptr->setEnuEcef(R_ecef_enu.transpose(), R_ecef_enu.transpose()*(-t_ecef_enu)); + std::cout << "gnss sensor installed" << std::endl; + ProcessorParamsGnssFixPtr gnss_params_ptr = std::make_shared<ProcessorParamsGnssFix>(); + gnss_params_ptr->time_tolerance = -1.0; + gnss_params_ptr->voting_active = true; + problem_ptr->installProcessor("GNSS FIX", "gnss fix", gnss_sensor_ptr, gnss_params_ptr); + std::cout << "gnss processor installed" << std::endl; + + // set prior (FIXED) + Eigen::Vector3s frame_pose; + frame_pose << t_map_base.head(2), o_map_base; + FrameBasePtr prior_frame_ptr = problem_ptr->setPrior(frame_pose, Matrix3s::Identity(), TimeStamp(0), Scalar(0.1)); + prior_frame_ptr->fix(); + }; + + virtual void SetUp() + { + // reset grountruth parameters + R_enu_map = AngleAxis<Scalar>(o_enu_map(0), Vector3s::UnitZ()).toRotationMatrix(); + R_map_base = Matrix3s::Identity(); + R_map_base.topLeftCorner(2,2) = Rotation2D<Scalar>(o_map_base(0)).matrix(); + t_ecef_antena = R_ecef_enu * (R_enu_map * (R_map_base * t_base_antena + t_map_base) + t_enu_map ) + t_ecef_enu; + + // Reset antena extrinsics + gnss_sensor_ptr->getPPtr()->setState(t_base_antena); + + // Reset ENU_ECEF + gnss_sensor_ptr->setEnuEcef(R_ecef_enu.transpose(), R_ecef_enu.transpose()*(-t_ecef_enu)); + } +}; + +//////////////////////////////////////////////////////// + +TEST_F(ConstraintGnssFix2DTest, check_tree) +{ + ASSERT_TRUE(problem_ptr->check(0)); +} + +/* + * Test with one GNSS fix capture. + * + * Estimating: MAP_BASE position. + * Fixed: ENU_MAP, MAP_BASE orientation, BASE_ANTENA. + */ +TEST_F(ConstraintGnssFix2DTest, gnss_1_map_base_position) +{ + // Create GNSS Fix capture + CaptureGnssFixPtr cap_gnss_ptr = std::make_shared<CaptureGnssFix>(TimeStamp(0), gnss_sensor_ptr, t_ecef_antena, 1e-3*Matrix3s::Identity()); + gnss_sensor_ptr->process(cap_gnss_ptr); + + // fixing things + gnss_sensor_ptr->getEnuMapTranslationStatePtr()->fix();// enu-map yaw translation + gnss_sensor_ptr->getEnuMapYawStatePtr()->fix();// enu-map yaw orientation + cap_gnss_ptr->getFramePtr()->getOPtr()->setState(o_map_base); // frame orientation + cap_gnss_ptr->getFramePtr()->getOPtr()->fix(); + + // distort frm position + Vector3s frm_dist = cap_gnss_ptr->getFramePtr()->getState(); + frm_dist(0) += 0.18; + frm_dist(1) += -0.58; + cap_gnss_ptr->getFramePtr()->setState(frm_dist); + + // solve for frm + std::string report = ceres_mgr_ptr->solve(SolverManager::ReportVerbosity::FULL); + + std::cout << report << std::endl; + + ASSERT_EQ(ceres_mgr_ptr->getSummary().num_parameter_blocks_reduced, 1); + ASSERT_EQ(ceres_mgr_ptr->getSummary().num_parameters_reduced, 2); + ASSERT_EQ(ceres_mgr_ptr->getSummary().num_residual_blocks_reduced, 1); + ASSERT_EQ(ceres_mgr_ptr->getSummary().num_residuals_reduced, 3); + + ASSERT_TRUE(cap_gnss_ptr->getFramePtr()->isKey()); + ASSERT_MATRIX_APPROX(cap_gnss_ptr->getFramePtr()->getState().head(2), t_map_base.head(2), 1e-6); + + cap_gnss_ptr->getFramePtr()->remove(); +} + +int main(int argc, char **argv) +{ + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} + diff --git a/test/gtest_constraint_gnss_fix_2D_2.cpp b/test/gtest_constraint_gnss_fix_2D_2.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3eac818ce578912b00e2461d5b8b37eb2afcafb5 --- /dev/null +++ b/test/gtest_constraint_gnss_fix_2D_2.cpp @@ -0,0 +1,155 @@ +/** + * \file gtest_constraint_gnss_fix_2D.cpp + * + * Created on: Aug 1, 2018 + * \author: jvallve + */ + + +#include "base/constraint/constraint_gnss_fix_2D.h" +#include "utils_gtest.h" + +#include "base/capture/capture_motion.h" +#include "base/problem.h" +#include "base/sensor/sensor_gnss.h" +#include "base/processor/processor_gnss_fix.h" + +#include "base/ceres_wrapper/ceres_manager.h" + + +using namespace Eigen; +using namespace wolf; +using std::cout; +using std::endl; + + +class ConstraintGnssFix2DTest : public testing::Test +{ + public: + + // groundtruth transformations + Vector3s t_ecef_enu; + Matrix3s R_ecef_enu, R_enu_map, R_map_base; + Vector3s t_base_antena, t_ecef_antena; + Vector1s o_enu_map; + Vector3s t_enu_map; + Vector3s t_map_base; + Vector1s o_map_base; + + // WOLF + ProblemPtr problem_ptr; + CeresManagerPtr ceres_mgr_ptr; + SensorGnssPtr gnss_sensor_ptr; + + ConstraintGnssFix2DTest() + { + o_enu_map << 2.6; + t_enu_map << 12, -34, 4; + t_map_base << 32, -34, 0; // z=0 + o_map_base << -0.4; + t_base_antena << 3,-2,8;// Antena extrinsics + t_ecef_enu << 100,30,50; + R_ecef_enu = (AngleAxis<Scalar>(1.3, Vector3s::UnitX()) + *AngleAxis<Scalar>(-2.2, Vector3s::UnitY()) + *AngleAxis<Scalar>(-1.8, Vector3s::UnitZ())).toRotationMatrix(); + R_enu_map = AngleAxis<Scalar>(o_enu_map(0), Vector3s::UnitZ()).toRotationMatrix(); + R_map_base = Matrix3s::Identity(); + R_map_base.topLeftCorner(2,2) = Rotation2D<Scalar>(o_map_base(0)).matrix(); + t_ecef_antena = R_ecef_enu * R_enu_map * (R_map_base * t_base_antena + t_map_base) + t_ecef_enu; + + // ---------------------------------------------------- + // Problem and solver + problem_ptr = Problem::create("PO 2D"); + ceres_mgr_ptr = std::make_shared<CeresManager>(problem_ptr); + ceres_mgr_ptr->getSolverOptions().max_num_iterations = 100; + + // gnss sensor & processor + gnss_sensor_ptr = std::static_pointer_cast<SensorGnss>(problem_ptr->installSensor("GNSS", "gnss", t_base_antena, std::make_shared<IntrinsicsBase>())); + gnss_sensor_ptr->getEnuMapTranslationStatePtr()->setState(t_enu_map); + gnss_sensor_ptr->getEnuMapYawStatePtr()->setState(o_enu_map); + gnss_sensor_ptr->getEnuMapRollStatePtr()->fix(); + gnss_sensor_ptr->getEnuMapPitchStatePtr()->fix(); + gnss_sensor_ptr->setEnuEcef(R_ecef_enu.transpose(), R_ecef_enu.transpose()*(-t_ecef_enu)); + std::cout << "gnss sensor installed" << std::endl; + ProcessorParamsGnssFixPtr gnss_params_ptr = std::make_shared<ProcessorParamsGnssFix>(); + gnss_params_ptr->time_tolerance = -1.0; + gnss_params_ptr->voting_active = true; + problem_ptr->installProcessor("GNSS FIX", "gnss fix", gnss_sensor_ptr, gnss_params_ptr); + std::cout << "gnss processor installed" << std::endl; + + // set prior (FIXED) + Eigen::Vector3s frame_pose; + frame_pose << t_map_base.head(2), o_map_base; + FrameBasePtr prior_frame_ptr = problem_ptr->setPrior(frame_pose, Matrix3s::Identity(), TimeStamp(0), Scalar(0.1)); + prior_frame_ptr->fix(); + }; + + virtual void SetUp() + { + // reset grountruth parameters + R_enu_map = AngleAxis<Scalar>(o_enu_map(0), Vector3s::UnitZ()).toRotationMatrix(); + R_map_base = Matrix3s::Identity(); + R_map_base.topLeftCorner(2,2) = Rotation2D<Scalar>(o_map_base(0)).matrix(); + t_ecef_antena = R_ecef_enu * (R_enu_map * (R_map_base * t_base_antena + t_map_base) + t_enu_map ) + t_ecef_enu; + + // Reset antena extrinsics + gnss_sensor_ptr->getPPtr()->setState(t_base_antena); + + // Reset ENU_ECEF + gnss_sensor_ptr->setEnuEcef(R_ecef_enu.transpose(), R_ecef_enu.transpose()*(-t_ecef_enu)); + } +}; + +//////////////////////////////////////////////////////// + +TEST_F(ConstraintGnssFix2DTest, check_tree) +{ + ASSERT_TRUE(problem_ptr->check(0)); +} + +/* + * Test with one GNSS fix capture. + * + * Estimating: MAP_BASE position. + * Fixed: ENU_MAP, MAP_BASE orientation, BASE_ANTENA. + */ +TEST_F(ConstraintGnssFix2DTest, gnss_1_map_base_position) +{ + // Create GNSS Fix capture + CaptureGnssFixPtr cap_gnss_ptr = std::make_shared<CaptureGnssFix>(TimeStamp(0), gnss_sensor_ptr, t_ecef_antena, 1e-3*Matrix3s::Identity()); + gnss_sensor_ptr->process(cap_gnss_ptr); + + // fixing things + gnss_sensor_ptr->getEnuMapTranslationStatePtr()->fix();// enu-map yaw translation + gnss_sensor_ptr->getEnuMapYawStatePtr()->fix();// enu-map yaw orientation + cap_gnss_ptr->getFramePtr()->getOPtr()->setState(o_map_base); // frame orientation + cap_gnss_ptr->getFramePtr()->getOPtr()->fix(); + + // distort frm position + Vector3s frm_dist = cap_gnss_ptr->getFramePtr()->getState(); + frm_dist(0) += 0.18; + frm_dist(1) += -0.58; + cap_gnss_ptr->getFramePtr()->setState(frm_dist); + + // solve for frm + std::string report = ceres_mgr_ptr->solve(SolverManager::ReportVerbosity::FULL); + + std::cout << report << std::endl; + + ASSERT_EQ(ceres_mgr_ptr->getSummary().num_parameter_blocks_reduced, 1); + ASSERT_EQ(ceres_mgr_ptr->getSummary().num_parameters_reduced, 2); + ASSERT_EQ(ceres_mgr_ptr->getSummary().num_residual_blocks_reduced, 1); + ASSERT_EQ(ceres_mgr_ptr->getSummary().num_residuals_reduced, 3); + + ASSERT_TRUE(cap_gnss_ptr->getFramePtr()->isKey()); + ASSERT_MATRIX_APPROX(cap_gnss_ptr->getFramePtr()->getState().head(2), t_map_base.head(2), 1e-6); + + cap_gnss_ptr->getFramePtr()->remove(); +} + +int main(int argc, char **argv) +{ + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} +