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_BODY2D_H 00010 #define GCOP_BODY2D_H 00011 00012 #include "system.h" 00013 #include <utility> 00014 #include "body2dforce.h" 00015 #include "body2dmanifold.h" 00016 #include "se2.h" 00017 #include "rn.h" 00018 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, 6, 3> Matrix63d; 00028 typedef Matrix<double, 3, 6> Matrix36d; 00029 00030 typedef pair<Matrix3d, Vector3d> Body2dState; 00031 00042 template<int c = 3> 00043 class Body2d : public System<Body2dState, 6, c> { 00044 public: 00045 00046 typedef Matrix<double, c, 1> Vectorcd; 00047 typedef Matrix<double, 6, c> Matrix6cd; 00048 typedef Matrix<double, 3, c> Matrix3cd; 00049 00050 Body2d(Body2dForce<c> *f = 0); 00051 00052 double Step(Body2dState &xb, double t, const Body2dState &xa, 00053 const Vectorcd &u, double h, const VectorXd *p = 0, 00054 Matrix6d *A = 0, Matrix6cd *B = 0, Matrix<double, 6, Dynamic> *C = 0); 00055 00056 Vector2d d; 00057 Vector3d I; 00058 00059 Body2dForce<c> *force; 00060 00061 }; 00062 00063 template<int c> 00064 Body2d<c>::Body2d(Body2dForce<c> *force) : 00065 System<Body2dState, 6, c>(Body2dManifold::Instance()), 00066 d(1, .3), I(.3,10,10), force(force) 00067 { 00068 } 00069 00070 template<int c> 00071 double Body2d<c>::Step(Body2dState& xb, double t, const Body2dState& xa, 00072 const Vectorcd& u, double h, const VectorXd* p, 00073 Matrix6d *A, Matrix6cd *B, Matrix<double, 6, Dynamic> *C) { 00074 Matrix36d fx; // force Jacobian with respect to x 00075 Matrix3cd fu; // force Jacobian with respect to u 00076 Matrix<double, 3, Dynamic> fp; // force Jacobian with respect to p 00077 00078 if (p && C) 00079 fp.resize(3, p->size()); 00080 00081 if (force) { 00082 Vector3d f; 00083 force->Set(f, xa, t, u, h, p, 00084 A ? &fx : 0, 00085 B ? &fu : 0, 00086 C ? &fp : 0); 00087 xb.second = xa.second + h*f; 00088 } else { 00089 xb.second = xa.second; 00090 } 00091 00092 Vector3d hxib = h*xb.second; 00093 00094 SE2 &se2 = SE2::Instance(); 00095 00096 Matrix3d dg; 00097 00098 se2.cay(dg, hxib); 00099 xb.first = xa.first*dg; 00100 00101 if (A) { 00102 se2.cay(dg, -hxib); 00103 Matrix3d Adm; 00104 se2.Ad(Adm, dg); 00105 A->topLeftCorner<3,3>() = Adm; 00106 se2.dcay(dg, -hxib); 00107 A->topRightCorner<3,3>() = h*dg; 00108 if (force) { 00109 A->bottomRows<3>() = h*fx; 00110 } 00111 A->bottomRightCorner<3,3>() += Matrix3d::Identity(); 00112 } 00113 00114 if (B) { 00115 // A should've been called too 00116 assert(A); 00117 00118 B->topRows(3) = (h*h)*(dg*fu); 00119 // B->bottomRows(3) = (Vector3d(h, h, h).cwiseQuotient(I)).asDiagonal()*fu; 00120 B->bottomRows(3) = h*fu; 00121 00122 } 00123 00124 if (C) { 00125 if (p) { 00126 assert(C->cols() == p->size() && C->rows() == 6); 00127 } 00128 if (force) { 00129 assert(A); 00130 C->topRows<3>() = (h*h)*(dg*fp); 00131 C->bottomRows<3>() = (Vector3d(h, h, h).cwiseQuotient(I)).asDiagonal()*fp; 00132 } else { 00133 C->setZero(); 00134 } 00135 } 00136 00137 return 1; 00138 } 00139 00140 00141 } 00142 00143 00144 #endif