00001
00002
00003
00004
00005
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
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);
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)", 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)", 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();
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
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();
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 }