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 }