edit frame and change atan to atan2

This commit is contained in:
gfuse
2021-08-25 23:00:53 +02:00
parent f9e5887b69
commit 2545349542
10 changed files with 32 additions and 46 deletions
+2 -2
View File
@@ -90,7 +90,7 @@ namespace vio
return T2_; return T2_;
} }
SE2 inverse() const{ SE2 inverse() const{
double yaw=atan(T2_.so2().unit_complex().imag()/T2_.so2().unit_complex().real()); double yaw=atan2(T2_.so2().unit_complex().imag(),T2_.so2().unit_complex().real());
if(yaw<0.0) if(yaw<0.0)
yaw=M_PI-yaw; yaw=M_PI-yaw;
else else
@@ -98,7 +98,7 @@ namespace vio
return SE2(yaw,-1.0*T2_.translation()); return SE2(yaw,-1.0*T2_.translation());
} }
double pitch()const{ double pitch()const{
return atan(T2_.rotation_matrix()(0,1)/T2_.rotation_matrix()(0,0)); return atan2(T2_.rotation_matrix()(0,1),T2_.rotation_matrix()(0,0));
} }
SE3 se3() const{ SE3 se3() const{
Eigen::Matrix<double,3,3> R; Eigen::Matrix<double,3,3> R;
+3 -12
View File
@@ -127,25 +127,16 @@ public:
std::pair<Eigen::Matrix<double,3,3>,vio::SE2_5> UpdateSvo(double x,double z,double pitch,size_t match,ros::Time& time) { std::pair<Eigen::Matrix<double,3,3>,vio::SE2_5> UpdateSvo(double x,double z,double pitch,size_t match,ros::Time& time) {
while(lock)usleep(5); while(lock)usleep(5);
lock=true; lock=true;
if(pitch<0.0) pitch=pitch+M_PI;
pitch=M_PI-pitch;
else
pitch=pitch-M_PI;
if(filter_->predict_up)filter_->correct(-x,-z,pitch,match,1e-9*time.toNSec()); if(filter_->predict_up)filter_->correct(-x,-z,pitch,match,1e-9*time.toNSec());
lock=false; lock=false;
double pitch_f; double pitch_f;
if(filter_->state_(0)<0.0) pitch_f=filter_->state_(2)+M_PI;
pitch_f=M_PI-filter_->state_(2);
else
pitch_f=filter_->state_(2)-M_PI;
return std::pair<Eigen::Matrix<double,3,3>,vio::SE2_5>(filter_->cov_,vio::SE2_5(-filter_->state_(0),-filter_->state_(1),pitch_f)); return std::pair<Eigen::Matrix<double,3,3>,vio::SE2_5>(filter_->cov_,vio::SE2_5(-filter_->state_(0),-filter_->state_(1),pitch_f));
}; };
std::pair<Eigen::Matrix<double,3,3>,vio::SE2_5> get_location(){ std::pair<Eigen::Matrix<double,3,3>,vio::SE2_5> get_location(){
double pitch_f; double pitch_f;
if(filter_->state_(0)<0.0) pitch_f=filter_->state_(2)+M_PI;
pitch_f=M_PI-filter_->state_(2);
else
pitch_f=filter_->state_(2)-M_PI;
return std::pair<Eigen::Matrix<double,3,3>,vio::SE2_5>(filter_->cov_,vio::SE2_5(-filter_->state_(0),-filter_->state_(1),pitch_f)); return std::pair<Eigen::Matrix<double,3,3>,vio::SE2_5>(filter_->cov_,vio::SE2_5(-filter_->state_(0),-filter_->state_(1),pitch_f));
} }
private: private:
+2 -2
View File
@@ -5,12 +5,12 @@ svo:
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: 90 #If within one frame, this amount of features are dropped. Tracking quality is bad. quality_max_drop_fts: 90 #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: 40 init_min_disparity: 60
structureoptim_max_pts: 50 structureoptim_max_pts: 50
kfselect_mindist: 0.01 kfselect_mindist: 0.01
poseoptim_thresh: 4.0 poseoptim_thresh: 4.0
init_min_inliers: 30 init_min_inliers: 30
ACC_noise: 0.5 #acc white noise in continuous in EKF ACC_noise: 0.5 #acc white noise in continuous in EKF
GYO_noise: 0.001 #gyro white noise in continuous in EKF GYO_noise: 0.001 #gyro white noise in continuous in EKF
svo_ekf: 1.5 #Svo noise that will be devided by number of Reprojected points after opmization in EKF svo_ekf: 1.0 #Svo noise that will be devided by number of Reprojected points after opmization in EKF
Cmd_Cov: 1.0 #control vector noise in EKF Cmd_Cov: 1.0 #control vector noise in EKF
+1 -1
View File
@@ -217,7 +217,7 @@ void DepthFilter::updateSeeds(FramePtr frame)
const double focal_length = frame->cam_->errorMultiplier2(); const double focal_length = frame->cam_->errorMultiplier2();
double px_noise = 1.0; double px_noise = 1.0;
double px_error_angle = atan(px_noise/(2.0*focal_length))*2.0; // law of chord (sehnensatz) double px_error_angle = atan2(px_noise,(2.0*focal_length))*2.0; // law of chord (sehnensatz)
while( it!=seeds_.end()) while( it!=seeds_.end())
{ {
// set this value true when seeds updating should be interrupted // set this value true when seeds updating should be interrupted
+1 -1
View File
@@ -202,7 +202,7 @@ bool align2D(
bool sign=true;// + bool sign=true;// +
// termination condition // termination condition
const float min_update_squared = 0.05;//0.001 const float min_update_squared = 0.5;//0.001
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();
+1 -1
View File
@@ -77,7 +77,7 @@ int FrameHandlerBase::finishFrameProcessingCommon(
if(dropout == RESULT_FAILURE && if(dropout == RESULT_FAILURE &&
(stage_ == STAGE_DEFAULT_FRAME || stage_ == STAGE_RELOCALIZING )) (stage_ == STAGE_DEFAULT_FRAME || stage_ == STAGE_RELOCALIZING ))
{ {
stage_ = STAGE_RELOCALIZING; //stage_ = STAGE_RELOCALIZING;
tracking_quality_ = TRACKING_INSUFFICIENT; tracking_quality_ = TRACKING_INSUFFICIENT;
} }
if(set_reset_) if(set_reset_)
+12 -14
View File
@@ -170,34 +170,31 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame()
//SparseImgAlign img_align(Config::kltMaxLevel(), Config::kltMinLevel(),30, SparseImgAlign::LevenbergMarquardt, false, false); //SparseImgAlign img_align(Config::kltMaxLevel(), Config::kltMinLevel(),30, SparseImgAlign::LevenbergMarquardt, false, false);
SparseImgAlignGpu img_align(Config::kltMaxLevel(), Config::kltMinLevel(),30, SparseImgAlignGpu::GaussNewton, false,gpu_fast_); SparseImgAlignGpu img_align(Config::kltMaxLevel(), Config::kltMinLevel(),30, SparseImgAlignGpu::GaussNewton, false,gpu_fast_);
if(img_align.run(last_frame_, new_frame_)==0)return RESULT_FAILURE; if(img_align.run(last_frame_, new_frame_)==0)return RESULT_FAILURE;
//assert (false); if((last_frame_->T_f_w_.se2().translation()-new_frame_->T_f_w_.se2().translation()).norm()>0.5 ||
fabs(last_frame_->T_f_w_.pitch()-new_frame_->T_f_w_.pitch())>M_PI){
return RESULT_FAILURE;
}
reprojector_.reprojectMap(new_frame_, overlap_kfs_); reprojector_.reprojectMap(new_frame_, overlap_kfs_);
/* /*
std::cout<<"Reprojection Map nPoint: "<<overlap_kfs_.back().second std::cout<<"Reprojection Map nPoint: "<<overlap_kfs_.back().second
<<"\tnCell: "<<reprojector_.n_trials_<<"\t nMatches: "<<reprojector_.n_matches_ <<"\tnCell: "<<reprojector_.n_trials_<<"\t nMatches: "<<reprojector_.n_matches_
<<"\t distance between two frames: "<< <<"\t distance between two frames: "<<
(last_frame_->T_f_w_.se2().translation()-new_frame_->T_f_w_.se2().translation()).norm()<<'\n';*/ (last_frame_->T_f_w_.se2().translation()-new_frame_->T_f_w_.se2().translation()).norm()<<'\n';*/
if( reprojector_.n_matches_ < 5)return RESULT_FAILURE;
size_t sfba_n_edges_final=0; size_t sfba_n_edges_final=0;
double sfba_thresh, sfba_error_init, sfba_error_final; double sfba_thresh, sfba_error_init, sfba_error_final;
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);
if((last_frame_->T_f_w_.se2().translation()-new_frame_->T_f_w_.se2().translation()).norm()>2.0 ||
fabs(last_frame_->T_f_w_.pitch()-new_frame_->T_f_w_.pitch())>M_PI ||
sfba_n_edges_final < Config::qualityMinFts() || reprojector_.n_matches_ < Config::qualityMinFts()){
new_frame_=last_frame_;
return RESULT_NO_KEYFRAME;
}
auto result=ukfPtr_.UpdateSvo(new_frame_->T_f_w_.se2().translation()(0), auto result=ukfPtr_.UpdateSvo(new_frame_->T_f_w_.se2().translation()(0),
new_frame_->T_f_w_.se2().translation()(1),new_frame_->T_f_w_.pitch(),sfba_n_edges_final,time_); new_frame_->T_f_w_.se2().translation()(1),new_frame_->T_f_w_.pitch(),sfba_n_edges_final,time_);
new_frame_->T_f_w_ =result.second; new_frame_->T_f_w_ =result.second;
new_frame_->Cov_ = result.first; new_frame_->Cov_ = result.first;
/* if(sfba_n_edges_final < Config::qualityMinFts() || reprojector_.n_matches_ < Config::qualityMinFts()){
std::cout<<"Reprojection Map nPoint: "<<overlap_kfs_.back().second return RESULT_FAILURE;
<<"\tnCell: "<<reprojector_.n_trials_<<"\t nMatches: "<<reprojector_.n_matches_ }
<<"\tReprojected points after opmization: "<<sfba_n_edges_final<<"\t distance between two frames: "<<
(last_frame_->T_f_w_.se2().translation()-new_frame_->T_f_w_.se2().translation()).norm()<<'\n';
*/
optimizeStructure(new_frame_, Config::structureOptimMaxPts(), Config::structureOptimNumIter()); optimizeStructure(new_frame_, Config::structureOptimMaxPts(), Config::structureOptimNumIter());
// select keyframe // select keyframe
core_kfs_.insert(new_frame_); core_kfs_.insert(new_frame_);
@@ -209,6 +206,7 @@ FrameHandlerBase::UpdateResult FrameHandlerMono::processFrame()
double depth_mean, depth_min; double depth_mean, depth_min;
frame_utils::getSceneDepth(*new_frame_, depth_mean, depth_min); frame_utils::getSceneDepth(*new_frame_, depth_mean, depth_min);
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_);
+3 -6
View File
@@ -64,8 +64,6 @@ size_t SparseImgAlignGpu::run(FramePtr ref_frame, FramePtr cur_frame)
{ {
cv::Mat cur_img = cur_frame->img_pyr_.at(level_); cv::Mat cur_img = cur_frame->img_pyr_.at(level_);
cv::Mat ref_img = ref_frame->img_pyr_.at(level_); cv::Mat ref_img = ref_frame->img_pyr_.at(level_);
// cv::imwrite(std::string(getenv("HOME"))+"/Project/cur"+to_string(level_)+".png",cur_img);
// cv::imwrite(std::string(getenv("HOME"))+"/Project/fer"+to_string(level_)+".png",ref_img);
residual_->reload_buf(1,0,cur_img); residual_->reload_buf(1,0,cur_img);
residual_->reload_buf(1,1,ref_img); residual_->reload_buf(1,1,ref_img);
residual_->write_buf(1,6,level_); residual_->write_buf(1,6,level_);
@@ -74,6 +72,7 @@ size_t SparseImgAlignGpu::run(FramePtr ref_frame, FramePtr cur_frame)
} }
cl_float3 pos[1]={0}; cl_float3 pos[1]={0};
residual_->read(1,2,1,pos); residual_->read(1,2,1,pos);
if(isnan(pos[0].x) || isnan(pos[0].y) || isnan(pos[0].z))return 0;
cur_frame->T_f_w_ = SE2_5(pos[0].x,pos[0].y,pos[0].z); cur_frame->T_f_w_ = SE2_5(pos[0].x,pos[0].y,pos[0].z);
return 1; return 1;
} }
@@ -90,7 +89,6 @@ double SparseImgAlignGpu::computeResiduals(
residual_->reload_buf(1,10,chi2_); residual_->reload_buf(1,10,chi2_);
residual_->reload_buf(1,8,H); residual_->reload_buf(1,8,H);
residual_->reload_buf(1,9,J); residual_->reload_buf(1,9,J);
/// TODO GPU compute based on the feature
residual_->run(1,feature_counter_); residual_->run(1,feature_counter_);
float error[300]={0.0}; float error[300]={0.0};
float chi[300]={0.0}; float chi[300]={0.0};
@@ -129,19 +127,18 @@ int SparseImgAlignGpu::solve()
(double)H[6],(double)H[7],(double)H[8]}; (double)H[6],(double)H[7],(double)H[8]};
double Jd[3]={(double)J[0].x,(double)J[0].y,(double)J[0].z}; double Jd[3]={(double)J[0].x,(double)J[0].y,(double)J[0].z};
x_ = Eigen::Matrix<double,3,3>(Hd).ldlt().solve(Eigen::Vector3d(Jd[0],Jd[1],Jd[2])); x_ = Eigen::Matrix<double,3,3>(Hd).ldlt().solve(Eigen::Vector3d(Jd[0],Jd[1],Jd[2]));
if((bool) std::isnan((double) x_[0])) if((bool) std::isnan((double) x_[0]) || (bool) std::isnan((double) x_[1]) ||(bool) std::isnan((double) x_[2]))
return 0; return 0;
return 1; return 1;
} }
void SparseImgAlignGpu::update() void SparseImgAlignGpu::update()
{ {
/// TODO the update situation may have a smarter solution
cl_float3 pos[1]={0.0,0.0,0.0}; cl_float3 pos[1]={0.0,0.0,0.0};
residual_->read(1,2,1,pos); residual_->read(1,2,1,pos);
Sophus::SE2 update = Sophus::SE2(pos[0].z,Eigen::Vector2d(pos[0].x,pos[0].y)) * Sophus::SE2::exp(-1.0*x_); Sophus::SE2 update = Sophus::SE2(pos[0].z,Eigen::Vector2d(pos[0].x,pos[0].y)) * Sophus::SE2::exp(-1.0*x_);
pos[0].x=(float)update.translation()(0); pos[0].x=(float)update.translation()(0);
pos[0].y=(float)update.translation()(1); pos[0].y=(float)update.translation()(1);
pos[0].z=(float)atan(update.so2().unit_complex().imag()/update.so2().unit_complex().real()); pos[0].z=(float)atan2(update.so2().unit_complex().imag(),update.so2().unit_complex().real());
residual_->reload_buf(1,2,pos); residual_->reload_buf(1,2,pos);
} }
+3 -3
View File
@@ -55,8 +55,8 @@ void Visualizer::publishMinimal(
Quaterniond q(AngleAxisd(odom.second.pitch(), Vector3d::UnitZ())); Quaterniond q(AngleAxisd(odom.second.pitch(), Vector3d::UnitZ()));
geometry_msgs::PoseWithCovarianceStampedPtr msg_pose_with_cov(new geometry_msgs::PoseWithCovarianceStamped); geometry_msgs::PoseWithCovarianceStampedPtr msg_pose_with_cov(new geometry_msgs::PoseWithCovarianceStamped);
msg_pose_with_cov->header = header_msg; msg_pose_with_cov->header = header_msg;
msg_pose_with_cov->pose.pose.position.x = -odom.second.se2().translation()(0); msg_pose_with_cov->pose.pose.position.x = odom.second.se2().translation()(1);
msg_pose_with_cov->pose.pose.position.y = -odom.second.se2().translation()(1); msg_pose_with_cov->pose.pose.position.y = odom.second.se2().translation()(0);
msg_pose_with_cov->pose.pose.position.z = 0.0; msg_pose_with_cov->pose.pose.position.z = 0.0;
msg_pose_with_cov->pose.pose.orientation.x = q.x(); msg_pose_with_cov->pose.pose.orientation.x = q.x();
msg_pose_with_cov->pose.pose.orientation.y = q.y(); msg_pose_with_cov->pose.pose.orientation.y = q.y();
@@ -71,7 +71,7 @@ void Visualizer::publishMinimal(
pub_pose_with_cov_.publish(msg_pose_with_cov); pub_pose_with_cov_.publish(msg_pose_with_cov);
if(pub_frames_.getNumSubscribers() > 0 || pub_points_.getNumSubscribers() > 0){ if(pub_frames_.getNumSubscribers() > 0 || pub_points_.getNumSubscribers() > 0){
publishPointMarker( publishPointMarker(
pub_points_, Eigen::Vector3d(-odom.second.se2().translation()(0),-odom.second.se2().translation()(1),0.0), "trajectory", pub_points_, Eigen::Vector3d(odom.second.se2().translation()(1),odom.second.se2().translation()(0),0.0), "trajectory",
ros::Time::now(), trace_id_, 0, 0.01, Vector3d(0.,0.,0.5)); ros::Time::now(), trace_id_, 0, 0.01, Vector3d(0.,0.,0.5));
} }
} }
+4 -4
View File
@@ -13,7 +13,7 @@
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
#define VIO_DEBUG false #define VIO_DEBUG true
#include <ros/ros.h> #include <ros/ros.h>
#include <string> #include <string>
#include <chrono> #include <chrono>
@@ -107,7 +107,7 @@ VioNode::VioNode() :
if(!vk::camera_loader::loadFromRosNs("vio", cam_)) if(!vk::camera_loader::loadFromRosNs("vio", cam_))
throw std::runtime_error("Camera model not correctly specified."); throw std::runtime_error("Camera model not correctly specified.");
Eigen::Matrix<double,3,1> init; Eigen::Matrix<double,3,1> init;
init<<1e-19,1e-19,1e-19; init<<1e-19,1e-19,M_PI;
vo_ = new vio::FrameHandlerMono(cam_,init); vo_ = new vio::FrameHandlerMono(cam_,init);
usleep(500); usleep(500);
} }
@@ -184,8 +184,8 @@ bool VioNode::getOdom(vio::getOdom::Request &req, vio::getOdom::Response &res) {
res.header.frame_id = "/world"; res.header.frame_id = "/world";
res.header.seq = trace_id_; res.header.seq = trace_id_;
auto odom=vo_->ukfPtr_.get_location(); auto odom=vo_->ukfPtr_.get_location();
res.x=-odom.second.se2().translation()(0); res.x=odom.second.se2().translation()(1);
res.y=-odom.second.se2().translation()(1); res.y=odom.second.se2().translation()(0);
res.yaw=odom.second.pitch(); res.yaw=odom.second.pitch();
res.cov={odom.first(0,0),odom.first(0,1),odom.first(0,2), res.cov={odom.first(0,0),odom.first(0,1),odom.first(0,2),
odom.first(1,0),odom.first(1,1),odom.first(1,2), odom.first(1,0),odom.first(1,1),odom.first(1,2),