GCOP
1.0
|
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