1
0
Fork 0

- fix the <condition> element which was no longer working due to an invalid property root

- allow multiple <autopilot> elements within an aircraft. All autopilot live in an individual FGXMLAutopilot subsystem which run within a subsystem group now.
This commit is contained in:
torsten 2009-11-27 15:12:34 +00:00 committed by Tim Moore
parent 6fcd9f967b
commit 179a799333
3 changed files with 98 additions and 39 deletions

View file

@ -69,7 +69,7 @@ void FGXMLAutoInput::parse( SGPropertyNode_ptr node, double aValue, double aOffs
SGPropertyNode * n; SGPropertyNode * n;
if( (n = node->getChild("condition")) != NULL ) { if( (n = node->getChild("condition")) != NULL ) {
_condition = sgReadCondition(node, n); _condition = sgReadCondition(fgGetNode("/"), n);
} }
if( (n = node->getChild( "scale" )) != NULL ) { if( (n = node->getChild( "scale" )) != NULL ) {
@ -200,7 +200,7 @@ void FGXMLAutoComponent::parseNode(SGPropertyNode* aNode)
debug = child->getBoolValue(); debug = child->getBoolValue();
} else if ( cname == "enable" ) { } else if ( cname == "enable" ) {
if( (prop = child->getChild("condition")) != NULL ) { if( (prop = child->getChild("condition")) != NULL ) {
_condition = sgReadCondition(child, prop); _condition = sgReadCondition(fgGetNode("/"), prop);
} else { } else {
if ( (prop = child->getChild( "prop" )) != NULL ) { if ( (prop = child->getChild( "prop" )) != NULL ) {
enable_prop = fgGetNode( prop->getStringValue(), true ); enable_prop = fgGetNode( prop->getStringValue(), true );
@ -793,6 +793,83 @@ void FGDigitalFilter::update(double dt)
} }
} }
FGXMLAutopilotGroup::FGXMLAutopilotGroup()
{
}
void FGXMLAutopilotGroup::reinit()
{
for( vector<string>::size_type i = 0; i < _autopilotNames.size(); i++ ) {
FGXMLAutopilot * ap = (FGXMLAutopilot*)get_subsystem( _autopilotNames[i] );
if( ap == NULL ) continue; // ?
remove_subsystem( _autopilotNames[i] );
delete ap;
}
_autopilotNames.clear();
init();
}
void FGXMLAutopilotGroup::init()
{
vector<SGPropertyNode_ptr> autopilotNodes = fgGetNode( "/sim/systems", true )->getChildren("autopilot");
if( autopilotNodes.size() == 0 ) {
SG_LOG( SG_ALL, SG_WARN, "No autopilot configuration specified for this model!");
return;
}
for( vector<SGPropertyNode_ptr>::size_type i = 0; i < autopilotNodes.size(); i++ ) {
SGPropertyNode_ptr pathNode = autopilotNodes[i]->getNode( "path" );
if( pathNode == NULL ) {
SG_LOG( SG_ALL, SG_WARN, "No autopilot configuration file specified for this autopilot!");
continue;
}
string apName;
SGPropertyNode_ptr nameNode = autopilotNodes[i]->getNode( "name" );
if( nameNode != NULL ) {
apName = nameNode->getStringValue();
} else {
std::ostringstream buf;
buf << "unnamed_autopilot_" << i;
apName = buf.str();
}
if( get_subsystem( apName.c_str() ) != NULL ) {
SG_LOG( SG_ALL, SG_ALERT, "Duplicate autopilot configuration name " << apName << " ignored" );
continue;
}
SGPath config( globals->get_fg_root() );
config.append( pathNode->getStringValue() );
SG_LOG( SG_ALL, SG_INFO, "Reading autopilot configuration from " << config.str() );
// FGXMLAutopilot
FGXMLAutopilot * ap = new FGXMLAutopilot;
try {
SGPropertyNode_ptr root = new SGPropertyNode();
readProperties( config.str(), root );
if ( ! ap->build( root ) ) {
SG_LOG( SG_ALL, SG_ALERT,
"Detected an internal inconsistency in the autopilot configuration." << endl << " See earlier errors for details." );
delete ap;
continue;
}
} catch (const sg_exception& e) {
SG_LOG( SG_ALL, SG_ALERT, "Failed to load autopilot configuration: "
<< config.str() << ":" << e.getMessage() );
delete ap;
continue;
}
SG_LOG( SG_ALL, SG_INFO, "adding autopilot subsystem " << apName );
set_subsystem( apName, ap );
_autopilotNames.push_back( apName );
}
SGSubsystemGroup::init();
}
FGXMLAutopilot::FGXMLAutopilot() { FGXMLAutopilot::FGXMLAutopilot() {
} }
@ -802,38 +879,11 @@ FGXMLAutopilot::~FGXMLAutopilot() {
} }
void FGXMLAutopilot::init() { /* read all /sim/systems/autopilot[n]/path properties, try to read the file specified therein
config_props = fgGetNode( "/autopilot/new-config", true ); * and configure/add the digital filters specified in that file
*/
SGPropertyNode *path_n = fgGetNode("/sim/systems/autopilot/path"); void FGXMLAutopilot::init()
{
if ( path_n ) {
SGPath config( globals->get_fg_root() );
config.append( path_n->getStringValue() );
SG_LOG( SG_ALL, SG_INFO, "Reading autopilot configuration from "
<< config.str() );
try {
readProperties( config.str(), config_props );
if ( ! build() ) {
SG_LOG( SG_ALL, SG_ALERT,
"Detected an internal inconsistency in the autopilot");
SG_LOG( SG_ALL, SG_ALERT,
" configuration. See earlier errors for" );
SG_LOG( SG_ALL, SG_ALERT,
" details.");
exit(-1);
}
} catch (const sg_exception& e) {
SG_LOG( SG_ALL, SG_ALERT, "Failed to load autopilot configuration: "
<< config.str() << ":" << e.getMessage() );
}
} else {
SG_LOG( SG_ALL, SG_WARN,
"No autopilot configuration specified for this model!");
}
} }
@ -849,7 +899,7 @@ void FGXMLAutopilot::bind() {
void FGXMLAutopilot::unbind() { void FGXMLAutopilot::unbind() {
} }
bool FGXMLAutopilot::build() { bool FGXMLAutopilot::build( SGPropertyNode_ptr config_props ) {
SGPropertyNode *node; SGPropertyNode *node;
int i; int i;
@ -858,6 +908,7 @@ bool FGXMLAutopilot::build() {
node = config_props->getChild(i); node = config_props->getChild(i);
string name = node->getName(); string name = node->getName();
// cout << name << endl; // cout << name << endl;
SG_LOG( SG_ALL, SG_INFO, "adding autopilot component " << name );
if ( name == "pid-controller" ) { if ( name == "pid-controller" ) {
components.push_back( new FGPIDController( node ) ); components.push_back( new FGPIDController( node ) );
} else if ( name == "pi-simple-controller" ) { } else if ( name == "pi-simple-controller" ) {

View file

@ -357,6 +357,16 @@ public:
* *
*/ */
class FGXMLAutopilotGroup : public SGSubsystemGroup
{
public:
FGXMLAutopilotGroup();
void init();
void reinit();
private:
std::vector<std::string> _autopilotNames;
};
class FGXMLAutopilot : public SGSubsystem class FGXMLAutopilot : public SGSubsystem
{ {
@ -371,16 +381,14 @@ public:
void unbind(); void unbind();
void update( double dt ); void update( double dt );
bool build();
bool build( SGPropertyNode_ptr );
protected: protected:
typedef std::vector<SGSharedPtr<FGXMLAutoComponent> > comp_list; typedef std::vector<SGSharedPtr<FGXMLAutoComponent> > comp_list;
private: private:
bool serviceable; bool serviceable;
SGPropertyNode_ptr config_props;
comp_list components; comp_list components;
}; };

View file

@ -1537,7 +1537,7 @@ bool fgInitSubsystems() {
// Initialize the XML Autopilot subsystem. // Initialize the XML Autopilot subsystem.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
globals->add_subsystem( "xml-autopilot", new FGXMLAutopilot ); globals->add_subsystem( "xml-autopilot", new FGXMLAutopilotGroup );
globals->add_subsystem( "route-manager", new FGRouteMgr ); globals->add_subsystem( "route-manager", new FGRouteMgr );
globals->add_subsystem( "autobrake", new FGAutoBrake ); globals->add_subsystem( "autobrake", new FGAutoBrake );