RBModel.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Copyright (c) 2010, LABUST, UNIZG-FER
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  *
00011  *   * Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *   * Redistributions in binary form must reproduce the above
00014  *     copyright notice, this list of conditions and the following
00015  *     disclaimer in the documentation and/or other materials provided
00016  *     with the distribution.
00017  *   * Neither the name of the LABUST nor the names of its
00018  *     contributors may be used to endorse or promote products derived
00019  *     from this software without specific prior written permission.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  *  POSSIBILITY OF SUCH DAMAGE.
00033  *
00034  *  Author: Dula Nad
00035  *  Created: 01.02.2010.
00036  *********************************************************************/
00037 #include <labust/simulation/RBModel.hpp>
00038 #include <labust/math/NumberManipulation.hpp>
00039 
00040 using namespace labust::simulation;
00041 
00042 RBModel::RBModel():
00043     ae(0.15),be(0.2),ce(0.2),
00044     B(0),
00045     dT(0.1),
00046     waterLevel(0),
00047     nu0(vector::Zero()),
00048     eta0(vector::Zero()),
00049     nu(vector::Zero()),
00050     eta(vector::Zero()),
00051     g(vector::Zero()),
00052     isCoupled(false),
00053     current(vector3::Zero())
00054         {this->init();};
00055 
00056 RBModel::~RBModel(){};
00057 
00058 void RBModel::calculate_mrb()
00059 {
00060         using namespace labust::math;
00061         Mrb.block<3,3>(0,0) = m*matrix3::Identity();
00062         Mrb.block<3,3>(0,3) = -m*skewSymm3(rg);
00063         Mrb.block<3,3>(3,0) = -m*skewSymm3(rg);
00064         Mrb.block<3,3>(3,3) = Io;
00065 }
00066 
00067 void RBModel::step(const vector& tau)
00068 {
00069         //Assemble the linear and angluar velocity transformation matrices
00070         using namespace Eigen;
00071         matrix3 J1;
00072         J1 = AngleAxisd(eta(psi), Vector3d::UnitZ())
00073                         * AngleAxisd(eta(theta), Vector3d::UnitY())
00074                         * AngleAxisd(eta(phi), Vector3d::UnitX());
00075         double c1 = cos(eta(phi)), s1 = sin(eta(phi));
00076         double c2 = cos(eta(theta)), t2 = tan(eta(theta));
00077         if (!c2) c2 = 0.1;
00078         matrix3 J2;
00079         J2<<1,s1*t2,c1*t2,
00080                         0,c1,-s1,
00081                         0,s1/c2,c1/c2;
00082         //Calculate restoring forces
00083         restoring_force(J1);
00084 
00085         matrix M = Ma + Mrb;
00086         vector nu_old(nu);
00087         if (isCoupled)
00088         {
00089                 //Assemble coriolis
00090                 coriolis();
00091                 //Calculate the absolute values of the speed
00092                 matrix CD = Ca + Crb + Dlin + Dquad*nu.cwiseAbs2().asDiagonal();
00093                 FullPivLU<matrix> decomp(M+dT*CD);
00094                 if (decomp.isInvertible())
00095                 {
00096                         //Backward propagation model
00097                         nu = decomp.inverse()*(M*nu + dT*(tau-g));
00098                 }
00099                 else
00100                 {
00101                         std::cerr<<"Mass matrix is singular."<<std::endl;
00102                 }
00103         }
00104         else
00105         {
00106                 //Simplification for uncoupled
00107                 for (size_t i=0; i<nu.size(); ++i)
00108                 {
00109                         double beta = Dlin(i,i) + Dquad(i,i)*fabs(nu(i));
00110                         //Backward propagation model
00111                         nu(i) = (M(i,i)*nu(i) + dT*(tau(i)- g(i)))/(M(i,i) + dT*beta);
00112                 };
00113         }
00114         nuacc = (nu - nu_old)/dT;
00115 
00116         //From body to world coordinates
00117         eta.block<3,1>(0,0) += dT*(J1*nu.block<3,1>(0,0)+current);
00118         eta.block<3,1>(3,0) += dT*J2*nu.block<3,1>(3,0);
00119 }
00120 
00121 void RBModel::coriolis()
00122 {
00123         using namespace labust::math;
00124         //We assume that Mrb and Ma matrices are set
00125         vector3 nu1 = nu.block<3,1>(0,0);
00126         vector3 nu2 = nu.block<3,1>(3,0);
00127 
00128         Crb.block<3,3>(0,3) = -m*skewSymm3(nu1) - m*skewSymm3(nu2)*skewSymm3(rg);
00129         Crb.block<3,3>(3,0) = -m*skewSymm3(nu1) + m*skewSymm3(rg)*skewSymm3(nu2);
00130         Crb.block<3,3>(3,3) = -skewSymm3(Io*nu2);
00131 
00132         matrix3 M11=Ma.block<3,3>(0,0);
00133         matrix3 M12=Ma.block<3,3>(0,3);
00134         matrix3 M21=Ma.block<3,3>(3,0);
00135         matrix3 M22=Ma.block<3,3>(3,3);
00136 
00137         Ca.block<3,3>(0,3) = -skewSymm3(M11*nu1 + M12*nu2);
00138         Ca.block<3,3>(3,0) = -skewSymm3(M11*nu1 + M21*nu2);
00139         Ca.block<3,3>(3,3) = -skewSymm3(M21*nu1 + M22*nu2);
00140 }
00141 
00142 void RBModel::restoring_force(const matrix3& J1)
00143 {
00144         matrix3 invJ1;
00145         invJ1=J1.inverse();
00146 
00147         //Update the lift force
00148         //Currently a simple model
00149         B=2*labust::math::coerce((eta(z)+waterLevel+rb(z)/2)/ce+1,0,2)*M_PI/3*ae*be*ce*rho*g_acc;
00150 
00151         vector3 fg = invJ1*(m*g_acc*vector3::UnitZ());
00152         vector3 fb = -invJ1*(B*vector3::UnitZ());
00153 
00154         g.block<3,1>(0,0) = -fg-fb;
00155         g.block<3,1>(3,0) = -skewSymm3(rg)*fg-skewSymm3(rb)*fb;
00156 }


labust_sim
Author(s): Gyula Nagy
autogenerated on Fri Feb 7 2014 11:36:33