ThrustAllocation.hpp
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: 06.03.2013.
00036  *********************************************************************/
00037 #ifndef THRUSTALLOCATION_HPP_
00038 #define THRUSTALLOCATION_HPP_
00039 #include <labust/simulation/matrixfwd.hpp>
00040 #include <labust/math/NumberManipulation.hpp>
00041 
00042 #include <vector>
00043 #include <ros/ros.h>
00044 
00045 namespace labust
00046 {
00047         namespace vehicles
00048         {
00059                 class ThrustAllocator
00060                 {
00061                         enum {NoAlloc=0,SimpleAlloc=1, ScaleAlloc=2};
00062                 public:
00066                         ThrustAllocator():
00067                                 dofs(6,1),
00068                                 groups(1,dofs),
00069                                 B(labust::simulation::matrix::Identity()),
00070                                 Binv(B),
00071                                 tmax(1),
00072                                 tmin(-tmax),
00073                                 coercion(Eigen::VectorXi::Zero(6)),
00074                                 type(NoAlloc),
00075                                 num_thrusters(6){};
00076 
00080                         void allocate(const labust::simulation::vector& tauIn,
00081                                         labust::simulation::vector& tauOut)
00082                         {
00083                                 Eigen::VectorXd vi(dofs.size());
00084                                 for (int i=0; i<dofs.size(); ++i) vi(i)=tauIn(dofs[i]);
00085 
00086                                 tdes = Binv*vi;
00087 
00088                                 //ROS_ERROR("Before tdes: %f %f %f %f",tdes(0), tdes(1), tdes(2), tdes(3));
00089 
00090                                 switch (type)
00091                                 {
00092                                 case NoAlloc:
00093                                         //noalloc
00094                                         break;
00095                                 case SimpleAlloc:
00096                                         simple_alloc();
00097                                         break;
00098                                 case ScaleAlloc:
00099                                         scale_alloc();
00100                                         break;
00101                                 default:
00102                                         throw std::runtime_error("ThrustAllocator: Undefined allocation type.");
00103                                 }
00104 
00105                                 //ROS_ERROR("Forces %f %f %f",tdes(0), tdes(1), tdes(2), tdes(3));
00106                                 vi = B*tdes;
00107 
00108                                 for (int i=0; i<dofs.size(); ++i) tauOut(dofs[i])=vi(i);
00109 
00110                                 //Determine coercion for windup
00111                                 switch (type)
00112                                 {
00113                                 case NoAlloc:
00114                                         //noalloc
00115                                         break;
00116                                 case SimpleAlloc:
00117                                         //It is safe to compare these
00118                                         for (int i=0; i<dofs.size(); ++i)
00119                                         {
00120                                                 coercion(dofs[i]) = 0;
00121                                                 if (tauIn(dofs[i])>tauOut(dofs[i]))     coercion(dofs[i])=1;
00122                                                 else if (tauIn(dofs[i])<tauOut(dofs[i]))        coercion(dofs[i])=-1;
00123                                         }
00124                                         break;
00125                                 case ScaleAlloc:
00126                                         //                                              bool scaling;
00127                                         //                                              for (int i=0; i<group_scales.size(); ++i) if ((scaling = (group_scales[i]>1))) break;
00128                                         //                                              if (scaling)
00129                                         //                                              {
00130                                         //                                                      for (int i=0; i<dofs.size(); ++i)
00131                                         //                                                      {
00132                                         //                                                              if (tauIn(dofs[i])>tauOut(dofs[i]))     coercion(dofs[i])=1;
00133                                         //                                                              else if (tauIn(dofs[i])<tauOut(dofs[i]))        coercion(dofs[i])=-1;
00134                                         //                                                      }
00135                                         //                                              }
00136 
00137                                         //Alternative to scaling inspection
00138                                         for (int i=0; i<dofs.size(); ++i)
00139                                         {
00140                                                 coercion(dofs[i]) = 0;
00141                                                 //If there is deviation between input and output we assume
00142                                                 if (fabs(tauIn(dofs[i]) - tauOut(dofs[i])) > 0.01)
00143                                                 {
00144                                                         if (tauIn(dofs[i])>tauOut(dofs[i]))     coercion(dofs[i])=1;
00145                                                         else if (tauIn(dofs[i])<tauOut(dofs[i]))        coercion(dofs[i])=-1;
00146                                                 }
00147                                         }
00148                                         break;
00149                                 default:
00150                                         break;
00151                                 }
00152                         }
00153 
00154 
00155                         template <class AllocMatrix, class DOFMatrix, class ThrusterGroups>
00156                         void init(int alloc_type, const AllocMatrix& alloc, const DOFMatrix& use_dofs,
00157                                         const ThrusterGroups& thrust_groups)
00158                         {
00159                                 type = alloc_type;
00160                                 if (type >= 0)
00161                                 {
00162                                         dofs.clear();
00163                                         for (size_t i=0; i<use_dofs.size(); ++i) if (use_dofs(i)) dofs.push_back(i);
00164                                         groups.clear();
00165                                         num_thrusters=0;
00166                                         //Handle the optional group parameter
00167                                         if ((thrust_groups.cols() == 0) || (thrust_groups.rows() == 0))
00168                                         {
00169                                                 //If the table was not specified put all in one group
00170                                                 groups.push_back(std::vector<int>());
00171                                                 for(int i=0; i<alloc.cols(); ++i) groups[0].push_back(i);
00172                                                 num_thrusters=alloc.cols();
00173                                         }
00174                                         else
00175                                         {
00176                                                 //If the table is specified fill the vectors
00177                                                 for (size_t i=0; i<thrust_groups.rows();++i)
00178                                                 {
00179                                                         //For each new row create a new group
00180                                                         groups.push_back(std::vector<int>());
00181                                                         //If thruster in group add it to the list
00182                                                         for (size_t j=0; j<thrust_groups.cols(); ++j)
00183                                                                 if (thrust_groups(i,j))
00184                                                                 {
00185                                                                         ++num_thrusters;
00186                                                                         groups[i].push_back(j);
00187                                                                 }
00188                                                 }
00189                                         }
00190                                         group_scales.resize(groups.size());
00191 
00192                                         this->B=alloc;
00193                                         Binv = B.transpose()*(B*B.transpose()).inverse();
00194                                 }
00195                                 else
00196                                 {
00197                                         type = NoAlloc;
00198                                 };
00199 
00200                                 assert((B.cols() == num_thrusters) &&
00201                                                 "Allocation matrix must have number of columns equal to number of thrusters.");
00202 
00203                                 assert((B.rows() == dofs.size()) &&
00204                                                 "Allocation matrix must have the same number of rows as controllable DOFs.");
00205                         }
00206 
00210                         inline void setThrusterMinMax(double min, double max)
00211                         {
00212                                 this->tmax = max;
00213                                 this->tmin = min;
00214                         }
00215 
00216                         inline const Eigen::VectorXd& getThrusterForces(){return tdes;};
00217 
00218                         inline const Eigen::VectorXi& getCoercion(){return coercion;};
00219 
00220                 protected:
00224                         inline void simple_alloc()
00225                         {
00226                                 for (size_t i=0; i<tdes.rows();++i)
00227                                 {
00228                                         tdes(i)=labust::math::coerce(tdes(i),tmin,tmax);
00229                                 }
00230                         };
00231 
00235                         void scale_alloc()
00236                         {
00237                                 for (size_t i=0; i<groups.size(); ++i)
00238                                 {
00239                                         //ROS_ERROR("Group size %d",groups[i].size());
00240                                         Eigen::VectorXd ttdes(groups[i].size());
00241                                         //Map from vector into group
00242                                         for (size_t j=0; j<groups[i].size(); ++j) ttdes(j)=tdes(groups[i][j]);
00243 
00244                                         //ROS_ERROR("Before: %f %f %f %f",ttdes(0), ttdes(1), ttdes(2), ttdes(3));
00245                                         //Scale inside the group
00246                                         double scale_max = 1;
00247                                         for (size_t j=0; j<ttdes.rows();++j)
00248                                         {
00249                                                 double scale = fabs((ttdes(j)>0)?ttdes(j)/tmax:ttdes(j)/tmin);
00250                                                 if (scale>scale_max) scale_max=scale;
00251                                         }
00252                                         //ROS_ERROR("Scale max: %f",scale_max);
00253                                         group_scales[i] = scale_max;
00254                                         ttdes = ttdes/scale_max;
00255                                         //ROS_ERROR("After: %f %f %f %f",ttdes(0), ttdes(1), ttdes(2), ttdes(3));
00256 
00257                                         //Map from group to final vector
00258                                         for (size_t j=0; j<groups[i].size(); ++j) tdes(groups[i][j])=ttdes(j);
00259                                 }
00260                         }
00261 
00265                         std::vector<int> dofs;
00269                         std::vector< std::vector<int> > groups;
00273                         std::vector<double> group_scales;
00274 
00278                         Eigen::MatrixXd B, Binv;
00282                         double tmax, tmin;
00286                         Eigen::VectorXd tdes;
00290                         Eigen::VectorXi coercion;
00294                         int type, num_thrusters;
00295                 };
00296         }
00297 }
00298 
00299 /* ALLOCATIONMODELS_HPP_ */
00300 #endif


snippets
Author(s): Gyula Nagy
autogenerated on Mon Oct 6 2014 01:39:41