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