return value;
}
-bool AnalogComponent::configure( const std::string & nodeName, SGPropertyNode_ptr configNode )
+bool AnalogComponent::configure( SGPropertyNode& cfg_node,
+ const std::string& cfg_name,
+ SGPropertyNode& prop_root )
{
- SG_LOG( SG_AUTOPILOT, SG_BULK, "AnalogComponent::configure(" << nodeName << ")" );
- if( Component::configure( nodeName, configNode ) )
+ SG_LOG
+ (
+ SG_AUTOPILOT,
+ SG_BULK,
+ "AnalogComponent::configure(" << cfg_name << ")"
+ );
+
+ if( Component::configure(cfg_node, cfg_name, prop_root) )
return true;
- if ( nodeName == "feedback-if-disabled" ) {
- _feedback_if_disabled = configNode->getBoolValue();
+ if( cfg_name == "feedback-if-disabled" )
+ {
+ _feedback_if_disabled = cfg_node.getBoolValue();
return true;
}
- if ( nodeName == "output" ) {
- // grab all <prop> and <property> childs
- int found = 0;
- // backwards compatibility: allow <prop> elements
- SGPropertyNode_ptr prop;
- for( int i = 0; (prop = configNode->getChild("prop", i)) != NULL; i++ ) {
- SGPropertyNode *tmp = fgGetNode( prop->getStringValue(), true );
- _output_list.push_back( tmp );
- found++;
- }
- for( int i = 0; (prop = configNode->getChild("property", i)) != NULL; i++ ) {
- SGPropertyNode *tmp = fgGetNode( prop->getStringValue(), true );
- _output_list.push_back( tmp );
- found++;
+ if( cfg_name == "output" )
+ {
+ // grab all <prop> and <property> childs.
+ bool found = false;
+ for( int i = 0; i < cfg_node.nChildren(); ++i )
+ {
+ SGPropertyNode& child = *cfg_node.getChild(i);
+ const std::string& name = child.getNameString();
+
+ // Allow "prop" for backwards compatiblity
+ if( name != "property" && name != "prop" )
+ continue;
+
+ _output_list.push_back( prop_root.getNode(child.getStringValue(), true) );
+ found = true;
}
// no <prop> elements, text node of <output> is property name
- if( found == 0 )
- _output_list.push_back( fgGetNode(configNode->getStringValue(), true ) );
+ if( !found )
+ _output_list.push_back
+ (
+ prop_root.getNode(cfg_node.getStringValue(), true)
+ );
return true;
}
- if( nodeName == "input" ) {
- _valueInput.push_back( new InputValue( configNode ) );
+ if( cfg_name == "input" )
+ {
+ _valueInput.push_back( new InputValue(prop_root, cfg_node) );
return true;
}
- if( nodeName == "reference" ) {
- _referenceInput.push_back( new InputValue( configNode ) );
+ if( cfg_name == "reference" )
+ {
+ _referenceInput.push_back( new InputValue(prop_root, cfg_node) );
return true;
}
- if( nodeName == "min" || nodeName == "u_min" ) {
- _minInput.push_back( new InputValue( configNode ) );
+ if( cfg_name == "min" || cfg_name == "u_min" )
+ {
+ _minInput.push_back( new InputValue(prop_root, cfg_node) );
return true;
}
- if( nodeName == "max" || nodeName == "u_max" ) {
- _maxInput.push_back( new InputValue( configNode ) );
+ if( cfg_name == "max" || cfg_name == "u_max" )
+ {
+ _maxInput.push_back( new InputValue(prop_root, cfg_node) );
return true;
}
- if( nodeName == "period" ) {
- _periodical = new PeriodicalValue( configNode );
+ if( cfg_name == "period" )
+ {
+ _periodical = new PeriodicalValue(prop_root, cfg_node);
return true;
}
- SG_LOG( SG_AUTOPILOT, SG_BULK, "AnalogComponent::configure(" << nodeName << ") [unhandled]" );
+ SG_LOG
+ (
+ SG_AUTOPILOT,
+ SG_BULK,
+ "AnalogComponent::configure(" << cfg_name << ") [unhandled]"
+ );
return false;
}
AnalogComponent();
/**
- * @brief This method configures this analog component from a property node. Gets
- * called multiple times from the base class configure method for every
- config node.
- * @param nodeName the name of the configuration node provided in configNode
- * @param configNode the configuration node itself
+ * @brief This method configures this analog component from a property node.
+ * Gets called multiple times from the base class configure method
+ * for every configuration node.
+ * @param cfg_name Name of the configuration node provided in cfg_node
+ * @param cfg_node Configuration node itself
+ * @param prop_root Property root for all relative paths
* @return true if the node was handled, false otherwise.
*/
- virtual bool configure( const std::string & nodeName, SGPropertyNode_ptr configNode );
+ virtual bool configure( SGPropertyNode& cfg_node,
+ const std::string& cfg_name,
+ SGPropertyNode& prop_root );
/**
* @brief clamp the given value if <min> and/or <max> inputs were given
class StateMachineComponent : public Component
{
public:
- StateMachineComponent(SGPropertyNode_ptr config)
+ StateMachineComponent( SGPropertyNode& cfg,
+ SGPropertyNode& props_root )
{
- inner = simgear::StateMachine::createFromPlist(config, globals->get_props());
+ inner = simgear::StateMachine::createFromPlist(&cfg, &props_root);
}
virtual bool configure( const std::string & nodeName, SGPropertyNode_ptr config)
{
public:
virtual ~StateMachineFunctor() {}
- virtual Component* operator()( SGPropertyNode_ptr configNode )
+ virtual Component* operator()( SGPropertyNode& cfg,
+ SGPropertyNode& prop_root )
{
- return new StateMachineComponent(configNode);
+ return new StateMachineComponent(cfg, prop_root);
}
};
delete it->second;
}
+void readInterfaceProperties( SGPropertyNode_ptr prop_root,
+ SGPropertyNode_ptr cfg )
+{
+ simgear::PropertyList cfg_props = cfg->getChildren("property");
+ for( simgear::PropertyList::iterator it = cfg_props.begin();
+ it != cfg_props.end();
+ ++it )
+ {
+ SGPropertyNode_ptr prop = prop_root->getNode((*it)->getStringValue(), true);
+ SGPropertyNode* val = (*it)->getNode("_attr_/value");
+
+ if( val )
+ {
+ prop->setDoubleValue( val->getDoubleValue() );
+
+ // TODO should we keep the _attr_ node, as soon as the property browser is
+ // able to cope with it?
+ (*it)->removeChild("_attr_", 0, false);
+ }
+ }
+}
+
static ComponentForge componentForge;
Autopilot::Autopilot( SGPropertyNode_ptr rootNode, SGPropertyNode_ptr configNode ) :
componentForge["state-machine"] = new StateMachineFunctor();
}
- if( configNode == NULL ) configNode = rootNode;
+ if( !configNode )
+ configNode = rootNode;
+
+ // property-root can be set in config file and overridden in the local system
+ // node. This allows using the same autopilot multiple times but with
+ // different paths (with all relative property paths being relative to the
+ // node specified with property-root)
+ SGPropertyNode_ptr prop_root_node = rootNode->getChild("property-root");
+ if( !prop_root_node )
+ prop_root_node = configNode->getChild("property-root");
+
+ SGPropertyNode_ptr prop_root =
+ fgGetNode(prop_root_node ? prop_root_node->getStringValue() : "/", true);
+
+ // Just like the JSBSim interface properties for systems, create properties
+ // given in the autopilot file and set to given (default) values.
+ readInterfaceProperties(prop_root, configNode);
+
+ // Afterwards read the properties specified in local system node to allow
+ // overriding initial or default values. This allows reusing components with
+ // just different "parameter" values.
+ readInterfaceProperties(prop_root, rootNode);
int count = configNode->nChildren();
- for ( int i = 0; i < count; ++i ) {
+ for( int i = 0; i < count; ++i )
+ {
SGPropertyNode_ptr node = configNode->getChild(i);
string childName = node->getName();
- if( componentForge.count(childName) == 0 ) {
- SG_LOG( SG_AUTOPILOT, SG_BULK, "unhandled element <" << childName << ">" << std::endl );
+ if( childName == "property"
+ || childName == "property-root" )
+ continue;
+ if( componentForge.count(childName) == 0 )
+ {
+ SG_LOG(SG_AUTOPILOT, SG_BULK, "unhandled element <" << childName << ">");
continue;
}
- Component * component = (*componentForge[childName])(node);
+ Component * component = (*componentForge[childName])(*prop_root, *node);
if( component->get_name().length() == 0 ) {
std::ostringstream buf;
buf << "unnamed_component_" << i;
delete _enable_value;
}
-bool Component::configure( SGPropertyNode_ptr configNode )
+//------------------------------------------------------------------------------
+bool Component::configure( SGPropertyNode& prop_root,
+ SGPropertyNode& cfg )
{
- for (int i = 0; i < configNode->nChildren(); ++i ) {
- SGPropertyNode_ptr prop;
-
- SGPropertyNode_ptr child = configNode->getChild(i);
+ for( int i = 0; i < cfg.nChildren(); ++i )
+ {
+ SGPropertyNode_ptr child = cfg.getChild(i);
std::string cname(child->getName());
- if( configure( cname, child ) )
- continue;
-
- } // for configNode->nChildren()
+ if( !configure(*child, cname, prop_root) )
+ SG_LOG
+ (
+ SG_AUTOPILOT,
+ SG_INFO,
+ "Component::configure: unknown node: " << cname
+ );
+ }
return true;
}
-bool Component::configure( const std::string & nodeName, SGPropertyNode_ptr configNode )
+//------------------------------------------------------------------------------
+bool Component::configure( SGPropertyNode& cfg_node,
+ const std::string& cfg_name,
+ SGPropertyNode& prop_root )
{
- SG_LOG( SG_AUTOPILOT, SG_BULK, "Component::configure(" << nodeName << ")" << std::endl );
-
- if ( nodeName == "name" ) {
- _name = configNode->getStringValue();
+ SG_LOG
+ (
+ SG_AUTOPILOT,
+ SG_BULK,
+ "Component::configure(" << cfg_name << ")"
+ );
+
+ if ( cfg_name == "name" ) {
+ _name = cfg_node.getStringValue();
return true;
}
- if ( nodeName == "debug" ) {
- _debug = configNode->getBoolValue();
+ if ( cfg_name == "debug" ) {
+ _debug = cfg_node.getBoolValue();
return true;
}
- if ( nodeName == "enable" ) {
+ if ( cfg_name == "enable" ) {
SGPropertyNode_ptr prop;
- if( (prop = configNode->getChild("condition")) != NULL ) {
+ if( (prop = cfg_node.getChild("condition")) != NULL ) {
_condition = sgReadCondition(fgGetNode("/"), prop);
return true;
}
- if ( (prop = configNode->getChild( "property" )) != NULL ) {
+ if ( (prop = cfg_node.getChild( "property" )) != NULL ) {
_enable_prop = fgGetNode( prop->getStringValue(), true );
}
- if ( (prop = configNode->getChild( "prop" )) != NULL ) {
+ if ( (prop = cfg_node.getChild( "prop" )) != NULL ) {
_enable_prop = fgGetNode( prop->getStringValue(), true );
}
- if ( (prop = configNode->getChild( "value" )) != NULL ) {
+ if ( (prop = cfg_node.getChild( "value" )) != NULL ) {
delete _enable_value;
_enable_value = new std::string(prop->getStringValue());
}
- if ( (prop = configNode->getChild( "honor-passive" )) != NULL ) {
+ if ( (prop = cfg_node.getChild( "honor-passive" )) != NULL ) {
_honor_passive = prop->getBoolValue();
}
return true;
} // enable
- SG_LOG( SG_AUTOPILOT, SG_BULK, "Component::configure(" << nodeName << ") [unhandled]" << std::endl );
+ SG_LOG
+ (
+ SG_AUTOPILOT,
+ SG_BULK,
+ "Component::configure(" << cfg_name << ") [unhandled]"
+ );
return false;
}
protected:
- virtual bool configure( const std::string & nodeName, SGPropertyNode_ptr configNode );
+ virtual bool configure( SGPropertyNode& cfg_node,
+ const std::string& cfg_name,
+ SGPropertyNode& prop_root );
-
/**
* @brief the implementation of the update() method of the SGSubsystem
*/
virtual ~Component();
/**
- * @brief configure this component from a property node. Iterates through all nodes found
- * as childs under configNode and calls configure of the derived class for each child.
- * @param configNode the property node containing the configuration
+ * @brief configure this component from a property node. Iterates through
+ * all nodes found as children under configNode and calls configure
+ * of the derived class for each child.
+ *
+ * @param prop_root Property root for all relative paths
+ * @param cfg Property node containing the configuration
*/
- bool configure( SGPropertyNode_ptr configNode );
+ bool configure( SGPropertyNode& prop_root,
+ SGPropertyNode& cfg );
/**
* @brief getter for the name property
</output>
<output>/some/property</output>
*/
-bool DigitalComponent::configure( const std::string & nodeName, SGPropertyNode_ptr configNode )
+bool DigitalComponent::configure( SGPropertyNode& cfg_node,
+ const std::string& cfg_name,
+ SGPropertyNode& prop_root )
{
- if( Component::configure( nodeName, configNode ) )
+ if( Component::configure(cfg_node, cfg_name, prop_root) )
return true;
- if (nodeName == "input") {
- SGPropertyNode_ptr nameNode = configNode->getNode("name");
+ if (cfg_name == "input") {
+ SGPropertyNode_ptr nameNode = cfg_node.getNode("name");
string name;
if( nameNode != NULL ) {
name = nameNode->getStringValue();
buf << "Input" << _input.size();
name = buf.str();
}
- _input[name] = sgReadCondition( fgGetNode("/"), configNode );
+ _input[name] = sgReadCondition(&prop_root, &cfg_node);
return true;
}
- if (nodeName == "output") {
- SGPropertyNode_ptr n = configNode->getNode("name");
+ if (cfg_name == "output") {
+ SGPropertyNode_ptr n = cfg_node.getNode("name");
string name;
if( n != NULL ) {
name = n->getStringValue();
DigitalOutput_ptr o = new DigitalOutput();
_output[name] = o;
- if( (n = configNode->getNode("inverted")) != NULL )
+ if( (n = cfg_node.getNode("inverted")) != NULL )
o->setInverted( n->getBoolValue() );
- if( (n = configNode->getNode("property")) != NULL )
- o->setProperty( fgGetNode( n->getStringValue(), true ) );
+ if( (n = cfg_node.getNode("property")) != NULL )
+ o->setProperty( prop_root.getNode(n->getStringValue(), true) );
- if( configNode->nChildren() == 0 )
- o->setProperty( fgGetNode( configNode->getStringValue(), true ) );
+ if( cfg_node.nChildren() == 0 )
+ o->setProperty( prop_root.getNode(cfg_node.getStringValue(), true) );
return true;
}
- if (nodeName == "inverted") {
- _inverted = configNode->getBoolValue();
+ if (cfg_name == "inverted") {
+ _inverted = cfg_node.getBoolValue();
return true;
}
/**
* @brief Over-rideable hook method to allow derived classes to refine top-level
* node parsing.
- * @param aName
- * @param aNode
+ * @param cfg_node
+ * @param cfg_name
+ * @param prop_root
* @return true if the node was handled, false otherwise.
*/
- virtual bool configure( const std::string & nodeName, SGPropertyNode_ptr configNode );
+ virtual bool configure( SGPropertyNode& cfg_node,
+ const std::string& cfg_name,
+ SGPropertyNode& prop_root );
};
}
*/
class DigitalFilterImplementation : public SGReferenced {
protected:
- virtual bool configure( const std::string & nodeName, SGPropertyNode_ptr configNode) = 0;
+ virtual bool configure( SGPropertyNode& cfg_node,
+ const std::string& cfg_name,
+ SGPropertyNode& prop_root ) = 0;
public:
virtual ~DigitalFilterImplementation() {}
DigitalFilterImplementation();
virtual void initialize( double initvalue ) {}
virtual double compute( double dt, double input ) = 0;
- bool configure( SGPropertyNode_ptr configNode );
+ bool configure( SGPropertyNode& cfg,
+ SGPropertyNode& prop_root );
void setDigitalFilter( DigitalFilter * digitalFilter ) { _digitalFilter = digitalFilter; }
class GainFilterImplementation : public DigitalFilterImplementation {
protected:
InputValueList _gainInput;
- bool configure( const std::string & nodeName, SGPropertyNode_ptr configNode );
+ bool configure( SGPropertyNode& cfg_node,
+ const std::string& cfg_name,
+ SGPropertyNode& prop_root );
public:
GainFilterImplementation() : _gainInput(1.0) {}
double compute( double dt, double input );
class DerivativeFilterImplementation : public GainFilterImplementation {
InputValueList _TfInput;
double _input_1;
- bool configure( const std::string & nodeName, SGPropertyNode_ptr configNode );
+ bool configure( SGPropertyNode& cfg_node,
+ const std::string& cfg_name,
+ SGPropertyNode& prop_root );
public:
DerivativeFilterImplementation();
double compute( double dt, double input );
class ExponentialFilterImplementation : public GainFilterImplementation {
protected:
InputValueList _TfInput;
- bool configure( const std::string & nodeName, SGPropertyNode_ptr configNode );
+ bool configure( SGPropertyNode& cfg_node,
+ const std::string& cfg_name,
+ SGPropertyNode& prop_root );
bool _isSecondOrder;
double _output_1, _output_2;
public:
InputValueList _samplesInput;
double _output_1;
std::deque <double> _inputQueue;
- bool configure( const std::string & nodeName, SGPropertyNode_ptr configNode );
+ bool configure( SGPropertyNode& cfg_node,
+ const std::string& cfg_name,
+ SGPropertyNode& prop_root );
public:
MovingAverageFilterImplementation();
double compute( double dt, double input );
protected:
double _output_1;
InputValueList _rateOfChangeInput;
- bool configure( const std::string & nodeName, SGPropertyNode_ptr configNode );
+ bool configure( SGPropertyNode& cfg_node,
+ const std::string& cfg_name,
+ SGPropertyNode& prop_root );
public:
NoiseSpikeFilterImplementation();
double compute( double dt, double input );
double _output_1;
InputValueList _rateOfChangeMax;
InputValueList _rateOfChangeMin ;
- bool configure( const std::string & nodeName, SGPropertyNode_ptr configNode );
+ bool configure( SGPropertyNode& cfg_node,
+ const std::string& cfg_name,
+ SGPropertyNode& prop_root );
public:
RateLimitFilterImplementation();
double compute( double dt, double input );
InputValueList _maxInput;
double _input_1;
double _output_1;
- bool configure( const std::string & nodeName, SGPropertyNode_ptr configNode );
+ bool configure( SGPropertyNode& cfg_node,
+ const std::string& cfg_name,
+ SGPropertyNode& prop_root );
public:
IntegratorFilterImplementation();
double compute( double dt, double input );
InputValueList _TfInput;
double _input_1;
double _output_1;
- bool configure( const std::string & nodeName, SGPropertyNode_ptr configNode );
+ bool configure( SGPropertyNode& cfg_node,
+ const std::string& cfg_name,
+ SGPropertyNode& prop_root );
public:
HighPassFilterImplementation();
double compute( double dt, double input );
InputValueList _TfbInput;
double _input_1;
double _output_1;
- bool configure( const std::string & nodeName, SGPropertyNode_ptr configNode );
+ bool configure( SGPropertyNode& cfg_node,
+ const std::string& cfg_name,
+ SGPropertyNode& prop_root );
public:
LeadLagFilterImplementation();
double compute( double dt, double input );
{
}
-bool DigitalFilterImplementation::configure( SGPropertyNode_ptr configNode )
+//------------------------------------------------------------------------------
+bool DigitalFilterImplementation::configure( SGPropertyNode& cfg,
+ SGPropertyNode& prop_root )
{
- for (int i = 0; i < configNode->nChildren(); ++i ) {
- SGPropertyNode_ptr prop;
+ for (int i = 0; i < cfg.nChildren(); ++i )
+ {
+ SGPropertyNode_ptr child = cfg.getChild(i);
- SGPropertyNode_ptr child = configNode->getChild(i);
- string cname(child->getName());
-
- if( configure( cname, child ) )
+ if( configure(*child, child->getNameString(), prop_root) )
continue;
-
- } // for configNode->nChildren()
+ }
return true;
}
return _gainInput.get_value() * input;
}
-bool GainFilterImplementation::configure( const std::string & nodeName, SGPropertyNode_ptr configNode )
+bool GainFilterImplementation::configure( SGPropertyNode& cfg_node,
+ const std::string& cfg_name,
+ SGPropertyNode& prop_root )
{
- if (nodeName == "gain" ) {
- _gainInput.push_back( new InputValue( configNode, 1 ) );
+ if (cfg_name == "gain" ) {
+ _gainInput.push_back( new InputValue(prop_root, cfg_node, 1) );
return true;
}
_input_1 = initvalue;
}
-
-bool DerivativeFilterImplementation::configure( const std::string & nodeName, SGPropertyNode_ptr configNode )
+//------------------------------------------------------------------------------
+bool DerivativeFilterImplementation::configure( SGPropertyNode& cfg_node,
+ const std::string& cfg_name,
+ SGPropertyNode& prop_root )
{
- if( GainFilterImplementation::configure( nodeName, configNode ) )
+ if( GainFilterImplementation::configure(cfg_node, cfg_name, prop_root) )
return true;
- if (nodeName == "filter-time" ) {
- _TfInput.push_back( new InputValue( configNode, 1 ) );
+ if (cfg_name == "filter-time" ) {
+ _TfInput.push_back( new InputValue(prop_root, cfg_node, 1) );
return true;
}
return output_0;
}
-bool MovingAverageFilterImplementation::configure( const std::string & nodeName, SGPropertyNode_ptr configNode )
+bool MovingAverageFilterImplementation::configure( SGPropertyNode& cfg_node,
+ const std::string& cfg_name,
+ SGPropertyNode& prop_root )
{
- if (nodeName == "samples" ) {
- _samplesInput.push_back( new InputValue( configNode, 1 ) );
+ if (cfg_name == "samples" ) {
+ _samplesInput.push_back( new InputValue(prop_root, cfg_node, 1) );
return true;
}
return (_output_1 = _output_1 + copysign( maxChange, delta ));
}
-bool NoiseSpikeFilterImplementation::configure( const std::string & nodeName, SGPropertyNode_ptr configNode )
+//------------------------------------------------------------------------------
+bool NoiseSpikeFilterImplementation::configure( SGPropertyNode& cfg_node,
+ const std::string& cfg_name,
+ SGPropertyNode& prop_root )
{
- if (nodeName == "max-rate-of-change" ) {
- _rateOfChangeInput.push_back( new InputValue( configNode, 1 ) );
+ if (cfg_name == "max-rate-of-change" ) {
+ _rateOfChangeInput.push_back( new InputValue(prop_root, cfg_node, 1) );
return true;
}
return (output);
}
-bool RateLimitFilterImplementation::configure( const std::string & nodeName, SGPropertyNode_ptr configNode )
+bool RateLimitFilterImplementation::configure( SGPropertyNode& cfg_node,
+ const std::string& cfg_name,
+ SGPropertyNode& prop_root )
{
- if (nodeName == "max-rate-of-change" ) {
- _rateOfChangeMax.push_back( new InputValue( configNode, 1 ) );
+ if (cfg_name == "max-rate-of-change" ) {
+ _rateOfChangeMax.push_back( new InputValue(prop_root, cfg_node, 1) );
return true;
}
- if (nodeName == "min-rate-of-change" ) {
- _rateOfChangeMin.push_back( new InputValue( configNode, 1 ) );
+ if (cfg_name == "min-rate-of-change" ) {
+ _rateOfChangeMin.push_back( new InputValue(prop_root, cfg_node, 1) );
return true;
}
return (_output_1 = output_0);
}
-bool ExponentialFilterImplementation::configure( const std::string & nodeName, SGPropertyNode_ptr configNode )
+//------------------------------------------------------------------------------
+bool ExponentialFilterImplementation::configure( SGPropertyNode& cfg_node,
+ const std::string& cfg_name,
+ SGPropertyNode& prop_root )
{
- if( GainFilterImplementation::configure( nodeName, configNode ) )
+ if( GainFilterImplementation::configure(cfg_node, cfg_name, prop_root) )
return true;
- if (nodeName == "filter-time" ) {
- _TfInput.push_back( new InputValue( configNode, 1 ) );
+ if (cfg_name == "filter-time" ) {
+ _TfInput.push_back( new InputValue(prop_root, cfg_node, 1) );
return true;
}
- if (nodeName == "type" ) {
- string type(configNode->getStringValue());
+ if (cfg_name == "type" ) {
+ string type(cfg_node.getStringValue());
_isSecondOrder = type == "double-exponential";
}
_input_1 = _output_1 = initvalue;
}
-
-bool IntegratorFilterImplementation::configure( const std::string & nodeName, SGPropertyNode_ptr configNode )
+//------------------------------------------------------------------------------
+bool IntegratorFilterImplementation::configure( SGPropertyNode& cfg_node,
+ const std::string& cfg_name,
+ SGPropertyNode& prop_root )
{
- if( GainFilterImplementation::configure( nodeName, configNode ) )
+ if( GainFilterImplementation::configure(cfg_node, cfg_name, prop_root) )
return true;
- if (nodeName == "u_min" ) {
- _minInput.push_back( new InputValue( configNode, 1 ) );
+
+ if (cfg_name == "u_min" ) {
+ _minInput.push_back( new InputValue(prop_root, cfg_node, 1) );
return true;
}
- if (nodeName == "u_max" ) {
- _maxInput.push_back( new InputValue( configNode, 1 ) );
+ if (cfg_name == "u_max" ) {
+ _maxInput.push_back( new InputValue(prop_root, cfg_node, 1) );
return true;
}
return false;
return output;
}
-bool HighPassFilterImplementation::configure( const std::string & nodeName, SGPropertyNode_ptr configNode )
+//------------------------------------------------------------------------------
+bool HighPassFilterImplementation::configure( SGPropertyNode& cfg_node,
+ const std::string& cfg_name,
+ SGPropertyNode& prop_root )
{
- if( GainFilterImplementation::configure( nodeName, configNode ) )
+ if( GainFilterImplementation::configure(cfg_node, cfg_name, prop_root) )
return true;
- if (nodeName == "filter-time" ) {
- _TfInput.push_back( new InputValue( configNode, 1 ) );
+ if (cfg_name == "filter-time" ) {
+ _TfInput.push_back( new InputValue(prop_root, cfg_node, 1) );
return true;
}
return output;
}
-bool LeadLagFilterImplementation::configure( const std::string & nodeName, SGPropertyNode_ptr configNode )
+//------------------------------------------------------------------------------
+bool LeadLagFilterImplementation::configure( SGPropertyNode& cfg_node,
+ const std::string& cfg_name,
+ SGPropertyNode& prop_root )
{
- if( GainFilterImplementation::configure( nodeName, configNode ) )
+ if( GainFilterImplementation::configure(cfg_node, cfg_name, prop_root) )
return true;
- if (nodeName == "filter-time-a" ) {
- _TfaInput.push_back( new InputValue( configNode, 1 ) );
+ if (cfg_name == "filter-time-a" ) {
+ _TfaInput.push_back( new InputValue(prop_root, cfg_node, 1) );
return true;
}
- if (nodeName == "filter-time-b" ) {
- _TfbInput.push_back( new InputValue( configNode, 1 ) );
+ if (cfg_name == "filter-time-b" ) {
+ _TfbInput.push_back( new InputValue(prop_root, cfg_node, 1) );
return true;
}
return false;
}
-/* --------------------------------------------------------------------------------- */
-/* Digital Filter Component Implementation */
-/* --------------------------------------------------------------------------------- */
+/* -------------------------------------------------------------------------- */
+/* Digital Filter Component Implementation */
+/* -------------------------------------------------------------------------- */
DigitalFilter::DigitalFilter() :
AnalogComponent(),
static map<string,FunctorBase<DigitalFilterImplementation> *> componentForge;
-bool DigitalFilter::configure(const string& nodeName, SGPropertyNode_ptr configNode)
+//------------------------------------------------------------------------------
+bool DigitalFilter::configure( SGPropertyNode& cfg_node,
+ const std::string& cfg_name,
+ SGPropertyNode& prop_root )
{
if( componentForge.empty() ) {
componentForge["gain"] = new CreateAndConfigureFunctor<GainFilterImplementation,DigitalFilterImplementation>();
componentForge["integrator"] = new CreateAndConfigureFunctor<IntegratorFilterImplementation,DigitalFilterImplementation>();
}
- SG_LOG( SG_AUTOPILOT, SG_BULK, "DigitalFilter::configure(" << nodeName << ")" << endl );
- if( AnalogComponent::configure( nodeName, configNode ) )
+ SG_LOG(SG_AUTOPILOT, SG_BULK, "DigitalFilter::configure(" << cfg_name << ")");
+
+ if( AnalogComponent::configure(cfg_node, cfg_name, prop_root) )
return true;
- if (nodeName == "type" ) {
- string type( configNode->getStringValue() );
+ if (cfg_name == "type" ) {
+ string type( cfg_node.getStringValue() );
if( componentForge.count(type) == 0 ) {
SG_LOG( SG_AUTOPILOT, SG_BULK, "unhandled filter type <" << type << ">" << endl );
return true;
}
- _implementation = (*componentForge[type])( configNode->getParent() );
+ _implementation = (*componentForge[type])(*cfg_node.getParent(), prop_root);
_implementation->setDigitalFilter( this );
return true;
}
- if( nodeName == "initialize-to" ) {
- string s( configNode->getStringValue() );
+ if( cfg_name == "initialize-to" ) {
+ string s( cfg_node.getStringValue() );
if( s == "input" ) {
_initializeTo = INITIALIZE_INPUT;
} else if( s == "output" ) {
return true;
}
- SG_LOG( SG_AUTOPILOT, SG_BULK, "DigitalFilter::configure(" << nodeName << ") [unhandled]" << endl );
+ SG_LOG
+ (
+ SG_AUTOPILOT,
+ SG_BULK,
+ "DigitalFilter::configure(" << cfg_name << ") [unhandled]"
+ );
return false; // not handled by us, let the base class try
}
};
protected:
- bool configure( const std::string & nodeName, SGPropertyNode_ptr configNode);
- void update( bool firstTime, double dt);
+ virtual bool configure( SGPropertyNode& cfg_node,
+ const std::string& cfg_name,
+ SGPropertyNode& prop_root );
+ virtual void update( bool firstTime, double dt);
InputValueList _Tf;
InputValueList _samples;
*/
class MonoFlopImplementation : public JKFlipFlopImplementation {
protected:
- virtual bool configure( const std::string & nodeName, SGPropertyNode_ptr configNode );
+ virtual bool configure( SGPropertyNode& cfg_node,
+ const std::string& cfg_name,
+ SGPropertyNode& prop_root );
InputValueList _time;
double _t;
public:
using namespace FGXMLAutopilot;
-bool MonoFlopImplementation::configure( const std::string & nodeName, SGPropertyNode_ptr configNode )
+//------------------------------------------------------------------------------
+bool MonoFlopImplementation::configure( SGPropertyNode& cfg_node,
+ const std::string& cfg_name,
+ SGPropertyNode& prop_root )
{
- if( JKFlipFlopImplementation::configure( nodeName, configNode ) )
+ if( JKFlipFlopImplementation::configure(cfg_node, cfg_name, prop_root) )
return true;
- if (nodeName == "time") {
- _time.push_back( new InputValue( configNode ) );
+ if (cfg_name == "time") {
+ _time.push_back( new InputValue(prop_root, cfg_node) );
return true;
}
return false; // signal no change
}
-bool FlipFlopImplementation::configure( SGPropertyNode_ptr configNode )
+//------------------------------------------------------------------------------
+bool FlipFlopImplementation::configure( SGPropertyNode& prop_root,
+ SGPropertyNode& cfg )
{
- for (int i = 0; i < configNode->nChildren(); ++i ) {
- SGPropertyNode_ptr prop;
-
- SGPropertyNode_ptr child = configNode->getChild(i);
+ for( int i = 0; i < cfg.nChildren(); ++i )
+ {
+ SGPropertyNode_ptr child = cfg.getChild(i);
string cname(child->getName());
- if( configure( cname, child ) )
+ if( configure(*child, cname, prop_root) )
continue;
-
- } // for configNode->nChildren()
+ }
return true;
}
static map<string,FunctorBase<FlipFlopImplementation> *> componentForge;
-bool FlipFlop::configure( const std::string & nodeName, SGPropertyNode_ptr configNode )
+//------------------------------------------------------------------------------
+bool FlipFlop::configure( SGPropertyNode& cfg_node,
+ const std::string& cfg_name,
+ SGPropertyNode& prop_root )
{
if( componentForge.empty() ) {
componentForge["RS"] = new CreateAndConfigureFunctor<RSFlipFlopImplementation,FlipFlopImplementation>();
componentForge["monostable"] = new CreateAndConfigureFunctor<MonoFlopImplementation, FlipFlopImplementation>();
}
- if( DigitalComponent::configure( nodeName, configNode ) )
+ if( DigitalComponent::configure(cfg_node, cfg_name, prop_root) )
return true;
- if( nodeName == "type" ) {
- string type(configNode->getStringValue());
+ if( cfg_name == "type" ) {
+ string type(cfg_node.getStringValue());
if( componentForge.count(type) == 0 ) {
- SG_LOG( SG_AUTOPILOT, SG_BULK, "unhandled flip-flop type <" << type << ">" << endl );
+ SG_LOG
+ (
+ SG_AUTOPILOT,
+ SG_BULK,
+ "unhandled flip-flop type <" << type << ">"
+ );
return true;
}
- _implementation = (*componentForge[type])( configNode->getParent() );
+ _implementation = (*componentForge[type])(prop_root, *cfg_node.getParent());
return true;
}
- if (nodeName == "set"||nodeName == "S") {
- _input["S"] = sgReadCondition( fgGetNode("/"), configNode );
+ if (cfg_name == "set"||cfg_name == "S") {
+ _input["S"] = sgReadCondition(&prop_root, &cfg_node);
return true;
}
- if (nodeName == "reset" || nodeName == "R" ) {
- _input["R"] = sgReadCondition( fgGetNode("/"), configNode );
+ if (cfg_name == "reset" || cfg_name == "R" ) {
+ _input["R"] = sgReadCondition(&prop_root, &cfg_node);
return true;
}
- if (nodeName == "J") {
- _input["J"] = sgReadCondition( fgGetNode("/"), configNode );
+ if (cfg_name == "J") {
+ _input["J"] = sgReadCondition(&prop_root, &cfg_node);
return true;
}
- if (nodeName == "K") {
- _input["K"] = sgReadCondition( fgGetNode("/"), configNode );
+ if (cfg_name == "K") {
+ _input["K"] = sgReadCondition(&prop_root, &cfg_node);
return true;
}
- if (nodeName == "D") {
- _input["D"] = sgReadCondition( fgGetNode("/"), configNode );
+ if (cfg_name == "D") {
+ _input["D"] = sgReadCondition(&prop_root, &cfg_node);
return true;
}
- if (nodeName == "clock") {
- _input["clock"] = sgReadCondition( fgGetNode("/"), configNode );
+ if (cfg_name == "clock") {
+ _input["clock"] = sgReadCondition(&prop_root, &cfg_node);
return true;
}
* as childs under configNode and calls configure of the derived class for each child.
* @param configNode the property node containing the configuration
*/
- virtual bool configure( const std::string & nodeName, SGPropertyNode_ptr configNode ) { return false; }
+ virtual bool configure( SGPropertyNode& cfg_node,
+ const std::string& cfg_name,
+ SGPropertyNode& prop_root )
+ { return false; }
public:
virtual ~FlipFlopImplementation() {}
/**
* as childs under configNode and calls configure of the derived class for each child.
* @param configNode the property node containing the configuration
*/
- bool configure( SGPropertyNode_ptr configNode );
+ bool configure( SGPropertyNode& prop_root,
+ SGPropertyNode& cfg );
};
/**
* @param aNode
* @return true if the node was handled, false otherwise.
*/
- virtual bool configure( const std::string & nodeName, SGPropertyNode_ptr configNode );
+ virtual bool configure( SGPropertyNode& cfg_node,
+ const std::string& cfg_name,
+ SGPropertyNode& prop_root );
/**
* @brief Implementation of the pure virtual function of the Component class. Gets called from
template <class TBase> class FunctorBase {
public:
virtual ~FunctorBase() {}
- virtual TBase * operator()( SGPropertyNode_ptr configNode ) = 0;
+ virtual TBase * operator()( SGPropertyNode& prop_root,
+ SGPropertyNode& cfg ) = 0;
};
template <class TClass,class TBase> class CreateAndConfigureFunctor :
public FunctorBase<TBase> {
public:
- virtual TBase * operator()( SGPropertyNode_ptr configNode ) {
+ virtual TBase * operator()( SGPropertyNode& prop_root,
+ SGPropertyNode& cfg )
+ {
TBase * base = new TClass();
- base->configure( configNode );
+ base->configure(prop_root, cfg);
return base;
}
};
using namespace FGXMLAutopilot;
-PeriodicalValue::PeriodicalValue( SGPropertyNode_ptr root )
+//------------------------------------------------------------------------------
+PeriodicalValue::PeriodicalValue( SGPropertyNode& prop_root,
+ SGPropertyNode& cfg )
{
- SGPropertyNode_ptr minNode = root->getChild( "min" );
- SGPropertyNode_ptr maxNode = root->getChild( "max" );
- if( minNode == NULL || maxNode == NULL ) {
- SG_LOG(SG_AUTOPILOT, SG_ALERT, "periodical defined, but no <min> and/or <max> tag. Period ignored." );
- } else {
- minPeriod = new InputValue( minNode );
- maxPeriod = new InputValue( maxNode );
+ SGPropertyNode_ptr minNode = cfg.getChild( "min" );
+ SGPropertyNode_ptr maxNode = cfg.getChild( "max" );
+ if( !minNode || !maxNode )
+ {
+ SG_LOG
+ (
+ SG_AUTOPILOT,
+ SG_ALERT,
+ "periodical defined, but no <min> and/or <max> tag. Period ignored."
+ );
+ }
+ else
+ {
+ minPeriod = new InputValue(prop_root, *minNode);
+ maxPeriod = new InputValue(prop_root, *maxNode);
}
}
+//------------------------------------------------------------------------------
double PeriodicalValue::normalize( double value ) const
{
- return SGMiscd::normalizePeriodic( minPeriod->get_value(), maxPeriod->get_value(), value );
+ return SGMiscd::normalizePeriodic( minPeriod->get_value(),
+ maxPeriod->get_value(),
+ value );
}
+//------------------------------------------------------------------------------
double PeriodicalValue::normalizeSymmetric( double value ) const
{
double minValue = minPeriod->get_value();
return value > width_2 ? width_2 - value : value;
}
-InputValue::InputValue( SGPropertyNode_ptr node, double value, double offset, double scale) :
+//------------------------------------------------------------------------------
+InputValue::InputValue( SGPropertyNode& prop_root,
+ SGPropertyNode& cfg,
+ double value,
+ double offset,
+ double scale ):
_value(0.0),
_abs(false)
{
- parse( node, value, offset, scale );
+ parse(prop_root, cfg, value, offset, scale);
}
-
-void InputValue::parse( SGPropertyNode_ptr node, double aValue, double aOffset, double aScale )
+//------------------------------------------------------------------------------
+void InputValue::parse( SGPropertyNode& prop_root,
+ SGPropertyNode& cfg,
+ double aValue,
+ double aOffset,
+ double aScale )
{
- _value = aValue;
- _property = NULL;
- _offset = NULL;
- _scale = NULL;
- _min = NULL;
- _max = NULL;
- _periodical = NULL;
+ _value = aValue;
+ _property = NULL;
+ _offset = NULL;
+ _scale = NULL;
+ _min = NULL;
+ _max = NULL;
+ _periodical = NULL;
- if( node == NULL )
- return;
+ SGPropertyNode * n;
- SGPropertyNode * n;
+ if( (n = cfg.getChild("condition")) != NULL )
+ _condition = sgReadCondition(&prop_root, n);
- if( (n = node->getChild("condition")) != NULL ) {
- _condition = sgReadCondition(fgGetNode("/"), n);
- }
+ if( (n = cfg.getChild( "scale" )) != NULL )
+ _scale = new InputValue(prop_root, *n, aScale);
- if( (n = node->getChild( "scale" )) != NULL ) {
- _scale = new InputValue( n, aScale );
- }
+ if( (n = cfg.getChild( "offset" )) != NULL )
+ _offset = new InputValue(prop_root, *n, aOffset);
- if( (n = node->getChild( "offset" )) != NULL ) {
- _offset = new InputValue( n, aOffset );
- }
+ if( (n = cfg.getChild( "max" )) != NULL )
+ _max = new InputValue(prop_root, *n);
- if( (n = node->getChild( "max" )) != NULL ) {
- _max = new InputValue( n );
- }
+ if( (n = cfg.getChild( "min" )) != NULL )
+ _min = new InputValue(prop_root, *n);
- if( (n = node->getChild( "min" )) != NULL ) {
- _min = new InputValue( n );
- }
+ if( (n = cfg.getChild( "abs" )) != NULL )
+ _abs = n->getBoolValue();
- if( (n = node->getChild( "abs" )) != NULL ) {
- _abs = n->getBoolValue();
- }
+ if( (n = cfg.getChild( "period" )) != NULL )
+ _periodical = new PeriodicalValue(prop_root, *n);
- if( (n = node->getChild( "period" )) != NULL ) {
- _periodical = new PeriodicalValue( n );
- }
- SGPropertyNode *valueNode = node->getChild( "value" );
- if ( valueNode != NULL ) {
- _value = valueNode->getDoubleValue();
- }
+ SGPropertyNode *valueNode = cfg.getChild("value");
+ if( valueNode != NULL )
+ _value = valueNode->getDoubleValue();
- if ((n = node->getChild("expression")) != NULL) {
- _expression = SGReadDoubleExpression(fgGetNode("/"), n->getChild(0));
- return;
- }
-
- n = node->getChild( "property" );
- // if no <property> element, check for <prop> element for backwards
- // compatibility
- if( n == NULL )
- n = node->getChild( "prop" );
-
- if ( n != NULL ) {
- _property = fgGetNode( n->getStringValue(), true );
- if ( valueNode != NULL ) {
- // initialize property with given value
- // if both <prop> and <value> exist
- double s = get_scale();
- if( s != 0 )
- _property->setDoubleValue( (_value - get_offset())/s );
- else
- _property->setDoubleValue( 0 ); // if scale is zero, value*scale is zero
- }
-
- return;
- } // of have a <property> or <prop>
+ if( (n = cfg.getChild("expression")) != NULL )
+ {
+ _expression = SGReadDoubleExpression(&prop_root, n->getChild(0));
+ return;
+ }
-
- if (valueNode == NULL) {
- // no <value>, <prop> or <expression> element, use text node
- const char * textnode = node->getStringValue();
- char * endp = NULL;
- // try to convert to a double value. If the textnode does not start with a number
- // endp will point to the beginning of the string. We assume this should be
- // a property name
- _value = strtod( textnode, &endp );
- if( endp == textnode ) {
- _property = fgGetNode( textnode, true );
- }
+ // if no <property> element, check for <prop> element for backwards
+ // compatibility
+ if( (n = cfg.getChild("property"))
+ || (n = cfg.getChild("prop" )) )
+ {
+ _property = prop_root.getNode(n->getStringValue(), true);
+ if( valueNode )
+ {
+ // initialize property with given value
+ // if both <prop> and <value> exist
+ double s = get_scale();
+ if( s != 0 )
+ _property->setDoubleValue( (_value - get_offset())/s );
+ else
+ _property->setDoubleValue(0); // if scale is zero, value*scale is zero
}
+
+ return;
+ } // of have a <property> or <prop>
+
+
+ if( !valueNode )
+ {
+ // no <value>, <prop> or <expression> element, use text node
+ const char * textnode = cfg.getStringValue();
+ char * endp = NULL;
+ // try to convert to a double value. If the textnode does not start with a number
+ // endp will point to the beginning of the string. We assume this should be
+ // a property name
+ _value = strtod( textnode, &endp );
+ if( endp == textnode )
+ _property = prop_root.getNode(textnode, true);
+ }
}
void InputValue::set_value( double aValue )
InputValue_ptr minPeriod; // The minimum value of the period
InputValue_ptr maxPeriod; // The maximum value of the period
public:
- PeriodicalValue( SGPropertyNode_ptr node );
+ PeriodicalValue( SGPropertyNode& prop_root,
+ SGPropertyNode& cfg );
double normalize( double value ) const;
double normalizeSymmetric( double value ) const;
};
SGSharedPtr<SGExpressiond> _expression; ///< expression to generate the value
public:
- InputValue( SGPropertyNode_ptr node = NULL, double value = 0.0, double offset = 0.0, double scale = 1.0 );
-
- void parse( SGPropertyNode_ptr, double value = 0.0, double offset = 0.0, double scale = 1.0 );
+ InputValue( SGPropertyNode& prop_root,
+ SGPropertyNode& node,
+ double value = 0.0,
+ double offset = 0.0,
+ double scale = 1.0 );
+
+ /**
+ *
+ * @param prop_root Root node for all properties with relative path
+ * @param cfg Configuration node
+ * @param value Default initial value
+ * @param offset Default initial offset
+ * @param scale Default initial scale
+ */
+ void parse( SGPropertyNode& prop_root,
+ SGPropertyNode& cfg,
+ double value = 0.0,
+ double offset = 0.0,
+ double scale = 1.0 );
/* get the value of this input, apply scale and offset and clipping */
double get_value() const;
}
}
-bool PIDController::configure( const std::string & nodeName, SGPropertyNode_ptr configNode )
+//------------------------------------------------------------------------------
+bool PIDController::configure( SGPropertyNode& cfg_node,
+ const std::string& cfg_name,
+ SGPropertyNode& prop_root )
{
- SG_LOG( SG_AUTOPILOT, SG_BULK, "PIDController::configure(" << nodeName << ")" << endl );
+ SG_LOG(SG_AUTOPILOT, SG_BULK, "PIDController::configure(" << cfg_name << ")");
- if( AnalogComponent::configure( nodeName, configNode ) )
+ if( AnalogComponent::configure(cfg_node, cfg_name, prop_root) )
return true;
- if( nodeName == "config" ) {
- Component::configure( configNode );
+ if( cfg_name == "config" ) {
+ Component::configure(prop_root, cfg_node);
return true;
}
- if (nodeName == "Ts") {
- desiredTs = configNode->getDoubleValue();
+ if (cfg_name == "Ts") {
+ desiredTs = cfg_node.getDoubleValue();
return true;
}
- if (nodeName == "Kp") {
- Kp.push_back( new InputValue(configNode) );
+ if (cfg_name == "Kp") {
+ Kp.push_back( new InputValue(prop_root, cfg_node) );
return true;
}
- if (nodeName == "Ti") {
- Ti.push_back( new InputValue(configNode) );
+ if (cfg_name == "Ti") {
+ Ti.push_back( new InputValue(prop_root, cfg_node) );
return true;
}
- if (nodeName == "Td") {
- Td.push_back( new InputValue(configNode) );
+ if (cfg_name == "Td") {
+ Td.push_back( new InputValue(prop_root, cfg_node) );
return true;
}
- if (nodeName == "beta") {
- beta = configNode->getDoubleValue();
+ if (cfg_name == "beta") {
+ beta = cfg_node.getDoubleValue();
return true;
}
- if (nodeName == "alpha") {
- alpha = configNode->getDoubleValue();
+ if (cfg_name == "alpha") {
+ alpha = cfg_node.getDoubleValue();
return true;
}
- if (nodeName == "gamma") {
- gamma = configNode->getDoubleValue();
+ if (cfg_name == "gamma") {
+ gamma = cfg_node.getDoubleValue();
return true;
}
- SG_LOG( SG_AUTOPILOT, SG_BULK, "PIDController::configure(" << nodeName << ") [unhandled]" << endl );
+ SG_LOG
+ (
+ SG_AUTOPILOT,
+ SG_BULK,
+ "PIDController::configure(" << cfg_name << ") [unhandled]"
+ );
return false;
}
double elapsedTime; // elapsed time (sec)
protected:
- bool configure( const std::string & nodeName, SGPropertyNode_ptr configNode);
+ virtual bool configure( SGPropertyNode& cfg_node,
+ const std::string& cfg_name,
+ SGPropertyNode& prop_root );
public:
PIDController();
~PIDController() {}
using namespace FGXMLAutopilot;
-using std::endl;
-using std::cout;
-
+//------------------------------------------------------------------------------
PISimpleController::PISimpleController() :
AnalogComponent(),
_int_sum( 0.0 )
{
}
-bool PISimpleController::configure( const std::string& nodeName, SGPropertyNode_ptr configNode)
+//------------------------------------------------------------------------------
+bool PISimpleController::configure( SGPropertyNode& cfg_node,
+ const std::string& cfg_name,
+ SGPropertyNode& prop_root )
{
- if( AnalogComponent::configure( nodeName, configNode ) )
+ if( AnalogComponent::configure(cfg_node, cfg_name, prop_root) )
return true;
- if( nodeName == "config" ) {
- Component::configure( configNode );
+ if( cfg_name == "config" ) {
+ Component::configure(prop_root, cfg_node);
return true;
}
- if (nodeName == "Kp") {
- _Kp.push_back( new InputValue(configNode) );
+ if (cfg_name == "Kp") {
+ _Kp.push_back( new InputValue(prop_root, cfg_node) );
return true;
}
- if (nodeName == "Ki") {
- _Ki.push_back( new InputValue(configNode) );
+ if (cfg_name == "Ki") {
+ _Ki.push_back( new InputValue(prop_root, cfg_node) );
return true;
}
_int_sum = 0.0;
}
- if ( _debug ) cout << "Updating " << get_name() << endl;
+ if ( _debug ) std::cout << "Updating " << get_name() << std::endl;
double y_n = _valueInput.get_value();
double r_n = _referenceInput.get_value();
double error = r_n - y_n;
- if ( _debug ) cout << "input = " << y_n
+ if ( _debug ) std::cout << "input = " << y_n
<< " reference = " << r_n
<< " error = " << error
- << endl;
+ << std::endl;
double prop_comp = clamp(error * _Kp.get_value());
_int_sum += error * _Ki.get_value() * dt;
if( output != clamped_output ) // anti-windup
_int_sum = clamped_output - prop_comp;
- if ( _debug ) cout << "prop_comp = " << prop_comp
- << " int_sum = " << _int_sum << endl;
+ if ( _debug ) std::cout << "prop_comp = " << prop_comp
+ << " int_sum = " << _int_sum << std::endl;
set_output_value( clamped_output );
- if ( _debug ) cout << "output = " << clamped_output << endl;
+ if ( _debug ) std::cout << "output = " << clamped_output << std::endl;
}
double _int_sum;
protected:
- bool configure( const std::string & nodeName, SGPropertyNode_ptr configNode );
+ virtual bool configure( SGPropertyNode& cfg_node,
+ const std::string& cfg_name,
+ SGPropertyNode& prop_root );
public:
using namespace FGXMLAutopilot;
-using std::endl;
-using std::cout;
-
+//------------------------------------------------------------------------------
Predictor::Predictor () :
- AnalogComponent(),
- _average(0.0)
+ AnalogComponent(),
+ _last_value(0),
+ _average(0)
{
}
-bool Predictor::configure(const std::string& nodeName, SGPropertyNode_ptr configNode)
+//------------------------------------------------------------------------------
+bool Predictor::configure( SGPropertyNode& cfg_node,
+ const std::string& cfg_name,
+ SGPropertyNode& prop_root )
{
- SG_LOG( SG_AUTOPILOT, SG_BULK, "Predictor::configure(" << nodeName << ")" << endl );
+ SG_LOG( SG_AUTOPILOT, SG_BULK, "Predictor::configure(" << cfg_name << ")");
- if( AnalogComponent::configure( nodeName, configNode ) )
+ if( AnalogComponent::configure(cfg_node, cfg_name, prop_root) )
return true;
- if( nodeName == "config" ) {
- Component::configure( configNode );
+ if( cfg_name == "config" ) {
+ Component::configure(prop_root, cfg_node);
return true;
}
- if (nodeName == "seconds") {
- _seconds.push_back( new InputValue( configNode, 0 ) );
+ if (cfg_name == "seconds") {
+ _seconds.push_back( new InputValue(prop_root, cfg_node, 0) );
return true;
}
- if (nodeName == "filter-gain") {
- _filter_gain.push_back( new InputValue( configNode, 0 ) );
+ if (cfg_name == "filter-gain") {
+ _filter_gain.push_back( new InputValue(prop_root, cfg_node, 0) );
return true;
}
- SG_LOG( SG_AUTOPILOT, SG_BULK, "Predictor::configure(" << nodeName << ") [unhandled]" << endl );
+ SG_LOG
+ (
+ SG_AUTOPILOT,
+ SG_BULK,
+ "Predictor::configure(" << cfg_name << ") [unhandled]"
+ );
return false;
}
+//------------------------------------------------------------------------------
void Predictor::update( bool firstTime, double dt )
{
double ivalue = _valueInput.get_value();
_last_value = ivalue;
}
-
-
InputValueList _filter_gain;
protected:
- bool configure(const std::string& nodeName, SGPropertyNode_ptr configNode );
+ virtual bool configure( SGPropertyNode& cfg_node,
+ const std::string& cfg_name,
+ SGPropertyNode& prop_root );
public:
Predictor();