StandardInertiaMatrixEstimator.cpp
Go to the documentation of this file.
00001 /*
00002  * StandardInertiaMatrixEstimator.cpp
00003  *
00004  *  Created on: Jul 28, 2012
00005  *      Author: rspica
00006  */
00007 
00008 #include "StandardInertiaMatrixEstimator.hpp"
00009 
00010 #include <pluginlib/class_list_macros.h>
00011 #include <geometry_msgs/Vector3Stamped.h>
00012 #include <telekyb_base/ROS.hpp>
00013 
00014 PLUGINLIB_DECLARE_CLASS(tk_param_estimator, StandardInertiaMatrixEstimator, TELEKYB_NAMESPACE::StandardInertiaMatrixEstimator, TELEKYB_NAMESPACE::InertiaMatrixEstimator);
00015 
00016 namespace TELEKYB_NAMESPACE {
00017 
00018 // Options
00019 StandardInertiaMatrixEstimOptions::StandardInertiaMatrixEstimOptions()
00020         : OptionContainer("StandardInertiaMatrixEstim")
00021 {
00022 
00023         tInitialInertiaMatrix = addOption<Eigen::Vector3d>("tInitialInertiaMatrix","Inertia Matrix Estimation: initial guess of the inertia matrix in kg*m^2 (diagonal)", Eigen::Vector3d(1.0079e-02, 1.0269e-02, 1.9461e-02), false, true);
00024 
00025         tAFiltCoeff = addOption<Eigen::Vector3d>("tAFiltCoeff","Inertia Matrix Estimation: Determines the speed of convergence", Eigen::Vector3d(0.2,0.2,0.2),false,true);/*a*/
00026         tLambdaZeroGain = addOption<Eigen::Vector3d>("tLambdaZeroGain","Inertia Matrix Estimation: Lambda Zero gain", Eigen::Vector3d(1.0,1.0,1.0),false,true);
00027         tKappaZeroGain = addOption<Eigen::Vector3d>("tKappaZeroGain","Inertia Matrix Estimation: Kappa Zero gain", Eigen::Vector3d(1.0,1.0,1.0),false,true);
00028 
00029         tSampleTime = addOption<double>("tSampleTime","Inertia Matrix Estimation: SamplingTime", 0.008,false,true);
00030 
00031         tMaxInertia = addOption<Eigen::Vector3d>("tMaxInertia","Inertia Matrix Estimation: Maximum inertia (diagonal)",  /*1.2**/Eigen::Vector3d(1.0079e-02, 1.0269e-02, 1.9461e-02),false,true);
00032         tMinInertia = addOption<Eigen::Vector3d>("tMinInertia","Inertia Matrix Estimation: Minimum inertia (diagonal)", /*0.8**/Eigen::Vector3d(1.0079e-02, 1.0269e-02, 1.9461e-02),false,true);
00033 
00034         tPublishInertia = addOption<bool>("tPublishInertia","Specifies if the estimated inertia matrix must be published", false, false, true);
00035         tInertiaTopic = addOption<std::string>("tInertiaTopic","Specifies the topic for publishing the inertia matrix", "EstimatedInertia", false, true);
00036 
00037         }
00038 
00039 StandardInertiaMatrixEstimator::StandardInertiaMatrixEstimator():
00040         nodeHandle( ROSModule::Instance().getMainNodeHandle() )
00041 {
00042 
00043 }
00044 
00045 
00046 void StandardInertiaMatrixEstimator::initialize()
00047 {
00048         if (options.tPublishInertia){
00049                 inertiaPub = nodeHandle.advertise<geometry_msgs::Vector3Stamped>(options.tInertiaTopic->getValue(), 1);
00050         }
00051 
00052         estInvInertia = options.tInitialInertiaMatrix->getValue().cwiseInverse();  //TODO check if this is correct!!!
00053         estGain = options.tKappaZeroGain->getValue();
00054 
00055         integInitialInvInertia = estInvInertia;
00056         integInitialGain = estGain;
00057 
00058         Eigen::Vector3d a = options.tAFiltCoeff->getValue();
00059         double samplTime = options.tSampleTime->getValue();
00060 
00061         std::vector<double> num(2);
00062         std::vector<double> den(1);
00063         // create Filters
00064         for (short unsigned int i = 0; i<3 ; i++){
00065                 num[0] = a(i) * samplTime / (2.0 + a(i) * samplTime);
00066                 num[1] = a(i) * samplTime / (2.0 + a(i) * samplTime);
00067                 den[0] = (a(i) * samplTime - 2.0) / (2.0 + a(i) * samplTime);
00068                 torqueFilter[i] = new IIRFilter(num,den);
00069                 angVelFilter[i] = new IIRFilter(num,den);
00070         }
00071 
00072         num[0] = 0.5 * samplTime;
00073         num[1] = 0.5 * samplTime;
00074         den[0] = -1.0;
00075 
00076         for (short unsigned int i = 0; i<3 ; i++){
00077                 estInvInertiaIntegrator[i] = new IIRFilter(num,den);
00078                 estGainIntegrator[i] = new IIRFilter(num,den);
00079         }
00080 
00081 }
00082 
00083 void StandardInertiaMatrixEstimator::destroy()
00084 {
00085         for (short unsigned int i = 0; i < 3; i++){
00086                 delete torqueFilter[i];
00087                 delete angVelFilter[i];
00088                 delete estInvInertiaIntegrator[i];
00089                 delete estGainIntegrator[i];
00090         }
00091 }
00092 
00093 std::string StandardInertiaMatrixEstimator::getName() const
00094 {
00095         return "StandardInertiaMatrixEstimator";
00096 }
00097 
00098 StandardInertiaMatrixEstimator::~StandardInertiaMatrixEstimator()
00099 {
00100 
00101 }
00102 
00103 void StandardInertiaMatrixEstimator::run(const InertiaMatrixEstimInput& in,InertiaMatrixEstimOutput& out)
00104 {
00105         Eigen::Vector3d a = options.tAFiltCoeff->getValue();
00106 
00107         std::vector<double> input(1);
00108 
00109         Eigen::Vector3d filtTorque;
00110         for (short unsigned int i = 0; i < 3; i++){
00111                 input[0] = in.torque(i);
00112                 torqueFilter[i]->step(input, filtTorque(i));
00113         }
00114 
00115         Eigen::Vector3d filtAngVel;
00116         for (short unsigned int i = 0; i < 3; i++){
00117                 input[0] = in.angVel(i);
00118                 angVelFilter[i]->step(input,filtAngVel(i));
00119         }
00120 
00121         Eigen::Vector3d w = filtTorque;
00122 
00123         Eigen::Vector3d y = a.cwiseProduct(in.angVel - filtAngVel);
00124 
00125         Eigen::Vector3d yHat = w.cwiseProduct(estInvInertia);
00126 
00127         Eigen::Vector3d e = y-yHat;
00128 
00129         Eigen::Vector3d lambda;
00130 
00131         for (short unsigned int i = 0; i < 3; i++){
00132                 lambda(i) = options.tLambdaZeroGain->getValue()(i)*(1 - fabs(estGain(i))/options.tKappaZeroGain->getValue()(i));
00133         }
00134 
00135 
00136 
00137         for (short unsigned int i = 0; i < 3; i++){
00138                 input[0] = estGain(i)*w(i)*e(i);
00139                 estInvInertiaIntegrator[i]->step(input,estInvInertia(i));
00140         }
00141 
00142         estInvInertia += integInitialInvInertia;
00143 
00144 
00145         Eigen::Vector3d estInertia = estInvInertia.cwiseInverse();
00146 
00147 
00148         for  (short unsigned int i = 0; i < 3; i++){
00149                 if(estInertia(i) >= options.tMaxInertia->getValue()(i)  || estInertia(i) <= options.tMinInertia->getValue()(i) ){
00150                         input[0] = -1.0 * estGain(i) * w(i) * e(i);
00151                         estInvInertiaIntegrator[i]->step(input,estInvInertia(i));
00152                         estInvInertia(i) += integInitialInvInertia(i);
00153                 }
00154 
00155                 estInertia(i) = std::min( options.tMaxInertia->getValue()(i) , std::max(estInertia(i),options.tMinInertia->getValue()(i)));
00156                 estInvInertia(i) = 1.0/estInertia(i);
00157 
00158                 input[0] = lambda(i) * estGain(i) - estGain(i) * w(i) * w(i) * estGain(i);
00159                 estGainIntegrator[i]->step(input,estGain(i));
00160         }
00161 
00162         estGain += integInitialGain;
00163 
00164 
00165         out.estInertiaMatrix = Eigen::Matrix3d::Zero();//estInertia.asDiagonal();
00166         out.estGain = estGain;
00167 
00168         if (options.tPublishInertia){
00169                 geometry_msgs::Vector3Stamped msg;
00170                 msg.header.stamp = ros::Time::now();
00171                 msg.vector.x = estInertia(0);
00172                 msg.vector.y = estInertia(1);
00173                 msg.vector.z = estInertia(2);
00174                 inertiaPub.publish(msg);
00175         }
00176 
00177 }
00178 
00179 Eigen::Matrix3d StandardInertiaMatrixEstimator::getInitialInertiaMatrix() const
00180 {
00181         return options.tInitialInertiaMatrix->getValue().asDiagonal();
00182 }
00183 
00184 }
 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