GCOP  1.0
kinbodyprojtrack.h
Go to the documentation of this file.
00001 #ifndef GCOP_KINBODYPROJTRACK_H
00002 #define GCOP_KINBODYPROJTRACK_H
00003 
00004 #include <Eigen/Dense>
00005 #include <vector>
00006 #include <type_traits>
00007 #include "kinbody3d.h"
00008 #include "kinbody3dtrack.h"
00009 
00010 namespace gcop {
00011   
00012   using namespace std;
00013   using namespace Eigen;
00014 
00015   
00021   template <int _nu = 6>
00022   class KinbodyProjTrack : public Kinbody3dTrack<_nu> {
00023   public:
00024     typedef Matrix<double, _nu, 1> Vectorud;
00025     typedef Matrix<double, 6, _nu> Matrix6ud;
00026     typedef Matrix<double, 6, 6> Matrix6d;
00027     
00039     KinbodyProjTrack(Kinbody3d<_nu> &sys, int nf, double vd0, double t0, double tf,
00040                 double r = 25,
00041                 bool extforce = false,
00042                 bool forces = false);
00043 
00044     virtual void Get(Matrix4d &x, double vd, double t) const;
00045 
00046     virtual void MakeTrue();
00047 
00048     virtual void Add(const Vectorud &u, const Matrix4d &x, double h);
00049 
00056     virtual void Add2(const Vectorud &u, const Matrix4d &x, double h);
00057   };
00058 
00059 template <int _nu>
00060 KinbodyProjTrack<_nu>::KinbodyProjTrack(Kinbody3d<_nu> &sys, int nf, double vd0, double t0, double tf,
00061                          double r,
00062                          bool extforce,
00063                          bool forces) : 
00064   Kinbody3dTrack<_nu>(sys, nf, vd0, t0, tf, r, extforce, forces)
00065 {
00066   Matrix4d x;
00067   Get(x, vd0, t0);
00068   this->xs.clear();
00069   this->xos.clear();
00070   this->xs.push_back(x);
00071   this->xos.push_back(x);
00072 }
00073 
00074 
00075 template <int _nu>
00076 void KinbodyProjTrack<_nu>::Add(const Vectorud &u, const Matrix4d &x, double h)
00077 {
00078   // add noisy controls/state to list, but use true controls/state for generating measurements
00079   Eigen::Matrix4d xn;
00080   double t = this->ts.back();
00081   
00082   Vectorud un;
00083   // noisy controls
00084   for(int i = 0; i < u.size(); i++)
00085   {
00086     un[i] = u[i] + sqrt(this->cw[i])*random_normal();
00087   }
00088 
00089   this->sys.Step(xn, t, this->xs.back(), un, h);
00090   this->us.push_back(un);
00091   this->xs.push_back(xn);
00092   this->ts.push_back(t + h);
00093 
00094   this->sys.Step(xn, t, this->xos.back(), un, h);
00095   this->xos.push_back(xn);
00096   this->uos.push_back(u);
00097   
00098   // time-stage 
00099   int k = this->xs.size()-1;
00100 
00101   const Matrix3d &R = x.block<3,3>(0,0);
00102   const Vector3d &px = x.block<3,1>(0,3);
00103   
00104   this->Is.resize(this->Is.size()+1);
00105   assert(k == this->Is.size()-1);
00106 
00107   for (int l = 0; l < this->ls.size(); ++l) {
00108     const Vector3d &pf = this->ls[l];
00109     //p.segment<2>(2*extforce + 2*l);
00110     
00111     double d = (px - pf).norm();
00112     if (d < this->dmax) {
00113       Vector3d z = R.transpose()*(pf - px);
00114       z /= z.norm();
00115       z(0) += sqrt(this->cp)*random_normal();
00116       z(1) += sqrt(this->cp)*random_normal();
00117       z(2) += sqrt(this->cp)*random_normal();
00118       z /= z.norm();
00119 
00120       // add to feature vector if not observed
00121       if (!this->observed[l]) {
00122         if (!this->init) {
00123           this->p.resize(3);
00124           this->init= true;
00125         } else {
00126           this->p.conservativeResize(this->p.size() + 3);
00127         }
00128         const Matrix3d &Rn = this->xs.back().block(0,0,3,3);
00129         const Vector3d &pxn = this->xs.back().block(0,3,3,1);
00130          
00131         // Initialize landmark position from estimated state
00132         this->p.tail(3) = Rn*this->dmax*z + pxn;
00133         this->pis.push_back(l);
00134         this->observed[l] = true;
00135         this->cis[l] = this->p.size()/3-1;
00136       }
00137 
00138       //        zs[k].push_back();      // add feature l to pose k
00139       
00140       this->Is[k].push_back(make_pair(l, z)); // add feature l to pose k      
00141       this->Js[l].push_back(make_pair(k, z)); // add pose k to feature l
00142       
00143       //        cout << "k=" << k << " l=" << l << " d=" << d << endl;
00144     }
00145   }
00146 }
00147 
00148 
00149 // add commanded control u, after which true noisy state x occured
00150 template <int _nu>
00151 void KinbodyProjTrack<_nu>::Add2(const Vectorud &u, const Matrix4d &x, double h)
00152 {
00153   // add noisy controls/state to list, but use true controls/state for generating measurements
00154   Eigen::Matrix4d xn;
00155   double t = this->ts.back();
00156   
00157 
00158   this->sys.Step(xn, t, this->xs.back(), u, h);
00159   this->us.push_back(u);
00160   this->xs.push_back(xn);
00161   this->ts.push_back(t + h);
00162 
00163   this->sys.Step(xn, t, this->xos.back(), u, h);
00164   this->xos.push_back(xn);
00165   this->uos.push_back(u);
00166   
00167   // time-stage 
00168   int k = this->xs.size()-1;
00169 
00170   /*
00171   sys.force->fext << 0, .5, 0;
00172   if (extforce) {
00173     p.head<2>() << .5, 0;
00174   }
00175   */
00176   
00177   /* // add noise
00178   for (int k = 0; k < N; ++k) {
00179     double t = k*h;
00180     Get(xs[k+1], r, vd, t+h);
00181     Vector3d f;
00182     us[k] = sys.I.cwiseProduct(xs[k+1].second - xs[k].second)/h + sys.force->D.cwiseProduct(xs[k].second);
00183     // add the constant external force
00184     us[k].tail<2>() -= xs[k].first.topLeftCorner<2,2>().transpose()*sys.force->fext.tail<2>();
00185   }
00186   */
00187 
00188   //  srand (time(NULL));
00189   
00190   const Matrix3d &R = x.block<3,3>(0,0);
00191   const Vector3d &px = x.block<3,1>(0,3);
00192   
00193   this->Is.resize(this->Is.size()+1);
00194   assert(k == this->Is.size()-1);
00195 
00196   for (int l = 0; l < this->ls.size(); ++l) {
00197     const Vector3d &pf = this->ls[l];
00198     //p.segment<2>(2*extforce + 2*l);
00199     
00200     double d = (px - pf).norm();
00201     if (d < this->dmax) {
00202 
00203       Vector3d z = R.transpose()*(pf - px);
00204       z /= z.norm();
00205       z(0) += sqrt(this->cp)*random_normal();
00206       z(1) += sqrt(this->cp)*random_normal();
00207       z(2) += sqrt(this->cp)*random_normal();
00208       z /= z.norm();
00209       
00210       // add to feature vector if not observed
00211       if (!this->observed[l]) {
00212         if (!this->init) {
00213           this->p.resize(3);
00214           this->init= true;
00215         } else {
00216           this->p.conservativeResize(this->p.size() + 3);
00217         }
00218         const Matrix3d &Rn = this->xs.back().block(0,0,3,3);
00219         const Vector3d &pxn = this->xs.back().block(0,3,3,1);
00220          
00221         // Initialize landmark position from estimated state
00222         this->p.tail(3) = Rn*this->dmax*z + pxn;
00223         // Initialize landmark position with its true position
00224         //p.tail<3>() = pf;
00225         this->pis.push_back(l);
00226         this->observed[l] = true;
00227         this->cis[l] = this->p.size()/3-1;
00228       }
00229       
00230       this->Is[k].push_back(make_pair(l, z)); // add feature l to pose k      
00231       this->Js[l].push_back(make_pair(k, z)); // add pose k to feature l
00232       
00233       //        cout << "k=" << k << " l=" << l << " d=" << d << endl;
00234     }
00235   }
00236 }
00237 
00238 
00239 // Makes the ground truth features to be observed
00240 template <int _nu>
00241 void KinbodyProjTrack<_nu>::MakeTrue()
00242 {
00243   //  srand (time(NULL));
00244   //  int nf = (p.size() - extforce*2)/2;
00245   int i = 0;  
00246   int bound = 40;
00247   for (int l =0; l < this->ls.size();) {
00248     //double a = RND*bound;
00249     double a = RND*2*M_PI;
00250     if (a> 0.2 + M_PI && a<0.2 + 1.5*M_PI || a>0.2 && a<0.2 + 0.5*M_PI)
00251       continue;
00252     double z = (RND-0.5)*1.5*this->h;
00253     double r_rand = 3*this->w*(RND-0.5) + this->r; 
00254     this->ls[l] = Vector3d(r_rand*cos(a), r_rand*sin(a), z);
00255     //ls[l] = Vector3d(a-bound/2., 5+z, z);
00256     ++l;
00257   }
00258 }
00259 
00260 
00261 // Get the desired state on the track for some time t
00262 template <int _nu>
00263 void KinbodyProjTrack<_nu>::Get(Matrix4d &x, double vd, double t) const
00264 {
00265   double a = 1.3*2*M_PI*t/this->tf;
00266   //double a = 20*t/tf;
00267   x.setIdentity();
00268   
00269   x(0,0) = cos(a+M_PI/2.); x(0,1) = -sin(a+M_PI/2.);
00270   x(1,0) = sin(a+M_PI/2.); x(1,1) = cos(a+M_PI/2.);
00271  
00272   x(0,3) = this->r*cos(a); x(1,3) = this->r*sin(a); x(2,3) = 0;
00273   
00274   //x(0,3) = 3*a;
00275 }
00276 }
00277 
00278 #endif