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