Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
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
00089
00090 switch (type)
00091 {
00092 case NoAlloc:
00093
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
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
00113 switch (type)
00114 {
00115 case NoAlloc:
00116
00117 break;
00118 case SimpleAlloc:
00119
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
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140 for (int i=0; i<dofs.size(); ++i)
00141 {
00142 coercion(dofs[i]) = 0;
00143
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
00169 if ((thrust_groups.cols() == 0) || (thrust_groups.rows() == 0))
00170 {
00171
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
00179 for (size_t i=0; i<thrust_groups.rows();++i)
00180 {
00181
00182 groups.push_back(std::vector<int>());
00183
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
00242 Eigen::VectorXd ttdes(groups[i].size());
00243
00244 for (size_t j=0; j<groups[i].size(); ++j) ttdes(j)=tdes(groups[i][j]);
00245
00246
00247
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
00255 group_scales[i] = scale_max;
00256 ttdes = ttdes/scale_max;
00257
00258
00259
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
00302 #endif