00001 #include "poseslam_alg.h"
00002
00003 PoseslamAlgorithm::PoseslamAlgorithm(void)
00004 :
00005 inicialitzat_(false)
00006 {
00007 }
00008
00009 PoseslamAlgorithm::~PoseslamAlgorithm(void)
00010 {
00011 delete pose_SLAM_;
00012 delete pose_SLAM_noLoops_;
00013 }
00014
00015 void PoseslamAlgorithm::config_update(Config& new_cfg, uint32_t level)
00016 {
00017 this->lock();
00018
00019
00020 this->config_=new_cfg;
00021
00022
00023 Params Parameters;
00024 Parameters.matchArea(0) = config_.match_area_x;
00025 Parameters.matchArea(1) = config_.match_area_y;
00026 Parameters.matchArea(2) = config_.match_area_th;
00027 Parameters.pdRange.first = config_.pd_range_1;
00028 Parameters.pdRange.second = config_.pd_range_2;
00029 Parameters.igRange.first = config_.ig_range_1;
00030 Parameters.igRange.second = config_.ig_range_2;
00031 Parameters.ignorePrevious = config_.ignore_previous_steps;
00032
00033 MatrixXd LoopNoise(3, 3);
00034 LoopNoise(0, 0) = config_.closing_loop_noise_xx * config_.ICP_covariance_correction_factor;
00035 LoopNoise(0, 1) = config_.closing_loop_noise_xy * config_.ICP_covariance_correction_factor;
00036 LoopNoise(1, 0) = config_.closing_loop_noise_xy * config_.ICP_covariance_correction_factor;
00037 LoopNoise(0, 2) = config_.closing_loop_noise_xth * config_.ICP_covariance_correction_factor;
00038 LoopNoise(2, 0) = config_.closing_loop_noise_xth * config_.ICP_covariance_correction_factor;
00039 LoopNoise(1, 1) = config_.closing_loop_noise_yy * config_.ICP_covariance_correction_factor;
00040 LoopNoise(1, 2) = config_.closing_loop_noise_yth * config_.ICP_covariance_correction_factor;
00041 LoopNoise(2, 1) = config_.closing_loop_noise_yth * config_.ICP_covariance_correction_factor;
00042 LoopNoise(2, 2) = config_.closing_loop_noise_thth * config_.ICP_covariance_correction_factor;
00043 Parameters.LoopNoise = LoopNoise;
00044
00045 if (!inicialitzat_)
00046 {
00047
00048 Vector3d initM;
00049 initM(0) = config_.initial_position_x;
00050 initM(1) = config_.initial_position_y;
00051 initM(2) = config_.initial_position_th;
00052
00053
00054 MatrixXd initS(3, 3);
00055 initS(0, 0) = config_.initial_covariance_xx;
00056 initS(0, 1) = config_.initial_covariance_xy;
00057 initS(1, 0) = config_.initial_covariance_xy;
00058 initS(0, 2) = config_.initial_covariance_xth;
00059 initS(2, 0) = config_.initial_covariance_xth;
00060 initS(1, 1) = config_.initial_covariance_yy;
00061 initS(1, 2) = config_.initial_covariance_yth;
00062 initS(2, 1) = config_.initial_covariance_yth;
00063 initS(2, 2) = config_.initial_covariance_thth;
00064
00065 pose_SLAM_ = new CPoseSLAM(initM, initS, Parameters);
00066 if (config_.also_no_loops)
00067 pose_SLAM_noLoops_ = new CPoseSLAM(initM, initS, Parameters);
00068
00069 Q_odom_ = Eigen::MatrixXd::Zero(3,3);
00070
00071 inicialitzat_ = true;
00072 ROS_INFO("----------- INICIALITZAT ------------");
00073 }
00074 else
00075 {
00076 pose_SLAM_->set_parameters(Parameters);
00077 if (config_.also_no_loops)
00078 pose_SLAM_noLoops_->set_parameters(Parameters);
00079 }
00080
00081 this->unlock();
00082 }
00083
00084
00085 void PoseslamAlgorithm::augmentation(const uint& step, const geometry_msgs::PoseWithCovarianceStamped& odom)
00086 {
00087
00088 Q_odom_(0,0) = odom.pose.covariance[0];
00089 Q_odom_(0,1) = odom.pose.covariance[1];
00090 Q_odom_(0,2) = odom.pose.covariance[5];
00091 Q_odom_(1,0) = odom.pose.covariance[6];
00092 Q_odom_(1,1) = odom.pose.covariance[7];
00093 Q_odom_(1,2) = odom.pose.covariance[11];
00094 Q_odom_(2,0) = odom.pose.covariance[30];
00095 Q_odom_(2,1) = odom.pose.covariance[31];
00096 Q_odom_(2,2) = odom.pose.covariance[35];
00097
00098 Vector3d d;
00099 d(0) = odom.pose.pose.position.x;
00100 d(1) = odom.pose.pose.position.y;
00101 d(2) = tf::getYaw(odom.pose.pose.orientation);
00102
00103 Q_aug_.push_back(Q_odom_);
00104 d_aug_.push_back(d);
00105
00106
00107
00108
00109
00110 if (config_.also_no_loops)
00111 {
00112 pose_SLAM_noLoops_->set_redundant(pose_SLAM_->is_redundant());
00113 pose_SLAM_noLoops_->augmentation(step, d, Q_odom_);
00114 }
00115 pose_SLAM_->augmentation(step, d, Q_odom_);
00116
00117
00118 pose_SLAM_->set_redundant(d.isZero() && Q_odom_.isZero());
00119 }
00120
00121 void PoseslamAlgorithm::create_candidates_list(const bool& realOdometryCov)
00122 {
00123 if (realOdometryCov)
00124 pose_SLAM_->create_candidates_list(Q_odom_);
00125 else
00126 pose_SLAM_->create_candidates_list();
00127 }
00128
00129 void PoseslamAlgorithm::redundant_evaluation()
00130 {
00131 pose_SLAM_->redundant_evaluation();
00132 }
00133
00134 bool PoseslamAlgorithm::loop_closure_requeriments() const
00135 {
00136 return pose_SLAM_->loop_closure_requeriments();
00137 }
00138
00139 bool PoseslamAlgorithm::try_loop_closure(const geometry_msgs::PoseWithCovarianceStamped& odom)
00140 {
00141 MatrixXd Q(3, 3);
00142
00143 Q(0,0) = odom.pose.covariance[0];
00144 Q(0,1) = odom.pose.covariance[1];
00145 Q(0,2) = odom.pose.covariance[5];
00146 Q(1,0) = odom.pose.covariance[6];
00147 Q(1,1) = odom.pose.covariance[7];
00148 Q(1,2) = odom.pose.covariance[11];
00149 Q(2,0) = odom.pose.covariance[30];
00150 Q(2,1) = odom.pose.covariance[31];
00151 Q(2,2) = odom.pose.covariance[35];
00152
00153 Vector3d d;
00154 d(0) = odom.pose.pose.position.x;
00155 d(1) = odom.pose.pose.position.y;
00156 d(2) = tf::getYaw(odom.pose.pose.orientation);
00157
00158 Q_loop_.push_back(Q);
00159 d_loop_.push_back(d);
00160
00161
00162
00163
00164
00165 bool success = pose_SLAM_->try_loop_closure(Q, d);
00166
00167 success_loop_.push_back(success);
00168
00169 return success;
00170 }
00171
00172 void PoseslamAlgorithm::update_candidates_list(const bool LoopClosure, const bool& realOdometryCov)
00173 {
00174 if (realOdometryCov)
00175 pose_SLAM_->update_candidates_list(LoopClosure, Q_odom_);
00176 else
00177 pose_SLAM_->update_candidates_list(LoopClosure);
00178 }
00179
00180 bool PoseslamAlgorithm::any_candidate() const
00181 {
00182 return pose_SLAM_->any_candidate();
00183 }
00184
00185 void PoseslamAlgorithm::select_best_candidate()
00186 {
00187 pose_SLAM_->select_best_candidate();
00188 }
00189
00190 uint PoseslamAlgorithm::get_candidate_step() const
00191 {
00192 return pose_SLAM_->get_candidate_step();
00193 }
00194
00195 geometry_msgs::Pose PoseslamAlgorithm::get_candidate_d() const
00196 {
00197 geometry_msgs::Pose disp;
00198 VectorXd d = pose_SLAM_->get_candidate_link().d;
00199
00200 disp.position.x = d(0);
00201 disp.position.y = d(1);
00202 disp.position.z = 0;
00203
00204 disp.orientation = tf::createQuaternionMsgFromYaw(d(2));
00205
00206 return disp;
00207 }
00208
00209 double PoseslamAlgorithm::get_candidate_ig() const
00210 {
00211 return pose_SLAM_->get_candidate_link().iGain;
00212 }
00213
00214 bool PoseslamAlgorithm::is_redundant() const
00215 {
00216 return pose_SLAM_->is_redundant();
00217 }
00218
00219 std::vector<VectorXd> PoseslamAlgorithm::get_trajectory() const
00220 {
00221 return pose_SLAM_->get_trajectory();
00222 }
00223
00224 std::vector<std::vector<double> > PoseslamAlgorithm::get_trajectory_covariance() const
00225 {
00226 std::vector<MatrixXd> covs = pose_SLAM_->get_trajectory_covariance();
00227 std::vector<std::vector<double> > trajectory_covariances(covs.size());
00228
00229 uint cov_size = covs.at(0).size();
00230
00231 for (uint k = 0; k < covs.size(); k++)
00232 {
00233 std::vector<double> covariance(cov_size);
00234
00235 std::copy(covs.at(k).data(),covs.at(k).data() + cov_size, covariance.begin());
00236 trajectory_covariances.at(k) = covariance;
00237 }
00238 return trajectory_covariances;
00239 }
00240
00241 std::vector<uint> PoseslamAlgorithm::get_trajectory_steps() const
00242 {
00243 return pose_SLAM_->get_trajectory_steps();
00244 }
00245
00246 std::vector<VectorXd> PoseslamAlgorithm::get_trajectory_no_loops() const
00247 {
00248 return pose_SLAM_noLoops_->get_trajectory();
00249 }
00250
00251 std::vector<std::vector<double> > PoseslamAlgorithm::get_trajectory_covariance_no_loops() const
00252 {
00253 std::vector<MatrixXd> covs = pose_SLAM_noLoops_->get_trajectory_covariance();
00254 std::vector<std::vector<double> > trajectory_covariances(covs.size());
00255
00256 uint cov_size = covs.at(0).size();
00257
00258 for (uint k = 0; k < covs.size(); k++)
00259 {
00260 std::vector<double> covariance(cov_size);
00261
00262 std::copy(covs.at(k).data(),covs.at(k).data() + cov_size, covariance.begin());
00263 trajectory_covariances.at(k) = covariance;
00264 }
00265 return trajectory_covariances;
00266 }
00267
00268 VectorXd PoseslamAlgorithm::get_last_pose() const
00269 {
00270 return pose_SLAM_-> get_FF().get_PD().back().get_mean().get_vector();
00271 }
00272
00273 std::vector<double> PoseslamAlgorithm::get_last_covariance() const
00274 {
00275 MatrixXd last_covariance_matrix = pose_SLAM_-> get_FF().get_PD().back().get_S();
00276 std::vector<double> last_covariance(last_covariance_matrix.size());
00277
00278 std::copy(last_covariance_matrix.data(), last_covariance_matrix.data() + last_covariance_matrix.size(), last_covariance.begin());
00279 return last_covariance;
00280 }
00281
00282 uint PoseslamAlgorithm::get_last_step() const
00283 {
00284 return pose_SLAM_-> get_FF().get_PF().state_2_step(pose_SLAM_-> get_FF().get_nStates() - 1);
00285 }
00286
00287 VectorXd PoseslamAlgorithm::get_last_pose_no_loops() const
00288 {
00289 return pose_SLAM_noLoops_-> get_FF().get_PD().back().get_mean().get_vector();
00290 }
00291
00292 std::vector<double> PoseslamAlgorithm::get_last_covariance_no_loops() const
00293 {
00294 MatrixXd last_covariance_matrix = pose_SLAM_noLoops_-> get_FF().get_PD().back().get_S();
00295 std::vector<double> last_covariance(last_covariance_matrix.size());
00296
00297 std::copy(last_covariance_matrix.data(),last_covariance_matrix.data() + last_covariance_matrix.size(), last_covariance.begin());
00298 return last_covariance;
00299 }
00300
00301 uint PoseslamAlgorithm::get_nStates() const
00302 {
00303 return pose_SLAM_-> get_FF().get_nStates();
00304 }
00305
00306
00307 void PoseslamAlgorithm::print_matrix_in_file(const MatrixXd& M, std::fstream& file) const
00308 {
00309 pose_SLAM_-> print_matrix_in_file(M, file);
00310 }
00311
00312 void PoseslamAlgorithm::print_vector_in_file(const std::vector<double>& v, std::fstream& file) const
00313 {
00314 pose_SLAM_-> print_vector_in_file(v, file);
00315 }
00316
00317 void PoseslamAlgorithm::print_vector_in_file(const std::vector<uint>& v, std::fstream& file) const
00318 {
00319 pose_SLAM_-> print_vector_in_file(v, file);
00320 }
00321
00322 void PoseslamAlgorithm::print_time_file(std::fstream& file) const
00323 {
00324 pose_SLAM_-> print_time_file(file);
00325 }