calibrate imu
This commit is contained in:
@@ -138,7 +138,6 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
feature_detection::DetectorPtr feature_detector_;
|
feature_detection::DetectorPtr feature_detector_;
|
||||||
callback_t seed_converged_cb_;
|
callback_t seed_converged_cb_;
|
||||||
//std::list<Seed> seeds_;
|
|
||||||
std::list<Seed, Eigen::aligned_allocator<Seed>> seeds_;
|
std::list<Seed, Eigen::aligned_allocator<Seed>> seeds_;
|
||||||
boost::mutex seeds_mut_;
|
boost::mutex seeds_mut_;
|
||||||
bool seeds_updating_halt_; //!< Set this value to true when seeds updating should be interrupted.
|
bool seeds_updating_halt_; //!< Set this value to true when seeds updating should be interrupted.
|
||||||
@@ -150,8 +149,8 @@ protected:
|
|||||||
bool new_keyframe_set_; //!< Do we have a new keyframe to process?.
|
bool new_keyframe_set_; //!< Do we have a new keyframe to process?.
|
||||||
double new_keyframe_min_depth_; //!< Minimum depth in the new keyframe. Used for range in new seeds.
|
double new_keyframe_min_depth_; //!< Minimum depth in the new keyframe. Used for range in new seeds.
|
||||||
double new_keyframe_mean_depth_; //!< Maximum depth in the new keyframe. Used for range in new seeds.
|
double new_keyframe_mean_depth_; //!< Maximum depth in the new keyframe. Used for range in new seeds.
|
||||||
//vk::PerformanceMonitor permon_; //!< Separate performance monitor since the DepthFilter runs in a parallel thread.
|
|
||||||
Matcher matcher_;
|
Matcher matcher_;
|
||||||
|
uint seeds_cont_=0;
|
||||||
|
|
||||||
/// Initialize new seeds from a frame.
|
/// Initialize new seeds from a frame.
|
||||||
void initializeSeeds(FramePtr frame);
|
void initializeSeeds(FramePtr frame);
|
||||||
|
|||||||
@@ -24,13 +24,13 @@ class Imu_Integration{
|
|||||||
public:
|
public:
|
||||||
Imu_Integration(Sophus::SE3& SE_init);
|
Imu_Integration(Sophus::SE3& SE_init);
|
||||||
~Imu_Integration();
|
~Imu_Integration();
|
||||||
bool reset(gtsam::ISAM2& optimizer,boost::shared_ptr<svo::Frame>& new_frame);
|
void reset();
|
||||||
bool reset(gtsam::LevenbergMarquardtOptimizer& optimizer,boost::shared_ptr<svo::Frame>& new_frame);
|
bool reset(gtsam::LevenbergMarquardtOptimizer& optimizer,boost::shared_ptr<svo::Frame>& new_frame);
|
||||||
bool update(double* imu= nullptr);
|
bool update(double* imu= nullptr);
|
||||||
bool predict(boost::shared_ptr<svo::Frame>&,
|
bool predict(boost::shared_ptr<svo::Frame>&,
|
||||||
boost::shared_ptr<svo::Frame>& last_frame ,std::size_t&,const double reproj_thresh);
|
boost::shared_ptr<svo::Frame>& last_frame ,const double match);
|
||||||
bool init(boost::shared_ptr<svo::Frame>&);
|
bool init(boost::shared_ptr<svo::Frame>&);
|
||||||
Sophus::SE3 preintegrate_predict();
|
bool preintegrate_predict(svo::SE2_5& frame);
|
||||||
private:
|
private:
|
||||||
FILE* logtime;
|
FILE* logtime;
|
||||||
std::shared_ptr<gtsam::NavState> statePtr;
|
std::shared_ptr<gtsam::NavState> statePtr;
|
||||||
|
|||||||
@@ -92,14 +92,17 @@ void DepthFilter::addFrame(FramePtr frame)
|
|||||||
seeds_updating_halt_ = false;
|
seeds_updating_halt_ = false;
|
||||||
frame_queue_cond_.notify_one();
|
frame_queue_cond_.notify_one();
|
||||||
}
|
}
|
||||||
else
|
else{
|
||||||
updateSeeds(frame);
|
updateSeeds(frame);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DepthFilter::addKeyframe(FramePtr frame, double depth_mean, double depth_min)
|
void DepthFilter::addKeyframe(FramePtr frame, double depth_mean, double depth_min)
|
||||||
{
|
{
|
||||||
new_keyframe_min_depth_ = depth_min;
|
new_keyframe_min_depth_ = depth_min;
|
||||||
new_keyframe_mean_depth_ = depth_mean;
|
new_keyframe_mean_depth_ = depth_mean;
|
||||||
|
++seeds_cont_;
|
||||||
if(thread_ != NULL)
|
if(thread_ != NULL)
|
||||||
{
|
{
|
||||||
new_keyframe_ = frame;
|
new_keyframe_ = frame;
|
||||||
@@ -108,7 +111,10 @@ void DepthFilter::addKeyframe(FramePtr frame, double depth_mean, double depth_mi
|
|||||||
frame_queue_cond_.notify_one();
|
frame_queue_cond_.notify_one();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
if(seeds_cont_>5){
|
||||||
initializeSeeds(frame);
|
initializeSeeds(frame);
|
||||||
|
seeds_cont_=0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DepthFilter::initializeSeeds(FramePtr frame)
|
void DepthFilter::initializeSeeds(FramePtr frame)
|
||||||
@@ -178,7 +184,9 @@ void DepthFilter::updateSeedsLoop()
|
|||||||
if(new_keyframe_set_)
|
if(new_keyframe_set_)
|
||||||
{
|
{
|
||||||
new_keyframe_set_ = false;
|
new_keyframe_set_ = false;
|
||||||
|
if(seeds_cont_>5){
|
||||||
seeds_updating_halt_ = false;
|
seeds_updating_halt_ = false;
|
||||||
|
}
|
||||||
clearFrameQueue();
|
clearFrameQueue();
|
||||||
frame = new_keyframe_;
|
frame = new_keyframe_;
|
||||||
}
|
}
|
||||||
@@ -189,8 +197,12 @@ void DepthFilter::updateSeedsLoop()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
updateSeeds(frame);
|
updateSeeds(frame);
|
||||||
if(frame->isKeyframe())
|
|
||||||
|
if(frame->isKeyframe() && seeds_cont_>5){
|
||||||
initializeSeeds(frame);
|
initializeSeeds(frame);
|
||||||
|
seeds_cont_=0;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,6 +245,10 @@ void DepthFilter::updateSeeds(FramePtr frame)
|
|||||||
// we are using inverse depth coordinates
|
// we are using inverse depth coordinates
|
||||||
float z_inv_min = it->mu + sqrt(it->sigma2);
|
float z_inv_min = it->mu + sqrt(it->sigma2);
|
||||||
float z_inv_max = max(it->mu - sqrt(it->sigma2), 0.00000001f);
|
float z_inv_max = max(it->mu - sqrt(it->sigma2), 0.00000001f);
|
||||||
|
if(z_inv_min <0){
|
||||||
|
++it;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
double z;
|
double z;
|
||||||
if(!matcher_.findEpipolarMatchDirect(
|
if(!matcher_.findEpipolarMatchDirect(
|
||||||
*it->ftr->frame, *frame, *it->ftr, 1.0/it->mu, 1.0/z_inv_min, 1.0/z_inv_max, z))
|
*it->ftr->frame, *frame, *it->ftr, 1.0/it->mu, 1.0/z_inv_min, 1.0/z_inv_max, z))
|
||||||
@@ -264,20 +280,7 @@ void DepthFilter::updateSeeds(FramePtr frame)
|
|||||||
Vector3d xyz_world(it->ftr->frame->T_f_w_.T->inverse() * (it->ftr->f * (1.0/it->mu)));
|
Vector3d xyz_world(it->ftr->frame->T_f_w_.T->inverse() * (it->ftr->f * (1.0/it->mu)));
|
||||||
Point* point = new Point(xyz_world, it->ftr);
|
Point* point = new Point(xyz_world, it->ftr);
|
||||||
it->ftr->point = point;
|
it->ftr->point = point;
|
||||||
/* FIXME it is not threadsafe to add a feature to the frame here.
|
|
||||||
if(frame->isKeyframe())
|
|
||||||
{
|
|
||||||
Feature* ftr = new Feature(frame.get(), matcher_.px_cur_, matcher_.search_level_);
|
|
||||||
ftr->point = point;
|
|
||||||
point->addFrameRef(ftr);
|
|
||||||
frame->addFeature(ftr);
|
|
||||||
it->ftr->frame->addFeature(it->ftr);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
seed_converged_cb_(point, it->sigma2); // put in candidate list
|
seed_converged_cb_(point, it->sigma2); // put in candidate list
|
||||||
}
|
|
||||||
it = seeds_.erase(it);
|
it = seeds_.erase(it);
|
||||||
}
|
}
|
||||||
else if(isnan(z_inv_min))
|
else if(isnan(z_inv_min))
|
||||||
|
|||||||
@@ -203,7 +203,7 @@ bool align2D(
|
|||||||
bool sign=true;// +
|
bool sign=true;// +
|
||||||
|
|
||||||
// termination condition
|
// termination condition
|
||||||
const float min_update_squared = 0.05;
|
const float min_update_squared = 0.3;
|
||||||
const int cur_step = cur_img.step.p[0];
|
const int cur_step = cur_img.step.p[0];
|
||||||
// float chi2 = 0;
|
// float chi2 = 0;
|
||||||
Vector3f update; update.setZero();
|
Vector3f update; update.setZero();
|
||||||
|
|||||||
@@ -136,14 +136,15 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processSecondFrame()
|
|||||||
|
|
||||||
FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame()
|
FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame()
|
||||||
{
|
{
|
||||||
SE3 tem=imu_integPtr_->preintegrate_predict();
|
bool IMU=false;
|
||||||
if((new_frame_->T_f_w_.T->translation()-tem.translation()).norm()>0.5){
|
SE2_5 tem(0.0,0.0,0.0);
|
||||||
new_frame_->T_f_w_ = SE2_5(tem.translation().x(),tem.translation().z(),atan(tem.rotation_matrix()(0,2)/tem.rotation_matrix()(0,0)));
|
if(imu_integPtr_->preintegrate_predict(tem))if((last_frame_->T_f_w_.T->translation()-tem.T->translation()).norm()>0.5){
|
||||||
|
new_frame_->T_f_w_ = tem;
|
||||||
|
IMU=true;
|
||||||
}else{
|
}else{
|
||||||
|
imu_integPtr_->reset();
|
||||||
new_frame_->T_f_w_ = last_frame_->T_f_w_;
|
new_frame_->T_f_w_ = last_frame_->T_f_w_;
|
||||||
}
|
}
|
||||||
new_frame_->T_f_w_.set();
|
|
||||||
//new_frame_->T_f_w_ = last_frame_->T_f_w_;
|
|
||||||
// sparse image align
|
// sparse image align
|
||||||
SparseImgAlign img_align(Config::kltMaxLevel(), Config::kltMinLevel(),
|
SparseImgAlign img_align(Config::kltMaxLevel(), Config::kltMinLevel(),
|
||||||
30, SparseImgAlign::LevenbergMarquardt, false, false);
|
30, SparseImgAlign::LevenbergMarquardt, false, false);
|
||||||
@@ -151,30 +152,32 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame()
|
|||||||
new_frame_->T_f_w_.set();
|
new_frame_->T_f_w_.set();
|
||||||
// map reprojection & feature alignment
|
// map reprojection & feature alignment
|
||||||
reprojector_.reprojectMap(new_frame_, overlap_kfs_);
|
reprojector_.reprojectMap(new_frame_, overlap_kfs_);
|
||||||
size_t sfba_n_edges_final=0;
|
|
||||||
new_frame_->T_f_w_.set();
|
new_frame_->T_f_w_.set();
|
||||||
double sfba_thresh, sfba_error_init, sfba_error_final;
|
if(IMU)if(!imu_integPtr_->predict(new_frame_,last_frame_,reprojector_.n_matches_)){
|
||||||
if(!imu_integPtr_->predict(new_frame_,last_frame_,sfba_n_edges_final,reprojector_.n_matches_)){
|
|
||||||
return RESULT_FAILURE;
|
return RESULT_FAILURE;
|
||||||
}
|
}
|
||||||
|
size_t sfba_n_edges_final=0;
|
||||||
|
double sfba_thresh, sfba_error_init, sfba_error_final;
|
||||||
new_frame_->T_f_w_.set();
|
new_frame_->T_f_w_.set();
|
||||||
pose_optimizer::optimizeGaussNewton(
|
pose_optimizer::optimizeGaussNewton(
|
||||||
Config::poseOptimThresh(), Config::poseOptimNumIter(), false,
|
Config::poseOptimThresh(), Config::poseOptimNumIter(), false,
|
||||||
new_frame_, sfba_thresh, sfba_error_init, sfba_error_final, sfba_n_edges_final);
|
new_frame_, sfba_thresh, sfba_error_init, sfba_error_final, sfba_n_edges_final);
|
||||||
|
|
||||||
new_frame_->T_f_w_.set();
|
new_frame_->T_f_w_.set();
|
||||||
std::cerr<<"Reprojection Map: "<<"\t nPoint:"<<overlap_kfs_.back().second
|
|
||||||
|
std::cout<<"Reprojection Map: "<<"\t nPoint:"<<overlap_kfs_.back().second
|
||||||
<<"\t nCell = "<<reprojector_.n_trials_<<"\t \t nMatches = "<<reprojector_.n_matches_
|
<<"\t nCell = "<<reprojector_.n_trials_<<"\t \t nMatches = "<<reprojector_.n_matches_
|
||||||
<<" \t Reprojected points after opmization: "<<sfba_n_edges_final<<'\n';
|
<<" \t Reprojected points after opmization: "<<sfba_n_edges_final<<'\n';
|
||||||
|
|
||||||
|
if((last_frame_->T_f_w_.T->translation()-new_frame_->T_f_w_.T->translation()).norm()>1.0){
|
||||||
|
new_frame_->T_f_w_ = last_frame_->T_f_w_;
|
||||||
|
return RESULT_NO_KEYFRAME;
|
||||||
|
}
|
||||||
if(sfba_n_edges_final < Config::qualityMinFts() || reprojector_.n_matches_ < Config::qualityMinFts()){
|
if(sfba_n_edges_final < Config::qualityMinFts() || reprojector_.n_matches_ < Config::qualityMinFts()){
|
||||||
return RESULT_NO_KEYFRAME;
|
return RESULT_NO_KEYFRAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
// structure optimization
|
|
||||||
// SVO_START_TIMER("point_optimizer");
|
|
||||||
optimizeStructure(new_frame_, Config::structureOptimMaxPts(), Config::structureOptimNumIter());
|
optimizeStructure(new_frame_, Config::structureOptimMaxPts(), Config::structureOptimNumIter());
|
||||||
//SVO_STOP_TIMER("point_optimizer");
|
|
||||||
|
|
||||||
new_frame_->T_f_w_.set();
|
new_frame_->T_f_w_.set();
|
||||||
// select keyframe
|
// select keyframe
|
||||||
@@ -188,8 +191,11 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame()
|
|||||||
|
|
||||||
new_frame_->T_f_w_.set();
|
new_frame_->T_f_w_.set();
|
||||||
frame_utils::getSceneDepth(*new_frame_, depth_mean, depth_min);
|
frame_utils::getSceneDepth(*new_frame_, depth_mean, depth_min);
|
||||||
|
if(depth_mean > 50 || depth_mean < 0.0)
|
||||||
|
{
|
||||||
|
return RESULT_NO_KEYFRAME;
|
||||||
|
}
|
||||||
|
|
||||||
new_frame_->T_f_w_.set();
|
|
||||||
if(!needNewKf(depth_mean) || tracking_quality_ == TRACKING_BAD)//edited
|
if(!needNewKf(depth_mean) || tracking_quality_ == TRACKING_BAD)//edited
|
||||||
{
|
{
|
||||||
depth_filter_->addFrame(new_frame_);
|
depth_filter_->addFrame(new_frame_);
|
||||||
@@ -204,7 +210,6 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame()
|
|||||||
}
|
}
|
||||||
map_.point_candidates_.addCandidatePointToFrame(new_frame_);
|
map_.point_candidates_.addCandidatePointToFrame(new_frame_);
|
||||||
|
|
||||||
new_frame_->T_f_w_.set();
|
|
||||||
// init new depth-filters
|
// init new depth-filters
|
||||||
depth_filter_->addKeyframe(new_frame_, depth_mean, 0.5*depth_min);
|
depth_filter_->addKeyframe(new_frame_, depth_mean, 0.5*depth_min);
|
||||||
|
|
||||||
@@ -219,7 +224,7 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame()
|
|||||||
new_frame_->T_f_w_.set();
|
new_frame_->T_f_w_.set();
|
||||||
// add keyframe to map
|
// add keyframe to map
|
||||||
map_.addKeyframe(new_frame_);
|
map_.addKeyframe(new_frame_);
|
||||||
std::cerr<<"Svo pipline was finished\n";
|
std::cout<<"Svo pipline was finished\n";
|
||||||
return RESULT_IS_KEYFRAME;
|
return RESULT_IS_KEYFRAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -294,11 +299,11 @@ bool FrameHandlerMono::needNewKf(double scene_depth_mean)
|
|||||||
for(auto&& it:overlap_kfs_)
|
for(auto&& it:overlap_kfs_)
|
||||||
{
|
{
|
||||||
Vector3d relpos = new_frame_->w2f(it.first->pos());
|
Vector3d relpos = new_frame_->w2f(it.first->pos());
|
||||||
if(fabs(relpos.x())/scene_depth_mean < Config::kfSelectMinDist() &&
|
if(fabs(relpos.norm())/scene_depth_mean < Config::kfSelectMinDist()){
|
||||||
fabs(relpos.y())/scene_depth_mean < Config::kfSelectMinDist() &&
|
|
||||||
fabs(relpos.z())/scene_depth_mean < Config::kfSelectMinDist())
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
#include <vikit/params_helper.h>
|
#include <vikit/params_helper.h>
|
||||||
#include <gpu_svo/config.h>
|
#include <gpu_svo/config.h>
|
||||||
#include <gpu_svo/for_it.hpp>
|
#include <gpu_svo/for_it.hpp>
|
||||||
#define debug 0
|
#define debug 1
|
||||||
Imu_Integration::Imu_Integration(Sophus::SE3& SE_init){
|
Imu_Integration::Imu_Integration(Sophus::SE3& SE_init){
|
||||||
graphPtr=std::make_shared<gtsam::NonlinearFactorGraph>();
|
graphPtr=std::make_shared<gtsam::NonlinearFactorGraph>();
|
||||||
valuesPtr=std::make_shared<gtsam::Values>();
|
valuesPtr=std::make_shared<gtsam::Values>();
|
||||||
@@ -49,10 +49,12 @@ Imu_Integration::~Imu_Integration(){
|
|||||||
bool Imu_Integration::update(double* imu){
|
bool Imu_Integration::update(double* imu){
|
||||||
if(syn)return false;
|
if(syn)return false;
|
||||||
if(imu_factor_id<1)return false;
|
if(imu_factor_id<1)return false;
|
||||||
|
if(abs(imu[0])<1.0)imu[0]=pow(imu[0],3);
|
||||||
|
if(abs(imu[1])<1.0)imu[0]=pow(imu[1],3);
|
||||||
auto in=std::chrono::steady_clock::now();
|
auto in=std::chrono::steady_clock::now();
|
||||||
if(std::chrono::duration<double>(in-t_1).count()>20.0){
|
if(std::chrono::duration<double>(in-t_1).count()>20.0){
|
||||||
t_1=in;
|
t_1=in;
|
||||||
preintegratedPtr->integrateMeasurement(Eigen::Vector3d(-1.0*(imu[0]-svo::Config::X_off()),0.0,-1.0*(imu[1]-svo::Config::Y_off())),Eigen::Vector3d(0.0,imu[5]-svo::Config::Teta_off(),0.0),0.005);
|
preintegratedPtr->integrateMeasurement(Eigen::Vector3d(-1.0*(imu[0]-svo::Config::X_off()),0.0,-1.0*(imu[1]-svo::Config::Y_off())),Eigen::Vector3d(0.0,imu[5]-svo::Config::Teta_off(),0.0),0.0005);
|
||||||
}else{
|
}else{
|
||||||
preintegratedPtr->integrateMeasurement(Eigen::Vector3d(-1.0*(imu[0]-svo::Config::X_off()),0.0,-1.0*(imu[1]-svo::Config::Y_off())),Eigen::Vector3d(0.0,imu[5]-svo::Config::Teta_off(),0.0),std::chrono::duration<double>(in-t_1).count());
|
preintegratedPtr->integrateMeasurement(Eigen::Vector3d(-1.0*(imu[0]-svo::Config::X_off()),0.0,-1.0*(imu[1]-svo::Config::Y_off())),Eigen::Vector3d(0.0,imu[5]-svo::Config::Teta_off(),0.0),std::chrono::duration<double>(in-t_1).count());
|
||||||
t_1=in;
|
t_1=in;
|
||||||
@@ -61,126 +63,79 @@ bool Imu_Integration::update(double* imu){
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
bool Imu_Integration::reset(gtsam::ISAM2& optimizer,boost::shared_ptr<svo::Frame>& new_frame){
|
|
||||||
gtsam::Values result = optimizer.calculateEstimate();
|
|
||||||
// Overwrite the beginning of the preintegration for the next step.
|
|
||||||
statePtr=std::make_shared<gtsam::NavState>(result.at<gtsam::Pose3>(P(imu_factor_id)), result.at<gtsam::Vector3>(V(imu_factor_id)));
|
|
||||||
imu_biasPtr=std::make_shared<gtsam::imuBias::ConstantBias>(result.at<gtsam::imuBias::ConstantBias>(B(imu_factor_id)));
|
|
||||||
preintegratedPtr->resetIntegrationAndSetBias(*imu_biasPtr);
|
|
||||||
++imu_factor_id;
|
|
||||||
syn=false;
|
|
||||||
new_frame->T_f_w_=svo::SE2_5(statePtr->t().x(),statePtr->t().z(),atan(statePtr->R()(0,2)/statePtr->R()(0,0)));
|
|
||||||
new_frame->Cov_=optimizer.marginalCovariance(P(imu_factor_id-1));
|
|
||||||
graphPtr->resize(0);
|
|
||||||
valuesPtr->clear();
|
|
||||||
valuesPtr->insert(P(imu_factor_id-1),statePtr->pose());
|
|
||||||
valuesPtr->insert(V(imu_factor_id-1),statePtr->v());
|
|
||||||
valuesPtr->insert(B(imu_factor_id-1),*imu_biasPtr);
|
|
||||||
graphPtr->addPrior(P(imu_factor_id-1),statePtr->pose(),optimizer.marginalCovariance(P(imu_factor_id-1)));
|
|
||||||
graphPtr->addPrior(V(imu_factor_id-1),statePtr->v(),optimizer.marginalCovariance(V(imu_factor_id-1)));
|
|
||||||
graphPtr->addPrior(B(imu_factor_id-1),*imu_biasPtr,optimizer.marginalCovariance(B(imu_factor_id-1)));
|
|
||||||
for(auto&& f_n:_for(new_frame->fts_)){
|
|
||||||
if(f_n.item->point == NULL)continue;
|
|
||||||
if(!result.exists(L(f_n.index)))continue;
|
|
||||||
f_n.item->point->pos_=result.at<gtsam::Point3>(L(f_n.index));
|
|
||||||
// valuesPtr->insert(L(f_n.index),f_n.item->point->pos_);
|
|
||||||
// graphPtr->emplace_shared<svo::VisionFactor>(f_n.item->f,f_n.item->level,ProjectNoisePtr,P(imu_factor_id),L(f_n.index));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
bool Imu_Integration::reset(gtsam::LevenbergMarquardtOptimizer& optimizer,boost::shared_ptr<svo::Frame>& new_frame){
|
bool Imu_Integration::reset(gtsam::LevenbergMarquardtOptimizer& optimizer,boost::shared_ptr<svo::Frame>& new_frame){
|
||||||
gtsam::Values result = optimizer.optimize();
|
gtsam::Values result = optimizer.optimize();
|
||||||
if(debug)optimizer.print();
|
|
||||||
// Overwrite the beginning of the preintegration for the next step.
|
|
||||||
statePtr=std::make_shared<gtsam::NavState>(result.at<gtsam::Pose3>(P(imu_factor_id)), result.at<gtsam::Vector3>(V(imu_factor_id)));
|
statePtr=std::make_shared<gtsam::NavState>(result.at<gtsam::Pose3>(P(imu_factor_id)), result.at<gtsam::Vector3>(V(imu_factor_id)));
|
||||||
imu_biasPtr=std::make_shared<gtsam::imuBias::ConstantBias>(result.at<gtsam::imuBias::ConstantBias>(B(imu_factor_id)));
|
imu_biasPtr=std::make_shared<gtsam::imuBias::ConstantBias>(result.at<gtsam::imuBias::ConstantBias>(B(imu_factor_id)));
|
||||||
preintegratedPtr->resetIntegrationAndSetBias(*imu_biasPtr);
|
preintegratedPtr->resetIntegrationAndSetBias(*imu_biasPtr);
|
||||||
++imu_factor_id;
|
++imu_factor_id;
|
||||||
syn=false;
|
syn=false;
|
||||||
gtsam::Marginals marginals(*graphPtr,result);
|
gtsam::Marginals marginals(*graphPtr,result);
|
||||||
if(debug)fprintf(logtime, "%f,%f,%f,%f,%f,%f,%f,%f,\n",
|
if(debug)fprintf(logtime, "%d,%f,%f,%f,%f,\n",
|
||||||
new_frame->T_f_w_.T->translation().x(),
|
imu_factor_id-1,
|
||||||
new_frame->T_f_w_.T->translation().y(),
|
|
||||||
new_frame->T_f_w_.T->translation().z(),
|
|
||||||
atan(new_frame->T_f_w_.T->rotation_matrix()(0,2)/new_frame->T_f_w_.T->rotation_matrix()(0,0)),
|
|
||||||
statePtr->pose().x(),
|
statePtr->pose().x(),
|
||||||
statePtr->pose().y(),
|
statePtr->pose().y(),
|
||||||
statePtr->pose().z(),
|
statePtr->pose().z(),
|
||||||
atan(statePtr->R()(0,2)/statePtr->R()(0,0)));
|
statePtr->pose().rotation().pitch());
|
||||||
if((statePtr->t()-new_frame->T_f_w_.T->translation()).norm()>2.0)return false;
|
new_frame->T_f_w_=svo::SE2_5(statePtr->pose().x(),statePtr->pose().z(),statePtr->pose().rotation().pitch());
|
||||||
new_frame->T_f_w_=svo::SE2_5(statePtr->t().x(),statePtr->t().z(),atan(statePtr->R()(0,2)/statePtr->R()(0,0)));
|
|
||||||
new_frame->Cov_=marginals.marginalCovariance(P(imu_factor_id-1));
|
new_frame->Cov_=marginals.marginalCovariance(P(imu_factor_id-1));
|
||||||
graphPtr->resize(0);
|
graphPtr->resize(0);
|
||||||
valuesPtr->clear();
|
valuesPtr->clear();
|
||||||
valuesPtr->insert(P(imu_factor_id-1),statePtr->pose());
|
valuesPtr->insert(P(imu_factor_id-1),gtsam::Pose3(new_frame->T_f_w_.T->matrix()));
|
||||||
valuesPtr->insert(V(imu_factor_id-1),statePtr->v());
|
valuesPtr->insert(V(imu_factor_id-1),statePtr->v());
|
||||||
valuesPtr->insert(B(imu_factor_id-1),*imu_biasPtr);
|
valuesPtr->insert(B(imu_factor_id-1),*imu_biasPtr);
|
||||||
graphPtr->addPrior(P(imu_factor_id-1),statePtr->pose(),marginals.marginalCovariance(P(imu_factor_id-1)));
|
graphPtr->addPrior(P(imu_factor_id-1),gtsam::Pose3(new_frame->T_f_w_.T->matrix()),marginals.marginalCovariance(P(imu_factor_id-1)));
|
||||||
graphPtr->addPrior(V(imu_factor_id-1),statePtr->v(),marginals.marginalCovariance(V(imu_factor_id-1)));
|
graphPtr->addPrior(V(imu_factor_id-1),statePtr->v(),marginals.marginalCovariance(V(imu_factor_id-1)));
|
||||||
graphPtr->addPrior(B(imu_factor_id-1),*imu_biasPtr,marginals.marginalCovariance(B(imu_factor_id-1)));
|
graphPtr->addPrior(B(imu_factor_id-1),*imu_biasPtr,marginals.marginalCovariance(B(imu_factor_id-1)));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
Sophus::SE3 Imu_Integration::preintegrate_predict() {
|
bool Imu_Integration::preintegrate_predict(svo::SE2_5& frame) {
|
||||||
if(imu_n<1){
|
if(imu_n<1){
|
||||||
syn= false;
|
syn= false;
|
||||||
usleep(10000);
|
return false;
|
||||||
syn=true;
|
|
||||||
}else{
|
}else{
|
||||||
syn=true;
|
syn=true;
|
||||||
}
|
}
|
||||||
auto preint_imu_combined =dynamic_cast<const gtsam::PreintegratedCombinedMeasurements&>(*preintegratedPtr);
|
Integ_predict=preintegratedPtr->predict(*statePtr,*imu_biasPtr);
|
||||||
Integ_predict=preint_imu_combined.predict(*statePtr,*imu_biasPtr);
|
frame =svo::SE2_5(Integ_predict.pose().x(),Integ_predict.pose().z(),Integ_predict.pose().rotation().pitch());
|
||||||
return Sophus::SE3(Integ_predict.R(),Integ_predict.t());
|
return true;
|
||||||
|
}
|
||||||
|
void Imu_Integration::reset() {
|
||||||
|
preintegratedPtr->resetIntegrationAndSetBias(*imu_biasPtr);
|
||||||
|
imu_n=0;
|
||||||
|
syn=false;
|
||||||
}
|
}
|
||||||
bool Imu_Integration::predict(boost::shared_ptr<svo::Frame>& new_frame,
|
bool Imu_Integration::predict(boost::shared_ptr<svo::Frame>& new_frame,
|
||||||
boost::shared_ptr<svo::Frame>& last_frame,
|
boost::shared_ptr<svo::Frame>& last_frame,
|
||||||
std::size_t& num_obs,const double cell_match){
|
const double cell_match){
|
||||||
if(debug)std::cout<<"----------------------------IMU infuse---------------------------------------\n";
|
|
||||||
//if(debug)preintegratedPtr->print();
|
|
||||||
auto preint_imu_combined =dynamic_cast<const gtsam::PreintegratedCombinedMeasurements&>(*preintegratedPtr);
|
|
||||||
valuesPtr->insert(P(imu_factor_id), Integ_predict.pose());
|
valuesPtr->insert(P(imu_factor_id), Integ_predict.pose());
|
||||||
valuesPtr->insert(V(imu_factor_id), Integ_predict.v());
|
valuesPtr->insert(V(imu_factor_id), Integ_predict.v());
|
||||||
valuesPtr->insert(B(imu_factor_id), *imu_biasPtr);
|
valuesPtr->insert(B(imu_factor_id), *imu_biasPtr);
|
||||||
gtsam::CombinedImuFactor imu_factor(P(imu_factor_id - 1), V(imu_factor_id - 1), P(imu_factor_id), V(imu_factor_id), B(imu_factor_id - 1), B(imu_factor_id),
|
gtsam::CombinedImuFactor imu_factor(P(imu_factor_id - 1), V(imu_factor_id - 1), P(imu_factor_id), V(imu_factor_id), B(imu_factor_id - 1), B(imu_factor_id),
|
||||||
preint_imu_combined);
|
*preintegratedPtr);
|
||||||
graphPtr->emplace_shared<gtsam::CombinedImuFactor>(imu_factor);
|
graphPtr->emplace_shared<gtsam::CombinedImuFactor>(imu_factor);
|
||||||
imu_n=0;
|
imu_n=0;
|
||||||
graphPtr->emplace_shared<svo::VisionFactor>(gtsam::Pose3(new_frame->T_f_w_.T->matrix()),
|
graphPtr->emplace_shared<svo::VisionFactor>(gtsam::Pose3(new_frame->T_f_w_.T->matrix()),
|
||||||
gtsam::noiseModel::Diagonal::Sigmas((gtsam::Vector(3) << 1.0, 1.0, 1.0).finished()/(cell_match+1)),
|
gtsam::noiseModel::Diagonal::Sigmas((gtsam::Vector(3) << 1.0, 1.0, 1.0).finished()/(cell_match+1)),
|
||||||
P(imu_factor_id));
|
P(imu_factor_id));
|
||||||
gtsam::LevenbergMarquardtParams params0;
|
gtsam::LevenbergMarquardtParams params0;
|
||||||
//params0.verbosity=gtsam::LevenbergMarquardtParams::LINEAR;
|
|
||||||
params0.verbosityLM = gtsam::LevenbergMarquardtParams::SILENT;
|
params0.verbosityLM = gtsam::LevenbergMarquardtParams::SILENT;
|
||||||
params0.setlambdaFactor(10.0);
|
params0.setlambdaFactor(10.0);
|
||||||
params0.setlambdaInitial(100);
|
params0.setlambdaInitial(100);
|
||||||
params0.setlambdaUpperBound(1e10);
|
params0.setlambdaUpperBound(1e10);
|
||||||
gtsam::LevenbergMarquardtOptimizer optimizer(*graphPtr, *valuesPtr,params0);
|
gtsam::LevenbergMarquardtOptimizer optimizer(*graphPtr, *valuesPtr,params0);
|
||||||
reset(optimizer,new_frame);
|
reset(optimizer,new_frame);
|
||||||
|
|
||||||
if(debug)std::cout<<"------------------------------------------------------------------------------\n";
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool Imu_Integration::init(boost::shared_ptr<svo::Frame>& new_frame){
|
bool Imu_Integration::init(boost::shared_ptr<svo::Frame>& new_frame){
|
||||||
statePtr=std::make_shared<gtsam::NavState>(gtsam::Pose3(new_frame->T_f_w_.T->matrix()),
|
statePtr=std::make_shared<gtsam::NavState>(gtsam::Pose3(new_frame->T_f_w_.T->matrix()),
|
||||||
gtsam::Vector3(1e-9,1e-9,1e-9));
|
gtsam::Vector3(1e-9,1e-9,1e-9));
|
||||||
/*
|
|
||||||
statePtr=std::make_shared<gtsam::NavState>(gtsam::Pose3(gtsam::Rot3::RzRyRx(0.0,0.0,0.0),gtsam::Point3(0.0,0.0,0.0)),
|
|
||||||
gtsam::Vector3(1e-9,1e-9,1e-9));
|
|
||||||
*/
|
|
||||||
valuesPtr->insert(P(0),statePtr->pose());
|
valuesPtr->insert(P(0),statePtr->pose());
|
||||||
valuesPtr->insert(V(0),statePtr->v());
|
valuesPtr->insert(V(0),statePtr->v());
|
||||||
valuesPtr->insert(B(0),*imu_biasPtr);
|
valuesPtr->insert(B(0),*imu_biasPtr);
|
||||||
graphPtr->addPrior(P(0),statePtr->pose(),gtsam::noiseModel::Diagonal::Sigmas((gtsam::Vector(6) << 1e-5, 1e-15, 1e-5, 1e-15, 1e-8, 1e-15).finished()));
|
graphPtr->addPrior(P(0),statePtr->pose(),gtsam::noiseModel::Diagonal::Sigmas((gtsam::Vector(6) << 1e-5, 1e-15, 1e-5, 1e-15, 1e-8, 1e-15).finished()));
|
||||||
graphPtr->addPrior(V(0),statePtr->v(),gtsam::noiseModel::Isotropic::Sigma(3, 1e-4));
|
graphPtr->addPrior(V(0),statePtr->v(),gtsam::noiseModel::Isotropic::Sigma(3, 1e-4));
|
||||||
graphPtr->addPrior(B(0),*imu_biasPtr,gtsam::noiseModel::Isotropic::Sigma(6, 1e-2));
|
graphPtr->addPrior(B(0),*imu_biasPtr,gtsam::noiseModel::Isotropic::Sigma(6, 1e-2));
|
||||||
/*
|
|
||||||
for(auto&& f_n:_for(new_frame->fts_)){
|
|
||||||
if(f_n.item->point == NULL)continue;
|
|
||||||
valuesPtr->insert(L(f_n.index),f_n.item->point->pos_);
|
|
||||||
graphPtr->emplace_shared<svo::VisionFactor>(f_n.item->f,f_n.item->level,ProjectNoisePtr,P(imu_factor_id),L(f_n.index));
|
|
||||||
}
|
|
||||||
graphPtr->addPrior(L(0),new_frame->fts_.front()->point->pos_,gtsam::noiseModel::Isotropic::Sigma(3, 1e-4));
|
|
||||||
*/
|
|
||||||
++imu_factor_id;
|
++imu_factor_id;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -184,6 +184,7 @@ bool Matcher::findEpipolarMatchDirect(
|
|||||||
const double d_max,
|
const double d_max,
|
||||||
double& depth)
|
double& depth)
|
||||||
{
|
{
|
||||||
|
if(isnan(d_min) || isnan(d_max))return false;
|
||||||
SE3 T_cur_ref = (*cur_frame.T_f_w_.T) * ref_frame.T_f_w_.T->inverse();
|
SE3 T_cur_ref = (*cur_frame.T_f_w_.T) * ref_frame.T_f_w_.T->inverse();
|
||||||
int zmssd_best = PatchScore::threshold();
|
int zmssd_best = PatchScore::threshold();
|
||||||
Vector2d uv_best;
|
Vector2d uv_best;
|
||||||
@@ -217,6 +218,7 @@ bool Matcher::findEpipolarMatchDirect(
|
|||||||
Vector2d px_B(cur_frame.cam_->world2cam(B));
|
Vector2d px_B(cur_frame.cam_->world2cam(B));
|
||||||
epi_length_ = (px_A-px_B).norm() / (1<<search_level_);
|
epi_length_ = (px_A-px_B).norm() / (1<<search_level_);
|
||||||
|
|
||||||
|
|
||||||
// Warp reference patch at ref_level
|
// Warp reference patch at ref_level
|
||||||
warp::warpAffine(A_cur_ref_, ref_frame.img_pyr_[ref_ftr.level], ref_ftr.px,
|
warp::warpAffine(A_cur_ref_, ref_frame.img_pyr_[ref_ftr.level], ref_ftr.px,
|
||||||
ref_ftr.level, search_level_, halfpatch_size_+1, patch_with_border_);
|
ref_ftr.level, search_level_, halfpatch_size_+1, patch_with_border_);
|
||||||
|
|||||||
@@ -54,11 +54,11 @@ size_t SparseImgAlign::run(FramePtr ref_frame, FramePtr cur_frame)
|
|||||||
cur_frame_ = cur_frame;
|
cur_frame_ = cur_frame;
|
||||||
ref_patch_cache_ = cv::Mat(ref_frame_->fts_.size(), patch_area_, CV_32F);
|
ref_patch_cache_ = cv::Mat(ref_frame_->fts_.size(), patch_area_, CV_32F);
|
||||||
jacobian_cache_.resize(Eigen::NoChange, ref_patch_cache_.rows*patch_area_);
|
jacobian_cache_.resize(Eigen::NoChange, ref_patch_cache_.rows*patch_area_);
|
||||||
//visible_fts_.resize(ref_patch_cache_.rows, false); // TODO: should it be reset at each level?
|
visible_fts_.resize(ref_patch_cache_.rows, false); // TODO: should it be reset at each level?
|
||||||
SE3 T_cur_from_ref(*cur_frame_->T_f_w_.T * ref_frame_->T_f_w_.T->inverse());
|
SE3 T_cur_from_ref(*cur_frame_->T_f_w_.T * ref_frame_->T_f_w_.T->inverse());
|
||||||
for(level_=max_level_; level_>=min_level_; --level_)
|
for(level_=max_level_; level_>=min_level_; --level_)
|
||||||
{
|
{
|
||||||
visible_fts_.resize(ref_patch_cache_.rows, false); // TODO: should it be reset at each level?
|
//visible_fts_.resize(ref_patch_cache_.rows, false); // TODO: should it be reset at each level?
|
||||||
mu_ = 0.1;
|
mu_ = 0.1;
|
||||||
jacobian_cache_.setZero();
|
jacobian_cache_.setZero();
|
||||||
have_ref_patch_cache_ = false;
|
have_ref_patch_cache_ = false;
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ public:
|
|||||||
size_t trace_id_;
|
size_t trace_id_;
|
||||||
ros::Publisher pub_frames_;
|
ros::Publisher pub_frames_;
|
||||||
ros::Publisher pub_points_;
|
ros::Publisher pub_points_;
|
||||||
ros::Publisher pub_pose_;
|
ros::Publisher pub_pose_with_cov_;
|
||||||
ros::Publisher pub_info_;
|
ros::Publisher pub_info_;
|
||||||
tf::TransformBroadcaster br_;
|
tf::TransformBroadcaster br_;
|
||||||
SE3 T_world_from_vision_;
|
SE3 T_world_from_vision_;
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
svo:
|
svo:
|
||||||
grid_size: 30 #Feature grid size of a cell in [px].
|
grid_size: 30 #Feature grid size of a cell in [px].
|
||||||
max_n_kfs: 10 #Limit the number of keyframes in the map. This makes nslam essentially. a Visual Odometry. Set to 0 if unlimited number of keyframes are allowed. Minimum number of keyframes is 3.
|
max_n_kfs: 20 #Limit the number of keyframes in the map. This makes nslam essentially. a Visual Odometry. Set to 0 if unlimited number of keyframes are allowed. Minimum number of keyframes is 3.
|
||||||
loba_num_iter: 0 #Number of iterations in the local bundle adjustment.
|
loba_num_iter: 0 #Number of iterations in the local bundle adjustment.
|
||||||
quality_min_fts: 10 #If the number of tracked features drops below this threshold. Tracking quality is bad.
|
quality_min_fts: 10 #If the number of tracked features drops below this threshold. Tracking quality is bad.
|
||||||
quality_max_drop_fts: 60 #If within one frame, this amount of features are dropped. Tracking quality is bad.
|
quality_max_drop_fts: 60 #If within one frame, this amount of features are dropped. Tracking quality is bad.
|
||||||
init_min_tracked: 100
|
init_min_tracked: 100
|
||||||
init_min_disparity: 25
|
init_min_disparity: 20
|
||||||
structureoptim_max_pts: 50
|
structureoptim_max_pts: 50
|
||||||
kfselect_mindist: 0.12
|
kfselect_mindist: 0.05
|
||||||
poseoptim_thresh: 4.0
|
poseoptim_thresh: 4.0
|
||||||
ACC_noise: 0.0001 #acc white noise in continuous
|
ACC_noise: 0.0001 #acc white noise in continuous
|
||||||
GYO_noise: 0.0001 #gyro white noise in continuous
|
GYO_noise: 0.0001 #gyro white noise in continuous
|
||||||
@@ -17,6 +17,6 @@ svo:
|
|||||||
EBP: 0.1 #error in the bias used for preintegration
|
EBP: 0.1 #error in the bias used for preintegration
|
||||||
NRP: 0.001 #noise used for projection in preintegration
|
NRP: 0.001 #noise used for projection in preintegration
|
||||||
gravity: -9.65
|
gravity: -9.65
|
||||||
Acceleration_offset_x: 0.0 #-0.05
|
Acceleration_offset_x: 0.0
|
||||||
Acceleration_offset_y: 0.0 #-0.04
|
Acceleration_offset_y: 0.0
|
||||||
Gyroscope_offset_z: 0.0 #0.001
|
Gyroscope_offset_z: 0.0
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include <gpu_svo/feature.h>
|
#include <gpu_svo/feature.h>
|
||||||
#include <vio_gpu/Info.h>
|
#include <vio_gpu/Info.h>
|
||||||
#include <geometry_msgs/PoseWithCovarianceStamped.h>
|
#include <geometry_msgs/PoseWithCovarianceStamped.h>
|
||||||
|
#include <geometry_msgs/PoseStamped.h>
|
||||||
#include <gpu_svo/timer.h>
|
#include <gpu_svo/timer.h>
|
||||||
#include <vio_gpu/output_helper.h>
|
#include <vio_gpu/output_helper.h>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
@@ -35,8 +36,8 @@ Visualizer() :
|
|||||||
{
|
{
|
||||||
// Init ROS Marker Publishers
|
// Init ROS Marker Publishers
|
||||||
//pub_frames_ = pnh_.advertise<visualization_msgs::Marker>("keyframes", 10);
|
//pub_frames_ = pnh_.advertise<visualization_msgs::Marker>("keyframes", 10);
|
||||||
// pub_points_ = pnh_.advertise<visualization_msgs::Marker>("points", 1000);
|
pub_points_ = pnh_.advertise<visualization_msgs::Marker>("points", 1000);
|
||||||
pub_pose_ = pnh_.advertise<geometry_msgs::PoseWithCovarianceStamped>("pose",10);
|
pub_pose_with_cov_ = pnh_.advertise<geometry_msgs::PoseWithCovarianceStamped>("pose_cov",10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Visualizer::publishMinimal(
|
void Visualizer::publishMinimal(
|
||||||
@@ -50,28 +51,31 @@ void Visualizer::publishMinimal(
|
|||||||
header_msg.frame_id = "/world";
|
header_msg.frame_id = "/world";
|
||||||
header_msg.seq = trace_id_;
|
header_msg.seq = trace_id_;
|
||||||
header_msg.stamp = ros::Time(timestamp);
|
header_msg.stamp = ros::Time(timestamp);
|
||||||
if(pub_pose_.getNumSubscribers() > 0 && slam.stage() == FrameHandlerBase::STAGE_DEFAULT_FRAME)
|
if(pub_pose_with_cov_.getNumSubscribers() > 0 && slam.stage() == FrameHandlerBase::STAGE_DEFAULT_FRAME)
|
||||||
{
|
{
|
||||||
Quaterniond q;
|
//Quaterniond q;
|
||||||
Vector3d p;
|
|
||||||
Matrix<double,6,6> Cov;
|
Matrix<double,6,6> Cov;
|
||||||
// publish cam in world frame (Estimated odometry in the worls frame)
|
// publish cam in world frame (Estimated odometry in the worls frame)
|
||||||
SE3 T_world_from_cam(T_world_from_vision_*frame->T_f_w_.T->inverse());// do not confused with inverse. the T_f_w_ is the from camera to initial position with reference of camera
|
SE3 T_world_from_cam(T_world_from_vision_*frame->T_f_w_.T->inverse());// do not confused with inverse. the T_f_w_ is the from camera to initial position with reference of camera
|
||||||
//q = Quaterniond(T_world_from_cam.rotation_matrix()*T_world_from_vision_.rotation_matrix().transpose());
|
//q = Quaterniond(T_world_from_cam.rotation_matrix()*T_world_from_vision_.rotation_matrix().transpose());
|
||||||
//p = T_world_from_cam.translation();
|
|
||||||
Cov = T_world_from_cam.Adj()*frame->Cov_*T_world_from_cam.inverse().Adj();
|
Cov = T_world_from_cam.Adj()*frame->Cov_*T_world_from_cam.inverse().Adj();
|
||||||
geometry_msgs::PoseWithCovarianceStampedPtr msg_pose(new geometry_msgs::PoseWithCovarianceStamped);
|
geometry_msgs::PoseWithCovarianceStampedPtr msg_pose_with_cov(new geometry_msgs::PoseWithCovarianceStamped);
|
||||||
msg_pose->header = header_msg;
|
msg_pose_with_cov->header = header_msg;
|
||||||
msg_pose->pose.pose.position.x = p[0];
|
msg_pose_with_cov->pose.pose.position.x = T_world_from_cam.translation().x();
|
||||||
msg_pose->pose.pose.position.y = p[1];
|
msg_pose_with_cov->pose.pose.position.y = T_world_from_cam.translation().y();
|
||||||
msg_pose->pose.pose.position.z = p[2];
|
msg_pose_with_cov->pose.pose.position.z = T_world_from_cam.translation().z();
|
||||||
msg_pose->pose.pose.orientation.x = q.x()/q.norm();
|
msg_pose_with_cov->pose.pose.orientation.x = frame->T_f_w_.T->unit_quaternion().x()/frame->T_f_w_.T->unit_quaternion().norm();
|
||||||
msg_pose->pose.pose.orientation.y = q.y()/q.norm();
|
msg_pose_with_cov->pose.pose.orientation.y = frame->T_f_w_.T->unit_quaternion().y()/frame->T_f_w_.T->unit_quaternion().norm();
|
||||||
msg_pose->pose.pose.orientation.z = q.z()/q.norm();
|
msg_pose_with_cov->pose.pose.orientation.z = frame->T_f_w_.T->unit_quaternion().z()/frame->T_f_w_.T->unit_quaternion().norm();
|
||||||
msg_pose->pose.pose.orientation.w = q.w()/q.norm();
|
msg_pose_with_cov->pose.pose.orientation.w = frame->T_f_w_.T->unit_quaternion().w()/frame->T_f_w_.T->unit_quaternion().norm();
|
||||||
for(size_t i=0; i<36; ++i)
|
for(size_t i=0; i<36; ++i)
|
||||||
msg_pose->pose.covariance[i] = Cov(i%6, i/6);
|
msg_pose_with_cov->pose.covariance[i] = Cov(i%6, i/6);
|
||||||
pub_pose_.publish(msg_pose);
|
pub_pose_with_cov_.publish(msg_pose_with_cov);
|
||||||
|
}
|
||||||
|
if(pub_frames_.getNumSubscribers() > 0 || pub_points_.getNumSubscribers() > 0){
|
||||||
|
vk::output_helper::publishPointMarker(
|
||||||
|
pub_points_, T_world_from_vision_*frame->pos(), "trajectory",
|
||||||
|
ros::Time::now(), trace_id_, 0, 0.01, Vector3d(0.,0.,0.5));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user