$search
00001 00014 /***************************************************************************** 00015 ** Includes 00016 *****************************************************************************/ 00017 00018 #include <iostream> 00019 #include <string> 00020 #include <vector> 00021 #include <ecl/formatters.hpp> 00022 #include <ecl/utilities/parameter.hpp> 00023 #include <ecl/slam/slam_ekf_base.hpp> 00024 #include <ecl/slam/slam_ekf/odometry_generic.hpp> 00025 #include <ecl/slam/slam_ekf/observation_generic.hpp> 00026 00027 /***************************************************************************** 00028 ** Using 00029 *****************************************************************************/ 00030 00031 using std::string; 00032 using std::vector; 00033 using ecl::Format; 00034 using ecl::RightAlign; 00035 using ecl::linear_algebra::Matrix; 00036 using ecl::linear_algebra::MatrixXd; 00037 using ecl::linear_algebra::Vector2d; 00038 using ecl::linear_algebra::Vector3d; 00039 using ecl::linear_algebra::VectorXd; 00040 using ecl::slam_ekf::GenericOdometryModel; 00041 using ecl::slam_ekf::GenericObservationModel; 00042 using ecl::SlamEkfBase; 00043 using ecl::Parameter; 00044 00045 /***************************************************************************** 00046 ** Classes 00047 *****************************************************************************/ 00048 00049 namespace ecl { 00050 namespace demos { 00051 00052 /****************************************** 00053 ** LandMark 00054 *******************************************/ 00055 00056 class LandMark { 00057 public: 00058 static const unsigned int observation_dimension = 1; 00059 typedef Matrix<double,observation_dimension,1> Observation; 00060 00061 friend class SlidingObservationModel; 00062 00063 const unsigned int& id() const { return unique_id; } 00064 00072 void observation(const Observation& obs) { 00073 last_observation = obs; 00074 } 00075 const Observation& observation() const { return last_observation; } 00076 00077 00078 Parameter<unsigned int> correspondence; 00079 ~LandMark() {}; 00080 00081 private: 00082 LandMark(const unsigned int& corr) : 00083 correspondence(corr) 00084 { 00085 static unsigned int id_counter = 0; 00086 unique_id = id_counter++; 00087 } 00088 00089 Observation last_observation; 00090 unsigned int unique_id; 00091 }; 00092 00093 /****************************************** 00094 ** Odometry 00095 *******************************************/ 00096 00097 typedef SlamEkfBase<1,1,1,2> SlidingFilterBase; 00098 00099 class SlidingOdometryModel : public GenericOdometryModel< SlidingFilterBase > { 00100 public: 00101 SlidingOdometryModel(const double &noise_lvl, SlidingFilterBase &ekf_arrays) : GenericOdometryModel< SlidingFilterBase >(ekf_arrays), noise_level(noise_lvl) {} 00102 00103 private: 00104 Pose poseUpdate(const Measurement &incoming ) { 00105 Pose update = incoming; 00106 return update; 00107 } 00108 00109 MotionJacobian motionJacobian(const Measurement & /* incoming */) { 00110 MotionJacobian jacobian; 00111 jacobian << 1; 00112 return jacobian; 00113 } 00114 00115 NoiseJacobian noiseJacobian(const Measurement & /* incoming */) { 00116 NoiseJacobian noise_jacobian; 00117 noise_jacobian << 1; 00118 return noise_jacobian; 00119 } 00120 00121 Noise noise(const Measurement &incoming) { 00122 Noise noise_matrix; 00123 noise_matrix << noise_level*fabs(incoming[0])*noise_level*fabs(incoming[0]); 00124 return noise_matrix; 00125 } 00126 00127 double noise_level; 00128 }; 00129 00130 /****************************************** 00131 ** LandMarkManager 00132 *******************************************/ 00133 00134 class SlidingObservationModel : public GenericObservationModel< SlidingFilterBase > { 00135 public: 00136 SlidingObservationModel( SlidingFilterBase &ekf_arrays) : GenericObservationModel< SlidingFilterBase >(ekf_arrays) { 00137 initial_variance = Matrix<double,feature_dimension,feature_dimension>::Zero(); 00138 for ( unsigned int i = 0; i < feature_dimension; ++i ) { 00139 initial_variance(i,i) = 20; 00140 } 00141 } 00142 LandMark createLandMark(const Vector2d &initial_state) { 00143 int correspondence = filter_base.insert(initial_state, initial_variance); 00144 return LandMark(correspondence); 00145 } 00146 void deleteLandMark(const LandMark& landmark) { 00147 filter_base.remove(landmark.correspondence()); 00148 } 00149 00150 Observation prediction( const Feature &feature, const Pose ¤t_pose ) { 00151 double x_r = current_pose[0]; 00152 Observation pred; 00153 pred << atan2(feature[1],feature[0]-x_r); 00154 return pred; 00155 } 00156 00157 Innovation innovation( const Observation &observation, const Feature &feature, const Pose ¤t_pose ) { 00158 return prediction(feature, current_pose)-observation; 00159 } 00160 00161 private: 00162 00171 Jacobian observationJacobian( const Feature &feature, const Pose ¤t_pose ) { 00172 Jacobian observation_jacobian; 00173 double z_l = feature[1]; 00174 double dx = feature[0] - current_pose[0]; 00175 double dadxr = z_l/(z_l*z_l+dx*dx); 00176 double dadxl = -dadxr; 00177 double dadzl = dx/(z_l*z_l+dx*dx); 00178 observation_jacobian << dadxr, dadxl, dadzl; 00179 return observation_jacobian; 00180 } 00181 00182 Noise noise() { 00183 static Noise noise_matrix = Noise::Zero(); 00184 static bool noise_initialised = false; 00185 if ( !noise_initialised ) { 00186 noise_matrix << 0.001; 00187 } 00188 return noise_matrix; 00189 } 00190 00191 FeatureVariance initial_variance; 00192 }; 00193 00194 } // namespace demos 00195 } // namespace ecl 00196 00197 /***************************************************************************** 00198 ** Using 00199 *****************************************************************************/ 00200 00201 using namespace ecl::demos; 00202 00203 /***************************************************************************** 00204 ** Main 00205 *****************************************************************************/ 00206 00207 int main() { 00208 Format<string> string_format; string_format.width(8); string_format.align(RightAlign); 00209 Format<double> format; format.width(8); format.precision(2); format.align(RightAlign); 00210 00211 std::cout << std::endl; 00212 std::cout << "***********************************************************" << std::endl; 00213 std::cout << " Construction" << std::endl; 00214 std::cout << "***********************************************************" << std::endl; 00215 std::cout << std::endl; 00216 00217 const unsigned int initial_capacity = 5; 00218 SlidingFilterBase filter_base(initial_capacity); 00219 00220 SlidingOdometryModel odometry_model(0.1, filter_base); 00221 SlidingObservationModel observation_model(filter_base); 00222 00223 std::cout << std::endl; 00224 std::cout << "***********************************************************" << std::endl; 00225 std::cout << " Adding a LandMark" << std::endl; 00226 std::cout << "***********************************************************" << std::endl; 00227 std::cout << std::endl; 00228 00229 Vector2d initial_state; 00230 initial_state << 0.3, 2.6; 00231 LandMark landmark = observation_model.createLandMark(initial_state); 00232 initial_state << 0.6, 2.6; 00233 LandMark landmark_two = observation_model.createLandMark(initial_state); 00234 initial_state << 0.9, 2.6; 00235 LandMark landmark_three = observation_model.createLandMark(initial_state); 00236 00237 std::cout << std::endl; 00238 std::cout << "***********************************************************" << std::endl; 00239 std::cout << " Deleting a landmark" << std::endl; 00240 std::cout << "***********************************************************" << std::endl; 00241 std::cout << std::endl; 00242 00243 observation_model.deleteLandMark(landmark_two); 00244 00245 std::cout << std::endl; 00246 std::cout << "***********************************************************" << std::endl; 00247 std::cout << " Update Loop" << std::endl; 00248 std::cout << "***********************************************************" << std::endl; 00249 std::cout << std::endl; 00250 00251 vector<SlidingObservationModel::Observation> observations; 00252 vector<unsigned int> correspondences; 00253 SlidingOdometryModel::Measurement incoming; 00254 incoming << 0.1; 00255 for ( unsigned int i = 0; i < 10; ++i ) { 00256 observations.clear(); 00257 correspondences.clear(); 00258 odometry_model.updateFilter(incoming); 00259 if ( i == 4 ) { 00260 std::cout << std::endl; 00261 std::cout << "***********************************************************" << std::endl; 00262 std::cout << " Before" << std::endl; 00263 std::cout << "***********************************************************" << std::endl; 00264 std::cout << std::endl; 00265 SlidingObservationModel::Observation obs; 00266 obs << 1.65; // actual 1.648 00267 observations.push_back(obs); 00268 correspondences.push_back(landmark.correspondence()); 00269 obs << 1.42; // Actual 1.418 00270 observations.push_back(obs); 00271 correspondences.push_back(landmark_three.correspondence()); 00272 observation_model.updateFilter(observations, correspondences); 00273 std::cout << std::endl; 00274 std::cout << "***********************************************************" << std::endl; 00275 std::cout << " After" << std::endl; 00276 std::cout << "***********************************************************" << std::endl; 00277 std::cout << std::endl; 00278 } 00279 } 00280 00281 std::cout << std::endl; 00282 std::cout << "***********************************************************" << std::endl; 00283 std::cout << " Results" << std::endl; 00284 std::cout << "***********************************************************" << std::endl; 00285 std::cout << std::endl; 00286 00287 std::cout << "Pose Estimate: " << odometry_model.pose().transpose() << std::endl; 00288 00289 std::cout << std::endl; 00290 00291 filter_base.reserve(10); 00292 00293 std::cout << std::endl; 00294 std::cout << "***********************************************************" << std::endl; 00295 std::cout << " Passed" << std::endl; 00296 std::cout << "***********************************************************" << std::endl; 00297 std::cout << std::endl; 00298 00299 return 0; 00300 } 00301 00302