Add my old ultra-simplistic PI controller. The fancy PID controller doesn't
seem to be fully deterministic in P-only mode. This old simple controller does what I expect, so it's good for calulating stage #1's of multi-stage controllers.
This commit is contained in:
parent
869aa997a5
commit
bffca78da4
2 changed files with 40 additions and 58 deletions
|
@ -296,13 +296,13 @@ void FGPIDController::update( double dt ) {
|
|||
}
|
||||
|
||||
|
||||
FGSimplePIController::FGSimplePIController( SGPropertyNode *node ):
|
||||
FGPISimpleController::FGPISimpleController( SGPropertyNode *node ):
|
||||
proportional( false ),
|
||||
factor( 0.0 ),
|
||||
Kp( 0.0 ),
|
||||
offset_prop( NULL ),
|
||||
offset_value( 0.0 ),
|
||||
integral( false ),
|
||||
gain( 0.0 ),
|
||||
Ki( 0.0 ),
|
||||
int_sum( 0.0 ),
|
||||
clamp( false ),
|
||||
debug( false ),
|
||||
|
@ -318,6 +318,8 @@ FGSimplePIController::FGSimplePIController( SGPropertyNode *node ):
|
|||
string cval = child->getStringValue();
|
||||
if ( cname == "name" ) {
|
||||
name = cval;
|
||||
} else if ( cname == "debug" ) {
|
||||
debug = child->getBoolValue();
|
||||
} else if ( cname == "enable" ) {
|
||||
// cout << "parsing enable" << endl;
|
||||
SGPropertyNode *prop = child->getChild( "prop" );
|
||||
|
@ -331,8 +333,6 @@ FGSimplePIController::FGSimplePIController( SGPropertyNode *node ):
|
|||
if ( val != NULL ) {
|
||||
enable_value = val->getStringValue();
|
||||
}
|
||||
} else if ( cname == "debug" ) {
|
||||
debug = child->getBoolValue();
|
||||
} else if ( cname == "input" ) {
|
||||
SGPropertyNode *prop = child->getChild( "prop" );
|
||||
if ( prop != NULL ) {
|
||||
|
@ -345,7 +345,7 @@ FGSimplePIController::FGSimplePIController( SGPropertyNode *node ):
|
|||
} else {
|
||||
prop = child->getChild( "value" );
|
||||
if ( prop != NULL ) {
|
||||
r_n_value = prop->getDoubleValue();
|
||||
r_n = prop->getDoubleValue();
|
||||
}
|
||||
}
|
||||
} else if ( cname == "output" ) {
|
||||
|
@ -356,64 +356,43 @@ FGSimplePIController::FGSimplePIController( SGPropertyNode *node ):
|
|||
output_list.push_back( tmp );
|
||||
i++;
|
||||
}
|
||||
prop = child->getChild( "clamp" );
|
||||
} else if ( cname == "config" ) {
|
||||
SGPropertyNode *prop;
|
||||
|
||||
prop = child->getChild( "Kp" );
|
||||
if ( prop != NULL ) {
|
||||
Kp = prop->getDoubleValue();
|
||||
proportional = true;
|
||||
}
|
||||
|
||||
prop = child->getChild( "Ki" );
|
||||
if ( prop != NULL ) {
|
||||
Ki = prop->getDoubleValue();
|
||||
integral = true;
|
||||
}
|
||||
|
||||
prop = child->getChild( "u_min" );
|
||||
if ( prop != NULL ) {
|
||||
u_min = prop->getDoubleValue();
|
||||
clamp = true;
|
||||
|
||||
SGPropertyNode *tmp;
|
||||
|
||||
tmp = prop->getChild( "min" );
|
||||
if ( tmp != NULL ) {
|
||||
u_min = tmp->getDoubleValue();
|
||||
// cout << "min = " << u_min << endl;
|
||||
}
|
||||
|
||||
tmp = prop->getChild( "max" );
|
||||
if ( tmp != NULL ) {
|
||||
u_max = tmp->getDoubleValue();
|
||||
// cout << "max = " << u_max << endl;
|
||||
}
|
||||
}
|
||||
} else if ( cname == "proportional" ) {
|
||||
proportional = true;
|
||||
|
||||
SGPropertyNode *prop;
|
||||
|
||||
prop = child->getChild( "factor" );
|
||||
if ( prop != NULL ) {
|
||||
factor = prop->getDoubleValue();
|
||||
}
|
||||
|
||||
prop = child->getChild( "offset" );
|
||||
prop = child->getChild( "u_max" );
|
||||
if ( prop != NULL ) {
|
||||
SGPropertyNode *sub = prop->getChild( "prop" );
|
||||
if ( sub != NULL ) {
|
||||
offset_prop = fgGetNode( sub->getStringValue(), true );
|
||||
// cout << "offset prop = " << sub->getStringValue() << endl;
|
||||
} else {
|
||||
sub = prop->getChild( "value" );
|
||||
if ( sub != NULL ) {
|
||||
offset_value = sub->getDoubleValue();
|
||||
// cout << "offset value = " << offset_value << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if ( cname == "integral" ) {
|
||||
integral = true;
|
||||
|
||||
SGPropertyNode *prop;
|
||||
prop = child->getChild( "gain" );
|
||||
if ( prop != NULL ) {
|
||||
gain = prop->getDoubleValue();
|
||||
u_max = prop->getDoubleValue();
|
||||
clamp = true;
|
||||
}
|
||||
} else {
|
||||
SG_LOG( SG_AUTOPILOT, SG_WARN, "Error in autopilot config logic" );
|
||||
if ( name.length() ) {
|
||||
SG_LOG( SG_AUTOPILOT, SG_WARN, "Section = " << name );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FGSimplePIController::update( double dt ) {
|
||||
void FGPISimpleController::update( double dt ) {
|
||||
if (enable_prop != NULL && enable_prop->getStringValue() == enable_value) {
|
||||
if ( !enabled ) {
|
||||
// we have just been enabled, zero out int_sum
|
||||
|
@ -454,11 +433,11 @@ void FGSimplePIController::update( double dt ) {
|
|||
}
|
||||
|
||||
if ( proportional ) {
|
||||
prop_comp = error * factor + offset;
|
||||
prop_comp = error * Kp + offset;
|
||||
}
|
||||
|
||||
if ( integral ) {
|
||||
int_sum += error * gain * dt;
|
||||
int_sum += error * Ki * dt;
|
||||
} else {
|
||||
int_sum = 0.0;
|
||||
}
|
||||
|
@ -554,6 +533,9 @@ bool FGXMLAutopilot::build() {
|
|||
if ( name == "pid-controller" ) {
|
||||
FGXMLAutoComponent *c = new FGPIDController( node );
|
||||
components.push_back( c );
|
||||
} else if ( name == "pi-simple-controller" ) {
|
||||
FGXMLAutoComponent *c = new FGPISimpleController( node );
|
||||
components.push_back( c );
|
||||
} else {
|
||||
SG_LOG( SG_ALL, SG_ALERT, "Unknown top level section: "
|
||||
<< name );
|
||||
|
|
|
@ -137,19 +137,19 @@ public:
|
|||
* A simplistic P [ + I ] PID controller
|
||||
*/
|
||||
|
||||
class FGSimplePIController : public FGXMLAutoComponent {
|
||||
class FGPISimpleController : public FGXMLAutoComponent {
|
||||
|
||||
private:
|
||||
|
||||
// proportional component data
|
||||
bool proportional;
|
||||
double factor;
|
||||
double Kp;
|
||||
SGPropertyNode *offset_prop;
|
||||
double offset_value;
|
||||
|
||||
// integral component data
|
||||
bool integral;
|
||||
double gain;
|
||||
double Ki;
|
||||
double int_sum;
|
||||
|
||||
// post functions for output
|
||||
|
@ -168,8 +168,8 @@ private:
|
|||
|
||||
public:
|
||||
|
||||
FGSimplePIController( SGPropertyNode *node );
|
||||
~FGSimplePIController() {}
|
||||
FGPISimpleController( SGPropertyNode *node );
|
||||
~FGPISimpleController() {}
|
||||
|
||||
void update( double dt );
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue