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