00001
00002
00003 #ifndef SLAM_SEGMENT_FEATURE_HPP
00004 #define SLAM_SEGMENT_FEATURE_HPP
00005
00006 #include "boost/tuple/tuple.hpp"
00007
00008 #include "jmath/jblas.hpp"
00009 #include "jmath/ublasExtra.hpp"
00010
00011 #include "geom/t3d.hpp"
00012
00013 #include "filter/constraintModel.hpp"
00014
00015 #include "filter/predictModel.hpp"
00016
00017 #include "slam/eulerTools.hpp"
00018 #include "slam/observation.hpp"
00019 #include "slam/bearingOnlyFeature.hpp"
00020 #include "camera/cameraPinhole.hpp"
00021
00022 namespace jafar {
00023 namespace slam {
00024
00025 class BearingOnlySlam;
00026
00031 class SegmentObservation : public Observation {
00032
00033 public:
00034
00036 jblas::vec2 ext1;
00038 jblas::vec2 ext2;
00039
00043 SegmentObservation(ObservationType type_, unsigned int _robotId = 0) :
00044 Observation(type_, _robotId),
00045 ext1(), ext2()
00046 {
00047 JFR_ASSERT( type_ == SEGMENT_IMAGE or type_ == SEGMENTAP_IMAGE or type_ == SEGMENTID_IMAGE or type == SEGMENTID_EXT_IMAGE or type == SEGMENT_STEREOIMAGE, "Not a segment type");
00048 }
00049
00053 SegmentObservation(SegmentObservation const& obs) :
00054 Observation(obs),
00055 ext1(obs.ext1),
00056 ext2(obs.ext2)
00057 {}
00058
00060 virtual ~SegmentObservation() {}
00061
00065 void setExtremities(jblas::vec2 const& ext1_, jblas::vec2 const& ext2_) {
00066 ext1.assign(ext1_);
00067 ext2.assign(ext2_);
00068 }
00069
00070 };
00071
00072 std::ostream& operator <<(std::ostream& s, const jafar::slam::SegmentObservation& o_);
00073
00078 class StereoSegmentObservation : public Observation {
00079
00080 public:
00081
00083 jblas::vec3 ext1;
00085 jblas::vec3 ext2;
00086
00090 StereoSegmentObservation(unsigned int _robotId = 0) :
00091 Observation(SEGMENT_STEREOIMAGE, _robotId),
00092 ext1(), ext2()
00093 {}
00094
00098 StereoSegmentObservation(StereoSegmentObservation const& obs) :
00099 Observation(obs),
00100 ext1(obs.ext1),
00101 ext2(obs.ext2)
00102 {}
00103
00105 virtual ~StereoSegmentObservation() {}
00106
00110 void setExtremities(jblas::vec3 const& ext1_, jblas::vec3 const& ext2_) {
00111 ext1.assign(ext1_);
00112 ext2.assign(ext2_);
00113 }
00114
00115 };
00116
00117
00118 std::ostream& operator <<(std::ostream& s, const jafar::slam::StereoSegmentObservation& o_);
00119
00121 class SegmentUConstraint : public jafar::filter::JacobianStrongConstraintModel {
00122
00123 public:
00124
00125 SegmentUConstraint(double alpha, int maxNbTimesApplied) :
00126 JacobianStrongConstraintModel(6, 1.0, alpha, maxNbTimesApplied)
00127 {
00128
00129 J.clear();
00130 }
00131
00132 ~SegmentUConstraint() {}
00133
00134 double estimateValue(jblas::vec_range const& x0) const {
00135 using namespace ublas;
00136 return norm_2(project(x0, range(3,6)));
00137 }
00138
00139 void estimateValueJac(jblas::vec_range const& x0) {
00140 using namespace ublas;
00141 jblas::mat_range J_r(J, range(0,1), range(3,6));
00142 jmath::ublasExtra::norm_2Jac<3>(project(x0, range(3,6)), J_r);
00143 }
00144
00145 };
00146
00147 class SegmentPluckerConstraint : public jafar::filter::JacobianStrongConstraintModel {
00148
00149 public:
00150
00151 SegmentPluckerConstraint(double alpha, int maxNbTimesApplied) :
00152 JacobianStrongConstraintModel(6, 0.0, alpha, maxNbTimesApplied) {}
00153
00154 ~SegmentPluckerConstraint() {}
00155
00156 double estimateValue(jblas::vec_range const& x0) const {
00157 using namespace ublas;
00158 p_estimatedValue = inner_prod(project(x0, range(0,3)), project(x0, range(3,6)));
00159 return p_estimatedValue;
00160 }
00161
00162 void estimateValueJac(jblas::vec_range const& x0) {
00163 using namespace ublas;
00164 jmath::ublasExtra::inner_prodJac<3>(project(x0, range(0,3)), project(x0, range(3,6)), J);
00165 }
00166
00167
00168
00169
00170
00171
00172 };
00173
00174
00179 class SegmentFeatureContraintModel :
00180 public jafar::filter::JacobianBlockPredictModel {
00181
00182 public:
00183
00184 SegmentFeatureContraintModel();
00185 ~SegmentFeatureContraintModel() {}
00186
00187 void fixFeature(jblas::vec_range& L);
00188 void fixFeatureJac(jblas::vec_range& L, jblas::mat& JfL);
00189
00190 void predict(jblas::vec_range& x_r);
00191
00192 };
00193
00194
00201 class SegmentFeature : public BaseFeature {
00202
00203 public:
00204
00205 std::string debugObs;
00206
00208 double s1;
00210 double s2;
00211
00213 bool ENLARGE;
00214
00215
00216
00217
00218 SegmentFeature(unsigned int id, FeatureModel& model, std::size_t sizeObs, Observation::ObservationType typeObs_);
00219 virtual ~SegmentFeature();
00220
00221 jblas::vec_range const& u() const {return *p_u;}
00222 jblas::vec_range& u() {return *p_u;}
00223 jblas::vec_range const& n() const {return *p_n;}
00224 jblas::vec_range& n() {return *p_n;}
00225
00226 void setFlagEnlarge() {ENLARGE=true;}
00227
00228 virtual void setState(jblas::vec& x_, jblas::sym_mat& P_);
00229
00230 jblas::vec3 getExt1() const;
00231 jblas::sym_mat getExt1Cov() const;
00232 jblas::vec3 getExt2() const;
00233 jblas::sym_mat getExt2Cov() const;
00234 jblas::mat getExt1Jac() const;
00235 jblas::mat getExt2Jac() const;
00236
00237
00238 static void setConstraintAlpha(double alpha) {p_constraintAlpha = alpha;}
00239 static double getConstraintAlpha() {return p_constraintAlpha;}
00240 static void setConstraintMaxNbTimesApplied(int maxNbTimesApplied) {p_constraintMaxNbTimesApplied = maxNbTimesApplied;}
00241 static int getConstraintMaxNbTimesApplied() {return p_constraintMaxNbTimesApplied;}
00242 static void setFlagPlucklerConstraint(bool pluckerConstraint) {ENABLE_PLUCKER_CONSTRAINT=pluckerConstraint;}
00243
00245
00246
00247 protected:
00248
00249 virtual void writeLogHeader(jafar::kernel::DataLogger& log) const;
00250 virtual void writeLogData(jafar::kernel::DataLogger& log) const;
00251
00252 private:
00253
00257 jblas::vec_range* p_n;
00258
00260 jblas::vec_range* p_u;
00261
00263 void computeExt(double s_, jblas::vec3& ext) const;
00264
00266 void computeExtJac(double s_, jblas::mat& J) const;
00267
00269 void computeExtCov(double s_, jblas::sym_mat& extCov) const;
00270
00271
00272 static double p_constraintAlpha;
00273 static int p_constraintMaxNbTimesApplied;
00274 static bool ENABLE_PLUCKER_CONSTRAINT;
00275
00276 };
00277
00278
00279 std::ostream& operator <<(std::ostream& s, const jafar::slam::SegmentFeature& f);
00280
00285 class SegmentFeatureModel : public FeatureModel {
00286
00287 public:
00288
00289 SegmentFeatureModel();
00290 ~SegmentFeatureModel();
00291
00292
00293 void toFrame(const jblas::vec& frame_, const jblas::vec& x_, jblas::vec& xRes);
00294 void toFrameJac(const jblas::vec& frame_, const jblas::vec& x_);
00295
00296 void fromFrame(const jblas::vec& frame_, const jblas::vec& x_, jblas::vec& xRes);
00297 void fromFrame(const jblas::vec& frame_, const jblas::vec& x_, jblas::vec_range& xRes);
00298 void fromFrameJac(const jblas::vec& frame_, const jblas::vec& x_);
00299
00300 void computeMergeState( const jblas::vec& x_, jblas::vec& mergeX_, jblas::mat& jac );
00301
00302 };
00303
00308 class ImageEuclideanPluckerFeatureObserveModel : public BearingOnlyFeatureObserveModel {
00309
00310 protected:
00311
00312 jafar::camera::CameraPinhole camera;
00313 jblas::mat33 Pl;
00314 jblas::mat33 Plinv;
00315
00316 void pluckerLineInit(jblas::vec const& z_, double d_, double phi_, double sg_, jblas::vec& pluckerLine) const;
00317
00318 void pluckerLineInitJac(jblas::vec const& z_, double d_, double phi_, double sg_, jblas::mat& J) const;
00319
00320 jblas::vec const& predictObservationInSensorFrame(const jblas::vec& feature_);
00321
00322 void predictObservationInSensorFrameJac(const jblas::vec& feature_);
00323
00324 jblas::vec const& predictObservationInImageFrame(jblas::vec3 const& l_);
00325 void predictObservationInImageFrameJac(jblas::vec3 const& l_,
00326 jblas::mat& Jl) const;
00327
00328 boost::tuple<double,double> computeExtremitiesAbscissa(SegmentFeature const& segFeature_,
00329 geom::T3DEuler const& robotPose_,
00330 SegmentObservation const& obs_) const;
00331
00332 void segmentExtremitiesPluckerLines(SegmentObservation const& segObs_,
00333 jblas::vec& lineExt1Sensor,
00334 jblas::vec& lineExt2Sensor) const;
00335
00336 static boost::tuple<double, double, double> pluckerLinesDistance(jblas::vec const& line1_,
00337 jblas::vec const& line2_);
00338
00340 jblas::sym_mat p_pixCov;
00341
00342
00344 virtual void computeSensorR(Observation const& obs);
00345
00347
00348
00350 double computeBaselineInSensorFrame(jblas::vec_range const& deltaPose, Observation const& obsRef) const {return 1.0;}
00351
00352 public:
00353
00357 double depthAlpha;
00361 double depthBeta;
00362
00365 double phiMin;
00368 double phiMax;
00369
00372 double phiSigma;
00373
00376 double phiKSigma;
00377
00378
00379 ImageEuclideanPluckerFeatureObserveModel(SegmentFeatureModel& featureModel_,
00380 jafar::camera::CameraPinhole const& camera_,
00381 double depthAlpha_, double depthKSigma_,
00382 double phiMin_, double phiMax_,
00383 double phiSigma_,
00384 double phiKSigma_);
00385
00386 ~ImageEuclideanPluckerFeatureObserveModel();
00387
00388 Observation::ObservationType typeObs() const {return Observation::SEGMENT_IMAGE;}
00389
00390 void setPixCov(jblas::vec const& pixCov_, double stabilizingFactor = 1.0);
00391
00392 void initStateInSensorFrame(InitFeature& feature_,
00393 Observation const& obs_,
00394 double dMin_, double dMax_);
00395
00398 void initInternalState(BaseFeature& feature, jafar::geom::T3DEuler const& robotPose_, Observation const& obs_) const;
00399
00402 void updateInternalState(BaseFeature& feature, jafar::geom::T3DEuler const& robotPose_, Observation const& obs_) const;
00403
00404 jblas::vec const& computeInnovation(jblas::vec const& z_,
00405 jblas::vec const& zPred_);
00406
00414 void predictExtObs(jblas::vec_range const& pose, jblas::sym_mat_range const& poseCov,
00415 jblas::vec3 const& ext, jblas::sym_mat const& extCov,
00416 jblas::vec& zPredExt, jblas::sym_mat& zPredExtCov);
00422 void predictExtObsJac(jblas::vec_range const& pose, jblas::vec3 const Ext, jblas::vec& eInImage, jblas::mat& JeR, jblas::mat& JeExt);
00426 static jblas::vec2 extToLine(jblas::vec const& ext1,jblas::vec const& ext2);
00427
00432 static void extToLineJac(jblas::vec const& ext1,jblas::vec const& ext2, jblas::mat& J);
00433
00434 friend std::string boSegFeatureInitState(InitFeature const& f_, BearingOnlySlam& slam_);
00435
00436 };
00437
00438
00446
00447
00448 class ImagePluckerFeatureObserveModel : public FeatureObserveModel {
00449
00450 protected:
00452 SegmentFeatureModel& segmentFeatureModel;
00453
00455 jafar::camera::CameraPinhole camera;
00457 jblas::mat33 Pl;
00459 jblas::mat33 Plinv;
00460
00462 jblas::vec2 beta;
00464 jblas::mat22 covar_beta;
00465
00467 jblas::mat JbBeta;
00468
00469
00472 virtual jblas::vec const& homogeneousToImageModel(jblas::vec3 const& l_) = 0;
00473
00476 virtual void homogeneousToImageModelJac(jblas::vec3 const& l_,
00477 jblas::mat& Jl) const = 0;
00478
00479
00484 virtual jblas::vec3 imageModelToHomogeneous(jblas::vec const& rt_) = 0;
00485
00490 virtual void imageModelToHomogeneousJac(jblas::vec const& rt_, jblas::mat& HMrt) = 0;
00491
00497 virtual void imageModelToHomogeneousJac(jblas::vec const& rt_, jblas::vec3& l, jblas::mat& HMrt) = 0;
00498
00499
00501 jblas::vec3 planeBaseToDirVector(jblas::vec3 const& an_, jblas::vec2 const& beta_);
00502
00504 void planeBaseToDirVectorJac(jblas::vec_range const& an_, jblas::vec2 const& beta_, jblas::vec_range& b, jblas::mat33& B_a);
00505
00506
00507 boost::tuple<double,double> computeExtremitiesAbscissa(SegmentFeature const& segFeature_,
00508 geom::T3DEuler const& robotPose_,
00509 SegmentObservation const& obs_) const;
00510
00511 void segmentExtremitiesPluckerLines(SegmentObservation const& segObs_,
00512 jblas::vec& lineExt1Sensor,
00513 jblas::vec& lineExt2Sensor) const;
00514
00515 static boost::tuple<double, double, double> pluckerLinesDistance(jblas::vec const& line1_,
00516 jblas::vec const& line2_);
00517
00519 jblas::sym_mat p_pixCov;
00520
00521
00522
00523 public:
00524
00525 ImagePluckerFeatureObserveModel(SegmentFeatureModel& featureModel_, jafar::camera::CameraPinhole const& camera_);
00526 ~ImagePluckerFeatureObserveModel();
00527
00528 Observation::ObservationType typeObs() const {return Observation::SEGMENT_IMAGE;}
00529
00530 void setPixCov(jblas::vec const& pixCov_, double stabilizingFactor = 1.0);
00531
00532
00535 void initInternalState(BaseFeature& feature, jafar::geom::T3DEuler const& robotPose_, Observation const& obs_) const;
00536
00539 void updateInternalState(BaseFeature& feature, jafar::geom::T3DEuler const& robotPose_, Observation const& obs_) const;
00540
00551 void predictExtObs(jblas::vec_range const& pose, jblas::sym_mat_range const& poseCov,
00552 jblas::vec3 const& ext, jblas::sym_mat const& extCov,
00553 jblas::vec& zPredExt, jblas::sym_mat& zPredExtCov);
00559 void predictExtObsJac(jblas::vec_range const& pose, jblas::vec3 const Ext, jblas::vec& eInImage, jblas::mat& JeR, jblas::mat& JeExt);
00560
00561
00565 void postInitCovariance(jblas::sym_mat_range & P, jblas::mat const& Jx);
00566
00571 void setup(double beta0 = 0, double beta1 = 0, double sigma_beta = 0.5);
00572
00573
00574 };
00575
00576
00577
00578
00583 class RhoThetaImagePluckerFeatureObserveModel :
00584 public ImagePluckerFeatureObserveModel {
00585
00586 protected:
00587
00589 jblas::vec const& predictObservationInSensorFrame( jblas::vec const& feature_);
00590
00592 void predictObservationInSensorFrameJac( jblas::vec const& feature_);
00593
00594
00597 virtual jblas::vec const& homogeneousToImageModel(jblas::vec3 const& l_);
00598
00601 virtual void homogeneousToImageModelJac(jblas::vec3 const& l_,
00602 jblas::mat& Jl) const;
00603
00604
00609 virtual jblas::vec3 imageModelToHomogeneous(jblas::vec const& rt_);
00610
00615 virtual void imageModelToHomogeneousJac(jblas::vec const& rt_, jblas::vec3& l, jblas::mat& HMrt);
00616
00622 virtual void imageModelToHomogeneousJac(jblas::vec const& rt_, jblas::mat& HMrt);
00623
00624
00625
00626
00627
00628
00629
00630
00631
00634 virtual jblas::vec inverseObservationInSensorFrame(Observation const& obs_);
00635
00638 virtual void inverseObservationInSensorFrameJac(Observation const& obs_);
00639
00640 public:
00641
00642 RhoThetaImagePluckerFeatureObserveModel(SegmentFeatureModel& featureModel_, jafar::camera::CameraPinhole const& camera_);
00643 ~RhoThetaImagePluckerFeatureObserveModel();
00644
00646 virtual jblas::vec const& computeInnovation(jblas::vec const& z_, jblas::vec const& zPred_);
00647
00651 static jblas::vec2 extToImageModel(jblas::vec const& ext1,jblas::vec const& ext2);
00652
00657 static void extToImageModelJac(jblas::vec const& ext1, jblas::vec const& ext2, jblas::mat& J);
00658
00659
00662 virtual void computeSensorR(Observation const& obs);
00663
00664
00665 };
00666
00667
00668
00673 class ScaledHomogeneousImagePluckerFeatureObserveModel :
00674 public ImagePluckerFeatureObserveModel {
00675
00676 protected:
00677
00679 jblas::vec const& predictObservationInSensorFrame( jblas::vec const& feature_);
00680
00682 void predictObservationInSensorFrameJac( jblas::vec const& feature_);
00683
00684
00687 virtual jblas::vec const& homogeneousToImageModel(jblas::vec3 const& l_);
00688
00691 virtual void homogeneousToImageModelJac(jblas::vec3 const& l_,
00692 jblas::mat& Jl) const;
00693
00694
00699 virtual jblas::vec3 imageModelToHomogeneous(jblas::vec const& sh_);
00700
00701
00706 virtual void imageModelToHomogeneousJac(jblas::vec const& sh_,
00707 jblas::vec3& l,
00708 jblas::mat& HM_sh);
00709
00710
00716 virtual void imageModelToHomogeneousJac(jblas::vec const& sh_,
00717 jblas::mat& HM_sh);
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00731 virtual jblas::vec inverseObservationInSensorFrame(Observation const& obs_);
00732
00733
00736 virtual void inverseObservationInSensorFrameJac(Observation const& obs_);
00737
00738 public:
00739
00741 ScaledHomogeneousImagePluckerFeatureObserveModel(SegmentFeatureModel& featureModel_, jafar::camera::CameraPinhole const& camera_);
00742
00744 ~ScaledHomogeneousImagePluckerFeatureObserveModel();
00745
00747 virtual jblas::vec const& computeInnovation(jblas::vec const& z_,
00748 jblas::vec const& zPred_);
00749
00752 virtual void computeSensorR(Observation const& obs);
00753
00754
00758 static jblas::vec3 extToImageModel(jblas::vec const& ext1,
00759 jblas::vec const& ext2);
00760
00761
00766 static jblas::vec3 extToImageModel(jblas::vec const& ext1,
00767 jblas::vec const& ext2,
00768 jblas::vec3 const& ref);
00769
00770
00775 static void extToImageModelJac(jblas::vec const& ext1,
00776 jblas::vec const& ext2,
00777 jblas::mat& H_e);
00778
00784 static void extToImageModelJac(jblas::vec const& ext1,
00785 jblas::vec const& ext2,
00786 jblas::vec3 const& ref,
00787 jblas::mat& HM_e);
00788
00789
00790
00791 };
00792
00793
00798 class StereoImagePluckerFeatureObserveModel : public FeatureObserveModel {
00799
00800 protected:
00801
00802 SegmentFeatureModel& segmentFeatureModel;
00803
00804 jafar::camera::StereoBench stereoBench;
00805
00806 jblas::mat33 Pl;
00807
00808 jblas::mat33 Plinv;
00809
00811 jblas::vec3 planeBaseToDirVector(jblas::vec3 const& an_, jblas::vec2 const& beta_);
00812
00814 void planeBaseToDirVectorJac(jblas::vec_range const& an_, jblas::vec2 const& beta_, jblas::vec_range& b, jblas::mat33& B_a);
00815
00816
00817 boost::tuple<double,double> computeExtremitiesAbscissa(SegmentFeature const& segFeature_,
00818 geom::T3DEuler const& robotPose_,
00819 StereoSegmentObservation const& obs_) const;
00820
00821 void segmentExtremitiesPluckerLines(StereoSegmentObservation const& segObs_,
00822 jblas::vec& lineExt1Sensor,
00823 jblas::vec& lineExt2Sensor) const;
00824
00825 static boost::tuple<double, double, double> pluckerLinesDistance(jblas::vec const& line1_,
00826 jblas::vec const& line2_);
00827
00829 jblas::sym_mat p_pixCov;
00830
00832 double p_dispVar;
00833
00834 jblas::vec const& predictObservationInSensorFrame(const jblas::vec& feature_);
00835
00836 void predictObservationInSensorFrameJac(const jblas::vec& feature_);
00837
00838
00839
00840
00841
00842 void computeSensorRInit(Observation const& obs);
00843
00844 jblas::vec inverseObservationInSensorFrame(Observation const& obs_);
00845
00846 void inverseObservationInSensorFrameJac(Observation const& obs_);
00847
00848 public:
00849 StereoImagePluckerFeatureObserveModel(SegmentFeatureModel& featureModel_, jafar::camera::StereoBench const& stereoBench_);
00850
00851 ~StereoImagePluckerFeatureObserveModel();
00852
00854 Observation::ObservationType typeObs() const {return Observation::SEGMENT_STEREOIMAGE;}
00855
00857 void setPixCov(jblas::vec const& pixCov_, double stabilizingFactor = 1.0);
00858
00860 void setDispVar(double dispVar, double stabilizingFactor = 1.0);
00861
00862
00863
00866 void initInternalState(BaseFeature& feature, jafar::geom::T3DEuler const& robotPose_, Observation const& obs_) const;
00867
00870 void updateInternalState(BaseFeature& feature, jafar::geom::T3DEuler const& robotPose_, Observation const& obs_) const;
00871
00882 void predictExtObs(jblas::vec_range const& pose, jblas::sym_mat_range const& poseCov,
00883 jblas::vec3 const& ext, jblas::sym_mat const& extCov,
00884 jblas::vec& zPredExt, jblas::sym_mat& zPredExtCov);
00890 void predictExtObsJac(jblas::vec_range const& pose, jblas::vec3 const Ext, jblas::vec& eInImage, jblas::mat& JeR, jblas::mat& JeExt);
00891
00893 jblas::vec const& computeInnovation(jblas::vec const& z_,
00894 jblas::vec const& zPred_);
00895
00899 void computeSensorR(Observation const& obs);
00900
00904 jblas::vec2 extToRhoTheta(jblas::vec const& ext1,jblas::vec const& ext2);
00905
00906
00911 void extToRhoThetaJac(jblas::vec const& ext1,jblas::vec const& ext2, jblas::mat& J);
00912
00913
00914 };
00915
00916
00917 }
00918 }
00919
00920
00921 #endif // SLAM_SEGMENT_FEATURE_HPP