00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 #include <tk_ctrlalgo/PositionControl.hpp>
00009 #include <algorithm>
00010 
00011 #include <telekyb_defines/physic_defines.hpp>
00012 
00013 #define MAX_INT_TIME_STEP 0.04
00014 
00015 namespace TELEKYB_NAMESPACE {
00016 
00017 
00018 PositionControlOptions::PositionControlOptions()
00019         : OptionContainer("PositionControl")
00020 {
00021         tPropGain = addOption<double>( "tPropGain", "Proportional gain on xy plane", 9.0, false, false);
00022         tDerivGain = addOption<double>( "tDerivGain", "Derivative  gain on xy plane", 7.5, false, false);
00023         tIntegGain = addOption<double>( "tIntegGain", "Integral  gain on xy plane", 4.5, false, false);
00024 
00025         tDerGainVelMode = addOption<double>( "tDerGainVelMode", "Derivative  gain on xy plane in velocity mode", 7.5, false, false);
00026 
00027         tZPropGain = addOption<double>( "tZPropGain", "Z axis Proportional gain", 9.0, false, false);
00028         tZDerivGain = addOption<double>( "tZDerivGain", "Z axis Derivative  gain", 7.5, false, false);
00029 
00030         tSatIntTerm = addOption<double>( "tSatIntTerm",
00031                         "Saturation value on the integral term  (sine of the maximum inclination angle) (on xy plane)", 0.475, false, false);
00032 
00033         tMinThrust = addOption<double>( "tMinThrust", "Mimimum thrust", 5.0, false, true);
00034 
00035         tMaxRollSin = addOption<double>( "tMaxRollSin", "Sinus of the max roll", sin(30.0*M_PI/180.0), false, true);
00036         tMaxPitchSin = addOption<double>( "tMaxPitchSin", "Sinus of the max pitch", sin(30.0*M_PI/180.0), false, true);
00037 
00038         
00039 
00040         tGravity = addOption<double>( "tGravity", "Gravity Value for the Position Controller", GRAVITY, false, false);
00041 }
00042 
00043 PositionControl::PositionControl()
00044 {
00045 
00046 }
00047 
00048 PositionControl::~PositionControl()
00049 {
00050 
00051 }
00052 
00053 
00054 
00055 
00056 
00057 
00058 void PositionControl::run(const TKTrajectory& input, const TKState& currentState, const double mass, PosCtrlOutput& output)
00059 {
00060         
00061         Position3D curPosition = currentState.position;
00062         Velocity3D curLinVelocity = currentState.linVelocity;
00063         Vector3D curOrientation = currentState.getEulerRPY();
00064         
00065 
00066         
00067         Position3D desPosition = input.position;
00068         Velocity3D desLinVelocity = input.velocity;
00069         Acceleration3D desLinAcceleration = input.acceleration;
00070 
00071         
00072 
00073 
00074 
00075 
00076 
00077 
00078 
00079         
00080 
00081 
00082 
00083 
00084 
00085 
00086 
00087 
00088 
00089         
00090 
00091 
00092 
00093 
00094 
00095 
00096 
00097 
00098 
00099 
00100 
00101 
00102 
00103 
00104         double xPropGain = 0.0, yPropGain = 0.0, zPropGain = 0.0;
00105         double xIntegGain = 0.0, yIntegGain = 0.0;
00106         double xDerivGain = 0.0, yDerivGain = 0.0, zDerivGain = 0.0;
00107 
00108         if (input.xAxisCtrl == PosControlType::Position) {
00109                 xPropGain   = options.tPropGain->getValue();
00110                 xDerivGain  = options.tDerivGain->getValue();
00111                 xIntegGain  = options.tIntegGain->getValue();
00112         } else if (input.xAxisCtrl == PosControlType::Velocity) {
00113 
00114                 xDerivGain  = options.tDerGainVelMode->getValue();
00115 
00116                 xIntErr = 0.0;
00117         } else if (input.xAxisCtrl == PosControlType::Acceleration) {
00118 
00119 
00120 
00121                 xIntErr = 0.0;
00122         }
00123 
00124         if (input.yAxisCtrl == PosControlType::Position) {
00125                 yPropGain   = options.tPropGain->getValue();
00126                 yDerivGain  = options.tDerivGain->getValue();
00127                 yIntegGain  = options.tIntegGain->getValue();
00128         } else if (input.yAxisCtrl == PosControlType::Velocity) {
00129 
00130                 yDerivGain  = options.tDerGainVelMode->getValue();
00131 
00132                 yIntErr = 0.0;
00133         } else if (input.yAxisCtrl == PosControlType::Acceleration) {
00134 
00135 
00136 
00137                 yIntErr = 0.0;
00138         }
00139 
00140         if (input.zAxisCtrl == PosControlType::Position) {
00141                 zPropGain  = options.tZPropGain->getValue();
00142                 zDerivGain = options.tZDerivGain->getValue();
00143         } else if (input.zAxisCtrl == PosControlType::Velocity) {
00144 
00145                 zDerivGain = options.tZDerivGain->getValue();
00146         } else if (input.zAxisCtrl == PosControlType::Acceleration) {
00147 
00148 
00149         }
00150 
00151 
00152         
00153 
00154         
00155         double maxIntTerm = options.tSatIntTerm->getValue() / options.tIntegGain->getValue();
00156         
00157 
00158         double comX = desLinAcceleration(0) +
00159                                                 xDerivGain* (desLinVelocity(0) - curLinVelocity(0)) +
00160                                                 xPropGain* (desPosition(0) - curPosition(0)) +
00161                                                 xIntegGain*(xIntErr);
00162 
00163         double comY = desLinAcceleration(1) +
00164                                                 yDerivGain* (desLinVelocity(1) - curLinVelocity(1)) +
00165                                                 yPropGain* (desPosition(1) - curPosition(1)) +
00166                                                 yIntegGain*(yIntErr);
00167 
00168         double comZ = desLinAcceleration(2) +
00169                                                 zDerivGain*(desLinVelocity(2) - curLinVelocity(2)) +
00170                                                 zPropGain*(desPosition(2) - curPosition(2));
00171 
00172 
00173 
00174 
00175 
00176         double timeStep = integTimer.getElapsed().toDSec();
00177         integTimer.reset();
00178         if (timeStep < MAX_INT_TIME_STEP) {
00179                 xIntErr += (desPosition(0) - curPosition(0))*timeStep;
00180                 yIntErr += (desPosition(1) - curPosition(1))*timeStep;
00181         }
00182 
00183         if (fabs(xIntErr) > maxIntTerm) {
00184                 xIntErr = copysign(maxIntTerm, xIntErr);
00185                 
00186         }
00187 
00188         if (fabs(yIntErr) > maxIntTerm) {
00189                 yIntErr = copysign(maxIntTerm, yIntErr);
00190                 
00191         }
00192 
00193 
00194 
00195 
00196 
00197 
00198 
00199 
00200 
00201 
00202 
00203 
00204 
00205 
00206         double comThrust =  ( mass/(cos( curOrientation(0) )*cos( curOrientation(1) )) ) * ( -1.0 * options.tGravity->getValue() + comZ );
00207 
00208         
00209 
00210 
00211 
00212 
00213 
00214 
00215 
00216 
00217         comThrust = std::min( comThrust, -1.0 * options.tMinThrust->getValue() );
00218         comThrust = std::max( comThrust, -2.0 * mass * options.tGravity->getValue() + options.tMinThrust->getValue() );
00219 
00220 
00221 
00222 
00223 
00224         double comRoll = ( mass / comThrust) * ( -sin(curOrientation(2))*comX + cos(curOrientation(2))*comY);
00225         double comPitch = ( mass / (comThrust*cos(curOrientation(0)))) * ( cos(curOrientation(2))*comX + sin(curOrientation(2))*comY);
00226 
00227 
00228 
00229         if (fabs(comRoll) > options.tMaxRollSin->getValue()){
00230 
00231                 comRoll = copysign(options.tMaxRollSin->getValue(), comRoll);
00232         }
00233 
00234         if (fabs(comPitch) > options.tMaxPitchSin->getValue()){
00235 
00236                 comPitch = copysign(options.tMaxPitchSin->getValue(), comPitch);
00237         }
00238 
00239         output.comRoll = -asin( comRoll );
00240         output.comPitch = asin( comPitch );
00241         output.comThrust = comThrust;
00242 
00243 
00244 
00245 
00246 
00247 
00248 
00249 }
00250 
00251 
00252 }