diff --git a/demos/solo_real_estimation.yaml b/demos/solo_real_estimation.yaml index 62258179f3d786b1093ca314d2e9895bf765b7c3..c00ef31936d3db340ceefa227cf9d159f4c6e0d5 100644 --- a/demos/solo_real_estimation.yaml +++ b/demos/solo_real_estimation.yaml @@ -43,6 +43,8 @@ std_pose_o_deg: 1 std_mocap_extr_o_deg: 0.1 std_mocap_extr_p: 10 unfix_extr_sensor_pose: true +time_shift_mocap: 0 +time_tolerance_mocap: 0.001 bias_imu_prior: [0,0,0, 0,0,0] # bias_imu_prior: [0,0,-0.011,-0.000079251, 0.00439540765, -0.0002120267] diff --git a/demos/solo_real_pov_estimation.cpp b/demos/solo_real_pov_estimation.cpp index f52ae06bb3f9ca1379b6171f42485e81c53f6b69..83cc8497bad7a63d861d97dd5540f17bb0a073d6 100644 --- a/demos/solo_real_pov_estimation.cpp +++ b/demos/solo_real_pov_estimation.cpp @@ -26,6 +26,7 @@ #include <core/capture/capture_base.h> #include <core/capture/capture_pose.h> #include <core/feature/feature_base.h> +#include <core/factor/factor_pose_3d_with_extrinsics.h> #include <core/factor/factor_block_absolute.h> #include <core/processor/processor_odom_3d.h> #include <core/sensor/sensor_odom_3d.h> @@ -39,6 +40,7 @@ #include "imu/sensor/sensor_imu.h" #include "imu/capture/capture_imu.h" #include "imu/processor/processor_imu.h" +#include "imu/factor/factor_imu.h" // BODYDYNAMICS #include "bodydynamics/internal/config.h" @@ -115,9 +117,10 @@ int main (int argc, char **argv) { double std_pose_o_deg = config["std_pose_o_deg"].as<double>(); double std_mocap_extr_p = config["std_mocap_extr_p"].as<double>(); double std_mocap_extr_o_deg = config["std_mocap_extr_o_deg"].as<double>(); - // - bool unfix_extr_sensor_pose = config["unfix_extr_sensor_pose"].as<bool>(); + bool time_tolerance_mocap = config["time_tolerance_mocap"].as<double>(); + double time_shift_mocap = config["time_shift_mocap"].as<double>(); + std::string data_file_path = config["data_file_path"].as<std::string>(); std::string out_npz_file_path = config["out_npz_file_path"].as<std::string>(); @@ -255,7 +258,7 @@ int main (int argc, char **argv) { Vector7d extr_pose; extr_pose << i_p_ib, i_q_b.coeffs(); auto sensor_pose = problem->installSensor("SensorPose", "pose", extr_pose, intr_sp); auto params_proc = std::make_shared<ParamsProcessorPose>(); - params_proc->time_tolerance = 0.005; + params_proc->time_tolerance = time_tolerance_mocap; auto proc_pose = problem->installProcessor("ProcessorPose", "pose", sensor_pose, params_proc); // somehow by default the sensor extrinsics is fixed Matrix3d cov_sp_p = pow(std_mocap_extr_p, 2)*Matrix3d::Identity(); @@ -308,11 +311,12 @@ int main (int argc, char **argv) { std::vector<Vector3d> p_ob_fbk_v; std::vector<Vector4d> q_ob_fbk_v; std::vector<Vector3d> v_ob_fbk_v; - double o_p_ob_fbk_carr[3*N]; - double o_q_b_fbk_carr[4*N]; - double o_v_ob_fbk_carr[3*N]; - double imu_bias_fbk_carr[6*N]; - double extr_mocap_fbk_carr[7*N]; + // Allocate on the heap to prevent stack overflow for large datasets + double* o_p_ob_fbk_carr = new double[3*N]; + double* o_q_b_fbk_carr = new double[4*N]; + double* o_v_ob_fbk_carr = new double[3*N]; + double* imu_bias_fbk_carr = new double[6*N]; + double* extr_mocap_fbk_carr = new double[7*N]; std::vector<Vector3d> i_omg_oi_v; ////////////////////////////////////////// @@ -453,7 +457,7 @@ int main (int argc, char **argv) { // Vector7d pose_meas; pose_meas << w_p_wm, w_qvec_wm; Vector7d pose_meas; pose_meas << w_p_wm, w_qvec_wm; - CapturePosePtr CP = std::make_shared<CapturePose>(ts, sensor_pose, pose_meas, sensor_pose->getNoiseCov()); + CapturePosePtr CP = std::make_shared<CapturePose>(ts+time_shift_mocap, sensor_pose, pose_meas, sensor_pose->getNoiseCov()); CP->process(); // ts_since_last_kf += dt; @@ -515,11 +519,11 @@ int main (int argc, char **argv) { problem->print(4,true,true,true); std::cout << report << std::endl; } - - double o_p_ob_carr[3*N]; - double o_q_b_carr[4*N]; - double o_v_ob_carr[3*N]; - double imu_bias_carr[6*N]; + + double* o_p_ob_carr = new double[3*N]; + double* o_q_b_carr = new double[4*N]; + double* imu_bias_carr = new double[6*N]; + double* o_v_ob_carr = new double[6*N]; for (unsigned int i=0; i < N; i++) { VectorComposite state_est = problem->getState(t_arr[i]); Vector3d i_omg_oi = i_omg_oi_v[i]; @@ -547,6 +551,97 @@ int main (int argc, char **argv) { } + // Compute Covariances + unsigned int Nkf = problem->getTrajectory()->getFrameMap().size(); + double* tkf_carr = new double[1*Nkf]; + double* Qp_carr = new double[3*Nkf]; + double* Qo_carr = new double[3*Nkf]; + double* Qv_carr = new double[3*Nkf]; + double* Qbi_carr = new double[6*Nkf]; + double* Qm_carr = new double[6*Nkf]; + // factor errors + double* fac_imu_err_carr = new double[9*Nkf]; + double* fac_pose_err_carr = new double[6*Nkf]; + int i = 0; + for (auto& elt: problem->getTrajectory()->getFrameMap()){ + std::cout << "Traj " << i << "/" << problem->getTrajectory()->getFrameMap().size() << std::endl; + tkf_carr[i] = elt.first.get(); + auto kf = elt.second; + VectorComposite kf_state = kf->getState(); + + // compute covariances of KF and capture stateblocks + Eigen::MatrixXd Qp = Eigen::Matrix3d::Identity(); + Eigen::MatrixXd Qo = Eigen::Matrix3d::Identity(); // global or local? + Eigen::MatrixXd Qv = Eigen::Matrix3d::Identity(); + Eigen::MatrixXd Qbi = Eigen::Matrix6d::Identity(); + Eigen::MatrixXd Qmp = Eigen::Matrix3d::Identity(); // extr mocap + Eigen::MatrixXd Qmo = Eigen::Matrix3d::Identity(); // extr mocap + + solver->computeCovariances(SolverManager::CovarianceBlocksToBeComputed::ALL); // should not be computed every time !! see below + problem->getCovarianceBlock(kf->getStateBlock('P'), Qp); + problem->getCovarianceBlock(kf->getStateBlock('O'), Qo); + problem->getCovarianceBlock(kf->getStateBlock('V'), Qv); + + CaptureBasePtr cap_imu = kf->getCaptureOf(sen_imu); + + std::vector<StateBlockPtr> extr_sb_vec = {sensor_pose->getP(), sensor_pose->getO()}; + solver->computeCovariances(extr_sb_vec); // not computed by ALL and destroys other computed covs -> issue to raise + problem->getCovarianceBlock(sensor_pose->getP(), Qmp); + problem->getCovarianceBlock(sensor_pose->getO(), Qmo); + // std::cout << "Qbp\n" << Qbp << std::endl; + solver->computeCovariances(cap_imu->getStateBlockVec()); // not computed by ALL and destroys other computed covs -> issue to raise + problem->getCovarianceBlock(cap_imu->getSensorIntrinsic(), Qbi); + + // diagonal components + Vector3d Qp_diag = Qp.diagonal(); + Vector3d Qo_diag = Qo.diagonal(); + Vector3d Qv_diag = Qv.diagonal(); + Vector6d Qbi_diag = Qbi.diagonal(); + Vector6d Qm_diag; Qm_diag << Qmp.diagonal(), Qmo.diagonal(); + + memcpy(Qp_carr + 3*i, Qp_diag.data(), 3*sizeof(double)); + memcpy(Qo_carr + 3*i, Qo_diag.data(), 3*sizeof(double)); + memcpy(Qv_carr + 3*i, Qv_diag.data(), 3*sizeof(double)); + memcpy(Qbi_carr + 6*i, Qbi_diag.data(), 6*sizeof(double)); + memcpy(Qm_carr + 6*i, Qm_diag.data(), 6*sizeof(double)); + + // Factor errors + // std::cout << "Factors " << kf->getTimeStamp().get() << std::endl; + FactorBasePtrList fac_lst; + kf->getFactorList(fac_lst); + Vector9d imu_err = Vector9d::Zero(); + Vector6d pose_err = Vector6d::Zero(); + for (auto fac: fac_lst){ + if (fac->getProcessor() == proc_imu){ + auto f = std::dynamic_pointer_cast<FactorImu>(fac); + // Matrix6d R_bias_drift = f->getMeasurementSquareRootInformationUpper().bottomRightCorner<6,6>(); + // Matrix6d R_bias_drift = f->getFeature()->getMeasurementSquareRootInformationUpper().bottomRightCorner<6,6>(); + // std::cout << R_bias_drift << std::endl; + // MatrixXd R_bias_drift = f->getFeature()->getMeasurementSquareRootInformationUpper(); + // MatrixXd Cov_bias_drift = f->getFeature()->getMeasurementCovariance(); + // std::cout << "R_bias_drift" << std::endl; + // std::cout << R_bias_drift << std::endl; + // std::cout << "Cov_bias_drift" << std::endl; + // std::cout << Cov_bias_drift << std::endl; + + if (f){ + imu_err = f->error(); + } + } + if (fac->getProcessor() == proc_pose){ + auto f = std::dynamic_pointer_cast<FactorPose3dWithExtrinsics>(fac); + if (f){ + pose_err = f->error(); + } + } + } + memcpy(fac_imu_err_carr + 9*i, imu_err.data(), 9*sizeof(double)); + memcpy(fac_pose_err_carr + 6*i, pose_err.data(), 6*sizeof(double)); + + + i++; + } + // Save trajectories in npz file // save ground truth cnpy::npz_save(out_npz_file_path, "t", t_arr, {N}, "w"); // "w" overwrites any file with same name @@ -554,13 +649,14 @@ int main (int argc, char **argv) { cnpy::npz_save(out_npz_file_path, "w_q_m", w_q_m_arr, {N,4}, "a"); cnpy::npz_save(out_npz_file_path, "w_v_wm", w_v_wm_arr, {N,3}, "a"); cnpy::npz_save(out_npz_file_path, "m_v_wm", m_v_wm_arr, {N,3}, "a"); - cnpy::npz_save(out_npz_file_path, "o_q_i", o_q_i_arr, {N,3}, "a"); - cnpy::npz_save(out_npz_file_path, "qa", qa_arr, {N,12}, "a"); + cnpy::npz_save(out_npz_file_path, "o_q_i", o_q_i_arr, {N,3}, "a"); + cnpy::npz_save(out_npz_file_path, "qa", qa_arr, {N,12}, "a"); // save estimates cnpy::npz_save(out_npz_file_path, "o_p_ob_fbk", o_p_ob_fbk_carr, {N,3}, "a"); cnpy::npz_save(out_npz_file_path, "o_q_b_fbk", o_q_b_fbk_carr, {N,4}, "a"); cnpy::npz_save(out_npz_file_path, "o_v_ob_fbk", o_v_ob_fbk_carr, {N,3}, "a"); + cnpy::npz_save(out_npz_file_path, "o_p_ob", o_p_ob_carr, {N,3}, "a"); cnpy::npz_save(out_npz_file_path, "o_q_b", o_q_b_carr, {N,4}, "a"); cnpy::npz_save(out_npz_file_path, "o_v_ob", o_v_ob_carr, {N,3}, "a"); @@ -570,4 +666,14 @@ int main (int argc, char **argv) { cnpy::npz_save(out_npz_file_path, "imu_bias", imu_bias_carr, {N,6}, "a"); cnpy::npz_save(out_npz_file_path, "extr_mocap_fbk", extr_mocap_fbk_carr, {N,7}, "a"); + // covariances + cnpy::npz_save(out_npz_file_path, "tkf", tkf_carr, {Nkf}, "a"); + cnpy::npz_save(out_npz_file_path, "Qp", Qp_carr, {Nkf,3}, "a"); + cnpy::npz_save(out_npz_file_path, "Qo", Qo_carr, {Nkf,3}, "a"); + cnpy::npz_save(out_npz_file_path, "Qv", Qv_carr, {Nkf,3}, "a"); + cnpy::npz_save(out_npz_file_path, "Qbi", Qbi_carr, {Nkf,6}, "a"); + cnpy::npz_save(out_npz_file_path, "Qm", Qm_carr, {Nkf,6}, "a"); + cnpy::npz_save(out_npz_file_path, "fac_imu_err", fac_imu_err_carr, {Nkf,9}, "a"); + cnpy::npz_save(out_npz_file_path, "fac_pose_err", fac_pose_err_carr, {Nkf,6}, "a"); + }