StandardMassEstimator.cpp
Go to the documentation of this file.
00001 /*
00002  * StandardMassEstimator.cpp
00003  *
00004  *  Created on: Oct 27, 2011
00005  *      Author: mriedel
00006  */
00007 
00008 #include "StandardMassEstimator.hpp"
00009 
00010 #include <tk_draft_msgs/MassStamped.h>
00011 #include <telekyb_base/ROS.hpp>
00012 
00013 #include <pluginlib/class_list_macros.h>
00014 
00015 PLUGINLIB_DECLARE_CLASS(tk_param_estimator, StandardMassEstimator, TELEKYB_NAMESPACE::StandardMassEstimator, TELEKYB_NAMESPACE::MassEstimator);
00016 
00017 namespace TELEKYB_NAMESPACE {
00018 
00019 // Options
00020 StandardMassEstimOptions::StandardMassEstimOptions()
00021         : OptionContainer("StandardMassEstim")
00022 {
00023         tInitialMass = addOption<double>("tInitialMass","Mass of UAV in kg", 0.8, false, true);
00024 
00025         tAFiltCoeff = addOption<double>("tAFiltCoeff","Mass Estimation: Determines the speed of convergence", 0.2,false,true);/*a*/
00026         tLambdaZeroGain = addOption<double>("tLambdaZeroGain","Mass Estimation: Lambda Zero gain", 1.0,false,true);
00027         tKappaZeroGain = addOption<double>("tKappaZeroGain","Mass Estimation: Kappa Zero gain", 1.0,false,true);
00028         tSampleTime = addOption<double>("tSampleTime","Mass Estimation: SamplingTime", 0.008,false,true);
00029 
00030         tMaxMass = addOption<double>("tMaxMass","Mass Estimation: Maximum mass", 1.8,false,true);
00031         tMinMass = addOption<double>("tMinMass","Mass Estimation: Minimum mass", 0.5,false,true);
00032 
00033         tGravity = addOption<double>("tGravity","Mass Estimation: Intial Value for Gravity", 9.81, false, true);
00034 
00035         tPublishMass = addOption<bool>("tPublishMass","Specifies if the estimated mass must be published", false, false, true);
00036         tMassTopic = addOption<std::string>("tMassTopic","Specifies the topic for publishing the mass", "EstimatedMass", false, true);
00037 
00038 }
00039 
00040 StandardMassEstimator::StandardMassEstimator():
00041                 nodeHandle( ROSModule::Instance().getMainNodeHandle() )
00042 {
00043 
00044 }
00045 
00046 
00047 void StandardMassEstimator::initialize()
00048 {
00049         if (options.tPublishMass){
00050                 massPub = nodeHandle.advertise<tk_draft_msgs::MassStamped>(options.tMassTopic->getValue(), 1);
00051         }
00052 
00053         estInvMass = 1.0 / options.tInitialMass->getValue();
00054         estGain = options.tKappaZeroGain->getValue();
00055 
00056 //      _integratorInitInvMass = _estInvMass;
00057 //      _integratorInitGain = _estGain;
00058         integInitialInvMass = estInvMass;
00059         integInitialGain = estGain;
00060 
00061 //      double a = _options.aFiltCoeff->getValue();
00062 //      double samplTime = _options.samplTime->getValue();
00063         double a = options.tAFiltCoeff->getValue();
00064         double samplTime = options.tSampleTime->getValue();
00065 
00066         std::vector<double> num(2);
00067         std::vector<double> den(1);
00068 
00069         num[0] = a * samplTime / (2.0 + a * samplTime);
00070         num[1] = a * samplTime / (2.0 + a * samplTime);
00071         den[0] = (a * samplTime - 2.0) / (2.0 + a * samplTime);
00072 
00073         //      _filters.resize(3);
00074         //      for (int i=0; i<3;i++){
00075         //              _filters[i] = new IIRFilter(num,den);
00076         //      }
00077 
00078         // create Filters
00079         thrustFilter = new IIRFilter(num,den);
00080         vertVelFilter = new IIRFilter(num,den);
00081         gravityFilter = new IIRFilter(num,den);
00082 
00083         num[0] = 0.5 * samplTime;
00084         num[1] = 0.5 * samplTime;
00085         den[0] = -1.0;
00086 //      _integrators.resize(2);
00087 //      for (int i=0; i<2;i++){
00088 //              _integrators[i] = new IIRFilter(num,den);
00089 //      }
00090 
00091         estInvMassIntegrator = new IIRFilter(num,den);
00092         estGainIntegrator = new IIRFilter(num,den);
00093 
00094 
00095 //      if (LOG_FILE){
00096 //              _logMassEst=fopen("logMassEst.txt", "w");
00097 //      }else
00098 //              _logMassEst=0;
00099 }
00100 
00101 void StandardMassEstimator::destroy()
00102 {
00103         delete thrustFilter;
00104         delete vertVelFilter;
00105         delete gravityFilter;
00106         delete estInvMassIntegrator;
00107         delete estGainIntegrator;
00108 }
00109 
00110 std::string StandardMassEstimator::getName() const
00111 {
00112         return "StandardMassEstimator";
00113 }
00114 
00115 StandardMassEstimator::~StandardMassEstimator()
00116 {
00117 
00118 }
00119 
00120 void StandardMassEstimator::run(const MassEstimInput& in,MassEstimOutput& out)
00121 {
00122         double a = options.tAFiltCoeff->getValue();
00123 
00124         std::vector<double> input(1);
00125         input[0] = in.thrust * cos(in.roll) * cos(in.pitch);
00126         double filtThrust;
00127         thrustFilter->step(input,filtThrust);
00128 
00129 //      if (_logMassEst)
00130 //              fprintf(_logMassEst, "%f %f ", input[0], filtThrust);
00131 
00132         input[0] = in.vertVel;
00133         double filtVertVel;
00134         vertVelFilter->step(input,filtVertVel);
00135 
00136 //      if (_logMassEst)
00137 //              fprintf(_logMassEst, "%f %f ", input[0], filtVertVel);
00138 
00139         input[0] = options.tGravity->getValue();
00140         double filtGrav;
00141         gravityFilter->step(input,filtGrav);
00142 
00143 //      if (_logMassEst)
00144 //              fprintf(_logMassEst, "%f %f ", input[0], filtGrav);
00145 
00146         double w = filtThrust;
00147 
00148         double y = a*( in.vertVel - filtVertVel)  - filtGrav;
00149 
00150         double yHat = w * estInvMass;
00151 
00152         double e = y-yHat;
00153 
00154         double lambda = options.tLambdaZeroGain->getValue()*(1 - fabs(estGain)/options.tKappaZeroGain->getValue());
00155 
00156         input[0] = estGain*w*e;
00157 
00158         estInvMassIntegrator->step(input,estInvMass);
00159         estInvMass += integInitialInvMass;
00160 
00161 
00162         double estMass = 1.0/estInvMass;
00163 
00164         /*step back if mass outside allowed range*/
00165         if(estMass >= options.tMaxMass->getValue()  || estMass <= options.tMinMass->getValue() ){
00166 //              input[0] = -_estGain*w*e;
00167                 input[0] = -1.0 * estGain * w * e;
00168                 estInvMassIntegrator->step(input,estInvMass);
00169                 estInvMass += integInitialInvMass;
00170         }
00171 
00172         estMass = std::min( options.tMaxMass->getValue() , std::max(estMass,options.tMinMass->getValue()) );
00173         estInvMass = 1.0/estMass;
00174 
00175         input[0] = lambda * estGain - estGain * w * w * estGain;
00176         estGainIntegrator->step(input,estGain);
00177         estGain += integInitialGain;
00178 
00179 //      if (_logMassEst){
00180 //              fprintf(_logMassEst, "%f %f %f %f\n", input[0], _estInvMass, input[0], _estGain);
00181 //      }
00182 
00183         out.estMass = estMass;
00184         out.estGain = estGain;
00185 
00186         if (options.tPublishMass){
00187                 tk_draft_msgs::MassStamped msg;
00188                 msg.header.stamp = ros::Time::now();
00189                 msg.mass = estMass;
00190                 massPub.publish(msg);
00191         }
00192 
00193 }
00194 
00195 double StandardMassEstimator::getInitialMass() const
00196 {
00197         return options.tInitialMass->getValue();
00198 }
00199 
00200 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends


tk_param_estimator
Author(s): Riccardo Spica and Martin Riedel
autogenerated on Mon Nov 11 2013 11:13:10