diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0283d709e05c8ee46d06041ddc61a62de32c4950..4e669f9de1fcdf5e428c21037e9424a188f5e4db 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -69,12 +69,16 @@ yaml_templates_generation: stage: yaml_templates image: labrobotica/wolf_deps:20.04 cache: + - key: wolf-focal + paths: + - ci_deps/wolf/ - key: yamlschemacpp-focal paths: - ci_deps/yaml-schema-cpp/ before_script: - *preliminaries_definition - !reference [.install_yamlschemacpp_script] + - !reference [.install_wolf_script] script: - !reference [.generate_yaml_templates_script] diff --git a/CMakeLists.txt b/CMakeLists.txt index 7a79ed9a306a55b18844fbfb3fb8e79dc75ceb15..fa4b2502cd1fb86c1481aa2334197b820cdf94b6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -144,8 +144,6 @@ SET(SRCS_PROCESSOR src/processor/processor_compass.cpp src/processor/processor_imu_2d.cpp src/processor/processor_imu_3d.cpp - test/processor_imu_3d_tester.cpp - test/processor_imu_2d_tester.cpp ) SET(SRCS_SENSOR src/sensor/sensor_compass.cpp diff --git a/demos/demo_factor_imu_3d.cpp b/demos/demo_factor_imu_3d.cpp deleted file mode 100644 index 5896ff0066c4407519d1d0abfe938bfb18c68ddb..0000000000000000000000000000000000000000 --- a/demos/demo_factor_imu_3d.cpp +++ /dev/null @@ -1,299 +0,0 @@ -// WOLF - Copyright (C) 2020,2021,2022,2023 -// Institut de Robòtica i Informà tica Industrial, CSIC-UPC. -// Authors: Joan Solà Ortega (jsola@iri.upc.edu) and -// Joan Vallvé Navarro (jvallve@iri.upc.edu) -// All rights reserved. -// -// This file is part of WOLF: http://www.iri.upc.edu/wolf -// WOLF is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. - -//Wolf -#include <core/ceres_wrapper/solver_ceres.h> - -#include "core/capture/capture_imu.h" -#include "core/processor/processor_imu_3d.h" -#include "core/sensor/sensor_imu.h" -#include "core/capture/capture_pose.h" -#include "core/common/wolf.h" -#include "core/problem/problem.h" -#include "core/factor/factor_odom_3D.h" -#include "core/state_block/state_block.h" -#include "core/state_block/state_quaternion.h" - -//#define DEBUG_RESULTS - -int main(int argc, char** argv) -{ - using namespace wolf; - using std::shared_ptr; - using std::make_shared; - using std::static_pointer_cast; - - std::cout << std::endl << "==================== test_factor_imu ======================" << std::endl; - - bool c0(false), c1(false);// c2(true), c3(true), c4(true); - // Wolf problem - ProblemPtr wolf_problem_ptr_ = Problem::create("PQVBB 3D"); - Eigen::VectorXd IMU_extrinsics(7); - IMU_extrinsics << 0,0,0, 0,0,0,1; // IMU pose in the robot - SensorBasePtr sensor_ptr = wolf_problem_ptr_->installSensor("IMU", "Main IMU", IMU_extrinsics, shared_ptr<IntrinsicsBase>()); - wolf_problem_ptr_->installProcessor("IMU", "IMU pre-integrator", "Main IMU", ""); - - // Ceres wrappers - SolverCeres* ceres_manager_wolf_diff = new SolverCeres(wolf_problem_ptr_); - ceres_manager_wolf_diff->getSolverOptions().minimizer_type = ceres::TRUST_REGION; //ceres::TRUST_REGION;ceres::LINE_SEARCH - ceres_manager_wolf_diff->getSolverOptions().max_line_search_step_contraction = 1e-3; - ceres_manager_wolf_diff->getSolverOptions().max_num_iterations = 1e4; - - // Time and data variables - TimeStamp t; - Eigen::Vector6d data_; - double mpu_clock = 0; - - t.set(mpu_clock); - - // Set the origin - Eigen::VectorXd x0(16); - x0 << 0,0,0, 0,0,0,1, 0,0,0, 0,0,.001, 0,0,.002; // Try some non-zero biases - wolf_problem_ptr_->getMotionProvider()->setOrigin(x0, t); //this also creates a keyframe at origin - wolf_problem_ptr_->getTrajectory()->getFrameList().front()->fix(); //fix the keyframe at origin - - TimeStamp ts(0); - Eigen::VectorXd origin_state = x0; - - // Create one capture to store the IMU data arriving from (sensor / callback / file / etc.) - CaptureIMUPtr imu_ptr( std::make_shared<CaptureIMU>(t, sensor_ptr, data_, Eigen::Matrix6d::Identity()) ); - imu_ptr->setFrame(wolf_problem_ptr_->getTrajectory()->getFrameList().back()); - - // set variables - using namespace std; - Eigen::VectorXd state_vec; - Eigen::VectorXd delta_preint; - //FrameIMUPtr last_frame; - Eigen::Matrix<double,9,9> delta_preint_cov; - - //process data - mpu_clock = 0.001003; - //data_ << 0.579595, -0.143701, 9.939331, 0.127445, 0.187814, -0.055003; - data_ << 0.0, 0.0, 9.81, 0.0, 0.0, 0.0; - t.set(mpu_clock); - // assign data to capture - imu_ptr->setData(data_); - imu_ptr->setTimeStamp(t); - // process data in capture - sensor_ptr->process(imu_ptr); - - if(c0){ - /// ******************************************************************************************** /// - /// factor creation - //create FrameIMU - ts = wolf_problem_ptr_->getMotionProvider()->getBuffer().back().ts_; - state_vec = wolf_problem_ptr_->getMotionProvider()->getCurrentState(); - FrameIMUPtr last_frame = std::make_shared<FrameIMU>(KEY, ts, state_vec); - wolf_problem_ptr_->getTrajectory()->addFrame(last_frame); - - //create a feature - delta_preint_cov = wolf_problem_ptr_->getMotionProvider()->getCurrentDeltaPreintCov(); - delta_preint = wolf_problem_ptr_->getMotionProvider()->getMotion().delta_integr_; - std::shared_ptr<FeatureIMU> feat_imu = std::make_shared<FeatureIMU>(delta_preint, delta_preint_cov); - feat_imu->setCapture(imu_ptr); - - //create a factorIMU - FactorIMUPtr factor_imu = std::make_shared<FactorIMU>(feat_imu, last_frame); - feat_imu->addFactor(factor_imu); - last_frame->addConstrainedBy(factor_imu); - - FrameIMUPtr ref_frame_ptr(std::static_pointer_cast<FrameIMU>(imu_ptr->getFrame())); - - Eigen::Matrix<double, 10, 1> expect; - Eigen::Vector3d ref_frame_p = ref_frame_ptr->getP()->getVector(); - Eigen::Quaterniond ref_frame_o(ref_frame_ptr->getO()->getVector().data()); - Eigen::Vector3d ref_frame_v = ref_frame_ptr->getV()->getVector(); - Eigen::Vector3d current_frame_p = last_frame->getP()->getVector(); - Eigen::Quaterniond current_frame_o(last_frame->getO()->getVector().data()); - Eigen::Vector3d current_frame_v = last_frame->getV()->getVector(); - Eigen::Vector3d acc_bias(ref_frame_ptr->getAccBias()->getVector()), gyro_bias(ref_frame_ptr->getGyroBias()->getVector()); - Eigen::Matrix<double, 9, 1> residu; - residu << 0,0,0, 0,0,0, 0,0,0; - - factor_imu->expectation(ref_frame_p, ref_frame_o, ref_frame_v, current_frame_p, current_frame_o, current_frame_v, expect); - std::cout << "expectation : " << expect.transpose() << std::endl; - - factor_imu->getResiduals(ref_frame_p, ref_frame_o, ref_frame_v, acc_bias, gyro_bias, current_frame_p, current_frame_o, current_frame_v,residu); - std::cout << "residuals : " << residu.transpose() << std::endl; - - //reset origin of motion to new frame - wolf_problem_ptr_->getMotionProvider()->setOrigin(last_frame); - imu_ptr->setFrame(last_frame); - } - /// ******************************************************************************************** /// - - mpu_clock = 0.002135; - //data_ << 0.581990, -0.191602, 10.071057, 0.136836, 0.203912, -0.057686; - data_ << 0.0, 0.0, 9.81, 0.0, 0.0, 0.0; - t.set(mpu_clock); - imu_ptr->setData(data_); - imu_ptr->setTimeStamp(t); - sensor_ptr->process(imu_ptr); - - mpu_clock = 0.003040; - //data_ << 0.596360, -0.225132, 10.205178, 0.154276, 0.174399, -0.036221; - data_ << 0.0, 0.0, 9.81, 0.0, 0.0, 0.0; - t.set(mpu_clock); - imu_ptr->setData(data_); - imu_ptr->setTimeStamp(t); - sensor_ptr->process(imu_ptr); - - if(c1){ - /// ******************************************************************************************** /// - /// factor creation - //create FrameIMU - ts = wolf_problem_ptr_->getMotionProvider()->getBuffer().back().ts_; - state_vec = wolf_problem_ptr_->getMotionProvider()->getCurrentState(); - FrameIMUPtr last_frame = std::make_shared<FrameIMU>(KEY, ts, state_vec); - wolf_problem_ptr_->getTrajectory()->addFrame(last_frame); - - //create a feature - delta_preint_cov = wolf_problem_ptr_->getMotionProvider()->getCurrentDeltaPreintCov(); - delta_preint = wolf_problem_ptr_->getMotionProvider()->getMotion().delta_integr_; - std::shared_ptr<FeatureIMU> feat_imu = std::make_shared<FeatureIMU>(delta_preint, delta_preint_cov); - feat_imu->setCapture(imu_ptr); - - //create a factorIMU - FactorIMUPtr factor_imu = std::make_shared<FactorIMU>(feat_imu, last_frame); - feat_imu->addFactor(factor_imu); - last_frame->addConstrainedBy(factor_imu); - - FrameIMUPtr ref_frame_ptr(std::static_pointer_cast<FrameIMU>(imu_ptr->getFrame())); - - Eigen::Matrix<double, 10, 1> expect; - Eigen::Vector3d ref_frame_p = ref_frame_ptr->getP()->getVector(); - Eigen::Quaterniond ref_frame_o(ref_frame_ptr->getO()->getVector().data()); - Eigen::Vector3d ref_frame_v = ref_frame_ptr->getV()->getVector(); - Eigen::Vector3d current_frame_p = last_frame->getP()->getVector(); - Eigen::Quaterniond current_frame_o(last_frame->getO()->getVector().data()); - Eigen::Vector3d current_frame_v = last_frame->getV()->getVector(); - Eigen::Vector3d acc_bias(ref_frame_ptr->getAccBias()->getVector()), gyro_bias(ref_frame_ptr->getGyroBias()->getVector()); - Eigen::Matrix<double, 9, 1> residu; - residu << 0,0,0, 0,0,0, 0,0,0; - - factor_imu->expectation(ref_frame_p, ref_frame_o, ref_frame_v, acc_bias, gyro_bias, current_frame_p, current_frame_o, current_frame_v, expect); - std::cout << "expectation : " << expect.transpose() << std::endl; - - factor_imu->getResiduals(ref_frame_p, ref_frame_o, ref_frame_v, acc_bias, gyro_bias, current_frame_p, current_frame_o, current_frame_v,residu); - std::cout << "residuals : " << residu.transpose() << std::endl; - - //reset origin of motion to new frame - wolf_problem_ptr_->getMotionProvider()->setOrigin(last_frame); - imu_ptr->setFrame(last_frame); - } - - mpu_clock = 0.004046; - //data_ << 0.553250, -0.203577, 10.324929, 0.128787, 0.156959, -0.044270; - data_ << 0.0, 0.0, 9.81, 0.0, 0.0, 0.0; - t.set(mpu_clock); - imu_ptr->setData(data_); - imu_ptr->setTimeStamp(t); - sensor_ptr->process(imu_ptr); - - mpu_clock = 0.005045; - //data_ << 0.548459, -0.184417, 10.387200, 0.083175, 0.120738, -0.026831; - data_ << 0.0, 0.0, 9.81, 0.0, 0.0, 0.0; - t.set(mpu_clock); - imu_ptr->setData(data_); - imu_ptr->setTimeStamp(t); - sensor_ptr->process(imu_ptr); - - //create the factor - //create FrameIMU - ts = wolf_problem_ptr_->getMotionProvider()->getBuffer().back().ts_; - state_vec = wolf_problem_ptr_->getMotionProvider()->getCurrentState(); - FrameIMUPtr last_frame = std::make_shared<FrameIMU>(KEY, ts, state_vec); - wolf_problem_ptr_->getTrajectory()->addFrame(last_frame); - - //create a feature - delta_preint_cov = wolf_problem_ptr_->getMotionProvider()->getCurrentDeltaPreintCov(); - delta_preint = wolf_problem_ptr_->getMotionProvider()->getMotion().delta_integr_; - std::shared_ptr<FeatureIMU> feat_imu = std::make_shared<FeatureIMU>(delta_preint, delta_preint_cov); - feat_imu->setCapture(imu_ptr); - - //create a factorIMU - FactorIMUPtr factor_imu = std::make_shared<FactorIMU>(feat_imu, last_frame); - feat_imu->addFactor(factor_imu); - last_frame->addConstrainedBy(factor_imu); - - FrameIMUPtr ref_frame_ptr(std::static_pointer_cast<FrameIMU>(imu_ptr->getFrame())); - - Eigen::Matrix<double, 10, 1> expect; - Eigen::Vector3d ref_frame_p = ref_frame_ptr->getP()->getVector(); - Eigen::Quaterniond ref_frame_o(ref_frame_ptr->getO()->getVector().data()); - Eigen::Vector3d ref_frame_v = ref_frame_ptr->getV()->getVector(); - Eigen::Vector3d current_frame_p = last_frame->getP()->getVector(); - Eigen::Quaterniond current_frame_o(last_frame->getO()->getVector().data()); - Eigen::Vector3d current_frame_v = last_frame->getV()->getVector(); - Eigen::Vector3d acc_bias(ref_frame_ptr->getAccBias()->getVector()), gyro_bias(ref_frame_ptr->getGyroBias()->getVector()); - Eigen::Matrix<double, 9, 1> residu; - residu << 0,0,0, 0,0,0, 0,0,0; - - factor_imu->expectation(ref_frame_p, ref_frame_o, ref_frame_v, acc_bias, gyro_bias, current_frame_p, current_frame_o, current_frame_v, expect); - std::cout << "expectation : " << expect.transpose() << std::endl; - - factor_imu->getResiduals(ref_frame_p, ref_frame_o, ref_frame_v, acc_bias, gyro_bias, current_frame_p, current_frame_o, current_frame_v,residu); - std::cout << "residuals : " << residu.transpose() << std::endl; - - if(wolf_problem_ptr_->check(1)){ - wolf_problem_ptr_->print(4,1,1,1); - } - - ///having a look at covariances - Eigen::MatrixXd predelta_cov; - predelta_cov.resize(9,9); - predelta_cov = wolf_problem_ptr_->getMotionProvider()->getCurrentDeltaPreintCov(); - //std::cout << "predelta_cov : \n" << predelta_cov << std::endl; - - ///Optimization - // PRIOR - //FrameBasePtr first_frame = wolf_problem_ptr_->getTrajectory()->getFrameList().front(); - wolf_problem_ptr_->getMotionProvider()->setOrigin(wolf_problem_ptr_->getTrajectory()->getFrameList().front()); - //SensorBasePtr sensorbase = std::make_shared<SensorBase>("ABSOLUTE POSE", nullptr, nullptr, nullptr, 0); - //CapturePosePtr initial_covariance = std::make_shared<CaptureFix>(TimeStamp(0), sensorbase, first_frame->getState().head(7), Eigen::Matrix6d::Identity() * 0.01); - //first_frame->addCapture(initial_covariance); - //initial_covariance->process(); - //std::cout << "initial covariance: factor " << initial_covariance->getFeatureList().front()->getConstrainedByList().front()->id() << std::endl << initial_covariance->getFeatureList().front()->getMeasurementCovariance() << std::endl; - - // COMPUTE COVARIANCES - std::cout << "computing covariances..." << std::endl; - ceres_manager_wolf_diff->computeCovariances(ALL_MARGINALS);//ALL_MARGINALS, ALL - std::cout << "computed!" << std::endl; - - /* - // SOLVING PROBLEMS - ceres::Solver::Summary summary_diff; - std::cout << "solving..." << std::endl; - Eigen::VectorXd prev_wolf_state = wolf_problem_ptr_->getTrajectory()->getFrameList().back()->getState(); - summary_diff = ceres_manager_wolf_diff->solve(); - Eigen::VectorXd post_wolf_state = wolf_problem_ptr_->getTrajectory()->getFrameList().back()->getState(); - std::cout << " prev_wolf_state : " << prev_wolf_state.transpose() << "\n post_wolf_state : " << post_wolf_state.transpose() << std::endl; - //std::cout << summary_wolf_diff.BriefReport() << std::endl; - std::cout << "solved!" << std::endl; - */ - - /* - std::cout << "WOLF AUTO DIFF" << std::endl; - std::cout << "Jacobian evaluation: " << summary_wolf.jacobian_evaluation_time_in_seconds << std::endl; - std::cout << "Total time: " << summary_wolf.total_time_in_seconds << std::endl; - */ - - return 0; -} diff --git a/demos/demo_imuDock.cpp b/demos/demo_imuDock.cpp deleted file mode 100644 index 0a4d9646f87d2e8901aaf2b6db319956ac69ea1f..0000000000000000000000000000000000000000 --- a/demos/demo_imuDock.cpp +++ /dev/null @@ -1,332 +0,0 @@ -// WOLF - Copyright (C) 2020,2021,2022,2023 -// Institut de Robòtica i Informà tica Industrial, CSIC-UPC. -// Authors: Joan Solà Ortega (jsola@iri.upc.edu) and -// Joan Vallvé Navarro (jvallve@iri.upc.edu) -// All rights reserved. -// -// This file is part of WOLF: http://www.iri.upc.edu/wolf -// WOLF is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. - -#include <core/ceres_wrapper/solver_ceres.h> - -#include "core/processor/processor_imu_3d.h" -#include "core/sensor/sensor_imu.h" -#include "core/common/wolf.h" -#include "core/problem/problem.h" -#include "core/sensor/sensor_odom_3D.h" -#include "core/processor/processor_odom_3D.h" - -//Factors headers -#include "core/factor/factor_fix_bias.h" - -//std -#include <iostream> -#include <fstream> -#include "core/factor/factor_pose_3D.h" - -#define OUTPUT_RESULTS -//#define ADD_KF3 - -/* OFFLINE VERSION - In this test, we use the experimental conditions needed for Humanoids 2017. - IMU data are acquired using the docking station. - - Factors are (supposing to KeyFrames, stateblocks or first Keyframe are noted *1 and second Keyframes's are *2) : - invar : P1, V1, V2 - var : Q1,B1,P2,Q2,B2 - factors : Odometry factor between KeyFrames - IMU factor - FixBias factor --> makes the problem observable (adding a big covariance on all part but a smaller one on yaw) - Fix3D factor - - What we expect : Estimate biases (this will strongly depend on the actual trajectory of the IMU) - Estimate the position and orienttion of the IMU (check with the standard deviation using covariance matrix) - - Representation of the application: - - Imu - KF1----------◼----------KF2 - /----P1----------\ /----------P2 invar : P1, V1, V2 - Abs|------◼ ◼ var : Q1,B1,P2,Q2,B2 - \----Q1----------/ \----------Q2 - V1 Odom - Abs|------◼-----B1 -*/ -int main(int argc, char** argv) -{ - //#################################################### INITIALIZATION - using namespace wolf; - - //___get input file for imu data___ - std::ifstream imu_data_input; - const char * filename_imu; - if (argc < 02) - { - WOLF_ERROR("Missing 1 input argument (path to imu data file).") - return 1; //return with error - } - else - { - filename_imu = argv[1]; - - imu_data_input.open(filename_imu); - WOLF_INFO("imu file : ", filename_imu) - } - - // ___Check if the file is correctly opened___ - if(!imu_data_input.is_open()){ - WOLF_ERROR("Failed to open data file ! Exiting") - return 1; - } - - #ifdef OUTPUT_RESULTS - //define output file - std::ofstream output_results_before, output_results_after, checking; - output_results_before.open("imu_dock_beforeOptim.dat"); - output_results_after.open("imu_dock_afterOptim.dat"); - checking.open("KF_pose_stdev.dat"); - #endif - - // ___initialize variabes that will be used through the code___ - Eigen::VectorXd problem_origin(16); - Eigen::Vector7d imu_pose((Eigen::Vector7d()<<0,0,0,0,0,0,1).finished()), odom_pose((Eigen::Vector7d()<<0,0,0,0,0,0,1).finished()); - problem_origin << 0,0,0, 0,0,0,1, 0,0,0, 0,0,0, 0,0,0; - - //Create vectors to store data and time - Eigen::Vector6d data_imu, data_odom; - double clock; - TimeStamp ts(0), ts_output(0); //will be used to store the data timestamps and set timestamps in captures - - // ___Define expected values___ - Eigen::Vector7d expected_KF1_pose((Eigen::Vector7d()<<0,0,0,0,0,0,1).finished()), expected_KF2_pose((Eigen::Vector7d()<<0,-0.06,0,0,0,0,11).finished()); - - //#################################################### SETTING PROBLEM - std::string wolf_root = _WOLF_CODE_DIR; - - // ___Create the WOLF Problem + define origin of the problem___ - ProblemPtr problem = Problem::create("PQVBB 3D"); - SolverCeres* ceres_manager = new SolverCeres(problem); - - // ___Configure Ceres if needed___ - - // ___Create sensors + processors___ - SensorIMUPtr sensorIMU = std::static_pointer_cast<SensorIMU>(problem->installSensor("IMU", "Main IMU", imu_pose, wolf_root + "/src/examples/sensor_imu.yaml")); - ProcessorIMUPtr processorIMU = std::static_pointer_cast<ProcessorIMU>(problem->installProcessor("IMU", "IMU pre-integrator", "Main IMU", wolf_root + "/src/examples/processor_imu.yaml")); - - SensorOdom3DPtr sensorOdom = std::static_pointer_cast<SensorOdom3D>(problem->installSensor("ODOM 3D", "odom", odom_pose, wolf_root + "/src/examples/sensor_odom_3D_HQ.yaml")); - ProcessorOdom3DPtr processorOdom = std::static_pointer_cast<ProcessorOdom3D>(problem->installProcessor("ODOM 3D", "odom", "odom", wolf_root + "/src/examples/processor_odom_3D.yaml")); - - // ___set origin of processors to the problem's origin___ - FrameIMUPtr KF1 = std::static_pointer_cast<FrameIMU>(processorIMU->setOrigin(problem_origin, ts)); // XXX JS: setting ts to zero, and then reading clock from data, is inconsistent. - processorOdom->setOrigin(KF1); - - //#################################################### PROCESS DATA - // ___process IMU and odometry___ - - //Create captures - CaptureIMUPtr imu_ptr = std::make_shared<CaptureIMU>(ts, sensorIMU, data_imu, Matrix6d::Identity(), Vector6d::Zero()); //ts is set at 0 - CaptureMotionPtr mot_ptr = std::make_shared<CaptureMotion>(ts, sensorOdom, data_odom, 7, 6, nullptr); - - //while we do not reach the end of file, read IMU input (ts, Ax, Ay, Az, Wx, Wy, Wz) and process data through capture - while(!imu_data_input.eof()) - { - //read - imu_data_input >> clock >> data_imu[0] >> data_imu[1] >> data_imu[2] >> data_imu[3] >> data_imu[4] >> data_imu[5]; - - //set capture - ts.set(clock); - imu_ptr->setTimeStamp(ts); - imu_ptr->setData(data_imu); - - //process - sensorIMU->process(imu_ptr); - } - - //All IMU data have been processed, close the file - imu_data_input.close(); - - //A KeyFrame should have been created (depending on time_span in processors). get the last KeyFrame - // XXX JS: in my opinion, we should control the KF creation better, not using time span. Is it possible? - #ifdef ADD_KF3 - //Add a KeyFrame just before the motion actually starts (we did not move yet) - data_odom << 0,0,0, 0,0,0; - TimeStamp t_middle(0.307585); - mot_ptr->setTimeStamp(t_middle); - mot_ptr->setData(data_odom); - sensorOdom->process(mot_ptr); - - //Also add a keyframe at the end of the motion - data_odom << 0,-0.06,0, 0,0,0; - ts.set(0.981573); //comment this if you want the last KF to be created at last imu's ts - mot_ptr->setTimeStamp(ts); - mot_ptr->setData(data_odom); - sensorOdom->process(mot_ptr); - - FrameIMUPtr KF2 = std::static_pointer_cast<FrameIMU>(problem->getTrajectory()->closestKeyFrameToTimeStamp(t_middle)); - FrameIMUPtr KF3 = std::static_pointer_cast<FrameIMU>(problem->getTrajectory()->closestKeyFrameToTimeStamp(ts)); - #else - //now impose final odometry using last timestamp of imu - data_odom << 0,-0.06,0, 0,0,0; - mot_ptr->setTimeStamp(ts); - mot_ptr->setData(data_odom); - sensorOdom->process(mot_ptr); - - FrameIMUPtr KF2 = std::static_pointer_cast<FrameIMU>(problem->getTrajectory()->closestKeyFrameToTimeStamp(ts)); - #endif - - //#################################################### OPTIMIZATION PART - // ___Create needed factors___ - - //Add Fix3D factor on first KeyFrame (with large covariance except for yaw) - Eigen::MatrixXd featureFix_cov(6,6); - featureFix_cov = Eigen::MatrixXd::Identity(6,6); - featureFix_cov.topLeftCorner(3,3) *= 1e-8; // position variances (it's fixed anyway) - featureFix_cov(3,3) = pow( .02 , 2); // roll variance - featureFix_cov(4,4) = pow( .02 , 2); // pitch variance - featureFix_cov(5,5) = pow( .01 , 2); // yaw variance - CaptureBasePtr cap_fix = KF1->addCapture(std::make_shared<CaptureMotion>(0, nullptr, problem_origin.head(7), 7, 6, nullptr)); - FeatureBasePtr featureFix = cap_fix->addFeature(std::make_shared<FeatureBase>("ODOM 3D", problem_origin.head(7), featureFix_cov)); - FactorFix3DPtr fac_fix = std::static_pointer_cast<FactorPose3D>(featureFix->addFactor(std::make_shared<FactorPose3D>(featureFix))); - - Eigen::MatrixXd featureFixBias_cov(6,6); - featureFixBias_cov = Eigen::MatrixXd::Identity(6,6); - featureFixBias_cov.topLeftCorner(3,3) *= sensorIMU->getAbInitialStdev() * sensorIMU->getAbInitialStdev(); - featureFixBias_cov.bottomRightCorner(3,3) *= sensorIMU->getWbInitialStdev() * sensorIMU->getWbInitialStdev(); - CaptureBasePtr cap_fixbias = KF1->addCapture(std::make_shared<CaptureMotion>(0, nullptr, problem_origin.tail(6), featureFixBias_cov, 6, 6, nullptr)); - //create a FeatureBase to factor biases - FeatureBasePtr featureFixBias = cap_fixbias->addFeature(std::make_shared<FeatureBase>("FIX BIAS", problem_origin.tail(6), featureFixBias_cov)); - FactorFixBiasPtr fac_fixBias = std::static_pointer_cast<FactorFixBias>(featureFixBias->addFactor(std::make_shared<FactorFixBias>(featureFixBias))); - - // ___Fix/Unfix stateblocks___ - KF1->getP()->fix(); - KF1->getO()->unfix(); - KF1->getV()->fix(); - KF1->getAccBias()->unfix(); - KF1->getGyroBias()->unfix(); - - #ifdef ADD_KF3 - KF2->getP()->fix(); - KF2->getO()->unfix(); - KF2->getV()->fix(); - KF2->getAccBias()->unfix(); - KF2->getGyroBias()->unfix(); - - KF3->getP()->unfix(); - KF3->getO()->unfix(); - KF3->getV()->fix(); - KF3->getAccBias()->unfix(); - KF3->getGyroBias()->unfix(); - #else - KF2->getP()->unfix(); - KF2->getO()->unfix(); - KF2->getV()->fix(); - KF2->getAccBias()->unfix(); - KF2->getGyroBias()->unfix(); - #endif - - #ifdef OUTPUT_RESULTS - // ___OUTPUT___ - /* Produce output file for matlab visualization - * first output : estimated trajectory BEFORE optimization (getting the states each millisecond) - */ - - unsigned int time_iter(0); - double ms(0.001); - ts_output.set(0); - while(ts_output.get() < ts.get() + ms) - { - output_results_before << ts_output.get() << "\t" << problem->getState(ts_output).transpose() << std::endl; - time_iter++; - ts_output.set(time_iter * ms); - } - #endif - - // ___Solve + compute covariances___ - problem->print(4,0,1,0); - std::string report = ceres_manager->solve(SolverManager::ReportVerbosity::BRIEF); // 0: nothing, 1: BriefReport, 2: FullReport - ceres_manager->computeCovariances(SolverManager::CovarianceBlocksToBeComputed::ALL_MARGINALS); - problem->print(1,0,1,0); - - //#################################################### RESULTS PART - - // ___Get standard deviation from covariances___ - #ifdef ADD_KF3 - Eigen::MatrixXd cov_KF1(16,16), cov_KF2(16,16), cov_KF3(16,16); - - problem->getCovariance(KF1, cov_KF1); - problem->getCovariance(KF2, cov_KF2); - problem->getCovariance(KF3, cov_KF3); - - Eigen::Matrix<double, 16, 1> stdev_KF1, stdev_KF2, stdev_KF3; - - stdev_KF1 = cov_KF1.diagonal().array().sqrt(); - stdev_KF2 = cov_KF2.diagonal().array().sqrt(); - stdev_KF3 = cov_KF3.diagonal().array().sqrt(); - - WOLF_DEBUG("stdev KF1 : ", stdev_KF1.transpose()); - WOLF_DEBUG("stdev KF2 : ", stdev_KF2.transpose()); - WOLF_DEBUG("stdev KF3 : ", stdev_KF3.transpose()); - #else - Eigen::MatrixXd cov_KF1(16,16), cov_KF2(16,16); - - problem->getCovariance(KF1, cov_KF1); - problem->getCovariance(KF2, cov_KF2); - - Eigen::Matrix<double, 16, 1> stdev_KF1, stdev_KF2; - - stdev_KF1 = cov_KF1.diagonal().array().sqrt(); - stdev_KF2 = cov_KF2.diagonal().array().sqrt(); - - WOLF_DEBUG("stdev KF1 : \n", stdev_KF1.transpose()); - WOLF_DEBUG("stdev KF2 : \n", stdev_KF2.transpose()); - #endif - - - #ifdef OUTPUT_RESULTS - // ___OUTPUT___ - /* Produce output file for matlab visualization - * Second output: KF2 position standard deviation computed - * estimated trajectory AFTER optimization - * + get KF2 timestamp + state just in case the loop is not working as expected - */ - - //estimated trajectort - time_iter = 0; - ts_output.set(0); - while(ts_output.get() < ts.get() + ms) - { - output_results_after << ts_output.get() << "\t" << problem->getState(ts_output).transpose() << std::endl; - time_iter++; - ts_output.set(time_iter * ms); - } - - //finally, output the timestamp, state and stdev associated to KFs - #ifdef ADD_KF3 - checking << KF2->getTimeStamp().get() << "\t" << KF2->getState().transpose() << "\t" << stdev_KF2.transpose() << std::endl; - checking << KF3->getTimeStamp().get() << "\t" << KF3->getState().transpose() << "\t" << stdev_KF3.transpose() << std::endl; - #else - checking << KF2->getTimeStamp().get() << "\t" << KF2->getState().transpose() << "\t" << stdev_KF2.transpose() << std::endl; - #endif - #endif - - // ___Are expected values in the range of estimated +/- 2*stdev ?___ - - #ifdef OUTPUT_RESULTS - output_results_before.close(); - output_results_after.close(); - checking.close(); - #endif - - return 0; -} diff --git a/demos/demo_imuDock_autoKFs.cpp b/demos/demo_imuDock_autoKFs.cpp deleted file mode 100644 index 6b4a5240cc602a5636f241509cc66d4d478a5f93..0000000000000000000000000000000000000000 --- a/demos/demo_imuDock_autoKFs.cpp +++ /dev/null @@ -1,325 +0,0 @@ -// WOLF - Copyright (C) 2020,2021,2022,2023 -// Institut de Robòtica i Informà tica Industrial, CSIC-UPC. -// Authors: Joan Solà Ortega (jsola@iri.upc.edu) and -// Joan Vallvé Navarro (jvallve@iri.upc.edu) -// All rights reserved. -// -// This file is part of WOLF: http://www.iri.upc.edu/wolf -// WOLF is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. - -#include <core/ceres_wrapper/solver_ceres.h> - -#include "core/processor/processor_imu_3d.h" -#include "core/sensor/sensor_imu.h" -#include "core/common/wolf.h" -#include "core/problem/problem.h" -#include "core/sensor/sensor_odom_3D.h" -#include "core/processor/processor_odom_3D.h" - -//Factors headers -#include "core/factor/factor_fix_bias.h" - -//std -#include <iostream> -#include <fstream> -#include "core/factor/factor_pose_3D.h" - -#define OUTPUT_RESULTS -//#define AUTO_KFS - -/* OFFLINE VERSION - In this test, we use the experimental conditions needed for Humanoids 2017. - IMU data are acquired using the docking station. - - Factors are (supposing to KeyFrames, stateblocks or first Keyframe are noted *1 and second Keyframes's are *2) : - invar : P1, V1, V2 - var : Q1,B1,P2,Q2,B2 - - All Keyframes coming after KF2 are constrained just like KF2 - factors : Odometry factor between KeyFrames - IMU factor - FixBias factor --> makes the problem observable (adding a big covariance on all part but a smaller one on yaw) - Fix3D factor - - What we expect : Estimate biases (this will strongly depend on the actual trajectory of the IMU) - Estimate the position and orienttion of the IMU (check with the standard deviation using covariance matrix) - - Representation of the application: - - Imu - KF1----------◼----------KF2--.. - /----P1----------\ /----------P2--.. invar : P1, V1, V2 - Abs|------◼ ◼ var : Q1,B1,P2,Q2,B2 - \----Q1----------/ \----------Q2--.. - V1 Odom v2 .. - Abs|------◼-----B1 B2 .. -*/ -int main(int argc, char** argv) -{ - //#################################################### INITIALIZATION - using namespace wolf; - - //___get input files for imu and odom data___ - std::ifstream imu_data_input, odom_data_input; - const char * filename_imu; - const char * filename_odom; - if (argc < 03) - { - WOLF_ERROR("Missing input argument : path to imu or/and odom data file(s).") - return 1; //return with error - } - else - { - filename_imu = argv[1]; - filename_odom = argv[2]; - - imu_data_input.open(filename_imu); - WOLF_INFO("imu file : ", filename_imu) - odom_data_input.open(filename_odom); - WOLF_INFO("odom file : ", filename_odom) - } - - // ___Check if the file is correctly opened___ - if(!imu_data_input.is_open() || !odom_data_input.is_open()){ - WOLF_ERROR("Failed to open data file ! Exiting") - return 1; - } - - #ifdef OUTPUT_RESULTS - //define output file - std::ofstream output_results_before, output_results_after, checking; - output_results_before.open("imu_dock_beforeOptim.dat"); - output_results_after.open("imu_dock_afterOptim.dat"); - checking.open("KF_pose_stdev.dat"); - #endif - - // ___initialize variabes that will be used through the code___ - Eigen::VectorXd problem_origin(16); - Eigen::Vector7d imu_pose((Eigen::Vector7d()<<0,0,0,0,0,0,1).finished()), odom_pose((Eigen::Vector7d()<<0,0,0,0,0,0,1).finished()); - problem_origin << 0,0,0, 0,0,0,1, 0,0,0, 0,0,0, 0,0,0; - - //Create vectors to store data and time - Eigen::Vector6d data_imu, data_odom; - double clock; - TimeStamp ts(0), ts_output(0); //will be used to store the data timestamps and set timestamps in captures - - // ___Define expected values___ - Eigen::Vector7d expected_KF1_pose((Eigen::Vector7d()<<0,0,0,0,0,0,1).finished()), expected_KF2_pose((Eigen::Vector7d()<<0,-0.06,0,0,0,0,11).finished()); - - #ifdef AUTO_KFs - std::array<double, 50> lastms_imuData; - #endif - //#################################################### SETTING PROBLEM - std::string wolf_root = _WOLF_CODE_DIR; - - // ___Create the WOLF Problem + define origin of the problem___ - ProblemPtr problem = Problem::create("PQVBB 3D"); - SolverCeres* ceres_manager = new SolverCeres(problem); - - // ___Configure Ceres if needed___ - - // ___Create sensors + processors___ - SensorIMUPtr sensorIMU = std::static_pointer_cast<SensorIMU>(problem->installSensor("IMU", "Main IMU", imu_pose, wolf_root + "/src/examples/sensor_imu.yaml")); - ProcessorIMUPtr processorIMU = std::static_pointer_cast<ProcessorIMU>(problem->installProcessor("IMU", "IMU pre-integrator", "Main IMU", wolf_root + "/src/examples/processor_imu.yaml")); - - SensorOdom3DPtr sensorOdom = std::static_pointer_cast<SensorOdom3D>(problem->installSensor("ODOM 3D", "odom", odom_pose, wolf_root + "/src/examples/sensor_odom_3D_HQ.yaml")); - ProcessorOdom3DPtr processorOdom = std::static_pointer_cast<ProcessorOdom3D>(problem->installProcessor("ODOM 3D", "odom", "odom", wolf_root + "/src/examples/processor_odom_3D.yaml")); - - // ___set origin of processors to the problem's origin___ - FrameIMUPtr KF1 = std::static_pointer_cast<FrameIMU>(processorIMU->setOrigin(problem_origin, ts)); // XXX JS: setting ts to zero, and then reading clock from data, is inconsistent. - processorOdom->setOrigin(KF1); - - //#################################################### PROCESS DATA - // ___process IMU and odometry___ - - //Create captures - CaptureIMUPtr imu_ptr = std::make_shared<CaptureIMU>(ts, sensorIMU, data_imu, Matrix6d::Identity(), Vector6d::Zero()); //ts is set at 0 - CaptureMotionPtr mot_ptr = std::make_shared<CaptureMotion>(ts, sensorOdom, data_odom, 7, 6, nullptr); - - //while we do not reach the end of file, read IMU input (ts, Ax, Ay, Az, Wx, Wy, Wz) and process data through capture - while(!imu_data_input.eof()) - { - //read - imu_data_input >> clock >> data_imu[0] >> data_imu[1] >> data_imu[2] >> data_imu[3] >> data_imu[4] >> data_imu[5]; - - //set capture - ts.set(clock); - imu_ptr->setTimeStamp(ts); - imu_ptr->setData(data_imu); - - //process - sensorIMU->process(imu_ptr); - } - - //Process all the odom data - // XXX JS: in my opinion, we should control the KF creation better, not using time span. Is it possible? - while(!odom_data_input.eof()) - { - //read - odom_data_input >> clock >> data_odom[0] >> data_odom[1] >> data_odom[2] >> data_odom[3] >> data_odom[4] >> data_odom[5]; - - //set capture - ts.set(clock); - mot_ptr->setTimeStamp(ts); - mot_ptr->setData(data_odom); - - #ifdef AUTO_KFS - /* We want the KFs to be generated automatically but not using time span as argument of this generation - * For our application, w want the KFs to be generated when an odometry data is given under condition that the IMU is not moving - * We check wether the IMU is moving or not by computing the current stdev of the IMU based on data received during 50ms before the odom timestamp - * We compare this value to the stdev (noise) of the sensor (see sensor_imu.yaml) - * If the current stdev is below a threshold then we process the odometry data ! - */ - - // TODO : get data to compute stdev with directly from the capture - // -> see how these data are stored and change getIMUStdev(..) function defined below main() in this file - // -> then just use the function to get this stdev of corresponding data - - #else - //process anyway. KFs will be generated based on the configuration given in processor_odom_3D.yaml - sensorOdom->process(mot_ptr); - #endif - } - - //All data have been processed, close the files - imu_data_input.close(); - odom_data_input.close(); - - //A KeyFrame should have been created (depending on time_span in processors). get all frames - FrameBasePtrList trajectory = problem->getTrajectory()->getFrameList(); - - - //#################################################### OPTIMIZATION PART - // ___Create needed factors___ - - //Add Fix3D factor on first KeyFrame (with large covariance except for yaw) - Eigen::MatrixXd featureFix_cov(6,6); - featureFix_cov = Eigen::MatrixXd::Identity(6,6); - featureFix_cov.topLeftCorner(3,3) *= 1e-8; // position variances (it's fixed anyway) - featureFix_cov(3,3) = pow( .01 , 2); // roll variance - featureFix_cov(4,4) = pow( .01 , 2); // pitch variance - featureFix_cov(5,5) = pow( .001 , 2); // yaw variance - CaptureBasePtr cap_fix = KF1->addCapture(std::make_shared<CaptureMotion>(0, nullptr, problem_origin.head(7), 7, 6, nullptr)); - FeatureBasePtr featureFix = cap_fix->addFeature(std::make_shared<FeatureBase>("ODOM 3D", problem_origin.head(7), featureFix_cov)); - FactorFix3DPtr fac_fix = std::static_pointer_cast<FactorPose3D>(featureFix->addFactor(std::make_shared<FactorPose3D>(featureFix))); - - Eigen::MatrixXd featureFixBias_cov(6,6); - featureFixBias_cov = Eigen::MatrixXd::Identity(6,6); - featureFixBias_cov.topLeftCorner(3,3) *= sensorIMU->getAbInitialStdev() * sensorIMU->getAbInitialStdev(); - featureFixBias_cov.bottomRightCorner(3,3) *= sensorIMU->getWbInitialStdev() * sensorIMU->getWbInitialStdev(); - CaptureBasePtr cap_fixbias = KF1->addCapture(std::make_shared<CaptureMotion>(0, nullptr, problem_origin.tail(6), featureFixBias_cov, 6, 6, nullptr)); - //create a FeatureBase to factor biases - FeatureBasePtr featureFixBias = cap_fixbias->addFeature(std::make_shared<FeatureBase>("FIX BIAS", problem_origin.tail(6), featureFixBias_cov)); - FactorFixBiasPtr fac_fixBias = std::static_pointer_cast<FactorFixBias>(featureFixBias->addFactor(std::make_shared<FactorFixBias>(featureFixBias))); - - // ___Fix/Unfix stateblocks___ - // fix all Keyframes here - - FrameIMUPtr frame_imu; - for(auto frame : trajectory) - { - frame_imu = std::static_pointer_cast<FrameIMU>(frame); - if(frame_imu->isKey()) - { - frame_imu->getP()->fix(); - frame_imu->getO()->unfix(); - frame_imu->getV()->setState((Eigen::Vector3d()<<0,0,0).finished()); //fix all velocties to 0 () - frame_imu->getV()->fix(); - frame_imu->getAccBias()->unfix(); - frame_imu->getGyroBias()->unfix(); - } - } - - //KF1 (origin) needs to be also fixed in position - KF1->getP()->fix(); - - #ifdef OUTPUT_RESULTS - // ___OUTPUT___ - /* Produce output file for matlab visualization - * first output : estimated trajectory BEFORE optimization (getting the states each millisecond) - */ - - unsigned int time_iter(0); - double ms(0.001); - ts_output.set(0); - while(ts_output.get() < ts.get() + ms) - { - output_results_before << ts_output.get() << "\t" << problem->getState(ts_output).transpose() << std::endl; - time_iter++; - ts_output.set(time_iter * ms); - } - #endif - - // ___Solve + compute covariances___ - problem->print(4,0,1,0); - std::string report = ceres_manager->solve(SolverManager::ReportVerbosity::BRIEF); - ceres_manager->computeCovariances(SolverManager::CovarianceBlocksToBeComputed::ALL_MARGINALS); - problem->print(1,0,1,0); - - //#################################################### RESULTS PART - - // ___Get standard deviation from covariances___ and output this in a file - Eigen::MatrixXd cov_KF(16,16); - Eigen::Matrix<double, 16, 1> stdev_KF; - for(auto frame : trajectory) - { - if(frame->isKey()) - { - problem->getCovariance(frame, cov_KF); - stdev_KF = cov_KF.diagonal().array().sqrt(); - #ifdef OUTPUT_RESULTS - checking << frame->getTimeStamp().get() << "\t" << frame->getState().transpose() << "\t" << stdev_KF.transpose() << std::endl; - #endif - } - } - - #ifdef OUTPUT_RESULTS - // ___OUTPUT___ - /* Produce output file for matlab visualization - * Second output: KF position standard deviation computed - * estimated trajectory AFTER optimization - */ - - //estimated trajectort - time_iter = 0; - ts_output.set(0); - while(ts_output.get() < ts.get() + ms) - { - output_results_after << ts_output.get() << "\t" << problem->getState(ts_output).transpose() << std::endl; - time_iter++; - ts_output.set(time_iter * ms); - } - - //Finished writing in files : close them - output_results_before.close(); - output_results_after.close(); - checking.close(); - #endif - - return 0; -} - -/*double getIMUStdev(Eigen::VectorXd _data) //input argument : whatever will contain the data in the capture -{ - Eigen::Vector6d mean(Eigen::Vector6d::Zero()), stdev(Eigen::Vector6d::Zero()); - unsigned int _data_size(_data.size()); - - mean = _data.mean()/_data_size; - - for (unsigned int i = 0; i < _data_size; i++) - { - stdev += pow(_data()-mean,2); //get the correct data from the container - } - return (stdev.array().sqrt()).maxCoeff(); -}*/ diff --git a/demos/demo_imuPlateform_Offline.cpp b/demos/demo_imuPlateform_Offline.cpp deleted file mode 100644 index fe13bf27c75f0ffcddd282f9e992e95f13fbc3a0..0000000000000000000000000000000000000000 --- a/demos/demo_imuPlateform_Offline.cpp +++ /dev/null @@ -1,284 +0,0 @@ -// WOLF - Copyright (C) 2020,2021,2022,2023 -// Institut de Robòtica i Informà tica Industrial, CSIC-UPC. -// Authors: Joan Solà Ortega (jsola@iri.upc.edu) and -// Joan Vallvé Navarro (jvallve@iri.upc.edu) -// All rights reserved. -// -// This file is part of WOLF: http://www.iri.upc.edu/wolf -// WOLF is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. - -//Wolf -#include <core/ceres_wrapper/solver_ceres.h> - -#include "core/capture/capture_imu.h" -#include "core/processor/processor_imu_3d.h" -#include "core/sensor/sensor_imu.h" -#include "core/common/wolf.h" -#include "core/problem/problem.h" -#include "core/sensor/sensor_odom_3D.h" -#include "core/factor/factor_odom_3D.h" -#include "core/state_block/state_block.h" -#include "core/state_block/state_quaternion.h" -#include "core/processor/processor_odom_3D.h" -#include <iostream> -#include <fstream> -#include <iomanip> -#include <ctime> -#include <cmath> - -#define DEBUG_RESULTS - -int _kbhit(); - -int main(int argc, char** argv) -{ - using namespace wolf; - using std::shared_ptr; - using std::make_shared; - using std::static_pointer_cast; - - // LOADING DATA FILE (IMU) - // FOR IMU, file content is : Timestampt\t Ax\t Ay\t Az\t Wx\t Wy\t Wz - - std::ifstream imu_data_input; - const char * filename_imu; - if (argc < 02) - { - - WOLF_ERROR("Missing input argument! : needs 1 argument (path to imu data file).") - return 1; - } - else - { - filename_imu = argv[1]; - - imu_data_input.open(filename_imu); - WOLF_INFO("imu file : ", filename_imu) - - //std::string dummy; //this is needed only if first line is headers or useless data - //getline(imu_data_input, dummy); - } - - if(!imu_data_input.is_open()){ - std::cerr << "Failed to open data files... Exiting" << std::endl; - return 1; - } - - #ifdef DEBUG_RESULTS - std::ofstream debug_results; - debug_results.open("debug_results_imu_constrained0.dat"); - if(debug_results) - debug_results << "%%TimeStamp\t" - << "X_x\t" << "X_y\t" << "X_z\t" << "Xq_x\t" << "Xq_y\t" << "Xq_z\t" << "Xq_w\t" << "Xv_x\t" << "Xv_y\t" << "Xv_z\t" - << "Cov_X\t" << "Cov_Y\t" << "Cov_Z\t" << "Cov_Qx\t" << "Cov_Qy\t" << "Cov_Qz\t" << "Cov_Qw" << "Cov_Vx\t" << "Cov_Vy\t" << "Cov_Vz\t" << std::endl; - #endif - - //===================================================== SETTING PROBLEM - std::string wolf_root = _WOLF_CODE_DIR; - - // WOLF PROBLEM - ProblemPtr wolf_problem_ptr_ = Problem::create("PQVBB 3D"); - Eigen::VectorXd x_origin(16); - x_origin << 0,0,0, 0,0,0,1, 0,0,0, 0,0,0, 0,0,0; //INITIAL CONDITIONS - TimeStamp t(0); - - // CERES WRAPPER - SolverCeres* ceres_manager_wolf_diff = new SolverCeres(wolf_problem_ptr_); - ceres_manager_wolf_diff->getSolverOptions().minimizer_type = ceres::TRUST_REGION; //ceres::TRUST_REGION;ceres::LINE_SEARCH - ceres_manager_wolf_diff->getSolverOptions().max_line_search_step_contraction = 1e-3; - ceres_manager_wolf_diff->getSolverOptions().max_num_iterations = 1e4; - - // SENSOR + PROCESSOR IMU - SensorBasePtr sen0_ptr = wolf_problem_ptr_->installSensor("IMU", "Main IMU", (Vector7d()<<0,0,0,0,0,0,1).finished(), wolf_root + "/src/examples/sensor_imu.yaml"); - ProcessorIMUParamsPtr prc_imu_params = std::make_shared<ProcessorParamsIMU>(); - prc_imu_params->max_time_span = 10; - prc_imu_params->max_buff_length = 1000000000; //make it very high so that this condition will not pass - prc_imu_params->dist_traveled = 1000000000; - prc_imu_params->angle_turned = 1000000000; - - ProcessorBasePtr processor_ptr_ = wolf_problem_ptr_->installProcessor("IMU", "IMU pre-integrator", sen0_ptr, prc_imu_params); - SensorIMUPtr sen_imu = std::static_pointer_cast<SensorIMU>(sen0_ptr); - ProcessorIMUPtr processor_ptr_imu = std::static_pointer_cast<ProcessorIMU>(processor_ptr_); - - // SENSOR + PROCESSOR ODOM 3D - SensorBasePtr sen1_ptr = wolf_problem_ptr_->installSensor("ODOM 3D", "odom", (Vector7d()<<0,0,0,0,0,0,1).finished(), wolf_root + "/src/examples/sensor_odom_3D.yaml"); - ProcessorParamsOdom3DPtr prc_odom3D_params = std::make_shared<ProcessorParamsOdom3D>(); - prc_odom3D_params->max_time_span = 1.9999; - prc_odom3D_params->max_buff_length = 1000000000; //make it very high so that this condition will not pass - prc_odom3D_params->dist_traveled = 1000000000; - prc_odom3D_params->angle_turned = 1000000000; - - ProcessorBasePtr processor_ptr_odom = wolf_problem_ptr_->installProcessor("ODOM 3D", "odom", sen1_ptr, prc_odom3D_params); - SensorOdom3DPtr sen_odom3D = std::static_pointer_cast<SensorOdom3D>(sen1_ptr); - ProcessorOdom3DPtr processor_ptr_odom3D = std::static_pointer_cast<ProcessorOdom3D>(processor_ptr_odom); - - // reset origin of problem - t.set(0); - - FrameIMUPtr origin_KF = std::static_pointer_cast<FrameIMU>(processor_ptr_imu->setOrigin(x_origin, t)); - processor_ptr_odom3D->setOrigin(origin_KF); - - //fix parts of the problem if needed - origin_KF->getP()->fix(); - origin_KF->getO()->fix(); - //===================================================== PROCESS DATA - // PROCESS DATA - - Eigen::Vector6d data_imu, data_odom3D; - data_imu << 0,0,-wolf::gravity()(2), 0,0,0; - data_odom3D << 0,-0.06,0, 0,0,0; - - double input_clock; - TimeStamp ts(0); - wolf::CaptureIMUPtr imu_ptr = std::make_shared<CaptureIMU>(ts, sen_imu, data_imu, Matrix6d::Identity(), Vector6d::Zero()); - wolf::CaptureMotionPtr mot_ptr = std::make_shared<CaptureMotion>(t, sen_odom3D, data_odom3D, 6, 6, nullptr); - - //when we find a IMU timestamp corresponding with this odometry timestamp then we process odometry measurement - t = ts; - - clock_t begin = clock(); - - while( !imu_data_input.eof()) - { - // PROCESS IMU DATA - // Time and data variables - imu_data_input >> input_clock >> data_imu[0] >> data_imu[1] >> data_imu[2] >> data_imu[3] >> data_imu[4] >> data_imu[5]; //Ax, Ay, Az, Gx, Gy, Gz - - ts.set(input_clock); - imu_ptr->setTimeStamp(ts); - imu_ptr->setData(data_imu); - - // process data in capture - imu_ptr->getTimeStamp(); - sen_imu->process(imu_ptr); - } - - TimeStamp t0, tf; - t0 = wolf_problem_ptr_->getMotionProvider()->getBuffer().front().ts_; - tf = wolf_problem_ptr_->getMotionProvider()->getBuffer().back().ts_; - int N = wolf_problem_ptr_->getMotionProvider()->getBuffer().size(); - - //Finally, process the only one odom input - mot_ptr->setTimeStamp(ts); - mot_ptr->setData(data_odom3D); - sen_odom3D->process(mot_ptr); - - clock_t end = clock(); - FrameIMUPtr last_KF = std::static_pointer_cast<FrameIMU>(wolf_problem_ptr_->getTrajectory()->closestKeyFrameToTimeStamp(ts)); - - //closing file - imu_data_input.close(); - //===================================================== END{PROCESS DATA} - - double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC; - - // Final state - std::cout << "\nIntegration results ----------------------------------------------------------------------------------------------" << std::endl; - std::cout << "Initial state: " << std::fixed << std::setprecision(3) << std::setw(8) - << x_origin.head(16).transpose() << std::endl; - std::cout << "Integrated delta: " << std::fixed << std::setprecision(3) << std::setw(8) - << wolf_problem_ptr_->getMotionProvider()->getMotion().delta_integr_.transpose() << std::endl; - std::cout << "Integrated state: " << std::fixed << std::setprecision(3) << std::setw(8) - << wolf_problem_ptr_->getMotionProvider()->getCurrentState().head(16).transpose() << std::endl; - std::cout << "Integrated std : " << std::fixed << std::setprecision(3) << std::setw(8) - << (wolf_problem_ptr_->getMotionProvider()->getMotion().delta_integr_cov_.diagonal().transpose()).array().sqrt() << std::endl; - - // Print statistics - std::cout << "\nStatistics -----------------------------------------------------------------------------------" << std::endl; - std::cout << "If you want meaningful CPU metrics, remove all couts in the loop / remove DEBUG_RESULTS definition variable, and compile in RELEASE mode!" << std::endl; - - /*TimeStamp t0, tf; - t0 = wolf_problem_ptr_->getMotionProvider()->getBuffer().front().ts_; - tf = wolf_problem_ptr_->getMotionProvider()->getBuffer().back().ts_; - int N = wolf_problem_ptr_->getMotionProvider()->getBuffer().size();*/ - std::cout << "t0 : " << t0.get() << " s" << std::endl; - std::cout << "tf : " << tf.get() << " s" << std::endl; - std::cout << "duration : " << tf-t0 << " s" << std::endl; - std::cout << "N samples : " << N << std::endl; - std::cout << "frequency : " << (N-1)/(tf-t0) << " Hz" << std::endl; - std::cout << "CPU time : " << elapsed_secs << " s" << std::endl; - std::cout << "s/integr : " << elapsed_secs/(N-1)*1e6 << " us" << std::endl; - std::cout << "integr/s : " << (N-1)/elapsed_secs << " ips" << std::endl; - - //fix parts of the problem if needed - origin_KF->getP()->fix(); - origin_KF->getO()->fix(); - origin_KF->getV()->fix(); - - std::cout << "\t\t\t ______solving______" << std::endl; - std::string report = ceres_manager_wolf_diff->solve(SolverManager::ReportVerbosity::FULL);// 0: nothing, 1: BriefReport, 2: FullReport - std::cout << report << std::endl; - ceres_manager_wolf_diff->computeCovariances(SolverManager::CovarianceBlocksToBeComputed::ALL); - std::cout << "\t\t\t ______solved______" << std::endl; - - wolf_problem_ptr_->print(4,1,1,1); - - #ifdef DEBUG_RESULTS - Eigen::VectorXd frm_state(16); - Eigen::Matrix<double, 16, 1> cov_stdev; - Eigen::MatrixXd covX(16,16); - Eigen::MatrixXd cov3(Eigen::Matrix3d::Zero()); - - wolf::FrameBasePtrList frame_list = wolf_problem_ptr_->getTrajectory()->getFrameList(); - for(FrameBasePtr frm_ptr : frame_list) - { - if(frm_ptr->isKey()) - { - //prepare needed variables - FrameIMUPtr frmIMU_ptr = std::static_pointer_cast<FrameIMU>(frm_ptr); - frm_state = frmIMU_ptr->getState(); - ts = frmIMU_ptr->getTimeStamp(); - - //get data from covariance blocks - wolf_problem_ptr_->getCovariance(frmIMU_ptr, covX); - wolf_problem_ptr_->getCovarianceBlock(frmIMU_ptr->getV(), frmIMU_ptr->getV(), cov3); - covX.block(7,7,3,3) = cov3; - wolf_problem_ptr_->getCovarianceBlock(frmIMU_ptr->getAccBias(), frmIMU_ptr->getAccBias(), cov3); - covX.block(10,10,3,3) = cov3; - wolf_problem_ptr_->getCovarianceBlock(frmIMU_ptr->getGyroBias(), frmIMU_ptr->getGyroBias(), cov3); - covX.block(13,13,3,3) = cov3; - for(int i = 0; i<16; i++) - cov_stdev(i) = ( covX(i,i)? 2*sqrt(covX(i,i)):0); //if diagonal value is 0 then store 0 else store 2*sqrt(diag_value) - - debug_results << std::setprecision(16) << ts.get() << "\t" << frm_state(0) << "\t" << frm_state(1) << "\t" << frm_state(2) - << "\t" << frm_state(3) << "\t" << frm_state(4) << "\t" << frm_state(5) << "\t" << frm_state(6) - << "\t" << frm_state(7) << "\t" << frm_state(8) << "\t" << frm_state(9) - << "\t" << frm_state(10) << "\t" << frm_state(11) << "\t" << frm_state(12) << "\t" << frm_state(13) << "\t" << frm_state(14) << "\t" << frm_state(15) - << "\t" << cov_stdev(0) << "\t" << cov_stdev(1) << "\t" << cov_stdev(2) - << "\t" << cov_stdev(3) << "\t" << cov_stdev(4) << "\t" << cov_stdev(5) << "\t" << cov_stdev(6) - << "\t" << cov_stdev(7) << "\t" << cov_stdev(8) << "\t" << cov_stdev(9) - << "\t" << cov_stdev(10) << "\t" << cov_stdev(11) << "\t" << cov_stdev(12) << "\t" << cov_stdev(13) << "\t" << cov_stdev(14) << "\t" << cov_stdev(15) << std::endl; - } - } - - debug_results.close(); - WOLF_WARN("WARNING : DEBUG_RESULTS ACTIVATED - slows the process (writing results to result_debugs.dat file)") - - #endif - - return 0; - -} - -int _kbhit() -{ - struct timeval tv; - fd_set fds; - tv.tv_sec = 0; - tv.tv_usec = 0; - FD_ZERO(&fds); - FD_SET(STDIN_FILENO, &fds); //STDIN_FILENO is 0 - select(STDIN_FILENO+1, &fds, NULL, NULL, &tv); - return FD_ISSET(STDIN_FILENO, &fds); -} diff --git a/demos/demo_imu_constrained0.cpp b/demos/demo_imu_constrained0.cpp deleted file mode 100644 index 3c00b52f40f780301c479e9e051ac8d4b36e7e59..0000000000000000000000000000000000000000 --- a/demos/demo_imu_constrained0.cpp +++ /dev/null @@ -1,392 +0,0 @@ -// WOLF - Copyright (C) 2020,2021,2022,2023 -// Institut de Robòtica i Informà tica Industrial, CSIC-UPC. -// Authors: Joan Solà Ortega (jsola@iri.upc.edu) and -// Joan Vallvé Navarro (jvallve@iri.upc.edu) -// All rights reserved. -// -// This file is part of WOLF: http://www.iri.upc.edu/wolf -// WOLF is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. - -//Wolf -#include <core/ceres_wrapper/solver_ceres.h> - -#include "core/capture/capture_imu.h" -#include "core/processor/processor_imu_3d.h" -#include "core/sensor/sensor_imu.h" -#include "core/common/wolf.h" -#include "core/problem/problem.h" -#include "core/sensor/sensor_odom_3D.h" -#include "core/factor/factor_odom_3D.h" -#include "core/state_block/state_block.h" -#include "core/state_block/state_quaternion.h" -#include "core/processor/processor_odom_3D.h" -#include <iostream> -#include <fstream> -#include <iomanip> -#include <ctime> -#include <cmath> - -#define DEBUG_RESULTS -#define KF0_EVOLUTION - -int _kbhit(); - -int main(int argc, char** argv) -{ - using namespace wolf; - using std::shared_ptr; - using std::make_shared; - using std::static_pointer_cast; - - // LOADING DATA FILES (IMU + ODOM) - // FOR IMU, file content is : Timestampt\t Ax\t Ay\t Az\t Wx\t Wy\t Wz - // FOR ODOM, file content is : Timestampt\t Δpx\t Δpy\t Δpz\t Δox\t Δoy\t Δoz - - std::ifstream imu_data_input; - std::ifstream odom_data_input; - const char * filename_imu; - const char * filename_odom; - if (argc < 3) - { - std::cout << "Missing input argument! : needs 2 argument (path to imu and odom data files)." << std::endl; - return 1; - } - else - { - filename_imu = argv[1]; - filename_odom = argv[2]; - - imu_data_input.open(filename_imu); - odom_data_input.open(filename_odom); - - std::cout << "file imu : " << filename_imu <<"\t file odom : " << filename_odom << std::endl; - - //std::string dummy; //this is needed only if first line is headers or useless data - //getline(imu_data_input, dummy); - } - - if(!imu_data_input.is_open() || !odom_data_input.is_open()){ - std::cerr << "Failed to open data files... Exiting" << std::endl; - return 1; - } - - #ifdef DEBUG_RESULTS - std::ofstream debug_results; - debug_results.open("debug_results_imu_constrained0.dat"); - if(debug_results) - debug_results << "%%TimeStamp\t" - << "X_x\t" << "X_y\t" << "X_z\t" << "Xq_x\t" << "Xq_y\t" << "Xq_z\t" << "Xq_w\t" << "Xv_x\t" << "Xv_y\t" << "Xv_z\t" - << "Cov_X\t" << "Cov_Y\t" << "Cov_Z\t" << "Cov_Qx\t" << "Cov_Qy\t" << "Cov_Qz\t" << "Cov_Qw" << "Cov_Vx\t" << "Cov_Vy\t" << "Cov_Vz\t" << std::endl; - #endif - - #ifdef KF0_EVOLUTION - std::ofstream KF0_evolution; - KF0_evolution.open("KF0_evolution.dat"); - if(KF0_evolution) - KF0_evolution << "%%TimeStamp\t" - << "X_x\t" << "X_y\t" << "X_z\t" << "Xq_x\t" << "Xq_y\t" << "Xq_z\t" << "Xq_w\t" << "Xv_x\t" << "Xv_y\t" << "Xv_z\t" - << "Cov_X\t" << "Cov_Y\t" << "Cov_Z\t" << "Cov_Qx\t" << "Cov_Qy\t" << "Cov_Qz\t" << "Cov_Qw" << "Cov_Vx\t" << "Cov_Vy\t" << "Cov_Vz\t" << std::endl; - #endif - - //===================================================== SETTING PROBLEM - std::string wolf_root = _WOLF_CODE_DIR; - - // WOLF PROBLEM - ProblemPtr wolf_problem_ptr_ = Problem::create("PQVBB 3D"); - Eigen::VectorXd x_origin(16); - Eigen::Vector6d origin_bias; - x_origin << 0,0,0, 0,0,0,1, 0,0,0, 0,0,0, 0,0,0; //INITIAL CONDITIONS 0.05,0.03,.00, 0.2,-0.05,.00; - TimeStamp t(0); - - // initial conditions defined from data file - // remember that matlab's quaternion is W,X,Y,Z and the one in Eigen has X,Y,Z,W form - imu_data_input >> x_origin[0] >> x_origin[1] >> x_origin[2] >> x_origin[6] >> x_origin[3] >> x_origin[4] >> x_origin[5] >> x_origin[7] >> x_origin[8] >> x_origin[9]; - imu_data_input >> origin_bias[0] >> origin_bias[1] >> origin_bias[2] >> origin_bias[3] >> origin_bias[4] >> origin_bias[5]; - - // CERES WRAPPER - SolverCeres* ceres_manager_wolf_diff = new SolverCeres(wolf_problem_ptr_); - ceres_manager_wolf_diff->getSolverOptions().minimizer_type = ceres::TRUST_REGION; //ceres::TRUST_REGION;ceres::LINE_SEARCH - ceres_manager_wolf_diff->getSolverOptions().max_line_search_step_contraction = 1e-3; - ceres_manager_wolf_diff->getSolverOptions().max_num_iterations = 1e4; - - // SENSOR + PROCESSOR IMU - SensorBasePtr sen0_ptr = wolf_problem_ptr_->installSensor("IMU", "Main IMU", (Vector7d()<<0,0,0,0,0,0,1).finished(), wolf_root + "/src/examples/sensor_imu.yaml"); - ProcessorIMUParamsPtr prc_imu_params = std::make_shared<ProcessorParamsIMU>(); - prc_imu_params->max_time_span = 10; - prc_imu_params->max_buff_length = 1000000000; //make it very high so that this condition will not pass - prc_imu_params->dist_traveled = 1000000000; - prc_imu_params->angle_turned = 1000000000; - - ProcessorBasePtr processor_ptr_ = wolf_problem_ptr_->installProcessor("IMU", "IMU pre-integrator", sen0_ptr, prc_imu_params); - SensorIMUPtr sen_imu = std::static_pointer_cast<SensorIMU>(sen0_ptr); - ProcessorIMUPtr processor_ptr_imu = std::static_pointer_cast<ProcessorIMU>(processor_ptr_); - - // SENSOR + PROCESSOR ODOM 3D - SensorBasePtr sen1_ptr = wolf_problem_ptr_->installSensor("ODOM 3D", "odom", (Vector7d()<<0,0,0,0,0,0,1).finished(), wolf_root + "/src/examples/sensor_odom_3D_HQ.yaml"); - ProcessorParamsOdom3DPtr prc_odom3D_params = std::make_shared<ProcessorParamsOdom3D>(); - prc_odom3D_params->max_time_span = 20.9999; - prc_odom3D_params->max_buff_length = 1000000000; //make it very high so that this condition will not pass - prc_odom3D_params->dist_traveled = 1000000000; - prc_odom3D_params->angle_turned = 1000000000; - - ProcessorBasePtr processor_ptr_odom = wolf_problem_ptr_->installProcessor("ODOM 3D", "odom", sen1_ptr, prc_odom3D_params); - SensorOdom3DPtr sen_odom3D = std::static_pointer_cast<SensorOdom3D>(sen1_ptr); - ProcessorOdom3DPtr processor_ptr_odom3D = std::static_pointer_cast<ProcessorOdom3D>(processor_ptr_odom); - - // reset origin of problem - t.set(0); - Eigen::Matrix<double, 10, 1> expected_final_state; - - FrameIMUPtr origin_KF = std::static_pointer_cast<FrameIMU>(processor_ptr_imu->setOrigin(x_origin, t)); - processor_ptr_odom3D->setOrigin(origin_KF); - - odom_data_input >> expected_final_state[0] >> expected_final_state[1] >> expected_final_state[2] >> expected_final_state[6] >> expected_final_state[3] >> - expected_final_state[4] >> expected_final_state[5] >> expected_final_state[7] >> expected_final_state[8] >> expected_final_state[9]; - - //fix parts of the problem if needed - origin_KF->getP()->fix(); - origin_KF->getO()->fix(); - //===================================================== PROCESS DATA - // PROCESS DATA - - Eigen::Vector6d data_imu, data_odom3D; - data_imu << 0,0,-wolf::gravity()(2), 0,0,0; - data_odom3D << 0,0,0, 0,0,0; - - double input_clock; - TimeStamp ts(0); - TimeStamp t_odom(0); - wolf::CaptureIMUPtr imu_ptr = std::make_shared<CaptureIMU>(ts, sen_imu, data_imu, Matrix6d::Identity(), Vector6d::Zero()); - wolf::CaptureMotionPtr mot_ptr = std::make_shared<CaptureMotion>(t, sen_odom3D, data_odom3D, 6, 6, nullptr); - - //read first odom data from file - odom_data_input >> input_clock >> data_odom3D[0] >> data_odom3D[1] >> data_odom3D[2] >> data_odom3D[3] >> data_odom3D[4] >> data_odom3D[5]; - t_odom.set(input_clock); - //when we find a IMU timestamp corresponding with this odometry timestamp then we process odometry measurement - t = ts; - - clock_t begin = clock(); - - while( !imu_data_input.eof() && !odom_data_input.eof() ) - { - // PROCESS IMU DATA - // Time and data variables - imu_data_input >> input_clock >> data_imu[0] >> data_imu[1] >> data_imu[2] >> data_imu[3] >> data_imu[4] >> data_imu[5]; //Ax, Ay, Az, Gx, Gy, Gz - - ts.set(input_clock); - imu_ptr->setTimeStamp(ts); - imu_ptr->setData(data_imu); - - // process data in capture - imu_ptr->getTimeStamp(); - sen_imu->process(imu_ptr); - - if(ts.get() == t_odom.get()) - { - // PROCESS ODOM 3D DATA - mot_ptr->setTimeStamp(t_odom); - mot_ptr->setData(data_odom3D); - sen_odom3D->process(mot_ptr); - - //prepare next odometry measurement if there is any - odom_data_input >> input_clock >> data_odom3D[0] >> data_odom3D[1] >> data_odom3D[2] >> data_odom3D[3] >> data_odom3D[4] >> data_odom3D[5]; - t_odom.set(input_clock); - } - - #ifdef KF0_EVOLUTION - - if( (ts.get() - t.get()) >= 0.05 ) - { - t = ts; - //std::string report = ceres_manager_wolf_diff->solve(1); //0: nothing, 1: BriefReport, 2: FullReport - - Eigen::VectorXd frm_state(16); - frm_state = origin_KF->getState(); - - KF0_evolution << std::setprecision(16) << ts.get() << "\t" << frm_state(0) << "\t" << frm_state(1) << "\t" << frm_state(2) - << "\t" << frm_state(3) << "\t" << frm_state(4) << "\t" << frm_state(5) << "\t" << frm_state(6) - << "\t" << frm_state(7) << "\t" << frm_state(8) << "\t" << frm_state(9) - << "\t" << frm_state(10) << "\t" << frm_state(11) << "\t" << frm_state(12) << "\t" << frm_state(13) << "\t" << frm_state(14) << "\t" << frm_state(15) << std::endl; - } - - #endif - } - - clock_t end = clock(); - FrameIMUPtr last_KF = std::static_pointer_cast<FrameIMU>(wolf_problem_ptr_->getTrajectory()->closestKeyFrameToTimeStamp(ts)); - - //closing file - imu_data_input.close(); - odom_data_input.close(); - - #ifdef KF0_EVOLUTION - KF0_evolution.close(); - #endif - - //===================================================== END{PROCESS DATA} - - double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC; - - // Final state - std::cout << "\nIntegration results ----------------------------------------------------------------------------------------------" << std::endl; - std::cout << "Initial state: " << std::fixed << std::setprecision(3) << std::setw(8) - << x_origin.head(16).transpose() << std::endl; - std::cout << "Integrated delta: " << std::fixed << std::setprecision(3) << std::setw(8) - << wolf_problem_ptr_->getMotionProvider()->getMotion().delta_integr_.transpose() << std::endl; - std::cout << "Integrated state: " << std::fixed << std::setprecision(3) << std::setw(8) - << wolf_problem_ptr_->getMotionProvider()->getCurrentState().head(16).transpose() << std::endl; - std::cout << "Integrated std : " << std::fixed << std::setprecision(3) << std::setw(8) - << (wolf_problem_ptr_->getMotionProvider()->getMotion().delta_integr_cov_.diagonal()).array().sqrt() << std::endl; - - // Print statistics - std::cout << "\nStatistics -----------------------------------------------------------------------------------" << std::endl; - std::cout << "If you want meaningful CPU metrics, remove all couts in the loop / remove DEBUG_RESULTS definition variable, and compile in RELEASE mode!" << std::endl; - - TimeStamp t0, tf; - t0 = wolf_problem_ptr_->getMotionProvider()->getBuffer().front().ts_; - tf = wolf_problem_ptr_->getMotionProvider()->getBuffer().back().ts_; - int N = wolf_problem_ptr_->getMotionProvider()->getBuffer().size(); - std::cout << "t0 : " << t0.get() << " s" << std::endl; - std::cout << "tf : " << tf.get() << " s" << std::endl; - std::cout << "duration : " << tf-t0 << " s" << std::endl; - std::cout << "N samples : " << N << std::endl; - std::cout << "frequency : " << (N-1)/(tf-t0) << " Hz" << std::endl; - std::cout << "CPU time : " << elapsed_secs << " s" << std::endl; - std::cout << "s/integr : " << elapsed_secs/(N-1)*1e6 << " us" << std::endl; - std::cout << "integr/s : " << (N-1)/elapsed_secs << " ips" << std::endl; - - //fix parts of the problem if needed - origin_KF->getP()->fix(); - origin_KF->getO()->fix(); - origin_KF->getV()->fix(); - - - std::cout << "\t\t\t ______solving______" << std::endl; - std::string report = ceres_manager_wolf_diff->solve(SolverManager::ReportVerbosity::FULL); //0: nothing, 1: BriefReport, 2: FullReport - std::cout << report << std::endl; - - last_KF->getAccBias()->fix(); - last_KF->getGyroBias()->fix(); - - std::cout << "\t\t\t solving after fixBias" << std::endl; - report = ceres_manager_wolf_diff->solve(SolverManager::ReportVerbosity::BRIEF); //0: nothing, 1: BriefReport, 2: FullReport - std::cout << report << std::endl; - ceres_manager_wolf_diff->computeCovariances(SolverManager::CovarianceBlocksToBeComputed::ALL); - std::cout << "\t\t\t ______solved______" << std::endl; - - wolf_problem_ptr_->print(4,1,1,1); - - #ifdef DEBUG_RESULTS - Eigen::VectorXd frm_state(16); - Eigen::Matrix<double, 16, 1> cov_stdev; - Eigen::MatrixXd covX(16,16); - Eigen::MatrixXd cov3(Eigen::Matrix3d::Zero()); - - wolf::FrameBasePtrList frame_list = wolf_problem_ptr_->getTrajectory()->getFrameList(); - for(FrameBasePtr frm_ptr : frame_list) - { - if(frm_ptr->isKey()) - { - //prepare needed variables - FrameIMUPtr frmIMU_ptr = std::static_pointer_cast<FrameIMU>(frm_ptr); - frm_state = frmIMU_ptr->getState(); - ts = frmIMU_ptr->getTimeStamp(); - - //get data from covariance blocks - wolf_problem_ptr_->getCovariance(frmIMU_ptr, covX); - wolf_problem_ptr_->getCovarianceBlock(frmIMU_ptr->getV(), frmIMU_ptr->getV(), cov3); - covX.block(7,7,3,3) = cov3; - wolf_problem_ptr_->getCovarianceBlock(frmIMU_ptr->getAccBias(), frmIMU_ptr->getAccBias(), cov3); - covX.block(10,10,3,3) = cov3; - wolf_problem_ptr_->getCovarianceBlock(frmIMU_ptr->getGyroBias(), frmIMU_ptr->getGyroBias(), cov3); - covX.block(13,13,3,3) = cov3; - for(int i = 0; i<16; i++) - cov_stdev(i) = ( covX(i,i)? 2*sqrt(covX(i,i)):0); //if diagonal value is 0 then store 0 else store 2*sqrt(diag_value) - - debug_results << std::setprecision(16) << ts.get() << "\t" << frm_state(0) << "\t" << frm_state(1) << "\t" << frm_state(2) - << "\t" << frm_state(3) << "\t" << frm_state(4) << "\t" << frm_state(5) << "\t" << frm_state(6) - << "\t" << frm_state(7) << "\t" << frm_state(8) << "\t" << frm_state(9) - << "\t" << frm_state(10) << "\t" << frm_state(11) << "\t" << frm_state(12) << "\t" << frm_state(13) << "\t" << frm_state(14) << "\t" << frm_state(15) - << "\t" << cov_stdev(0) << "\t" << cov_stdev(1) << "\t" << cov_stdev(2) - << "\t" << cov_stdev(3) << "\t" << cov_stdev(4) << "\t" << cov_stdev(5) << "\t" << cov_stdev(6) - << "\t" << cov_stdev(7) << "\t" << cov_stdev(8) << "\t" << cov_stdev(9) - << "\t" << cov_stdev(10) << "\t" << cov_stdev(11) << "\t" << cov_stdev(12) << "\t" << cov_stdev(13) << "\t" << cov_stdev(14) << "\t" << cov_stdev(15) << std::endl; - } - } - - //trials to print all factorIMUs' residuals - Eigen::Matrix<double,15,1> IMU_residuals; - Eigen::Vector3d p1(Eigen::Vector3d::Zero()); - Eigen::Vector4d q1_vec(Eigen::Vector4d::Zero()); - Eigen::Map<Quaterniond> q1(q1_vec.data()); - Eigen::Vector3d v1(Eigen::Vector3d::Zero()); - Eigen::Vector3d ab1(Eigen::Vector3d::Zero()); - Eigen::Vector3d wb1(Eigen::Vector3d::Zero()); - Eigen::Vector3d p2(Eigen::Vector3d::Zero()); - Eigen::Vector4d q2_vec(Eigen::Vector4d::Zero()); - Eigen::Map<Quaterniond> q2(q2_vec.data()); - Eigen::Vector3d v2(Eigen::Vector3d::Zero()); - Eigen::Vector3d ab2(Eigen::Vector3d::Zero()); - Eigen::Vector3d wb2(Eigen::Vector3d::Zero()); - - for(FrameBasePtr frm_ptr : frame_list) - { - if(frm_ptr->isKey()) - { - FactorBasePtrList fac_list = frm_ptr->getConstrainedByList(); - for(FactorBasePtr fac_ptr : fac_list) - { - if(fac_ptr->getTypeId() == FAC_IMU) - { - //Eigen::VectorXd prev_KF_state(fac_ptr->getFrameOther()->getState()); - //Eigen::VectorXd curr_KF_state(fac_ptr->getFeature()->getFrame()->getState()); - p1 = fac_ptr->getFrameOther()->getP()->getState(); - q1_vec = fac_ptr->getFrameOther()->getO()->getState(); - v1 = fac_ptr->getFrameOther()->getV()->getState(); - ab1 = std::static_pointer_cast<FrameIMU>(fac_ptr->getFrameOther())->getAccBias()->getState(); - wb1 = std::static_pointer_cast<FrameIMU>(fac_ptr->getFrameOther())->getGyroBias()->getState(); - - p2 = fac_ptr->getFeature()->getFrame()->getP()->getState(); - q2_vec = fac_ptr->getFeature()->getFrame()->getO()->getState(); - v2 = fac_ptr->getFeature()->getFrame()->getV()->getState(); - ab2 = std::static_pointer_cast<FrameIMU>(fac_ptr->getFeature()->getFrame())->getAccBias()->getState(); - wb2 = std::static_pointer_cast<FrameIMU>(fac_ptr->getFeature()->getFrame())->getGyroBias()->getState(); - - std::static_pointer_cast<FactorIMU>(fac_ptr)->residual(p1, q1, v1, ab1, wb1, p2, q2, v2, ab2, wb2, IMU_residuals); - std::cout << "IMU residuals : " << IMU_residuals.transpose() << std::endl; - } - } - } - } - - debug_results.close(); - WOLF_WARN("WARNING : DEBUG_RESULTS ACTIVATED - slows the process (writing results to result_debugs.dat file)") - - #endif - - return 0; - -} - -int _kbhit() -{ - struct timeval tv; - fd_set fds; - tv.tv_sec = 0; - tv.tv_usec = 0; - FD_ZERO(&fds); - FD_SET(STDIN_FILENO, &fds); //STDIN_FILENO is 0 - select(STDIN_FILENO+1, &fds, NULL, NULL, &tv); - return FD_ISSET(STDIN_FILENO, &fds); -} diff --git a/demos/demo_processor_imu.cpp b/demos/demo_processor_imu.cpp deleted file mode 100644 index 8f372c0d05ecae859d44670f2153a5ec574fc6e4..0000000000000000000000000000000000000000 --- a/demos/demo_processor_imu.cpp +++ /dev/null @@ -1,227 +0,0 @@ -// WOLF - Copyright (C) 2020,2021,2022,2023 -// Institut de Robòtica i Informà tica Industrial, CSIC-UPC. -// Authors: Joan Solà Ortega (jsola@iri.upc.edu) and -// Joan Vallvé Navarro (jvallve@iri.upc.edu) -// All rights reserved. -// -// This file is part of WOLF: http://www.iri.upc.edu/wolf -// WOLF is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. - -//Wolf -#include "core/capture/capture_imu.h" -#include "core/processor/processor_imu_3d.h" -#include "core/sensor/sensor_imu.h" -#include "core/common/wolf.h" -#include "core/problem/problem.h" -#include "core/state_block/state_block.h" -#include "core/state_block/state_quaternion.h" -#include <iostream> -#include <fstream> -#include <iomanip> -#include <ctime> -#include <cmath> - -//#define DEBUG_RESULTS - -int main(int argc, char** argv) -{ - using namespace wolf; - using std::shared_ptr; - using std::make_shared; - using std::static_pointer_cast; - - std::cout << std::endl << "==================== processor IMU test ======================" << std::endl; - - //load files containing accelerometer and gyroscope data - std::ifstream data_file_acc; - std::ifstream data_file_gyro; - const char * filename_acc; - const char * filename_gyro; - - //prepare creation of file if DEBUG_RESULTS activated -#ifdef DEBUG_RESULTS - std::ofstream debug_results; - debug_results.open("debug_results.dat"); - if(debug_results) - debug_results << "%%TimeStamp\t" - << "dp_x\t" << "dp_y\t" << "dp_z\t" << "dq_x\t" << "dq_y\t" << "dq_z\t" << "dq_w\t" << "dv_x\t" << "dv_y\t" << "dv_z\t" - << "Dp_x\t" << "Dp_y\t" << "Dp_z\t" << "Dq_x\t" << "Dq_y\t" << "Dq_z\t" << "Dq_w\t" << "Dv_x\t" << "Dv_y\t" << "Dv_z\t" - << "X_x\t" << "X_y\t" << "X_z\t" << "Xq_x\t" << "Xq_y\t" << "Xq_z\t" << "Xq_w\t" << "Xv_x\t" << "Xv_y\t" << "Xv_z\t" << std::endl; -#endif - - if (argc < 3) - { - std::cout << "Missing input argument! : needs 2 arguments (path to accelerometer file and path to gyroscope data)." << std::endl; - } - else - { - filename_acc = argv[1]; - filename_gyro = argv[2]; - data_file_acc.open(filename_acc); - data_file_gyro.open(filename_gyro); - std::cout << "Acc file: " << filename_acc << std::endl; - std::cout << "Gyro file: " << filename_gyro << std::endl; - - std::string dummy; - getline(data_file_acc, dummy); getline(data_file_gyro, dummy); - - if(!data_file_acc.is_open() || !data_file_gyro.is_open()){ - std::cerr << "Failed to open data files... Exiting" << std::endl; - return 1; - } - } - - // Wolf problem - ProblemPtr problem_ptr_ = Problem::create("PQVBB 3D"); - Eigen::VectorXd extrinsics(7); - extrinsics << 0,0,0, 0,0,0,1; // IMU pose in the robot - SensorBasePtr sensor_ptr = problem_ptr_->installSensor("IMU", "Main IMU", extrinsics, IntrinsicsBasePtr()); - problem_ptr_->installProcessor("IMU", "IMU pre-integrator", "Main IMU", ""); - - // Time and data variables - TimeStamp t; - double mti_clock, tmp; - Eigen::Vector6d data; - Eigen::Matrix6d data_cov; - data_cov.setIdentity(); - data_cov.topLeftCorner(3,3) *= 0.01; - data_cov.bottomRightCorner(3,3) *= 0.01; - - // Get initial data - data_file_acc >> mti_clock >> data[0] >> data[1] >> data[2]; - data_file_gyro >> tmp >> data[3] >> data[4] >> data[5]; - t.set(mti_clock * 0.0001); // clock in 0,1 ms ticks - - // Set the origin - Eigen::VectorXd x0(16); - x0 << 0,0,0, 0,0,0,1, 0,0,0, 0,0,0, 0,0,0; // Try some non-zero biases - problem_ptr_->getMotionProvider()->setOrigin(x0, t); - - // Create one capture to store the IMU data arriving from (sensor / callback / file / etc.) - CaptureIMUPtr imu_ptr = make_shared<CaptureIMU>(t, sensor_ptr, data, data_cov, Vector6d::Zero()); - -// problem_ptr_->print(); - - std::cout << "Main loop -----------" << std::endl; - - // main loop - using namespace std; - clock_t begin = clock(); - int n = 1; - while(!data_file_acc.eof() && n < 5000){ - n++; - - // read new data - data_file_acc >> mti_clock >> data[0] >> data[1] >> data[2]; - data_file_gyro >> tmp >> data[3] >> data[4] >> data[5]; - t.set(mti_clock * 0.0001); // clock in 0,1 ms ticks - -// data.setZero(); -// data(2) = 9.8; - - // assign data to capture - imu_ptr->setData(data); - imu_ptr->setTimeStamp(t); - - // process data in capture - sensor_ptr->process(imu_ptr); - -#ifdef DEBUG_RESULTS - - // --- print to screen ---- - - std::cout << "Current data : " << std::fixed << std::setprecision(3) << std::setw(8) << std::right - << data.transpose() << std::endl; - - std::cout << "Current delta: " << std::fixed << std::setprecision(3) << std::setw(8) << std::right - << problem_ptr_->getMotionProvider()->getMotion().delta_.transpose() << std::endl; - - std::cout << "Integrated delta: " << std::fixed << std::setprecision(3) << std::setw(8) - << problem_ptr_->getMotionProvider()->getMotion().delta_integr_.transpose() << std::endl; - - Eigen::VectorXd x = problem_ptr_->getMotionProvider()->getCurrentState(); - - std::cout << "Integrated state: " << std::fixed << std::setprecision(3) << std::setw(8) - << x.head(10).transpose() << std::endl; - - std::cout << "Integrated std : " << std::fixed << std::setprecision(3) << std::setw(8) - << (problem_ptr_->getMotionProvider()->getMotion().delta_integr_cov_.diagonal().transpose()).array().sqrt() << std::endl; - - std::cout << std::endl; - -//#ifdef DEBUG_RESULTS - // ----- dump to file ----- - - Eigen::VectorXd delta_debug; - Eigen::VectorXd delta_integr_debug; - Eigen::VectorXd x_debug; - TimeStamp ts; - - delta_debug = problem_ptr_->getMotionProvider()->getMotion().delta_; - delta_integr_debug = problem_ptr_->getMotionProvider()->getMotion().delta_integr_; - x_debug = problem_ptr_->getMotionProvider()->getCurrentState(); - ts = problem_ptr_->getMotionProvider()->getBuffer().back().ts_; - - if(debug_results) - debug_results << ts.get() << "\t" << delta_debug(0) << "\t" << delta_debug(1) << "\t" << delta_debug(2) << "\t" << delta_debug(3) << "\t" << delta_debug(4) << "\t" - << delta_debug(5) << "\t" << delta_debug(6) << "\t" << delta_debug(7) << "\t" << delta_debug(8) << "\t" << delta_debug(9) << "\t" - << delta_integr_debug(0) << "\t" << delta_integr_debug(1) << "\t" << delta_integr_debug(2) << "\t" << delta_integr_debug(3) << "\t" << delta_integr_debug(4) << "\t" - << delta_integr_debug(5) << "\t" << delta_integr_debug(6) << "\t" << delta_integr_debug(7) << "\t" << delta_integr_debug(8) << "\t" << delta_integr_debug(9) << "\t" - << x_debug(0) << "\t" << x_debug(1) << "\t" << x_debug(2) << "\t" << x_debug(3) << "\t" << x_debug(4) << "\t" - << x_debug(5) << "\t" << x_debug(6) << "\t" << x_debug(7) << "\t" << x_debug(8) << "\t" << x_debug(9) << "\n"; -#endif - - } - clock_t end = clock(); - double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC; - - // Final state - std::cout << "\nIntegration results ----------------------------------------------------------------------------------------------" << std::endl; - std::cout << "Initial state: " << std::fixed << std::setprecision(3) << std::setw(8) - << x0.head(16).transpose() << std::endl; - std::cout << "Integrated delta: " << std::fixed << std::setprecision(3) << std::setw(8) - << problem_ptr_->getMotionProvider()->getMotion().delta_integr_.transpose() << std::endl; - std::cout << "Integrated state: " << std::fixed << std::setprecision(3) << std::setw(8) - << problem_ptr_->getMotionProvider()->getCurrentState().head(16).transpose() << std::endl; -// std::cout << "Integrated std : " << std::fixed << std::setprecision(3) << std::setw(8) -// << (problem_ptr_->getMotionProvider()->getMotion().delta_integr_cov_.diagonal().transpose()).array().sqrt() << std::endl; - - // Print statistics - std::cout << "\nStatistics -----------------------------------------------------------------------------------" << std::endl; - std::cout << "If you want meaningful CPU metrics, remove all couts in the loop / remove DEBUG_RESULTS definition variable, and compile in RELEASE mode!" << std::endl; - -#ifdef DEBUG_RESULTS - std::cout << "\t\tWARNING : DEBUG_RESULTS ACTIVATED - slows the process (writing results to result_debugs.dat file)" << std::endl; - debug_results.close(); -#endif - - TimeStamp t0, tf; - t0 = problem_ptr_->getMotionProvider()->getBuffer().front().ts_; - tf = problem_ptr_->getMotionProvider()->getBuffer().back().ts_; - int N = problem_ptr_->getMotionProvider()->getBuffer().size(); - std::cout << "t0 : " << t0.get() << " s" << std::endl; - std::cout << "tf : " << tf.get() << " s" << std::endl; - std::cout << "duration : " << tf-t0 << " s" << std::endl; - std::cout << "N samples : " << N << std::endl; - std::cout << "frequency : " << (N-1)/(tf-t0) << " Hz" << std::endl; - std::cout << "CPU time : " << elapsed_secs << " s" << std::endl; - std::cout << "s/integr : " << elapsed_secs/(N-1)*1e6 << " us" << std::endl; - std::cout << "integr/s : " << (N-1)/elapsed_secs << " ips" << std::endl; - - // close data files - data_file_acc.close(); // no impact on leaks - data_file_gyro.close(); - - return 0; -} diff --git a/demos/demo_processor_imu_jacobians.cpp b/demos/demo_processor_imu_jacobians.cpp deleted file mode 100644 index a23a4cbdc87eaf57d3c3ff12fcceb1eb0efd54e9..0000000000000000000000000000000000000000 --- a/demos/demo_processor_imu_jacobians.cpp +++ /dev/null @@ -1,431 +0,0 @@ -// WOLF - Copyright (C) 2020,2021,2022,2023 -// Institut de Robòtica i Informà tica Industrial, CSIC-UPC. -// Authors: Joan Solà Ortega (jsola@iri.upc.edu) and -// Joan Vallvé Navarro (jvallve@iri.upc.edu) -// All rights reserved. -// -// This file is part of WOLF: http://www.iri.upc.edu/wolf -// WOLF is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. - -//Wolf -#include "core/capture/capture_imu.h" -#include "core/sensor/sensor_imu.h" -#include <test/processor_imu_tester.h> -#include "core/common/wolf.h" -#include "core/problem/problem.h" -#include "core/state_block/state_block.h" -#include "core/state_block/state_quaternion.h" -#include <iostream> -#include <fstream> -#include <iomanip> -#include <ctime> -#include <cmath> - -//#define DEBUG_RESULTS - -using namespace wolf; - -void remapJacDeltas_quat0(IMU_jac_deltas& _jac_delta, Eigen::Map<Eigen::Quaterniond>& _Dq0, Eigen::Map<Eigen::Quaterniond>& _dq0); -void remapJacDeltas_quat(IMU_jac_deltas& _jac_delta, Eigen::Map<Eigen::Quaterniond>& _Dq, Eigen::Map<Eigen::Quaterniond>& _dq, const int& place ); - -int main(int argc, char** argv) -{ - using namespace wolf; - - std::cout << std::endl << "==================== processor IMU : Checking Jacobians ======================" << std::endl; - - TimeStamp t; - Eigen::Vector6d data_; - double deg_to_rad = 3.14159265359/180.0; - data_ << 10,0.5,3, 100*deg_to_rad,110*deg_to_rad,30*deg_to_rad; - - // Wolf problem - ProblemPtr wolf_problem_ptr_ = Problem::create("PQVBB 3D"); - Eigen::VectorXd IMU_extrinsics(7); - IMU_extrinsics << 0,0,0, 0,0,0,1; // IMU pose in the robot - //SensorBase* sensor_ptr = wolf_problem_ptr_->installSensor("IMU", "Main IMU", IMU_extrinsics, nullptr); - //wolf_problem_ptr_->installProcessor("IMU", "IMU pre-integrator", "Main IMU", ""); - - // Set the origin - t.set(0.0001); // clock in 0,1 ms ticks - Eigen::VectorXd x0(16); - x0 << 0,1,0, 0,0,0,1, 1,0,0, 0,0,.000, 0,0,.000; // P Q V B B - - //wolf_problem_ptr_->getMotionProvider()->setOrigin(x0, t); - - //CaptureIMU* imu_ptr; - - ProcessorImu3dTester processor_imu; - //processor_imu.setOrigin(x0, t); - double ddelta_bias = 0.00000001; - double dt = 0.001; - - //defining a random Delta to begin with (not to use Origin point) - Eigen::Matrix<double,10,1> Delta0; - Delta0 = Eigen::Matrix<double,10,1>::Random(); - Delta0.head<3>() = Delta0.head<3>()*100; - Delta0.tail<3>() = Delta0.tail<3>()*10; - Eigen::Vector3d ang0, ang; - ang0 << 120.08*deg_to_rad, 12.36*deg_to_rad, 54.32*deg_to_rad; - //Delta0 << 0,0,0, 0,0,0,1, 0,0,0; - Eigen::Map<Eigen::Quaterniond> Delta0_quat(Delta0.data()+3); - Delta0_quat = v2q(ang0); - Delta0_quat.normalize(); - ang = q2v(Delta0_quat); - - std::cout << "\ninput Delta0 : " << Delta0 << std::endl; - std::cout << "\n rotation vector we start with :\n" << ang << std::endl; - - struct IMU_jac_bias bias_jac = processor_imu.finite_diff_ab(dt, data_, ddelta_bias, Delta0); - - Eigen::Map<Eigen::Quaterniond> Dq0(NULL); - Eigen::Map<Eigen::Quaterniond> dq0(NULL); - Eigen::Map<Eigen::Quaterniond> Dq_noisy(NULL); - Eigen::Map<Eigen::Quaterniond> dq_noisy(NULL); - Eigen::Map<Eigen::Quaterniond> q_in_1(NULL), q_in_2(NULL); - - /* IMU_jac_deltas struct form : - contains vectors of size 7 : - Elements at place 0 are those not affected by the bias noise that we add (da_bx,..., dw_bx,... ). - place 1 : added da_bx in data place 2 : added da_by in data place 3 : added da_bz in data - place 4 : added dw_bx in data place 5 : added dw_by in data place 6 : added dw_bz in data - */ - - Eigen::Matrix3d dDp_dab, dDv_dab, dDp_dwb, dDv_dwb, dDq_dab, dDq_dwb; - - /* - dDp_dab = [dDp_dab_x, dDp_dab_y, dDp_dab_z] - dDp_dab_x = (dDp(ab_x + dab_x, ab_y, ab_z) - dDp(ab_x,ab_y,ab_z)) / dab_x - dDp_dab_x = (dDp(ab_x, ab_y + dab_y, ab_z) - dDp(ab_x,ab_y,ab_z)) / dab_y - dDp_dab_x = (dDp(ab_x, ab_y, ab_z + dab_z) - dDp(ab_x,ab_y,ab_z)) / dab_z - - similar for dDv_dab - note dDp_dab_x, dDp_dab_y, dDp_dab_z, dDv_dab_x, dDv_dab_y, dDv_dab_z are 3x1 vectors ! - - dDq_dab = 0_{3x3} - dDq_dwb = [dDq_dwb_x, dDq_dwb_y, dDq_dwb_z] - dDq_dwb_x = log( dR(wb).transpose() * dR(wb - dwb_x))/dwb_x - = log( dR(wb).transpose() * exp((wx - wbx - dwb_x)dt, (wy - wby)dt, (wy - wby)dt))/dwb_x - dDq_dwb_y = log( dR(wb).transpose() * dR(wb - dwb_y))/dwb_y - dDq_dwb_z = log( dR(wb).transpose() * dR(wb + dwb_z))/dwb_z - - Note : dDq_dwb must be computed recursively ! So comparing the one returned by processor_imu and the numerical - one will have no sense if we aredoing this from a random Delta. The Delta here should be the origin. - dDq_dwb_ = dR.tr()*dDq_dwb - Jr(wdt)*dt - Then at first step, dR.tr() = Id, dDq_dwb = 0_{3x3}, which boils down to dDq_dwb_ = Jr(wdt)*dt - */ - - std::cout << "\n input data : \n" << data_ << std::endl; - - new (&q_in_1) Eigen::Map<Eigen::Quaterniond>(bias_jac.Delta0_.data() + 3); - for(int i=0;i<3;i++){ - dDp_dab.block<3,1>(0,i) = (bias_jac.Deltas_noisy_vect_(i).head(3) - bias_jac.Delta0_.head(3))/ddelta_bias; - dDv_dab.block<3,1>(0,i) = (bias_jac.Deltas_noisy_vect_(i).tail(3) - bias_jac.Delta0_.tail(3))/ddelta_bias; - - dDp_dwb.block<3,1>(0,i) = (bias_jac.Deltas_noisy_vect_(i+3).head(3) - bias_jac.Delta0_.head(3))/ddelta_bias; - dDv_dwb.block<3,1>(0,i) = (bias_jac.Deltas_noisy_vect_(i+3).tail(3) - bias_jac.Delta0_.tail(3))/ddelta_bias; - - new (&q_in_2) Eigen::Map<Eigen::Quaterniond>(bias_jac.Deltas_noisy_vect_(i).data() + 3); - dDq_dab.block<3,1>(0,i) = R2v( q_in_1.matrix().transpose() * q_in_2.matrix())/ddelta_bias; - - new (&q_in_2) Eigen::Map<Eigen::Quaterniond>(bias_jac.Deltas_noisy_vect_(i+3).data() + 3); - dDq_dwb.block<3,1>(0,i) = R2v( q_in_1.matrix().transpose() * q_in_2.matrix())/ddelta_bias; - //std::cout << "matrix operation result :" << i << "\n" << q_in_1.matrix().transpose() * q_in_2.matrix() << std::endl; - //std::cout << "matrix operation result to vector :" << i << "\n" << R2v( q_in_1.matrix().transpose() * q_in_2.matrix()) << std::endl; - } -/* Delta1 = bias_jac.Deltas_noisy_vect_(3); - Delta2 = bias_jac.Deltas_noisy_vect_(4); - Delta3 = bias_jac.Deltas_noisy_vect_(5); - - if( (Delta1 == Delta2 || Delta1 == Delta3 )) - std::cout << "\n problem" << std::endl; - else - std::cout << "\n no problem" << std::endl; - if(Delta2 == Delta3) - std::cout << "\n problem" << std::endl; - else - std::cout << "\n no problem" << std::endl;*/ - - //Check the jacobians wrt to bias using finite difference - - if(dDp_dab.isApprox(bias_jac.dDp_dab_, wolf::Constants::EPS) ) - std::cout<< "dDp_dab_ jacobian is correct !" << std::endl; - else{ - std::cout<< "\t\tdDp_dab_ jacobian is not correct ..." << std::endl; - std::cout << "dDp_dab : \n" << dDp_dab << "\n bias_jac.dDp_dab_ :\n" << bias_jac.dDp_dab_ << "\n" << std::endl; - std::cout << "dDp_dab_a - dDp_dab_ : \n" << bias_jac.dDp_dab_ - dDp_dab << "\n" << std::endl; - } - - if(dDv_dab.isApprox(bias_jac.dDv_dab_, wolf::Constants::EPS) ) - std::cout<< "dDv_dab_ jacobian is correct !" << std::endl; - else{ - std::cout<< "\t\tdDv_dab_ jacobian is not correct ..." << std::endl; - std::cout << "dDv_dab_ : \n" << dDv_dab << "\n bias_jac.dDv_dab_ :\n" << bias_jac.dDv_dab_ << "\n" << std::endl; - std::cout << "dDv_dab_a - dDv_dab_ : \n" << bias_jac.dDv_dab_ - dDv_dab << "\n" << std::endl; - } - - if(dDp_dwb.isApprox(bias_jac.dDp_dwb_, wolf::Constants::EPS) ) - std::cout<< "dDp_dwb_ jacobian is correct !" << std::endl; - else{ - std::cout<< "\t\tdDp_dwb_ jacobian is not correct ..." << std::endl; - std::cout << "dDp_dwb_ : \n" << dDp_dwb << "\n bias_jac.dDp_dwb_ :\n" << bias_jac.dDp_dwb_ << "\n" << std::endl; - std::cout << "dDp_dwb_a - dDp_dwb_ : \n" << bias_jac.dDp_dwb_ - dDp_dwb << "\n" << std::endl; - } - - if(dDv_dwb.isApprox(bias_jac.dDv_dwb_, wolf::Constants::EPS) ) - std::cout<< "dDv_dwb_ jacobian is correct !" << std::endl; - else{ - std::cout<< "\t\tdDv_dwb_ jacobian is not correct ..." << std::endl; - std::cout << "dDv_dwb_ : \n" << dDv_dwb << "\n bias_jac.dDv_dwb_ :\n" << bias_jac.dDv_dwb_ << "\n" << std::endl; - std::cout << "dDv_dwb_a - dDv_dwb_ : \n" << bias_jac.dDv_dwb_ - dDv_dwb << "\n" << std::endl; - } - - if(dDq_dwb.isApprox(bias_jac.dDq_dwb_, wolf::Constants::EPS) ) - std::cout<< "dDq_dwb_ jacobian is correct !" << std::endl; - else{ - std::cout<< "\t\tdDq_dwb_ jacobian is not correct ..." << std::endl; - std::cout << "dDq_dwb_ : \n" << dDq_dwb << "\n bias_jac.dDq_dwb_ :\n" << bias_jac.dDq_dwb_ << "\n" << std::endl; - std::cout << "dDq_dwb_a - dDq_dwb_ : \n" << bias_jac.dDq_dwb_ - dDq_dwb << "\n" << std::endl; - } - - //Check jacobians that are supposed to be Zeros just in case - if(dDq_dab.isZero(wolf::Constants::EPS)) - std::cout<< "dDq_dab_ jacobian is correct (Zero) !" << std::endl; - else - std::cout<< "\t\tdDq_dab_ jacobian is not Zero :" << dDq_dab << std::endl; - - /* Numerical method to check jacobians wrt noise - - dDp_dP = [dDp_dPx, dDp_dPy, dDp_dPz] - dDp_dPx = ((P + dPx) - P)/dPx = Id - dDp_dPy = ((P + dPy) - P)/dPy = Id - dDp_dPz = ((P + dPz) - P)/dPz = Id - - dDp_dV = [dDp_dVx, dDp_dVy, dDp_dVz] - dDp_dVx = ((V + dVx)*dt - V*dt)/dVx = Id*dt - dDp_dVy = ((V + dVy)*dt - V*dt)/dVy = Id*dt - dDp_dVz = ((V + dVz)*dt - V*dt)/dVz = Id*dt - - dDp_dO = [dDp_dOx, dDp_dOy, dDp_dOz] - dDp_dOx = (( dR(Theta + dThetax)*dp ) - ( dR(Theta)*dp ))/dThetax - = (( dR(Theta) * exp(dThetax,0,0)*dp ) - ( dR(Theta)*dp ))/dThetax - dDp_dOy = (( dR(Theta) * exp(0,dThetay,0)*dp ) - ( dR(Theta)*dp ))/dThetay - dDp_dOz = (( dR(Theta) * exp(0,0,dThetaz)*dp ) - ( dR(Theta)*dp ))/dThetaz - - dDv_dP = [dDv_dPx, dDv_dPy, dDv_dPz] = [0, 0, 0] - - dDv_dV = [dDv_dVx, dDv_dVy, dDv_dVz] - dDv_dVx = ((V + dVx) - V)/dVx = Id - dDv_dVy = ((V + dVy) - V)/dVy = Id - dDv_dVz = ((V + dVz) - V)/dVz = Id - - dDv_dO = [dDv_dOx, dDv_dOy, dDv_dOz] - dDv_dOx = (( dR(Theta + dThetax)*dv ) - ( dR(Theta)*dv ))/dThetax - = (( dR(Theta) * exp(dThetax,0,0)*dv ) - ( dR(Theta)*dv ))/dThetax - dDv_dOx = (( dR(Theta) * exp(0,dThetay,0)*dv ) - ( dR(Theta)*dv ))/dThetay - dDv_dOz = (( dR(Theta) * exp(0,0,dThetaz)*dv ) - ( dR(Theta)*dv ))/dThetaz - - dDp_dp = [dDp_dpx, dDp_dpy, dDp_dpz] - dDp_dpx = ( dR*(p + dpx) - dR*(p))/dpx - dDp_dpy = ( dR*(p + dpy) - dR*(p))/dpy - dDp_dpz = ( dR*(p + dpz) - dR*(p))/dpy - - dDp_dv = [dDp_dvx, dDp_dvy, dDp_dvz] = [0, 0, 0] - - dDp_do = [dDp_dox, dDp_doy, dDp_doz] = [0, 0, 0] - - dDv_dp = [dDv_dpx, dDv_dpy, dDv_dpz] = [0, 0, 0] - - dDv_dv = [dDv_dvx, dDv_dvy, dDv_dvz] - dDv_dvx = ( dR*(v + dvx) - dR*(v))/dvx - dDv_dvy = ( dR*(v + dvy) - dR*(v))/dvy - dDv_dvz = ( dR*(v + dvz) - dR*(v))/dvz - - dDv_do = [dDv_dox, dDv_doy, dDv_doz] = [0, 0, 0] - - dDo_dp = dDo_dv = dDo_dP = dDo_dV = [0, 0, 0] - - dDo_dO = [dDo_dOx, dDo_dOy, dDo_dOz] - - dDo_dOx = log( (dR(Theta) * dr(theta)).transpose() * dR(Theta+dThetax) * dr(theta) )/dThetax - = log( (dR(Theta) * dr(theta)).transpose() * (dR(Theta)*exp(dThetax,0,0)) * dr(theta) )/dThetax - = log( (_Delta * _delta).transpose() * (_Delta_noisy * _delta)) - dDo_dOy = log( (dR(Theta) * dr(theta)).transpose() * (dR(Theta)*exp(0,dThetay,0)) * dr(theta) )/dThetay - dDo_dOz = log( (dR(Theta) * dr(theta)).transpose() * (dR(Theta)*exp(0,0,dThetaz)) * dr(theta) )/dThetaz - - dDo_do = [dDo_dox, dDo_doy, dDo_doz] - - dDo_dox = log( (dR(Theta) * dr(theta)).transpose() * dR(Theta) * dr(theta+dthetax) )/dthetax - = log( (dR(Theta) * dr(theta)).transpose() * dR(Theta) * (dr(theta)*exp(dthetax,0,0)) )/dthetax - = log( (_Delta * _delta).transpose() * (_Delta * _delta_noisy)) - dDo_doy = log( (dR(Theta) * dr(theta)).transpose() * dR(Theta) * (dr(theta)*exp(0,dthetay,0)) )/dthetay - dDo_doz = log( (dR(Theta) * dr(theta)).transpose() * dR(Theta) * (dr(theta)*exp(0,0,dthetaz)) )/dthetaz - */ - - //taking care of noise now - Eigen::Matrix<double,9,1> Delta_noise; - Eigen::Matrix<double,9,1> delta_noise; - - Delta_noise << 0.00000001, 0.00000001, 0.00000001, 0.0001, 0.0001, 0.0001, 0.00000001, 0.00000001, 0.00000001; - delta_noise << 0.00000001, 0.00000001, 0.00000001, 0.0001, 0.0001, 0.0001, 0.00000001, 0.00000001, 0.00000001; - - struct IMU_jac_deltas deltas_jac = processor_imu.finite_diff_noise(dt, data_, Delta_noise, delta_noise, Delta0); - - /* reminder : - jacobian_delta_preint_vect_ jacobian_delta_vect_ - 0: + 0, 0: + 0 - 1: +dPx, 2: +dPy, 3: +dPz 1: + dpx, 2: +dpy, 3: +dpz - 4: +dOx, 5: +dOy, 6: +dOz 4: + dox, 5: +doy, 6: +doz - 7: +dVx, 8: +dVy, 9: +dVz 7: + dvx, 8: +dvy, 9: +dvz - */ - - Eigen::Matrix3d dDp_dP, dDp_dV, dDp_dO, dDv_dP, dDv_dV, dDv_dO, dDo_dP, dDo_dV, dDo_dO; - Eigen::Matrix3d dDp_dp, dDp_dv, dDp_do, dDv_dp, dDv_dv, dDv_do, dDo_dp, dDo_dv, dDo_do; - - remapJacDeltas_quat0(deltas_jac, Dq0, dq0); - - for(int i = 0; i < 3; i++){ - - //dDp_dPx = ((P + dPx) - P)/dPx - dDp_dP.block<3,1>(0,i) = (deltas_jac.Delta_noisy_vect_(i).head(3) - deltas_jac.Delta0_.head(3))/Delta_noise(i); - //Dp_dVx = ((V + dVx)*dt - V*dt)/dVx - dDp_dV.block<3,1>(0,i) = (deltas_jac.Delta_noisy_vect_(i+6).tail(3)*dt - deltas_jac.Delta0_.tail(3)*dt)/Delta_noise(i+6); - //dDp_dOx = (( dR(Theta) * exp(dThetax,0,0)*dp ) - ( dR(Theta)*dp ))/dThetax - remapJacDeltas_quat(deltas_jac, Dq_noisy, dq_noisy, i+3); - dDp_dO.block<3,1>(0,i) = ((Dq_noisy.matrix() * deltas_jac.delta0_.head(3)) - (Dq0.matrix()* deltas_jac.delta0_.head(3)))/Delta_noise(i+3); - - //dDv_dP = [0, 0, 0] - //dDv_dVx = ((V + dVx) - V)/dVx - dDv_dV.block<3,1>(0,i) = (deltas_jac.Delta_noisy_vect_(i+6).tail(3) - deltas_jac.Delta0_.tail(3))/Delta_noise(i+6); - //dDv_dOx = (( dR(Theta) * exp(dThetax,0,0)*dv ) - ( dR(Theta)*dv ))/dThetax - dDv_dO.block<3,1>(0,i) = ((Dq_noisy.matrix() * deltas_jac.delta0_.tail(3)) - (Dq0.matrix()* deltas_jac.delta0_.tail(3)))/Delta_noise(i+3); - - //dDo_dP = dDo_dV = [0, 0, 0] - //dDo_dOx = log( (dR(Theta) * dr(theta)).transpose() * (dR(Theta)*exp(dThetax,0,0)) * dr(theta) )/dThetax - dDo_dO.block<3,1>(0,i) = R2v( (Dq0.matrix() * dq0.matrix()).transpose() * (Dq_noisy.matrix() * dq0.matrix()) )/Delta_noise(i+3); - - //dDp_dpx = ( dR*(p + dpx) - dR*(p))/dpx - dDp_dp.block<3,1>(0,i) = ( (Dq0.matrix() * deltas_jac.delta_noisy_vect_(i).head(3)) - (Dq0.matrix() * deltas_jac.delta0_.head(3)) )/delta_noise(i); - //dDp_dv = dDp_do = [0, 0, 0] - - //dDv_dp = [0, 0, 0] - //dDv_dvx = ( dR*(v + dvx) - dR*(v))/dvx - dDv_dv.block<3,1>(0,i) = ( (Dq0 * deltas_jac.delta_noisy_vect_(i+6).tail(3)) - (Dq0 * deltas_jac.delta0_.tail(3)) )/delta_noise(i+6); - //dDv_do = [0, 0, 0] - - //dDo_dp = dDo_dv = [0, 0, 0] - //dDo_dox = log( (dR(Theta) * dr(theta)).transpose() * dR(Theta) * (dr(theta)*exp(dthetax,0,0)) )/dthetax - dDo_do.block<3,1>(0,i) = R2v( (Dq0.matrix() * dq0.matrix()).transpose() * (Dq0.matrix() * dq_noisy.matrix()) )/Delta_noise(i+3); - } - - /* jacobians wrt deltas have PVQ form : - dDp_dP = deltas_jac.jacobian_delta_preint_.block(0,0,3,3); dDp_dV = deltas_jac.jacobian_delta_preint_.block(0,3,3,3); dDp_dO = deltas_jac.jacobian_delta_preint_.block(0,6,3,3); - dDv_dP = deltas_jac.jacobian_delta_preint_.block(3,0,3,3); dDv_dV = deltas_jac.jacobian_delta_preint_.block(3,3,3,3); dDv_dO = deltas_jac.jacobian_delta_preint_.block(3,6,3,3); - dDo_dP = deltas_jac.jacobian_delta_preint_.block(6,0,3,3); dDo_dV = deltas_jac.jacobian_delta_preint_.block(6,3,3,3); dDo_dO = deltas_jac.jacobian_delta_preint_.block(6,6,3,3); - */ - - if(dDp_dP.isApprox(deltas_jac.jacobian_delta_preint_.block(0,0,3,3), wolf::Constants::EPS) ) - std::cout<< "dDp_dP jacobian is correct !" << std::endl; - else{ - std::cout<< "\t\tdDp_dP jacobian is not correct ..." << std::endl; - std::cout << "dDp_dP : \n" << dDp_dP << "\n deltas_jac.jacobian_delta_preint_.block(0,0,3,3) :\n" << deltas_jac.jacobian_delta_preint_.block(0,0,3,3) << "\n" << std::endl; - std::cout << "dDp_dP_a - dDp_dP : \n" << deltas_jac.jacobian_delta_preint_.block(0,0,3,3) - dDp_dP << "\n" << std::endl; - } - - if(dDp_dV.isApprox(deltas_jac.jacobian_delta_preint_.block(0,6,3,3), wolf::Constants::EPS) ) - std::cout<< "dDp_dV jacobian is correct !" << std::endl; - else{ - std::cout<< "\t\tdDp_dV jacobian is not correct ..." << std::endl; - std::cout << "dDp_dV : \n" << dDp_dV << "\n deltas_jac.jacobian_delta_preint_.block(0,6,3,3) :\n" << deltas_jac.jacobian_delta_preint_.block(0,6,3,3) << "\n" << std::endl; - std::cout << "dDp_dV_a - dDp_dV : \n" << deltas_jac.jacobian_delta_preint_.block(0,6,3,3) - dDp_dV << "\n" << std::endl; - } - - if(dDp_dO.isApprox(deltas_jac.jacobian_delta_preint_.block(0,3,3,3), wolf::Constants::EPS) ) - std::cout<< "dDp_dO jacobian is correct !" << std::endl; - else{ - std::cout<< "\t\tdDp_dO jacobian is not correct ..." << std::endl; - std::cout << "dDp_dO : \n" << dDp_dO << "\n deltas_jac.jacobian_delta_preint_.block(0,3,3,3) :\n" << deltas_jac.jacobian_delta_preint_.block(0,3,3,3) << "\n" << std::endl; - std::cout << "dDp_dO_a - dDp_dO : \n" << deltas_jac.jacobian_delta_preint_.block(0,3,3,3) - dDp_dO << "\n" << std::endl; - } - - if(dDv_dV.isApprox(deltas_jac.jacobian_delta_preint_.block(6,6,3,3), wolf::Constants::EPS) ) - std::cout<< "dDv_dV jacobian is correct !" << std::endl; - else{ - std::cout<< "\t\tdDv_dV jacobian is not correct ..." << std::endl; - std::cout << "dDv_dV : \n" << dDv_dV << "\n deltas_jac.jacobian_delta_preint_.block(6,6,3,3) :\n" << deltas_jac.jacobian_delta_preint_.block(6,6,3,3) << "\n" << std::endl; - std::cout << "dDv_dV_a - dDv_dV : \n" << deltas_jac.jacobian_delta_preint_.block(6,6,3,3) - dDv_dV << "\n" << std::endl; - } - - if(dDv_dO.isApprox(deltas_jac.jacobian_delta_preint_.block(6,3,3,3), wolf::Constants::EPS) ) - std::cout<< "dDv_dO jacobian is correct !" << std::endl; - else{ - std::cout<< "\t\tdDv_dO jacobian is not correct ..." << std::endl; - std::cout << "dDv_dO : \n" << dDv_dO << "\n deltas_jac.jacobian_delta_preint_.block(6,3,3,3) :\n" << deltas_jac.jacobian_delta_preint_.block(6,3,3,3) << "\n" << std::endl; - std::cout << "dDv_dO_a - dDv_dO : \n" << deltas_jac.jacobian_delta_preint_.block(6,3,3,3) - dDv_dO << "\n" << std::endl; - } - - if(dDo_dO.isApprox(deltas_jac.jacobian_delta_preint_.block(3,3,3,3), wolf::Constants::EPS) ) - std::cout<< "dDo_dO jacobian is correct !" << std::endl; - else{ - std::cout<< "\t\tdDo_dO jacobian is not correct ..." << std::endl; - std::cout << "dDo_dO : \n" << dDo_dO << "\n deltas_jac.jacobian_delta_preint_.block(3,3,3,3) :\n" << deltas_jac.jacobian_delta_preint_.block(3,3,3,3) << "\n" << std::endl; - std::cout << "dDo_dO_a - dDo_dO : \n" << deltas_jac.jacobian_delta_preint_.block(3,3,3,3) - dDo_dO << "\n" << std::endl; - } - - Eigen::Matrix3d dDp_dp_a, dDv_dv_a, dDo_do_a; - dDp_dp_a = deltas_jac.jacobian_delta_.block(0,0,3,3); - dDv_dv_a = deltas_jac.jacobian_delta_.block(6,6,3,3); - dDo_do_a = deltas_jac.jacobian_delta_.block(3,3,3,3); - - if(dDp_dp.isApprox(dDp_dp_a, wolf::Constants::EPS) ) - std::cout<< "dDp_dp jacobian is correct !" << std::endl; - else{ - std::cout<< "\t\tdDp_dp jacobian is not correct ..." << std::endl; - std::cout << "dDp_dp : \n" << dDv_dp << "\n dDp_dp_a :\n" << dDp_dp_a << "\n" << std::endl; - std::cout << "dDp_dp_a - dDp_dp : \n" << dDp_dp_a - dDv_dp << "\n" << std::endl; - } - - if(dDv_dv.isApprox(dDv_dv_a, wolf::Constants::EPS) ) - std::cout<< "dDv_dv jacobian is correct !" << std::endl; - else{ - std::cout<< "\t\tdDv_dv jacobian is not correct ..." << std::endl; - std::cout << "dDv_dv : \n" << dDv_dv << "\n dDv_dv_a :\n" << dDv_dv_a << "\n" << std::endl; - std::cout << "dDv_dv_a - dDv_dv : \n" << dDv_dv_a - dDv_dv << "\n" << std::endl; - } - - if(dDo_do.isApprox(dDo_do_a, wolf::Constants::EPS) ) - std::cout<< "dDo_do jacobian is correct !" << std::endl; - else{ - std::cout<< "\t\tdDo_do jacobian is not correct ..." << std::endl; - std::cout << "dDo_do : \n" << dDo_do << "\n dDo_do_a :\n" << dDo_do_a << "\n" << std::endl; - std::cout << "dDo_do_a - dDo_do : \n" << dDo_do_a - dDo_do << "\n" << std::endl; - } - - return 0; -} - -using namespace wolf; - -void remapJacDeltas_quat0(IMU_jac_deltas& _jac_delta, Eigen::Map<Eigen::Quaterniond>& _Dq0, Eigen::Map<Eigen::Quaterniond>& _dq0){ - - new (&_Dq0) Eigen::Map<const Eigen::Quaterniond>(_jac_delta.Delta0_.data() + 3); - new (&_dq0) Eigen::Map<const Eigen::Quaterniond>(_jac_delta.delta0_.data() + 3); -} - -void remapJacDeltas_quat(IMU_jac_deltas& _jac_delta, Eigen::Map<Eigen::Quaterniond>& _Dq, Eigen::Map<Eigen::Quaterniond>& _dq, const int& place ){ - - assert(place < _jac_delta.Delta_noisy_vect_.size()); - new (&_Dq) Eigen::Map<const Eigen::Quaterniond>(_jac_delta.Delta_noisy_vect_(place).data() + 3); - new (&_dq) Eigen::Map<const Eigen::Quaterniond>(_jac_delta.delta_noisy_vect_(place).data() + 3); -} diff --git a/demos/processor_imu.yaml b/demos/processor_imu.yaml deleted file mode 100644 index 1afbb00a6ab5112cbad1555098985ae1f0687f8b..0000000000000000000000000000000000000000 --- a/demos/processor_imu.yaml +++ /dev/null @@ -1,16 +0,0 @@ -type: "ProcessorImu" # This must match the KEY used in the SensorFactory. Otherwise it is an error. - -time_tolerance: 0.0025 # Time tolerance for joining KFs -unmeasured_perturbation_std: 0.00001 - -keyframe_vote: - voting_active: false - max_time_span: 2.0 # seconds - max_buff_length: 20000 # motion deltas - dist_traveled: 2.0 # meters - angle_turned: 0.2 # radians (1 rad approx 57 deg, approx 60 deg) - -bootstrap: - enable: false - method: "G" - averaging_length: 0.10 # seconds \ No newline at end of file diff --git a/demos/processor_imu2d.yaml b/demos/processor_imu2d.yaml deleted file mode 100644 index 6d8d756c415d5d9db4b32ab80cf1ea06f72736fd..0000000000000000000000000000000000000000 --- a/demos/processor_imu2d.yaml +++ /dev/null @@ -1,12 +0,0 @@ -type: "ProcessorImu2d" # This must match the KEY used in the SensorFactory. Otherwise it is an error. - -time_tolerance: 0.0025 # Time tolerance for joining KFs -unmeasured_perturbation_std: 0.00001 - -keyframe_vote: - voting_active: false - voting_aux_active: false - max_time_span: 2.0 # seconds - max_buff_length: 20000 # motion deltas - dist_traveled: 2.0 # meters - angle_turned: 0.2 # radians (1 rad approx 57 deg, approx 60 deg) diff --git a/demos/processor_imu_bootstrap.yaml b/demos/processor_imu_bootstrap.yaml deleted file mode 100644 index 3a6c6c9587ab23aeb66ae95495c8054be46e0c96..0000000000000000000000000000000000000000 --- a/demos/processor_imu_bootstrap.yaml +++ /dev/null @@ -1,17 +0,0 @@ -type: "ProcessorImu" # This must match the KEY used in the SensorFactory. Otherwise it is an error. - -time_tolerance: 0.0025 # Time tolerance for joining KFs -unmeasured_perturbation_std: 0.00001 - -keyframe_vote: - voting_active: false - max_time_span: 2.0 # seconds - max_buff_length: 20000 # motion deltas - dist_traveled: 2.0 # meters - angle_turned: 0.2 # radians (1 rad approx 57 deg, approx 60 deg) - -bootstrap: - enable: true - method: "G" # methods: "G", "STATIC" or "V0_G" - averaging_length: 0.10 # seconds - keyframe_provider_processor_name: "processor_other_name" # Not yet implemented \ No newline at end of file diff --git a/demos/processor_odom_3d.yaml b/demos/processor_odom_3d.yaml deleted file mode 100644 index 9ee3321a500e229837b29fb1d03f366f71223f19..0000000000000000000000000000000000000000 --- a/demos/processor_odom_3d.yaml +++ /dev/null @@ -1,12 +0,0 @@ -type: "ProcessorOdom3d" # This must match the KEY used in the SensorFactory. Otherwise it is an error. - -time_tolerance: 0.01 # seconds - -keyframe_vote: - voting_active: false - max_time_span: 0.2 # seconds - max_buff_length: 10 # motion deltas - dist_traveled: 0.5 # meters - angle_turned: 0.1 # radians (1 rad approx 57 deg, approx 60 deg) - -unmeasured_perturbation_std: 0.001 diff --git a/demos/sensor_imu.yaml b/demos/sensor_imu.yaml deleted file mode 100644 index 38a3df944cc7e8a7021e0bfe418fb5c79b324b2f..0000000000000000000000000000000000000000 --- a/demos/sensor_imu.yaml +++ /dev/null @@ -1,11 +0,0 @@ -type: "SensorImu" # This must match the KEY used in the SensorFactory. Otherwise it is an error. - -motion_variances: - a_noise: 0.053 # standard deviation of Acceleration noise (same for all the axis) in m/s2 - w_noise: 0.0011 # standard deviation of Gyroscope noise (same for all the axis) in rad/sec - ab_initial_stdev: 0.800 # m/s2 - initial bias - wb_initial_stdev: 0.350 # rad/sec - initial bias - ab_rate_stdev: 0.1 # m/s2/sqrt(s) - wb_rate_stdev: 0.0400 # rad/s/sqrt(s) - -dynamic_imu_bias: true \ No newline at end of file diff --git a/demos/sensor_imu2d.yaml b/demos/sensor_imu2d.yaml deleted file mode 100644 index 2db3ed90f61e62e596fab85d5d9f1d6c85d89a65..0000000000000000000000000000000000000000 --- a/demos/sensor_imu2d.yaml +++ /dev/null @@ -1,18 +0,0 @@ -states: - P: - state: [0, 0] - mode: fix - dynamic: false - O: - state: [0] - mode: fix - dynamic: false - I: - state: [0, 0, 0] - mode: factor - dynamic: true - noise_std: [0.800, 0.800, 0.350] # Previously named ab_initial_stdev [m/s²] and wb_initial_stdev [rad/sec] - drift_std: [0.1, 0.1, 0.04] # Previously named ab_rate_stdev [m/s²/sqrt(s)] and wb_rate_stdev [rad/s/sqrt(s)] - -a_noise: 0.053 # standard deviation of Acceleration noise (same for all the axis) in m/s² -w_noise: 0.0011 # standard deviation of Gyroscope noise (same for all the axis) in rad/sec \ No newline at end of file diff --git a/demos/sensor_imu2d_with_gravity.yaml b/demos/sensor_imu2d_with_gravity.yaml deleted file mode 100644 index eb30116dd303e9fc0d497ff62e2102d66adeca7d..0000000000000000000000000000000000000000 --- a/demos/sensor_imu2d_with_gravity.yaml +++ /dev/null @@ -1,10 +0,0 @@ -type: "SensorImu2d" # This must match the KEY used in the SensorFactory. Otherwise it is an error. - -motion_variances: - a_noise: 0.053 # standard deviation of Acceleration noise (same for all the axis) in m/s2 - w_noise: 0.0011 # standard deviation of Gyroscope noise (same for all the axis) in rad/sec - ab_initial_stdev: 0.800 # m/s2 - initial bias - wb_initial_stdev: 0.350 # rad/sec - initial bias - ab_rate_stdev: 0.1 # m/s2/sqrt(s) - wb_rate_stdev: 0.0400 # rad/s/sqrt(s) - orthogonal_gravity: false diff --git a/demos/sensor_odom_3d.yaml b/demos/sensor_odom_3d.yaml deleted file mode 100644 index 58db1c088fbc80339a78ba815fddbaf69674d3b6..0000000000000000000000000000000000000000 --- a/demos/sensor_odom_3d.yaml +++ /dev/null @@ -1,7 +0,0 @@ -type: "SensorOdom3d" # This must match the KEY used in the SensorFactory. Otherwise it is an error. - -k_disp_to_disp: 0.02 # m^2 / m -k_disp_to_rot: 0.02 # rad^2 / m -k_rot_to_rot: 0.01 # rad^2 / rad -min_disp_var: 0.01 # m^2 -min_rot_var: 0.01 # rad^2 diff --git a/include/imu/processor/processor_imu_3d.h b/include/imu/processor/processor_imu_3d.h index 74a06972d50ec7b70c3559387fdfdbafbc08cf05..e28c98c92e1e395f1291182c1e37439a3416c620 100644 --- a/include/imu/processor/processor_imu_3d.h +++ b/include/imu/processor/processor_imu_3d.h @@ -91,9 +91,13 @@ class ProcessorImu3d : public ProcessorMotion virtual void emplaceFeaturesAndFactors(CaptureBasePtr _capture_origin, CaptureMotionPtr _capture_own) override; public: + /** \brief Disable bootstrapping process + */ + void bootstrapDisable(); + /** \brief Enable bootstrapping process */ - void bootstrapEnable(bool _bootstrap_enable = true); + void bootstrapEnable(BootstrapMethod _method, const double& _averaging_length); protected: /** \brief Bootstrap the IMU initial conditions diff --git a/src/processor/processor_imu_3d.cpp b/src/processor/processor_imu_3d.cpp index 8fdd36ffd4d0f64d727a37bda48fc04ea149fdca..0461f1d4f513ae76a447c8ef7f47bab605b5ed8e 100644 --- a/src/processor/processor_imu_3d.cpp +++ b/src/processor/processor_imu_3d.cpp @@ -41,7 +41,6 @@ ProcessorImu3d::ProcessorImu3d(const YAML::Node& _params) 6, _params) { - WOLF_DEBUG("in ProcessorImu3d"); bootstrapping_ = _params["bootstrap"]["enabled"].as<bool>(); bootstrap_factor_list_.clear(); @@ -134,8 +133,7 @@ void ProcessorImu3d::setCalibration(const CaptureBasePtr _capture, const VectorX void ProcessorImu3d::configure(SensorBasePtr _sensor) { - if (_sensor->isStateBlockDynamic('I')) - imu_drift_cov_ = _sensor->getDriftCov('I'); + if (_sensor->isStateBlockDynamic('I')) imu_drift_cov_ = _sensor->getDriftCov('I'); } void ProcessorImu3d::emplaceFeaturesAndFactors(CaptureBasePtr _capture_origin, CaptureMotionPtr _capture_own) @@ -152,7 +150,8 @@ void ProcessorImu3d::emplaceFeaturesAndFactors(CaptureBasePtr _capture_origin, C CaptureImuPtr cap_imu = std::static_pointer_cast<CaptureImu>(_capture_origin); - auto fac_imu = FactorBase::emplace<FactorImu3d>(ftr_imu, ftr_imu, cap_imu, shared_from_this(), applyLossFunction()); + auto fac_imu = + FactorBase::emplace<FactorImu3d>(ftr_imu, ftr_imu, cap_imu, shared_from_this(), applyLossFunction()); if (bootstrapping_) { @@ -346,14 +345,14 @@ void ProcessorImu3d::bootstrap() VectorXd delta_int = bootstrapDelta(); // compute local g and transformation to global g - double dt = t_current - first_capture->getTimeStamp(); // - const auto& dv = delta_int.segment(7, 3); // - Vector3d g_l = -(q_l_s * dv / dt); // See eq. (20) - const auto& g_w = gravity(); // - const auto& p_w_l = Vector3d::Zero(); // will pivot around the origin - Quaterniond q_w_l = Quaterniond::FromTwoVectors(g_l, g_w); // - transfo_w_l.at('P') = p_w_l; // - transfo_w_l.at('O') = q_w_l.coeffs(); // + double dt = t_current - first_capture->getTimeStamp(); // + const auto& dv = delta_int.segment(7, 3); // + Vector3d g_l = -(q_l_s * dv / dt); // See eq. (20) + const auto& g_w = gravity(); // + const auto& p_w_l = Vector3d::Zero(); // will pivot around the origin + Quaterniond q_w_l = Quaterniond::FromTwoVectors(g_l, g_w); // + transfo_w_l['P'] = p_w_l; // + transfo_w_l['O'] = q_w_l.coeffs(); // // Transform problem to new reference getProblem()->transform(transfo_w_l); @@ -386,6 +385,8 @@ void ProcessorImu3d::bootstrap() // Implementation of G strategy. if (t_current - first_capture->getTimeStamp() >= bootstrap_averaging_length_) { + WOLF_DEBUG("Computing bootstrap method G, after averaging length ", bootstrap_averaging_length_); + // get initial IMU frame 's' expressed in local world frame 'l' Quaterniond q_l_r; q_l_r.coeffs() = first_capture->getFrame()->getO()->getState(); @@ -397,14 +398,14 @@ void ProcessorImu3d::bootstrap() VectorXd delta_int = bootstrapDelta(); // compute local g and transformation to global g - double dt = t_current - first_capture->getTimeStamp(); // - const auto& dv_l = delta_int.segment(7, 3); // - Vector3d g_l = -(q_l_s * dv_l / dt); // See eq. (20) - const auto& g_w = gravity(); // - const auto& p_w_l = Vector3d::Zero(); // will pivot around the origin - Quaterniond q_w_l = Quaterniond::FromTwoVectors(g_l, g_w); // - transfo_w_l.at('P') = p_w_l; // - transfo_w_l.at('O') = q_w_l.coeffs(); // + double dt = t_current - first_capture->getTimeStamp(); // + const auto& dv_l = delta_int.segment(7, 3); // + Vector3d g_l = -(q_l_s * dv_l / dt); // See eq. (20) + const auto& g_w = gravity(); // + const auto& p_w_l = Vector3d::Zero(); // will pivot around the origin + Quaterniond q_w_l = Quaterniond::FromTwoVectors(g_l, g_w); // + transfo_w_l['P'] = p_w_l; // + transfo_w_l['O'] = q_w_l.coeffs(); // // Transform problem to new reference getProblem()->transform(transfo_w_l); @@ -444,10 +445,18 @@ void ProcessorImu3d::bootstrap() } } -void ProcessorImu3d::bootstrapEnable(bool _bootstrap_enable) +void ProcessorImu3d::bootstrapDisable() +{ + bootstrapping_ = false; +} + +void ProcessorImu3d::bootstrapEnable(BootstrapMethod _method, const double& _averaging_length) { - bootstrapping_ = _bootstrap_enable; -}; + bootstrapping_ = true; + bootstrap_method_ = _method; + bootstrap_averaging_length_ = _averaging_length; + bootstrap_factor_list_.clear(); +} CaptureBasePtr ProcessorImu3d::bootstrapOrigin() const { diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 0ab211adef0f8fd3ebddf0af853b3dc851f3e920..019c2209000a152d666b730b529fd5ea78b8bde8 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,6 +1,14 @@ # Retrieve googletest from github & compile add_subdirectory(gtest) +# Add here the source (.cpp) files in dummy folder +set(SRC_DUMMY + dummy/load_dummy.cpp + dummy/processor_imu_2d_tester.cpp + dummy/processor_imu_3d_tester.cpp + ) +add_library(dummy SHARED ${SRC_DUMMY}) +target_link_libraries(dummy ${PLUGIN_NAME}) ############# USE THIS TEST AS AN EXAMPLE ################# # # @@ -25,6 +33,8 @@ wolf_add_gtest(gtest_imu_2d_static_init gtest_imu_2d_static_init.cpp) wolf_add_gtest(gtest_imu_2d_tools gtest_imu_2d_tools.cpp) +wolf_add_gtest(gtest_imu_3d_bootstrap gtest_imu_3d_bootstrap.cpp) + wolf_add_gtest(gtest_imu_3d_mocap_fusion gtest_imu_3d_mocap_fusion.cpp) wolf_add_gtest(gtest_imu_3d_static_init gtest_imu_3d_static_init.cpp) @@ -34,6 +44,7 @@ wolf_add_gtest(gtest_imu_3d_tools gtest_imu_3d_tools.cpp) wolf_add_gtest(gtest_imu_3d gtest_imu_3d.cpp) wolf_add_gtest(gtest_processor_imu_3d_jacobians gtest_processor_imu_3d_jacobians.cpp) +target_link_libraries(gtest_processor_imu_3d_jacobians PUBLIC dummy) wolf_add_gtest(gtest_processor_imu_3d gtest_processor_imu_3d.cpp) @@ -44,5 +55,6 @@ wolf_add_gtest(gtest_processor_imu_2d gtest_processor_imu_2d.cpp) wolf_add_gtest(gtest_processor_motion_intrinsics_update gtest_processor_motion_intrinsics_update.cpp) wolf_add_gtest(gtest_schema gtest_schema.cpp) +target_link_libraries(gtest_schema PUBLIC dummy) wolf_add_gtest(gtest_sensor_compass gtest_sensor_compass.cpp) diff --git a/test/dummy/load_dummy.cpp b/test/dummy/load_dummy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3aac5f6120338772769e7e21a7dc0bd1d4923cec --- /dev/null +++ b/test/dummy/load_dummy.cpp @@ -0,0 +1,35 @@ +// WOLF - Copyright (C) 2020,2021,2022,2023 +// Institut de Robòtica i Informà tica Industrial, CSIC-UPC. +// Authors: Joan Solà Ortega (jsola@iri.upc.edu) and +// Joan Vallvé Navarro (jvallve@iri.upc.edu) +// All rights reserved. +// +// This file is part of WOLF: http://www.iri.upc.edu/wolf +// WOLF is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "load_dummy.h" + +namespace wolf +{ +bool LoadDummy::aux_var = true; + +// LoadDummy::LoadDummy() +// { +// } + +// LoadDummy::~LoadDummy() +// { +// } + +} // namespace wolf diff --git a/test/dummy/load_dummy.h b/test/dummy/load_dummy.h new file mode 100644 index 0000000000000000000000000000000000000000..c64b2e3a0969de3c8be533a41bea56ccd572b97f --- /dev/null +++ b/test/dummy/load_dummy.h @@ -0,0 +1,52 @@ +// WOLF - Copyright (C) 2020,2021,2022,2023 +// Institut de Robòtica i Informà tica Industrial, CSIC-UPC. +// Authors: Joan Solà Ortega (jsola@iri.upc.edu) and +// Joan Vallvé Navarro (jvallve@iri.upc.edu) +// All rights reserved. +// +// This file is part of WOLF: http://www.iri.upc.edu/wolf +// WOLF is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#pragma once + +#include "core/common/factory.h" + +namespace wolf +{ +// This class is just to easily force loading of the .so in tests +struct LoadDummy +{ + static bool aux_var; +}; + +#ifdef __GNUC__ +#define WOLF_UNUSED __attribute__((used)) +#elif defined _MSC_VER +#pragma warning(disable : Cxxxxx) +#define WOLF_UNUSED +#elif defined(__LCLINT__) +#define WOLF_UNUSED /*@unused@*/ +#elif defined(__cplusplus) +#define WOLF_UNUSED +#else +#define UNUSED(x) x +#endif + +#define WOLF_LOAD_DUMMY \ + namespace \ + { \ + const bool WOLF_UNUSED aux_var_dummy = wolf::LoadDummy::aux_var; \ + } + +} // namespace wolf diff --git a/test/processor_imu_2d_tester.cpp b/test/dummy/processor_imu_2d_tester.cpp similarity index 100% rename from test/processor_imu_2d_tester.cpp rename to test/dummy/processor_imu_2d_tester.cpp diff --git a/test/processor_imu_2d_tester.h b/test/dummy/processor_imu_2d_tester.h similarity index 100% rename from test/processor_imu_2d_tester.h rename to test/dummy/processor_imu_2d_tester.h diff --git a/test/processor_imu_3d_tester.cpp b/test/dummy/processor_imu_3d_tester.cpp similarity index 100% rename from test/processor_imu_3d_tester.cpp rename to test/dummy/processor_imu_3d_tester.cpp diff --git a/test/processor_imu_3d_tester.h b/test/dummy/processor_imu_3d_tester.h similarity index 100% rename from test/processor_imu_3d_tester.h rename to test/dummy/processor_imu_3d_tester.h diff --git a/test/gtest_imu_3d.cpp b/test/gtest_imu_3d.cpp index 4212b159f07f563795abba33e469b8872269a9a2..3208626ec85d87c83a8209d1d79cd358a6984033 100644 --- a/test/gtest_imu_3d.cpp +++ b/test/gtest_imu_3d.cpp @@ -120,6 +120,8 @@ class Process_Factor_Imu : public testing::Test solver = FactorySolverFile::create( "SolverCeres", problem, imu_dir + "/test/yaml/solver_ceres.yaml", {wolf_schema_dir}); + // Time + t0 = 0; dt = 0.01; // Some initializations @@ -569,9 +571,13 @@ class Process_Factor_Imu : public testing::Test std::string runAll(SolverManager::ReportVerbosity verbose) { configureAll(); + WOLF_DEBUG("configured") integrateAll(); + WOLF_DEBUG("integrated all") buildProblem(); + WOLF_DEBUG("built problem") std::string report = solveProblem(verbose); + WOLF_DEBUG("solved") return report; } @@ -659,6 +665,7 @@ class Process_Factor_Imu_ODO : public Process_Factor_Imu { // ===================================== Imu Process_Factor_Imu::configureAll(); + WOLF_DEBUG("Process_Factor_Imu configured"); // ===================================== ODO processor_odo->setOrigin(KF_0); @@ -720,14 +727,8 @@ class Process_Factor_Imu_ODO : public Process_Factor_Imu TEST_F(Process_Factor_Imu, MotionConstant_PQV_b__PQV_b) // F_ixed___e_stimated { // ================================================================================================================ - // // // ==================================== INITIAL CONDITIONS -- USER OPTIONS ======================================== - // // // ================================================================================================================ - // // - // - // ---------- time - t0 = 0; num_integrations = 50; // ---------- initial pose @@ -750,11 +751,9 @@ TEST_F(Process_Factor_Imu, MotionConstant_PQV_b__PQV_b) // F_ixed___e_stimated p1_fixed = true; q1_fixed = true; v1_fixed = true; - // + // ===================================== INITIAL CONDITIONS -- USER INPUT ENDS HERE =============================== - // // // ================================================================================================================ - // // // ===================================== RUN ALL std::string report = runAll(SolverManager::ReportVerbosity::BRIEF); @@ -767,14 +766,8 @@ TEST_F(Process_Factor_Imu, MotionConstant_PQV_b__PQV_b) // F_ixed___e_stimated TEST_F(Process_Factor_Imu, test_capture) // F_ixed___e_stimated { // ================================================================================================================ - // // // ==================================== INITIAL CONDITIONS -- USER OPTIONS ======================================== - // // // ================================================================================================================ - // // - // - // ---------- time - t0 = 0; num_integrations = 50; // ---------- initial pose @@ -797,11 +790,9 @@ TEST_F(Process_Factor_Imu, test_capture) // F_ixed___e_stimated p1_fixed = true; q1_fixed = true; v1_fixed = true; - // + // ===================================== INITIAL CONDITIONS -- USER INPUT ENDS HERE =============================== - // // // ================================================================================================================ - // // // ===================================== RUN ALL Eigen::Vector6d initial_bias((Eigen::Vector6d() << .002, .0007, -.001, .003, -.002, .001).finished()); @@ -819,14 +810,8 @@ TEST_F(Process_Factor_Imu, test_capture) // F_ixed___e_stimated TEST_F(Process_Factor_Imu, MotionConstant_pqv_b__PQV_b) // F_ixed___e_stimated { // ================================================================================================================ - // // // ==================================== INITIAL CONDITIONS -- USER OPTIONS ======================================== - // // // ================================================================================================================ - // // - // - // ---------- time - t0 = 0; num_integrations = 50; // ---------- initial pose @@ -849,11 +834,9 @@ TEST_F(Process_Factor_Imu, MotionConstant_pqv_b__PQV_b) // F_ixed___e_stimated p1_fixed = true; q1_fixed = true; v1_fixed = true; - // + // ===================================== INITIAL CONDITIONS -- USER INPUT ENDS HERE =============================== - // // // ================================================================================================================ - // // // ===================================== RUN ALL std::string report = runAll(SolverManager::ReportVerbosity::BRIEF); @@ -866,14 +849,8 @@ TEST_F(Process_Factor_Imu, MotionConstant_pqv_b__PQV_b) // F_ixed___e_stimated TEST_F(Process_Factor_Imu, MotionConstant_pqV_b__PQv_b) // F_ixed___e_stimated { // ================================================================================================================ - // // // ==================================== INITIAL CONDITIONS -- USER OPTIONS ======================================== - // // // ================================================================================================================ - // // - // - // ---------- time - t0 = 0; num_integrations = 50; // ---------- initial pose @@ -896,11 +873,9 @@ TEST_F(Process_Factor_Imu, MotionConstant_pqV_b__PQv_b) // F_ixed___e_stimated p1_fixed = true; q1_fixed = true; v1_fixed = false; - // + // ===================================== INITIAL CONDITIONS -- USER INPUT ENDS HERE =============================== - // // // ================================================================================================================ - // // // ===================================== RUN ALL std::string report = runAll(SolverManager::ReportVerbosity::BRIEF); @@ -913,14 +888,8 @@ TEST_F(Process_Factor_Imu, MotionConstant_pqV_b__PQv_b) // F_ixed___e_stimated TEST_F(Process_Factor_Imu, MotionRandom_PQV_b__PQV_b) // F_ixed___e_stimated { // ================================================================================================================ - // // // ==================================== INITIAL CONDITIONS -- USER OPTIONS ======================================== - // // // ================================================================================================================ - // // - // - // ---------- time - t0 = 0; num_integrations = 50; // ---------- initial pose @@ -943,11 +912,9 @@ TEST_F(Process_Factor_Imu, MotionRandom_PQV_b__PQV_b) // F_ixed___e_stimated p1_fixed = true; q1_fixed = true; v1_fixed = true; - // + // ===================================== INITIAL CONDITIONS -- USER INPUT ENDS HERE =============================== - // // // ================================================================================================================ - // // // ===================================== RUN ALL std::string report = runAll(SolverManager::ReportVerbosity::BRIEF); @@ -960,14 +927,8 @@ TEST_F(Process_Factor_Imu, MotionRandom_PQV_b__PQV_b) // F_ixed___e_stimated TEST_F(Process_Factor_Imu, MotionRandom_pqV_b__PQv_b) // F_ixed___e_stimated { // ================================================================================================================ - // // // ==================================== INITIAL CONDITIONS -- USER OPTIONS ======================================== - // // // ================================================================================================================ - // // - // - // ---------- time - t0 = 0; num_integrations = 50; // ---------- initial pose @@ -990,11 +951,9 @@ TEST_F(Process_Factor_Imu, MotionRandom_pqV_b__PQv_b) // F_ixed___e_stimated p1_fixed = true; q1_fixed = true; v1_fixed = false; - // + // ===================================== INITIAL CONDITIONS -- USER INPUT ENDS HERE =============================== - // // // ================================================================================================================ - // // // ===================================== RUN ALL std::string report = runAll(SolverManager::ReportVerbosity::BRIEF); @@ -1007,14 +966,8 @@ TEST_F(Process_Factor_Imu, MotionRandom_pqV_b__PQv_b) // F_ixed___e_stimated TEST_F(Process_Factor_Imu, MotionRandom_pqV_b__pQV_b) // F_ixed___e_stimated { // ================================================================================================================ - // // // ==================================== INITIAL CONDITIONS -- USER OPTIONS ======================================== - // // // ================================================================================================================ - // // - // - // ---------- time - t0 = 0; num_integrations = 50; // ---------- initial pose @@ -1037,11 +990,9 @@ TEST_F(Process_Factor_Imu, MotionRandom_pqV_b__pQV_b) // F_ixed___e_stimated p1_fixed = false; q1_fixed = true; v1_fixed = true; - // + // ===================================== INITIAL CONDITIONS -- USER INPUT ENDS HERE =============================== - // // // ================================================================================================================ - // // // ===================================== RUN ALL std::string report = runAll(SolverManager::ReportVerbosity::BRIEF); @@ -1054,14 +1005,8 @@ TEST_F(Process_Factor_Imu, MotionRandom_pqV_b__pQV_b) // F_ixed___e_stimated TEST_F(Process_Factor_Imu, MotionConstant_NonNullState_PQV_b__PQV_b) // F_ixed___e_stimated { // ================================================================================================================ - // // // ==================================== INITIAL CONDITIONS -- USER OPTIONS ======================================== - // // // ================================================================================================================ - // // - // - // ---------- time - t0 = 0; num_integrations = 50; // ---------- initial pose @@ -1084,11 +1029,9 @@ TEST_F(Process_Factor_Imu, MotionConstant_NonNullState_PQV_b__PQV_b) // F_ixed_ p1_fixed = true; q1_fixed = true; v1_fixed = true; - // + // ===================================== INITIAL CONDITIONS -- USER INPUT ENDS HERE =============================== - // // // ================================================================================================================ - // // // ===================================== RUN ALL std::string report = runAll(SolverManager::ReportVerbosity::BRIEF); @@ -1101,14 +1044,8 @@ TEST_F(Process_Factor_Imu, MotionConstant_NonNullState_PQV_b__PQV_b) // F_ixed_ TEST_F(Process_Factor_Imu_ODO, MotionConstantRotation_PQV_b__PQV_b) // F_ixed___e_stimated { // ================================================================================================================ - // // // ==================================== INITIAL CONDITIONS -- USER OPTIONS ======================================== - // // // ================================================================================================================ - // // - // - // ---------- time - t0 = 0; num_integrations = 50; // ---------- initial pose @@ -1131,11 +1068,9 @@ TEST_F(Process_Factor_Imu_ODO, MotionConstantRotation_PQV_b__PQV_b) // F_ixed__ p1_fixed = true; q1_fixed = true; v1_fixed = true; - // + // ===================================== INITIAL CONDITIONS -- USER INPUT ENDS HERE =============================== - // // // ================================================================================================================ - // // // ===================================== RUN ALL std::string report = runAll(SolverManager::ReportVerbosity::BRIEF); @@ -1148,14 +1083,8 @@ TEST_F(Process_Factor_Imu_ODO, MotionConstantRotation_PQV_b__PQV_b) // F_ixed__ TEST_F(Process_Factor_Imu_ODO, MotionConstantRotation_PQV_b__PQv_b) // F_ixed___e_stimated { // ================================================================================================================ - // // // ==================================== INITIAL CONDITIONS -- USER OPTIONS ======================================== - // // // ================================================================================================================ - // // - // - // ---------- time - t0 = 0; num_integrations = 50; // ---------- initial pose @@ -1178,11 +1107,9 @@ TEST_F(Process_Factor_Imu_ODO, MotionConstantRotation_PQV_b__PQv_b) // F_ixed__ p1_fixed = true; q1_fixed = true; v1_fixed = false; - // + // ===================================== INITIAL CONDITIONS -- USER INPUT ENDS HERE =============================== - // // // ================================================================================================================ - // // // ===================================== RUN ALL std::string report = runAll(SolverManager::ReportVerbosity::BRIEF); @@ -1195,14 +1122,8 @@ TEST_F(Process_Factor_Imu_ODO, MotionConstantRotation_PQV_b__PQv_b) // F_ixed__ TEST_F(Process_Factor_Imu_ODO, MotionConstantRotation_PQV_b__Pqv_b) // F_ixed___e_stimated { // ================================================================================================================ - // // // ==================================== INITIAL CONDITIONS -- USER OPTIONS ======================================== - // // // ================================================================================================================ - // // - // - // ---------- time - t0 = 0; num_integrations = 50; // ---------- initial pose @@ -1225,11 +1146,9 @@ TEST_F(Process_Factor_Imu_ODO, MotionConstantRotation_PQV_b__Pqv_b) // F_ixed__ p1_fixed = true; q1_fixed = false; v1_fixed = false; - // + // ===================================== INITIAL CONDITIONS -- USER INPUT ENDS HERE =============================== - // // // ================================================================================================================ - // // // ===================================== RUN ALL std::string report = runAll(SolverManager::ReportVerbosity::BRIEF); @@ -1242,14 +1161,8 @@ TEST_F(Process_Factor_Imu_ODO, MotionConstantRotation_PQV_b__Pqv_b) // F_ixed__ TEST_F(Process_Factor_Imu_ODO, MotionConstantRotation_PQV_b__pQv_b) // F_ixed___e_stimated { // ================================================================================================================ - // // // ==================================== INITIAL CONDITIONS -- USER OPTIONS ======================================== - // // // ================================================================================================================ - // // - // - // ---------- time - t0 = 0; num_integrations = 50; // ---------- initial pose @@ -1272,11 +1185,9 @@ TEST_F(Process_Factor_Imu_ODO, MotionConstantRotation_PQV_b__pQv_b) // F_ixed__ p1_fixed = false; q1_fixed = true; v1_fixed = false; - // + // ===================================== INITIAL CONDITIONS -- USER INPUT ENDS HERE =============================== - // // // ================================================================================================================ - // // // ===================================== RUN ALL std::string report = runAll(SolverManager::ReportVerbosity::BRIEF); @@ -1289,14 +1200,8 @@ TEST_F(Process_Factor_Imu_ODO, MotionConstantRotation_PQV_b__pQv_b) // F_ixed__ TEST_F(Process_Factor_Imu_ODO, MotionConstantRotation_PQV_b__pqv_b) // F_ixed___e_stimated { // ================================================================================================================ - // // // ==================================== INITIAL CONDITIONS -- USER OPTIONS ======================================== - // // // ================================================================================================================ - // // - // - // ---------- time - t0 = 0; num_integrations = 50; // ---------- initial pose @@ -1319,11 +1224,9 @@ TEST_F(Process_Factor_Imu_ODO, MotionConstantRotation_PQV_b__pqv_b) // F_ixed__ p1_fixed = false; q1_fixed = false; v1_fixed = false; - // + // ===================================== INITIAL CONDITIONS -- USER INPUT ENDS HERE =============================== - // // // ================================================================================================================ - // // // ===================================== RUN ALL std::string report = runAll(SolverManager::ReportVerbosity::BRIEF); @@ -1336,14 +1239,8 @@ TEST_F(Process_Factor_Imu_ODO, MotionConstantRotation_PQV_b__pqv_b) // F_ixed__ TEST_F(Process_Factor_Imu_ODO, MotionConstant_pqv_b__pqV_b) // F_ixed___e_stimated { // ================================================================================================================ - // // // ==================================== INITIAL CONDITIONS -- USER OPTIONS ======================================== - // // // ================================================================================================================ - // // - // - // ---------- time - t0 = 0; num_integrations = 50; // ---------- initial pose @@ -1366,11 +1263,9 @@ TEST_F(Process_Factor_Imu_ODO, MotionConstant_pqv_b__pqV_b) // F_ixed___e_stima p1_fixed = false; q1_fixed = false; v1_fixed = true; - // + // ===================================== INITIAL CONDITIONS -- USER INPUT ENDS HERE =============================== - // // // ================================================================================================================ - // // // ===================================== RUN ALL std::string report = runAll(SolverManager::ReportVerbosity::BRIEF); @@ -1383,14 +1278,8 @@ TEST_F(Process_Factor_Imu_ODO, MotionConstant_pqv_b__pqV_b) // F_ixed___e_stima TEST_F(Process_Factor_Imu_ODO, MotionConstant_pqV_b__pqv_b) // F_ixed___e_stimated { // ================================================================================================================ - // // // ==================================== INITIAL CONDITIONS -- USER OPTIONS ======================================== - // // // ================================================================================================================ - // // - // - // ---------- time - t0 = 0; num_integrations = 50; // ---------- initial pose @@ -1413,11 +1302,9 @@ TEST_F(Process_Factor_Imu_ODO, MotionConstant_pqV_b__pqv_b) // F_ixed___e_stima p1_fixed = false; q1_fixed = false; v1_fixed = false; - // + // ===================================== INITIAL CONDITIONS -- USER INPUT ENDS HERE =============================== - // // // ================================================================================================================ - // // // ===================================== RUN ALL std::string report = runAll(SolverManager::ReportVerbosity::BRIEF); @@ -1430,14 +1317,8 @@ TEST_F(Process_Factor_Imu_ODO, MotionConstant_pqV_b__pqv_b) // F_ixed___e_stima TEST_F(Process_Factor_Imu_ODO, MotionRandom_PQV_b__pqv_b) // F_ixed___e_stimated { // ================================================================================================================ - // // // ==================================== INITIAL CONDITIONS -- USER OPTIONS ======================================== - // // // ================================================================================================================ - // // - // - // ---------- time - t0 = 0; num_integrations = 50; // ---------- initial pose @@ -1460,11 +1341,9 @@ TEST_F(Process_Factor_Imu_ODO, MotionRandom_PQV_b__pqv_b) // F_ixed___e_stimate p1_fixed = false; q1_fixed = false; v1_fixed = false; - // + // ===================================== INITIAL CONDITIONS -- USER INPUT ENDS HERE =============================== - // // // ================================================================================================================ - // // // ===================================== RUN ALL std::string report = runAll(SolverManager::ReportVerbosity::BRIEF); @@ -1477,14 +1356,8 @@ TEST_F(Process_Factor_Imu_ODO, MotionRandom_PQV_b__pqv_b) // F_ixed___e_stimate TEST_F(Process_Factor_Imu_ODO, MotionRandom_PqV_b__pqV_b) // F_ixed___e_stimated { // ================================================================================================================ - // // // ==================================== INITIAL CONDITIONS -- USER OPTIONS ======================================== - // // // ================================================================================================================ - // // - // - // ---------- time - t0 = 0; num_integrations = 50; // ---------- initial pose @@ -1507,11 +1380,9 @@ TEST_F(Process_Factor_Imu_ODO, MotionRandom_PqV_b__pqV_b) // F_ixed___e_stimate p1_fixed = false; q1_fixed = false; v1_fixed = true; - // + // ===================================== INITIAL CONDITIONS -- USER INPUT ENDS HERE =============================== - // // // ================================================================================================================ - // // // ===================================== RUN ALL std::string report = runAll(SolverManager::ReportVerbosity::BRIEF); @@ -1524,14 +1395,8 @@ TEST_F(Process_Factor_Imu_ODO, MotionRandom_PqV_b__pqV_b) // F_ixed___e_stimate TEST_F(Process_Factor_Imu_ODO, RecoverTrajectory_MotionRandom_PqV_b__pqV_b) // F_ixed___e_stimated { // ================================================================================================================ - // // // ==================================== INITIAL CONDITIONS -- USER OPTIONS ======================================== - // // // ================================================================================================================ - // // - // - // ---------- time - t0 = 0; num_integrations = 25; // ---------- initial pose @@ -1554,11 +1419,10 @@ TEST_F(Process_Factor_Imu_ODO, RecoverTrajectory_MotionRandom_PqV_b__pqV_b) // p1_fixed = false; q1_fixed = false; v1_fixed = true; - // + + WOLF_INFO("TEST initial conditions set"); // ===================================== INITIAL CONDITIONS -- USER INPUT ENDS HERE =============================== - // // // ================================================================================================================ - // // // ===================================== RUN ALL configureAll(); @@ -1616,48 +1480,11 @@ TEST_F(Process_Factor_Imu_ODO, RecoverTrajectory_MotionRandom_PqV_b__pqV_b) // ASSERT_MATRIX_APPROX(Trj_x_optim_prc.rightCols(1), x1_exact, 1e-6); } -TEST_F(Process_Factor_Imu, bootstrap) -{ - processor_imu->setVotingActive(true); - processor_imu->setMaxTimeSpan(0.04); - processor_imu->bootstrapEnable(true); - - // FIXME: error maybe due to enable bootstrap before problem->applyPriorOptions() - - // auto KF0 = problem->emplaceFrame(0.0); - // problem->keyFrameCallback(KF0, nullptr); - problem->print(4, 0, 1, 0); - - // Vector6d data(0,0,9.806, 0,0,0); // gravity on Z - // Vector6d data(0.0, 9.806, 0.0, 0.0, 0.0, 0.0); // gravity on Y - Vector6d data; - data << 0.0, 9.806, 0.0, 0.0, 0.0, 0.0; // gravity on Y - - capture_imu = std::make_shared<CaptureImu>(0.0, sensor_imu, data, Matrix6d::Identity()); - - for (t = 0; t < 0.14; t += dt) - { - capture_imu->setTimeStamp(t); - capture_imu->process(); - } - - problem->print(4, 0, 1, 1); - - Quaterniond qref(AngleAxisd(M_PI / 2, Vector3d::UnitX())); // turn of +90deg over X - for (auto pair_ts_frame : problem->getTrajectory()->getFrameMap()) - { - ASSERT_MATRIX_APPROX(pair_ts_frame.second->getStateVector("P"), Vector3d::Zero(), 1e-10); - ASSERT_MATRIX_APPROX(pair_ts_frame.second->getStateVector("O"), qref.coeffs(), 1e-10); - ASSERT_MATRIX_APPROX(pair_ts_frame.second->getStateVector("V"), Vector3d::Zero(), 1e-10); - } -} - int main(int argc, char** argv) { testing::InitGoogleTest(&argc, argv); - testing::GTEST_FLAG(filter) = "Process_Factor_Imu.bootstrap"; // testing::GTEST_FLAG(filter) = "Process_Factor_Imu_ODO.*"; - // testing::GTEST_FLAG(filter) = "Process_Factor_Imu_ODO.RecoverTrajectory_MotionRandom_PqV_b__pqV_b"; + testing::GTEST_FLAG(filter) = "Process_Factor_Imu_ODO.RecoverTrajectory_MotionRandom_PqV_b__pqV_b"; return RUN_ALL_TESTS(); } diff --git a/test/gtest_imu_3d_bootstrap.cpp b/test/gtest_imu_3d_bootstrap.cpp new file mode 100644 index 0000000000000000000000000000000000000000..95de61f08899c090e6bcb1e9ff1b8b6b1456f8ae --- /dev/null +++ b/test/gtest_imu_3d_bootstrap.cpp @@ -0,0 +1,121 @@ +// WOLF - Copyright (C) 2020,2021,2022,2023 +// Institut de Robòtica i Informà tica Industrial, CSIC-UPC. +// Authors: Joan Solà Ortega (jsola@iri.upc.edu) and +// Joan Vallvé Navarro (jvallve@iri.upc.edu) +// All rights reserved. +// +// This file is part of WOLF: http://www.iri.upc.edu/wolf +// WOLF is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#include "imu/common/imu.h" +#include "imu/processor/processor_imu_3d.h" +#include "imu/sensor/sensor_imu.h" +#include "imu/math/imu_3d_tools.h" + +#include <core/utils/utils_gtest.h> + +using namespace Eigen; +using namespace wolf; + +std::string imu_dir = _WOLF_IMU_CODE_DIR; + +class Imu3dBootstrap : public testing::Test +{ + public: + ProblemPtr problem; + SensorImu3dPtr sensor_imu; + ProcessorImu3dPtr processor_imu; + + TimeStamp t0; + double dt; + + void SetUp() override + { + // problem + problem = Problem::autoSetup(imu_dir + "/test/yaml/problem_imu_3d_bootstrap.yaml", {imu_dir}); + + // sensor imu + sensor_imu = std::static_pointer_cast<SensorImu3d>(problem->findSensor("cool sensor imu")); + + // processor imu + processor_imu = std::static_pointer_cast<ProcessorImu3d>(sensor_imu->getProcessorList().front()); + + // Time + t0 = 0; + dt = 0.01; + } +}; + +TEST_F(Imu3dBootstrap, bootstrap_static) +{ + // set bootstrap static + processor_imu->bootstrapEnable(BootstrapMethod::BOOTSTRAP_STATIC, 0.9); + + // capture + Vector6d data; + data << 0.0, 9.806, 0.0, 0.0, 0.0, 0.0; // gravity on Y + // data << 0.0, 0.0, 9.806, 0.0, 0.0, 0.0; // gravity on Z + auto capture_imu = std::make_shared<CaptureImu>(t0, sensor_imu, data, Matrix6d::Identity()); + + for (auto t = t0; t < 1; t += dt) + { + capture_imu->setTimeStamp(t); + capture_imu->process(); + } + problem->print(4, 1, 1, 1); + + // check correct frames states + Quaterniond qref(AngleAxisd(M_PI / 2, Vector3d::UnitX())); // turn of +90deg over X + for (auto pair_ts_frame : problem->getTrajectory()->getFrameMap()) + { + ASSERT_MATRIX_APPROX(pair_ts_frame.second->getStateVector("P"), Vector3d::Zero(), 1e-10); + ASSERT_MATRIX_APPROX(pair_ts_frame.second->getStateVector("O"), qref.coeffs(), 1e-10); + ASSERT_MATRIX_APPROX(pair_ts_frame.second->getStateVector("V"), Vector3d::Zero(), 1e-10); + } +} + +TEST_F(Imu3dBootstrap, bootstrap_G) +{ + // set bootstrap G + processor_imu->bootstrapEnable(BootstrapMethod::BOOTSTRAP_G, 0.9); + + // capture + Vector6d data; + data << 0.0, 9.806, 0.0, 0.0, 0.0, 0.0; // gravity on Y + // data << 0.0, 0.0, 9.806, 0.0, 0.0, 0.0; // gravity on Z + auto capture_imu = std::make_shared<CaptureImu>(t0, sensor_imu, data, Matrix6d::Identity()); + + for (auto t = t0; t < 1; t += dt) + { + capture_imu->setTimeStamp(t); + capture_imu->process(); + } + problem->print(4, 1, 1, 1); + + // check correct frames states + Quaterniond qref(AngleAxisd(M_PI / 2, Vector3d::UnitX())); // turn of +90deg over X + for (auto pair_ts_frame : problem->getTrajectory()->getFrameMap()) + { + ASSERT_MATRIX_APPROX(pair_ts_frame.second->getStateVector("P"), Vector3d::Zero(), 1e-10); + ASSERT_MATRIX_APPROX(pair_ts_frame.second->getStateVector("O"), qref.coeffs(), 1e-10); + ASSERT_MATRIX_APPROX(pair_ts_frame.second->getStateVector("V"), Vector3d::Zero(), 1e-10); + } +} + +int main(int argc, char** argv) +{ + testing::InitGoogleTest(&argc, argv); + // testing::GTEST_FLAG(filter) = "Imu3dBootstrap"; + return RUN_ALL_TESTS(); +} \ No newline at end of file diff --git a/test/gtest_processor_imu_3d_jacobians.cpp b/test/gtest_processor_imu_3d_jacobians.cpp index e4575c131cde13c7ab111c5aad6e401e059fcdbd..ec946665194c2d4d6c175cf5eee128adbfcd0f35 100644 --- a/test/gtest_processor_imu_3d_jacobians.cpp +++ b/test/gtest_processor_imu_3d_jacobians.cpp @@ -21,7 +21,7 @@ // Wolf #include "imu/capture/capture_imu.h" #include "imu/sensor/sensor_imu.h" -#include "processor_imu_3d_tester.h" +#include "dummy/processor_imu_3d_tester.h" #include "core/common/wolf.h" #include "core/problem/problem.h" #include "core/state_block/state_block.h" diff --git a/test/gtest_schema.cpp b/test/gtest_schema.cpp index d125b6a4a2b2eb299e70c82e8f32741819a4fa87..44501c36c59a79fc396a774d38a8fd2968cc5627 100644 --- a/test/gtest_schema.cpp +++ b/test/gtest_schema.cpp @@ -39,6 +39,10 @@ std::string imu_dir = _WOLF_IMU_CODE_DIR; WOLF_LOAD_CORE; WOLF_LOAD_IMU; +// Force load .so of dummy library +#include "dummy/load_dummy.h" +WOLF_LOAD_DUMMY; + bool existsSchema(std::string name_schema) { // Check extension diff --git a/test/yaml/imu_2d_static_init/processor_imu_2d.yaml b/test/yaml/imu_2d_static_init/processor_imu_2d.yaml index 0bc741fcab19bed2f140d0bc8f32a211c651d12f..68b453002af649674b7643d01e98396488f54312 100644 --- a/test/yaml/imu_2d_static_init/processor_imu_2d.yaml +++ b/test/yaml/imu_2d_static_init/processor_imu_2d.yaml @@ -13,11 +13,6 @@ keyframe_vote: max_buff_length: 1000000000 # motion deltas max_dist_traveled: 100000000000 # meters max_angle_turned: 10000000000 # radians (1 rad approx 57 deg, approx 60 deg) - -bootstrap: - enable: false - method: "G" - averaging_length: 10 state_provider: true state_provider_order: 1 diff --git a/test/yaml/imu_3d/processor_imu_3d.yaml b/test/yaml/imu_3d/processor_imu_3d.yaml index cd9cfab8c29bd983842841d242b647b1c67b093d..c9dcfe815e125ab2e7e8d297932f24d1392cd153 100644 --- a/test/yaml/imu_3d/processor_imu_3d.yaml +++ b/test/yaml/imu_3d/processor_imu_3d.yaml @@ -18,4 +18,4 @@ state_provider: true state_provider_order: 1 bootstrap: - enabled: false \ No newline at end of file + enabled: false \ No newline at end of file diff --git a/test/yaml/problem_imu_3d_bootstrap.yaml b/test/yaml/problem_imu_3d_bootstrap.yaml new file mode 100644 index 0000000000000000000000000000000000000000..351e63cdc4fbb166f1ebcfffa65b913a52eed25e --- /dev/null +++ b/test/yaml/problem_imu_3d_bootstrap.yaml @@ -0,0 +1,20 @@ +problem: + dimension: 3 + first_frame: + P: + state: [0,0,0] + mode: "initial_guess" + O: + state: [0,0,0,1] + mode: "initial_guess" + V: + state: [0,0,0] + mode: "initial_guess" + tree_manager: + type: "None" + +sensors: + - follow: sensor_imu_3d.yaml + +processors: + - follow: processor_imu_3d_bootstrap.yaml \ No newline at end of file diff --git a/test/yaml/processor_imu_3d_bootstrap.yaml b/test/yaml/processor_imu_3d_bootstrap.yaml new file mode 100644 index 0000000000000000000000000000000000000000..10c38d512068b216b5387d146d6a1c4c2ba4c348 --- /dev/null +++ b/test/yaml/processor_imu_3d_bootstrap.yaml @@ -0,0 +1,23 @@ +name: "cool processor imu" +plugin: imu +type: ProcessorImu3d +sensor_name: "cool sensor imu" + +time_tolerance: 0.0025 # Time tolerance for joining KFs +unmeasured_perturbation_std: 0.00001 +apply_loss_function: false + +keyframe_vote: + voting_active: true + max_time_span: 0.04 # seconds + max_buff_length: 20000 # motion deltas + max_dist_traveled: 2.0 # meters + max_angle_turned: 0.2 # radians (1 rad approx 57 deg, approx 60 deg) + +state_provider: true +state_provider_order: 1 + +bootstrap: + enabled: true + method: "G" + averaging_length: 0.95 \ No newline at end of file