GCOP  1.0
body2d.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_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