©2004,2008 Jim E. Brooks http://www.palomino3d.org
[2008/05]
The control module is a higher-level module (Mediator class) that handles system-neutral input propagated by the lower-level input module. control module has the joystick configuration. If the joystick is enabled, control will manipulate the current Aircraft in response to joystick events. The control module no longer needs to be involved in keyboard handling (see Lua Scripting).
+----------------+ | application | +----------------+ | control module | +----------------+ | input module | +----------------+ | device drivers | +----------------+
[2008/01]
An aircraft's rate-of-roll/pitch/yaw is computed by the physics code. The joystick/keyboard handlers in the control module rotate the "current craft" by calling Aircraft::PhysicalRotate(). Args passed are the level of control input (0.0,..,1.0 : 1.0 is all-the-way) and the frequency of polling control input. Internally, PhysicalRotate() computes an absolute/graphical degree that is passed to Aircraft::Rotate().
[2008/01]
There are two unrelated Joystick classes (Singletons):
input::Joystick and control::Joystick.
This documents control::Joystick.
control::Joystick is the higher-level joystick class. It is a client of the low-level input::Joystick. Note that input::Joystick is very simple: it enqueues raw axis/button values, and nothing else. Therefore, control::Joystick contains most of the higher-level joystick functionality. It does enabling, configuring, remapping, calibrating, and some handling of events. It handles axis events by controlling the current Aircraft. But it defers button events to listeners in the application.
control::Joystick is based on a joystick with 4 logical axises (roll/pitch/yaw/throttle). Joystick configuration is defined by joystick.conf. The configuration defines the mapping between logical and physical axises, and axis calibration.
The higher-level joystick code is based on 4 logical axises.
0 = roll (left/right) joy X by convention 1 = pitch (up/down) joy Y by convention 2 = yaw 3 = throttle
[2008/08]
The simulator abstracts control of a Aircraft in a Command
object.
The Aircraft class broadcasts control actions (rotation, throttle, brakes, etc)
in events containing a Command object.
Conversely, a Command object can apply a command to a Aircraft.
For example, Replay listens for Command events for a particular Aircraft and stores Commands in a container. To do a replay, Command::Execute(Aircraft) is called for every stored Command.
Command events could be used to network simulators.
[2008/09]
Replay registers a listener for Command events (roll, throttle, brakes, gear-down, etc) from a particular Aircraft. Replay stores Command objects with a time-stamp (Step class) in a STL container. To do a replay, the commands are replayed by calling Command::Execute(Aircraft).
Control replay means replaying events from input while being affected by the physics model. Graphical replay means replaying transformations. For example, recording a replay while piloting a F-15 Eagle, then applying a graphical replay to Spitfire would be unrealistic. But, a stored replay for Aircrafts with similar performance may be useful. Therefor, Replay records both types of data, but can replay either type (or a mixture) as needed.
To save space, the replay data is compressed by zlib, rotations are stored as quaternions, and only steps that change (keyframes) are stored. Since graphical coordinates vary according to different missions, the position of a Aircraft converted to geo coordinates before storing. Replay::Play() can be passed a parameter to animate replays in different geo positions..
Replay data is saved to a file compressed using zlib (replay.dat.gz).
Writing is done using gzstream
.
The format is human-readable.
The first line is the version info (replay format).
The following few lines provide other info and initial state.
The bulk of the lines are commands to control a Aircraft,
which begin with a time-stamp field (milliseconds),
then the serialized Command.
When recording first starts, the current state of the Aircraft is saved
(the lines with milliseconds=0).
In physics replay mode, phyRot
(rotate using physics)
are applied while qaut
(graphical rotation) are ignored.
version 3 craft F18Aircraft world flat 0 pos 8007 -15527.5 -528.25 0 quat 0.710016 0.0154926 0.015358 0.703847 0 throt 0 0 kph 0 0 gear 1 0 brake 0 363 throt 0.0629749 396 pos 7997 -15697 -528.25 443 kph 2.33392 458 throt 0.988189 3842 pos 7987.05 -15630.4 -528.25 3945 quat 0.70991 0.0527554 0.0520474 0.700383
Replay is factored as these classes:
The class Replay is the interface. ReplayRecorder and ReplayPlayer both contain shared pointer to a ReplayPath. After recording, the player is given the shared pointer to the recorded path.
ReplayPath::Cursor naturally tracks the current step in the animation path. But it also will lookahead to future steps that control position/rotation. Cursor maintains a pair of position/rotation steps that the player will interpolate to smooth animation across timer-ticks that occur late (if program is running slow).
[2008/05]
The control module once had keyboard handling, but was eliminated after keyboard handlers were implemented by Lua scripts which directly use InputQueue.The joystick C++ code in the control module survives because it's faster than Lua and its handling of axis events remains appropriate. But handling of button events is mission-specific, so the lua_bind module (sim.Joystick in Lua) registers a listener and provides an interface for Lua scripts to poll for button events. In summary, the control::Joystick interface remains the same as in previous versions but is used differently for Lua scripting.
Last modified: Sat Oct 4 13:12:05 EDT 2008