1
0
Fork 0

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:
curt 2004-02-05 17:11:47 +00:00
parent 869aa997a5
commit bffca78da4
2 changed files with 40 additions and 58 deletions

View file

@ -296,13 +296,13 @@ void FGPIDController::update( double dt ) {
} }
FGSimplePIController::FGSimplePIController( SGPropertyNode *node ): FGPISimpleController::FGPISimpleController( SGPropertyNode *node ):
proportional( false ), proportional( false ),
factor( 0.0 ), Kp( 0.0 ),
offset_prop( NULL ), offset_prop( NULL ),
offset_value( 0.0 ), offset_value( 0.0 ),
integral( false ), integral( false ),
gain( 0.0 ), Ki( 0.0 ),
int_sum( 0.0 ), int_sum( 0.0 ),
clamp( false ), clamp( false ),
debug( false ), debug( false ),
@ -318,6 +318,8 @@ FGSimplePIController::FGSimplePIController( SGPropertyNode *node ):
string cval = child->getStringValue(); string cval = child->getStringValue();
if ( cname == "name" ) { if ( cname == "name" ) {
name = cval; name = cval;
} else if ( cname == "debug" ) {
debug = child->getBoolValue();
} else if ( cname == "enable" ) { } else if ( cname == "enable" ) {
// cout << "parsing enable" << endl; // cout << "parsing enable" << endl;
SGPropertyNode *prop = child->getChild( "prop" ); SGPropertyNode *prop = child->getChild( "prop" );
@ -331,8 +333,6 @@ FGSimplePIController::FGSimplePIController( SGPropertyNode *node ):
if ( val != NULL ) { if ( val != NULL ) {
enable_value = val->getStringValue(); enable_value = val->getStringValue();
} }
} else if ( cname == "debug" ) {
debug = child->getBoolValue();
} else if ( cname == "input" ) { } else if ( cname == "input" ) {
SGPropertyNode *prop = child->getChild( "prop" ); SGPropertyNode *prop = child->getChild( "prop" );
if ( prop != NULL ) { if ( prop != NULL ) {
@ -345,7 +345,7 @@ FGSimplePIController::FGSimplePIController( SGPropertyNode *node ):
} else { } else {
prop = child->getChild( "value" ); prop = child->getChild( "value" );
if ( prop != NULL ) { if ( prop != NULL ) {
r_n_value = prop->getDoubleValue(); r_n = prop->getDoubleValue();
} }
} }
} else if ( cname == "output" ) { } else if ( cname == "output" ) {
@ -356,64 +356,43 @@ FGSimplePIController::FGSimplePIController( SGPropertyNode *node ):
output_list.push_back( tmp ); output_list.push_back( tmp );
i++; i++;
} }
prop = child->getChild( "clamp" ); } else if ( cname == "config" ) {
SGPropertyNode *prop;
prop = child->getChild( "Kp" );
if ( prop != NULL ) { 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; 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 ) { if ( prop != NULL ) {
SGPropertyNode *sub = prop->getChild( "prop" ); u_max = prop->getDoubleValue();
if ( sub != NULL ) { clamp = true;
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();
} }
} else { } else {
SG_LOG( SG_AUTOPILOT, SG_WARN, "Error in autopilot config logic" ); 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 (enable_prop != NULL && enable_prop->getStringValue() == enable_value) {
if ( !enabled ) { if ( !enabled ) {
// we have just been enabled, zero out int_sum // we have just been enabled, zero out int_sum
@ -454,11 +433,11 @@ void FGSimplePIController::update( double dt ) {
} }
if ( proportional ) { if ( proportional ) {
prop_comp = error * factor + offset; prop_comp = error * Kp + offset;
} }
if ( integral ) { if ( integral ) {
int_sum += error * gain * dt; int_sum += error * Ki * dt;
} else { } else {
int_sum = 0.0; int_sum = 0.0;
} }
@ -554,6 +533,9 @@ bool FGXMLAutopilot::build() {
if ( name == "pid-controller" ) { if ( name == "pid-controller" ) {
FGXMLAutoComponent *c = new FGPIDController( node ); FGXMLAutoComponent *c = new FGPIDController( node );
components.push_back( c ); components.push_back( c );
} else if ( name == "pi-simple-controller" ) {
FGXMLAutoComponent *c = new FGPISimpleController( node );
components.push_back( c );
} else { } else {
SG_LOG( SG_ALL, SG_ALERT, "Unknown top level section: " SG_LOG( SG_ALL, SG_ALERT, "Unknown top level section: "
<< name ); << name );

View file

@ -137,19 +137,19 @@ public:
* A simplistic P [ + I ] PID controller * A simplistic P [ + I ] PID controller
*/ */
class FGSimplePIController : public FGXMLAutoComponent { class FGPISimpleController : public FGXMLAutoComponent {
private: private:
// proportional component data // proportional component data
bool proportional; bool proportional;
double factor; double Kp;
SGPropertyNode *offset_prop; SGPropertyNode *offset_prop;
double offset_value; double offset_value;
// integral component data // integral component data
bool integral; bool integral;
double gain; double Ki;
double int_sum; double int_sum;
// post functions for output // post functions for output
@ -168,8 +168,8 @@ private:
public: public:
FGSimplePIController( SGPropertyNode *node ); FGPISimpleController( SGPropertyNode *node );
~FGSimplePIController() {} ~FGPISimpleController() {}
void update( double dt ); void update( double dt );
}; };