1 // analogcomponent.hxx - Base class for analog autopilot components
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.
23 #ifndef __ANALOGCOMPONENT_HXX
24 #define __ANALOGCOMPONENT_HXX 1
26 #include "inputvalue.hxx"
27 #include "component.hxx"
29 namespace FGXMLAutopilot {
32 * @brief Base class for analog autopilot components
34 * Each analog component has
36 * <li>one value input</li>
37 * <li>one reference input</li>
38 * <li>one minimum clamp input</li>
39 * <li>one maximum clamp input</li>
40 * <li>an optional periodical definition</li>
43 class AnalogComponent : public Component {
47 * @brief a flag signalling that the output property value shall be fed back
48 * to the active input property if this component is disabled. This flag
49 * reflects the <feedback-if-disabled> boolean property.
51 bool _feedback_if_disabled;
55 * @brief the value input
57 InputValueList _valueInput;
60 * @brief the reference input
62 InputValueList _referenceInput;
65 * @brief the minimum output clamp input
67 InputValueList _minInput;
70 * @brief the maximum output clamp input
72 InputValueList _maxInput;
75 * @brief the configuration for periodical outputs
77 PeriodicalValue_ptr _periodical;
80 * @brief A constructor for an analog component. Call configure() to
81 * configure this component from a property node
86 * @brief This method configures this analog component from a property node.
87 * Gets called multiple times from the base class configure method
88 * for every configuration node.
89 * @param cfg_name Name of the configuration node provided in cfg_node
90 * @param cfg_node Configuration node itself
91 * @param prop_root Property root for all relative paths
92 * @return true if the node was handled, false otherwise.
94 virtual bool configure( SGPropertyNode& cfg_node,
95 const std::string& cfg_name,
96 SGPropertyNode& prop_root );
99 * @brief clamp the given value if <min> and/or <max> inputs were given
100 * @param the value to clamp
101 * @return the clamped value
103 double clamp( double value ) const;
106 * @brief overideable method being called from the update() method if this component
107 * is disabled. Analog components feed back it's output value to the active
108 input value if disabled and feedback-if-disabled is true
110 virtual void disabled( double dt );
113 * @brief return the current double value of the output property
114 * @return the current value of the output property
115 * If no output property is configured, a value of zero will be returned.
116 * If more than one output property is configured, the value of the first output property
117 * is returned. The current value of the output property will be clamped to the configured
118 * values of <min> and/or <max>.
120 inline double get_output_value() const {
121 return _output_list.empty() ? 0.0 : clamp(_output_list[0]->getDoubleValue());
124 simgear::PropertyList _output_list;
125 SGPropertyNode_ptr _passive_mode;
127 inline void set_output_value( double value ) {
128 // passive_ignore == true means that we go through all the
129 // motions, but drive the outputs. This is analogous to
130 // running the autopilot with the "servos" off. This is
131 // helpful for things like flight directors which position
132 // their vbars from the autopilot computations.
133 if ( _honor_passive && _passive_mode->getBoolValue() ) return;
134 value = clamp( value );
135 for( simgear::PropertyList::iterator it = _output_list.begin();
136 it != _output_list.end(); ++it)
137 (*it)->setDoubleValue( value );
141 const PeriodicalValue * getPeriodicalValue() const { return _periodical; }
144 inline void AnalogComponent::disabled( double dt )
146 if( _feedback_if_disabled && ! _output_list.empty() ) {
148 if( (input = _valueInput.get_active() ) != NULL )
149 input->set_value( _output_list[0]->getDoubleValue() );
154 #endif // ANALOGCOMPONENT_HXX