GCOP  1.0
uuv.h
Go to the documentation of this file.
00001 // This file is part of libgcop, a library for Geometric Control, Optimization, and Planning (GCOP)
00002 //
00003 // Copyright (C) 2004-2014 Marin Kobilarov <marin(at)jhu.edu>
00004 //
00005 // This Source Code Form is subject to the terms of the Mozilla
00006 // Public License v. 2.0. If a copy of the MPL was not distributed
00007 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
00008 
00009 #ifndef GCOP_UUV_H
00010 #define GCOP_UUV_H
00011 
00012 #include "system.h"
00013 #include "uuvmanifold.h"
00014 #include "se3.h"
00015 #include <limits>
00016 #include <iostream>
00017 #include <utility>
00018 #include "function.h"
00019 
00020 namespace gcop {
00021   
00022   using namespace std;
00023   using namespace Eigen;
00024   
00025   typedef Matrix<double, 6, 1> Vector6d;
00026   typedef Matrix<double, 6, 6> Matrix6d;
00027   typedef Matrix<double, 12, 12> Matrix12d;
00028   
00035   template <int c = 6> class Uuv : public System<UuvState, 12, c> {
00036     
00037     typedef Matrix<double, c, 1> Vectorcd;
00038     typedef Matrix<double, c, c> Matrixcd;
00039     typedef Matrix<double, 6, c> Matrix6xcd;
00040     typedef Matrix<double, 12, c> Matrix12xcd;
00041     typedef Matrix<double, 12, Dynamic> Matrix12Xd;
00042     
00043   public:
00044     
00045     Uuv();
00046 
00047     virtual ~Uuv();
00048     
00049     double Step(UuvState &xb, double t, const UuvState &xa, 
00050                 const Vectorcd &u, double h, const VectorXd *p = 0,
00051                 Matrix12d *A = 0, Matrix12xcd *B = 0, Matrix12Xd *C = 0);
00052 
00053     double SympStep(double t, UuvState &xb, const UuvState &xa, 
00054                     const Vectorcd &u, double h, const VectorXd *p = 0,
00055                     Matrix12d *A = 0, Matrix12xcd *B = 0, Matrix12Xd *C = 0);
00056     
00057     double EulerStep(double t, UuvState &xb, const UuvState &xa, 
00058                      const Vectorcd &u, double h, const VectorXd *p = 0,
00059                      Matrix12d *A = 0, Matrix12xcd *B = 0, Matrix12Xd *C = 0);    
00060 
00061     static void Compute(Matrix6d &I, double m, const Vector3d &ds);
00062     
00063     Matrix6d I;    
00064 
00065     Vector6d d;    
00066     
00067     Vector3d b;    
00068 
00069     Vector3d fp;   
00070     
00071     Matrix6xcd B; 
00072 
00073     bool symp;     
00074     
00075     string name;   
00076 
00077     Vector3d ds;   
00078 
00079   };  
00080   
00081 
00082   
00083   template <int c> 
00084     Uuv<c>::Uuv() : 
00085     System<UuvState, 12, c>(UuvManifold::Instance()),
00086     I(Matrix6d::Identity()),
00087     d(Vector6d::Zero()),
00088     b(0,0,0),
00089     fp(0,0,0),
00090     B(Matrix<double, 6, c>::Identity()),
00091     symp(true),
00092     ds(1.5,.8,.5) {    
00093     Compute(I, 50, ds);
00094   }
00095   
00096   template<int c>  Uuv<c>::~Uuv()
00097     {
00098     }  
00099 
00100   template <int c>
00101     double Uuv<c>::Step(UuvState &xb, double t, const UuvState &xa, 
00102                            const Matrix<double, c, 1> &u, double h, const VectorXd *p,
00103                            Matrix12d *A, Matrix<double, 12, c> *B, Matrix12Xd *C) {
00104     if (symp)
00105       return SympStep(t, xb, xa, u, h, p, A, B, C);
00106     else
00107       return EulerStep(t, xb, xa, u, h, p, A, B, C);      
00108   }
00109   
00110   template <int c>
00111     double Uuv<c>::SympStep(double t, UuvState &xb, const UuvState &xa, 
00112                             const Matrix<double, c, 1> &u, double h, const VectorXd *p,
00113                             Matrix12d *A, Matrix<double, 12, c> *B, Matrix12Xd *C) {
00114     
00115     SE3 &se3 = SE3::Instance();
00116     
00117     Matrix6d Da, Db;
00118     
00119     // initialize wb
00120     xb.v = xa.v;
00121 
00122     // at this point the following can be iterated more than once
00123 
00124     se3.tln(Da, -h*xa.v);
00125     se3.tln(Db, h*xb.v);
00126 
00127     Vector6d fd = d.array()*(xa.v.array().abs()*xa.v.array() + xb.v.array().abs()*xb.v.array())/2;  // quadratic drag
00128 
00129     const Matrix3d &Ra = xa.g.topLeftCorner<3,3>();
00130 
00131     Vector6d fe;
00132     fe.head<3>() = b.cross(Ra.row(2));  // boyancy force
00133     fe.tail<3>() = Ra.transpose()*fp;  // gravity force
00134 
00135     // dynamic residual
00136     Vector6d e = Db.transpose()*I*xb.v - Da.transpose()*I*xa.v - h*(fd + fe + this->B*u);
00137 
00138     Matrix6d adv;
00139     Matrix6d admu;
00140     se3.ad(adv, xb.v); 
00141     se3.adt(admu, I*xb.v); 
00142 
00143     Vector6d dfd = 2*d.array()*xb.v.array().abs();
00144     Matrix6d De = I - h/2*(adv.transpose()*I + admu + Matrix6d(dfd.asDiagonal()));
00145     
00146     xb.v = xb.v - De.inverse()*e;    
00147 
00148     Matrix4d dg;
00149     se3.cay(dg, xb.v);
00150     xb.g = xa.g*dg;
00151     
00152     return 1;
00153   }
00154 
00155 
00157 
00158   template <int c>
00159     double Uuv<c>::EulerStep(double t, UuvState &xb, const UuvState &xa, 
00160                                 const Matrix<double, c, 1> &u, double h, const VectorXd *p,
00161                                 Matrix12d *A, Matrix<double, 12, c> *B, Matrix12Xd *C) {
00162     return 1;
00163   }
00164 
00165   template <int c> 
00166     void Uuv<c>::Compute(Matrix6d &I, double m, const Vector3d &ds) {
00167     I.setZero();
00168     I(0,0) = m*(ds[1]*ds[1] + ds[2]*ds[2])/3;
00169     I(1,1) = m*(ds[0]*ds[0] + ds[2]*ds[2])/3;
00170     I(2,2) = m*(ds[0]*ds[0] + ds[1]*ds[1])/3;
00171     I(3,3) = m; 
00172     I(4,4) = m;
00173     I(5,5) = m;
00174   }
00175 
00176 
00177 }
00178 #endif