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                                 bool scaling = false;
00111 
00112                                 //Determine coercion for windup
00113                                 switch (type)
00114                                 {
00115                                 case NoAlloc:
00116                                         //noalloc
00117                                         break;
00118                                 case SimpleAlloc:
00119                                         //It is safe to compare these
00120                                         for (int i=0; i<dofs.size(); ++i)
00121                                         {
00122                                                 coercion(dofs[i]) = 0;
00123                                                 if (tauIn(dofs[i])>tauOut(dofs[i]))     coercion(dofs[i])=1;
00124                                                 else if (tauIn(dofs[i])<tauOut(dofs[i]))        coercion(dofs[i])=-1;
00125                                         }
00126                                         break;
00127                                 case ScaleAlloc:
00128 //                                              for (int i=0; i<group_scales.size(); ++i) if ((scaling = (group_scales[i]>1))) break;
00129 //
00130 //                                              if (scaling)
00131 //                                              {
00132 //                                                      for (int i=0; i<dofs.size(); ++i)
00133 //                                                      {
00134 //                                                              if (tauIn(dofs[i])>=tauOut(dofs[i]))    coercion(dofs[i])=1;
00135 //                                                              else if (tauIn(dofs[i])<=tauOut(dofs[i]))       coercion(dofs[i])=-1;
00136 //                                                      }
00137 //                                              }
00138 
00139                                         //Alternative to scaling inspection
00140                                         for (int i=0; i<dofs.size(); ++i)
00141                                         {
00142                                                 coercion(dofs[i]) = 0;
00143                                                 //If there is deviation between input and output we assume
00144                                                 if (fabs(tauIn(dofs[i]) - tauOut(dofs[i])) > 0.01)
00145                                                 {
00146                                                         if (tauIn(dofs[i])>=tauOut(dofs[i]))    coercion(dofs[i])=1;
00147                                                         else if (tauIn(dofs[i])<=tauOut(dofs[i]))       coercion(dofs[i])=-1;
00148                                                 }
00149                                         }
00150                                         break;
00151                                 default:
00152                                         break;
00153                                 }
00154                         }
00155 
00156 
00157                         template <class AllocMatrix, class DOFMatrix, class ThrusterGroups>
00158                         void init(int alloc_type, const AllocMatrix& alloc, const DOFMatrix& use_dofs,
00159                                         const ThrusterGroups& thrust_groups)
00160                         {
00161                                 type = alloc_type;
00162                                 if (type >= 0)
00163                                 {
00164                                         dofs.clear();
00165                                         for (size_t i=0; i<use_dofs.size(); ++i) if (use_dofs(i)) dofs.push_back(i);
00166                                         groups.clear();
00167                                         num_thrusters=0;
00168                                         //Handle the optional group parameter
00169                                         if ((thrust_groups.cols() == 0) || (thrust_groups.rows() == 0))
00170                                         {
00171                                                 //If the table was not specified put all in one group
00172                                                 groups.push_back(std::vector<int>());
00173                                                 for(int i=0; i<alloc.cols(); ++i) groups[0].push_back(i);
00174                                                 num_thrusters=alloc.cols();
00175                                         }
00176                                         else
00177                                         {
00178                                                 //If the table is specified fill the vectors
00179                                                 for (size_t i=0; i<thrust_groups.rows();++i)
00180                                                 {
00181                                                         //For each new row create a new group
00182                                                         groups.push_back(std::vector<int>());
00183                                                         //If thruster in group add it to the list
00184                                                         for (size_t j=0; j<thrust_groups.cols(); ++j)
00185                                                                 if (thrust_groups(i,j))
00186                                                                 {
00187                                                                         ++num_thrusters;
00188                                                                         groups[i].push_back(j);
00189                                                                 }
00190                                                 }
00191                                         }
00192                                         group_scales.resize(groups.size());
00193 
00194                                         this->B=alloc;
00195                                         Binv = B.transpose()*(B*B.transpose()).inverse();
00196                                 }
00197                                 else
00198                                 {
00199                                         type = NoAlloc;
00200                                 };
00201 
00202                                 assert((B.cols() == num_thrusters) &&
00203                                                 "Allocation matrix must have number of columns equal to number of thrusters.");
00204 
00205                                 assert((B.rows() == dofs.size()) &&
00206                                                 "Allocation matrix must have the same number of rows as controllable DOFs.");
00207                         }
00208 
00212                         inline void setThrusterMinMax(double min, double max)
00213                         {
00214                                 this->tmax = max;
00215                                 this->tmin = min;
00216                         }
00217 
00218                         inline const Eigen::VectorXd& getThrusterForces(){return tdes;};
00219 
00220                         inline const Eigen::VectorXi& getCoercion(){return coercion;};
00221 
00222                 protected:
00226                         inline void simple_alloc()
00227                         {
00228                                 for (size_t i=0; i<tdes.rows();++i)
00229                                 {
00230                                         tdes(i)=labust::math::coerce(tdes(i),tmin,tmax);
00231                                 }
00232                         };
00233 
00237                         void scale_alloc()
00238                         {
00239                                 for (size_t i=0; i<groups.size(); ++i)
00240                                 {
00241                                         //ROS_ERROR("Group size %d",groups[i].size());
00242                                         Eigen::VectorXd ttdes(groups[i].size());
00243                                         //Map from vector into group
00244                                         for (size_t j=0; j<groups[i].size(); ++j) ttdes(j)=tdes(groups[i][j]);
00245 
00246                                         //ROS_ERROR("Before: %f %f %f %f",ttdes(0), ttdes(1), ttdes(2), ttdes(3));
00247                                         //Scale inside the group
00248                                         double scale_max = 1;
00249                                         for (size_t j=0; j<ttdes.rows();++j)
00250                                         {
00251                                                 double scale = fabs((ttdes(j)>0)?ttdes(j)/tmax:ttdes(j)/tmin);
00252                                                 if (scale>scale_max) scale_max=scale;
00253                                         }
00254                                         //ROS_ERROR("Scale max: %f",scale_max);
00255                                         group_scales[i] = scale_max;
00256                                         ttdes = ttdes/scale_max;
00257                                         //ROS_ERROR("After: %f %f %f %f",ttdes(0), ttdes(1), ttdes(2), ttdes(3));
00258 
00259                                         //Map from group to final vector
00260                                         for (size_t j=0; j<groups[i].size(); ++j) tdes(groups[i][j])=ttdes(j);
00261                                 }
00262                         }
00263 
00267                         std::vector<int> dofs;
00271                         std::vector< std::vector<int> > groups;
00275                         std::vector<double> group_scales;
00276 
00280                         Eigen::MatrixXd B, Binv;
00284                         double tmax, tmin;
00288                         Eigen::VectorXd tdes;
00292                         Eigen::VectorXi coercion;
00296                         int type, num_thrusters;
00297                 };
00298         }
00299 }
00300 
00301 /* ALLOCATIONMODELS_HPP_ */
00302 #endif


snippets
Author(s): Gyula Nagy
autogenerated on Fri Aug 28 2015 11:22:33