The autopilot has grown beyond being just an autopilot. It's
components, filters and controllers could be used to set property
values based on complex rules and driven from other property values.
That's why I chose to give it the name "property-rule".
This patch allows to define an arbitrary number of property rules under
a/sim/property-rule[n]/path
using the same syntax as autopilot configurations.
Add helper to look for an aircraft branch path in multiple candidate locations.
Update the main subsystems to use the helper, and hence load from any aircraft dir.
- Respect the global inverted flag in the get_output() method
- Check the clock state before processing the static R/S inputs
- Emit debug output only on a state change
Split the former single-file-implementation in xmlauto.?xx into multiple
files and use some OO techniques. Started with documentation to be used
with doxygen.
- reuse code
- undeclared inputs default to false where applicable
- remove unused tInput
- JK, D and T FF now inherit from RS with dominant R input, so they all
have a R and a S input to preset the output
- fix the nonfunctional <inverted> element of the logic element
Old calculation was
output = input * gain
and is now
output = (input-reference) * gain
Note: the PI(D) controller use (reference-input) which effectively reverses the sign. Our notation was picked for backwards compatibility to not break the myriads of <filter> elements currently existing.
All the rest is some code cleanup.
"logic filters" use well known conditions to drive output properties. Example for bax = baz & (foo | bar).
<logic>
<name>my first logic element</name>
<input>
<or>
<property>foo</property>
<property>bar</property>
</or>
<property>baz</property>
</input>
<output>bax</output>
</logic>
Supports various new editing features, including dragging to re-order, and
+/- keys to adjust the target altitude for a waypoint. Also displays some
additional information, and will display *even* more once I land airways/
SID/STAR support.
- default to an invalid altitude in routes, instead of cruise altitude (temporarily)
- only set an altitude on the autopilot, if valid
- only add departure airport/runway to the route, if not airborne
- allow multiple <autopilot> elements within an aircraft. All autopilot live in an individual FGXMLAutopilot subsystem which run within a subsystem group now.
* When the nav-radio is slaved, calculated radial/target-hdg-deg
(needed by some autopilot logic)
* Handle editing (including deletion) of route waypoints correctly,
including deleting the active waypoint
* Add a signal to the route manager when the last wpt is reached, and
use it in the GPS to revert to OBS mode.
* Change the altitude handling to use the specified cruise altitude
* Fix a bug where autopilot/locks/altitude was treated as a boolean
<abs>true</abs>
for input elements.
If set to true, the input value is filtered thru fabs() function.
Defaults to false if absent, so there is no impact for existing configurations
- a refactoring of the route manager to reduce indentation and duplication
- created a helper method to generate the ETA strings
- created a helper to update target_altitude and altitude_set when the active wp0 changes
- used early returns to make update() easier to follow
- removed spurious includes in both header and source file
Attached patch updates the route-manager to use FGPositioned to search
for waypoints, instead of a manual airport / fix / navaid search. This
is good because it's now using the 'strictly closest' match, rather
than arbitrarily picking a distant fix over a nearby navaid. In my
case, the TLA VOR is significant to several EGPH procedures, but also
happens to be the ident of a fix a long, long way away.
Also updates the FGPositioned class to stop using Point3D, partly
because it's deprecated and partly because I had misunderstood the
interface and was using it wrong. For now, all FGPositioned distance
checks use SGGeodesy::inverse, which is accurate but inefficient. Once
FGPositioned queries are used for something on a hot path, I'll
probably store the cartesian position as well as the geodetic, to make
these checks fast.
Here's part 2 - converting FGFix (the simplest one) to be both heap-based and inherit FGPositioned. One minor benefit from this is replacing some dangerous code in FGFixList which used to return the address of an iterator member ('&it->second'). To keep the diff a sensible size, I'm not updating the callers to use the richer FGPositioned types - i.e replacing separate lat/lon handling with SGGeod. I will make those cleanups, but in future patches.
- this exposed a bizarre issue on Mac where dragging in <AGL/agl.h> in
extensions.hxx was pulling in all of Carbon to the global namespace
- very scary. As a result, I now need to explicitly include CoreFoundation
in fg_init.cxx.
- change SG_USING_STD(x) to using std::x
SimGear change. It changes all the SG_xxxx to be the 'real' includes, and gets
rid of many #ifdef SG_HAVE_STD_INCLUDES. As an added bonus, rather than
replacing 'SG_USING_NAMESPACE(std)' with 'using namespace std', I just fixed
the small number of places to use std:: explicitly. So we're no longer polluting
the global namespace with the entire contents of std, in many cases.
There is one more 'mechanical' change to come - getting rid of SG_USING_STD(X),
but I want to keep that separate from everything else. (There's another
mechnical change, replacing <math.h> with <cmath> and so on *everywhere*, but
one step at a time)
Attached patch adds support for multiple FIXes with the same name.
Applies to both branches.
New functionality is in query_and_offset, which now returns the FIX
closest to the passed in location.
Updated route manager to take advantage of this.
Otherwise, query functions return an unspecified member from the set
of identically named FIXes. (This was previously the one occurring
last in the database file, but I don't think anybody counted on that.)
Thanks to Vivian Meazza for debugging this. The output deque for
FGDigitalFilter was not being kept long enough for the
doubleExponential filter. Reads from output[1] could cause a crash.
Lee has added two new filter types, "gain" and "reciprocal". These filters can
read their gain factor from a property. In the process we also added minimum
and maximum output clamps that are applicable to all filters.
I added the ability to configure adaptive controllers i.e. the controller gain
can be tied to a property, so that it can be changed at runtime. This
requires a change in the xml structure of the autopilot configuration file:
<Kp>
<prop>/autopilot/KAP140/settings/ROL/Kp</prop>
<value>0.10</value>
</Kp> <!-- proportional gain -->
The old method <Kp>0.10</Kp> still works so as to not break all existing
autopilots, but it will output a warning to use the new method.
Please find attatched a new version of xmlauto.cxx.
Remove the call to build() in reinit(). This prevents build() from being
called twice when Reload Autopilot is selected from the Debug menu.
I've also added the ability to define an enabled property for the filters.
It's used like the PID controllers. If there is no enabled tag then the
filter defaults to enabled so that nothing should get broken by this change.
This ability can be used to create a filter between the output of a PID
controller and the property that it controls (a control surface). By putting
a noise spike filter between the output of a controller and the control
surface that it controls, we can simulate the limited movement rate that is
inherent in autopilot servos.
autopilot with the servos off. In otherwords, the computer goes through the
motions of computing the desired behavior (pitch or roll) but doesn't actually
drive the outputs. This is potentially useful when implimenting a flight
director.
SGPropertyNode to guarded ones. This is also done for JSBSim/JSBSim.hxx,
for which JSB had given explicit permission a while ago. I postponed that
back then, but now is the time.
The ufo sets this to a very low value, "serious" aircraft (which don't want this
unrealistic automatism at all) set it to a very high value, and those that don't
care ... don't need to care.
there was the situation where four directories contained jst two files,
of which three directories were aircraft related, and one directory contained
test code from Curt that might be better of in SimGear anyhow.
This is just a patch to move a bunch of files to new locations. In case of
local changes to any of them you can do the following:
move replay.[ch]xx from src/Replay to src/Aircraft
move control.[ch]xx from src/Control to src/Aircraft
move ssgEntityArray.[ch]xx from src/Objects to simgear/screen
In addition it has been decided only to use .[ch]xx files in all directories
unless it's contained within an FDM specific directory, in which case the
author is free to do whatever (s)he wants.
In this repspect the following files have been renamed in src/Multiplayer:
tiny_xdr.[ch]pp has become tiny_xdr.[ch]xx
multiplaymgr.[ch]pp has become multiplaymgr.[ch]xx
* Use "const string&" rather than "string" in function calls when appropriate.
* Use "const Point3D&" instead of "Pint3D" in function calls when appropriate.
* Improved course calculation in calc_gc_course_dist()
* Safer thread handling code.
Vassilii Khachaturov:
Dont use "const Point3D&" for return types unless you're absolutely sure.
Erik Hofman:
* Use SGD_(2)PI(_[24]) as defined in simgear/constants.h rather than
calculating it by hand every time.
I found that all the current users of the companion
function, findByFreq() actually did assume radians despite the misleading
comment in the .hxx and .cxx saying it's degrees. I've fixed the
comment now, and no longer change the Navaids code. The new Navaids user
in NewWaypoint() is now passing radians to the findByIdent().
Note that along with fixing the comments in the navlist.hxx, I removed
an obsolete method findByLoc() declaration (there is no definition
anywhere).
I've prepared a patch as suggested by Hans-Georg Wunder and Jeff McBride.
In addition I've removed the ability to completely leave out the integral
action by setting Ti to zero. The velocity form of the PID algorithm _needs_
the integral action.
>> Hello List,
>>
>> I think there's a small bug in the moving-average filter in
>> xmlauto.cxx
>>
>> I noticed that the output from it was always out a bit and
>> checking with a calculator showed that it seemed to be dividing
>> by the number of samples + 1 instead of just the number of
>> samples.
>>
>> subtracting 1 from 'samples' in line 702 seems to fix the problem
>> and as 'samples' doesn't seem to be used elsewhere I think it's
>> safe. Possibly implies that the number of samples may be one
>> less than specified but I'm not familiar enough with c++ to spot
>> it.
Roy Ovesen:
You are right. I would suggest resizing input[] to (samples + 1) instead.
Change lines 654 and 661 to:
input.resize(samples + 1, 0.0);
That way we average over the number of samples as configured.
I just heard from John Wojnaroski that you and he are going to work on getting
a flightgear demo machine up for the linux expo thursday and Friday. John
indicated that he would very much like to get a CVS version with the new
traffic code up and running before the expo.
I've added some features to the PID controller:
Ability to set desired sampling interval in seconds. Use <Ts> under <config>
to set the desired sampling interval of the PID controller.
Example:
<config>
<Ts>0.1</Ts> <!-- desired sampling interval -->
<Kp>-0.05</Kp> <!-- proportional gain -->
<beta>1.0</beta> <!-- input value weighing factor -->
...
...
</config>
Ts defaults to 0.0, so if you don't set it it samples at the highest possible
frequency.
Add an offset to the input variables (input and reference).
Example:
<reference>
<prop>/controls/flight/elevator</prop>
<scale>-1.5</scale>
<offset>1.0</offset>
</reference>
Note that <scale> has higher precedence than <offset>, regardless of the order
that they appear in the config file.
a single apt.dat.gz file which is in the native X-Plane format.
To do this I wrote a front end loader than builds the airport and runway
list. Some of the changes I needed to make had a cascading effect, so there
are minor naming changes scattered throughout the code.
I've added some digital filters to the autopilot. They are all low-pass
filters that filter away high frequency signals/noise. There are 4 different
filters:
1. Exponential - The algorithm is essentially the same as the one used in the
fgGetLowPass() function.
2. Double exponential - Two exponential filters in series. This filter has a
"steeper" frequency response curve. It filters "better" than the single
exponential.
3. Moving average - Averages a number of inputs.
4. Noise spike - limits the amount that the output value can change from one
sample to the next.
Filters 1 and 2 are characterised by it's filter-time in seconds. For filter 3
you have to set the number of input samples to average over. For filter 4 you
set the maximum allowed rate of change as [1/s]. Since the sampling interval
(dt) isn't constant we have to calculate the maximum allowed change for every
update.
Example of a double exponential filter with filter time 0.1 seconds, that is
1/0.1 = 10 Hz.
<filter>
<name>pressure-rate-filter</name>
<debug>true</debug>
<type>double-exponential</type>
<input>/autopilot/internal/pressure-rate</input>
<output>/autopilot/internal/filtered-pressure-rate</output>
<filter-time>0.1</filter-time>
</filter>
This would go in the autopilot configuration file.
I've also removed the filtering of the "pressure-rate" helper value, use the
new filters if you want to filter it! ;-)
This patch adds the ability to do a simple scaling of input without having to
add hardcoded helpers. Example:
<reference>
<prop>/autopilot/settings/vertical-speed-fpm</prop>
<scale>0.01667</scale>
</reference>
Add FGPredictor class to xmlauto. Add support for horizontal navigation based
on flight track as opposed to heading. Add crosstrack-error support to nav.
Simplify error adjust calculation for horizontal nav (better interception).
Fixed potential divide by zero that was producing nan issues in the xmlauto
code.
I've done some changes to xmlauto.cxx.
Only calculate the derivate filtering if derivate time Td is greater than
zero. This means that one can set Td=0.0 in the xml file to completely remove
the derivate action. (Setting Td to zero in the current version would lead to
a division by zero and crash.)
Setting the integrator time Ti to zero doesn't make sense, right! I've
modified so that setting Ti to zero results in the integral action being
completely removed.
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.