1 // autopilotgroup.cxx - an even more flexible, generic way to build autopilots
3 // Written by Torsten Dreyer
4 // Based heavily on work created by Curtis Olson, started January 2004.
6 // Copyright (C) 2004 Curtis L. Olson - http://www.flightgear.org/~curt
7 // Copyright (C) 2010 Torsten Dreyer - Torsten (at) t3r (dot) de
9 // This program is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU General Public License as
11 // published by the Free Software Foundation; either version 2 of the
12 // License, or (at your option) any later version.
14 // This program is distributed in the hope that it will be useful, but
15 // WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 // General Public License for more details.
19 // You should have received a copy of the GNU General Public License
20 // along with this program; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
28 #include "autopilot.hxx"
29 #include "autopilotgroup.hxx"
34 #include <simgear/props/props_io.hxx>
35 #include <simgear/structure/subsystem_mgr.hxx>
36 #include <simgear/structure/exception.hxx>
37 #include <Main/fg_props.hxx>
38 #include <boost/foreach.hpp>
41 using simgear::PropertyList;
42 using FGXMLAutopilot::Autopilot;
44 class FGXMLAutopilotGroupImplementation:
45 public FGXMLAutopilotGroup
48 FGXMLAutopilotGroupImplementation(const std::string& nodeName):
49 FGXMLAutopilotGroup(),
53 virtual void addAutopilot( const std::string& name,
54 SGPropertyNode_ptr apNode,
55 SGPropertyNode_ptr config );
56 virtual void removeAutopilot( const std::string & name );
58 InitStatus incrementalInit();
62 void initFrom( SGPropertyNode_ptr rootNode, const char * childName );
63 std::string _nodeName;
67 //------------------------------------------------------------------------------
68 void FGXMLAutopilotGroupImplementation::addAutopilot( const std::string& name,
69 SGPropertyNode_ptr apNode,
70 SGPropertyNode_ptr config )
72 if( has_subsystem(name) )
76 "NOT adding duplicate " << _nodeName << " name '" << name << "'");
80 Autopilot* ap = new Autopilot(apNode, config);
83 double updateInterval = config->getDoubleValue("update-interval-secs", 0.0);
84 set_subsystem( name, ap, updateInterval );
87 //------------------------------------------------------------------------------
88 void FGXMLAutopilotGroupImplementation::removeAutopilot(const std::string& name)
90 Autopilot* ap = static_cast<Autopilot*>(get_subsystem(name));
95 "CAN NOT remove unknown " << _nodeName << " '" << name << "'");
99 remove_subsystem(name);
102 //------------------------------------------------------------------------------
103 void FGXMLAutopilotGroupImplementation::reinit()
105 SGSubsystemGroup::unbind();
111 //------------------------------------------------------------------------------
112 SGSubsystem::InitStatus FGXMLAutopilotGroupImplementation::incrementalInit()
118 //------------------------------------------------------------------------------
119 void FGXMLAutopilotGroupImplementation::init()
121 initFrom(fgGetNode("/sim/systems"), _nodeName.c_str());
123 SGSubsystemGroup::bind();
124 SGSubsystemGroup::init();
127 //------------------------------------------------------------------------------
128 void FGXMLAutopilotGroupImplementation::initFrom( SGPropertyNode_ptr rootNode,
129 const char* childName )
134 BOOST_FOREACH( SGPropertyNode_ptr autopilotNode,
135 rootNode->getChildren(childName) )
137 SGPropertyNode_ptr pathNode = autopilotNode->getNode("path");
144 "No configuration file specified for this " << childName << "!"
150 SGPropertyNode_ptr nameNode = autopilotNode->getNode( "name" );
151 if( nameNode != NULL ) {
152 apName = nameNode->getStringValue();
154 std::ostringstream buf;
155 buf << "unnamed_autopilot_" << autopilotNode->getIndex();
160 // check for duplicate names
161 std::string name = apName;
162 for( unsigned i = 0; get_subsystem( apName.c_str() ) != NULL; i++ ) {
163 std::ostringstream buf;
164 buf << name << "_" << i;
172 "Duplicate " << childName << " configuration name " << name
173 << ", renamed to " << apName
177 addAutopilotFromFile(apName, autopilotNode, pathNode->getStringValue());
181 void FGXMLAutopilotGroup::addAutopilotFromFile( const std::string& name,
182 SGPropertyNode_ptr apNode,
185 SGPath config = globals->resolve_maybe_aircraft_path(path);
186 if( config.isNull() )
192 "Cannot find property-rule configuration file '" << path << "'."
200 "Reading property-rule configuration from " << config.str()
205 SGPropertyNode_ptr configNode = new SGPropertyNode();
206 readProperties( config.str(), configNode );
208 SG_LOG(SG_AUTOPILOT, SG_INFO, "adding property-rule subsystem " << name);
209 addAutopilot(name, apNode, configNode);
211 catch (const sg_exception& e)
217 "Failed to load property-rule configuration: " << config.str()
218 << ": " << e.getMessage()
224 //------------------------------------------------------------------------------
226 FGXMLAutopilotGroup::createInstance(const std::string& nodeName)
228 return new FGXMLAutopilotGroupImplementation(nodeName);