1
0
Fork 0

Merge branch 'master' of git://mapserver.flightgear.org/fgdata

This commit is contained in:
Alexis Bory 2011-05-29 15:56:04 +02:00
commit 9a5cee138f
23 changed files with 1633 additions and 600 deletions

View file

@ -13,7 +13,14 @@ Started October 23 2001 by John Check, fgpanels@rockfish.net
<description>Cessna 172P Skyhawk (1981 model)</description>
<author>David Megginson</author>
<status>production</status>
<status>early production</status>
<rating>
<FDM type="int">3</FDM>
<systems type="int">4</systems>
<model type="int">5</model>
<cockpit type="int">4</cockpit>
</rating>
<flight-model archive="y">jsb</flight-model>
<aero archive="y">c172p</aero>

Binary file not shown.

View file

@ -83,8 +83,8 @@ property arguments.
<lat-deg> - Latitude t place the cloud, in degrees (default 0)
<alt-ft> - Altitude to place the cloud, relative to the layer (!) in ft
(default 0)
TODO: Add offset arguments for consistency with add-cloud.
<x-offset-m> - Offset in m from the lon-deg. +ve is south (default 0)
<y-offset-m> - Offset in m from the lat-deg. +ve is east (default 0)
Deleting Individual Clouds
===========================

View file

@ -7,7 +7,7 @@
<body>
<h1>Local Weather Package - v1.0</h1>
<h1>Local Weather Package - v1.1</h1>
<h2>1. Introduction</h2>
@ -15,19 +15,20 @@ The aim of a local weather system is to simulate weather phenomena tied to speci
This is in contrast to the current (v.2.0.0) global weather system of Flightgear where weather changes affect the weather everywhere in the simulated world and are (with few exceptions) not tied to specific locations. In such a system, it is impossible to observe e.g. the approach of a rainfront while flying in sunshine.<p>
The local weather package aims to provide the functionality to simulate such local phenomena. In version 1.0, the package supplies various cloud placement algorithms, as well as local control over most major weather parameters (wind, visibility, pressure, temperature, rain, snow, thermal lift, turbulence...) through interpolation routines and effect volumes. The dynamics of the different systems is tied together - for instance clouds and weather effects drift in the specified wind field. The package also contains a fairly detailed algorithm to generate convective clouds and thermals with a realistic distribution over the various terrain types. There is a simulation of the interaction of the convective cloud system with the terrain as a function of time. Clouds drifting in the wind flow over obstacles, i.e. they change their altitude dynamically. Convection is implemented with a life cycle model of Cumulus clouds - they are generated, evolve for a given lifetime dependent on the underlying terrain and decay at the end of their life cycle. Thermals associated with the clouds follow the same pattern. In particular, in the presence of wind favourable spots for convection generate 'alleys' of dense cloud cover downwind, or thermals and clouds generated over land decay rapidly once they reach open water.<p>
The local weather package aims to provide the functionality to simulate such local phenomena. In version 1.1, the package supplies various cloud placement algorithms, as well as local control over most major weather parameters (wind, visibility, pressure, temperature, rain, snow, thermal lift, turbulence...) through interpolation routines and effect volumes. The dynamics of the different systems is tied together - for instance clouds and weather effects drift in the specified wind field. The package also contains a fairly detailed algorithm to generate convective clouds and thermals with a realistic distribution over the various terrain types. There is a simulation of the interaction of the convective cloud system with the terrain as a function of time. Clouds drifting in the wind flow over obstacles, i.e. they change their altitude dynamically. Convection is implemented with a life cycle model of Cumulus clouds - they are generated, evolve for a given lifetime dependent on the underlying terrain and decay at the end of their life cycle. Thermals associated with the clouds follow the same pattern. In particular, in the presence of wind favourable spots for convection generate 'alleys' of dense cloud cover downwind, or thermals and clouds generated over land decay rapidly once they reach open water.<p>
For long-range flights, the system provides an offline weather system with plausible transitions between different large-scale weather patterns like fronts and low and high pressure areas, as well as the optional use of live METAR data. <p>
<h2>2. Installation</h2>
The package needs to be unpacked in the Flightgear root directory. It writes content into the <i>Nasal/, gui/, gui/dialogs/, Shaders, Effects/, Docs/</i>, and <i>Models/Weather/</i> subdirectories. The installation does not overwrite any of the default Flightgear files, but to be accessible from the menu for Flightgear 2.0.0, one must copy <i>gui/menubar.xml.alt</i> to the default <i>menubar.xml</i> or copy the three lines of the environemnt menu calling <i>local_weather</i>, <i>local_weather_tiles</i> and <i>local_weather_config</i> into the default file. More recent versions of Flightgear already provide the necessary menu items.<p>
The package needs to be unpacked in the Flightgear root directory. It writes content into the <i>Nasal/, gui/, gui/dialogs/, Shaders, Effects/, Docs/</i>, <i>Environment/</i> and <i>Models/Weather/</i> subdirectories. The installation does not overwrite any of the default Flightgear files, but to be accessible from the menu for Flightgear 2.0.0, one must copy <i>gui/menubar.xml.alt</i> to the default <i>menubar.xml</i> or copy the three lines of the environemnt menu calling <i>local_weather</i>, <i>local_weather_tiles</i> and <i>local_weather_config</i> into the default file. More recent versions of Flightgear already provide the necessary menu items. In order to read in the default menu entries, the line <b>&#60;local-weather include="Environment/local-weather-defaults.xml"/&#62;</b> needs to be added to the file <i>preferences.xml</i>.<p>
This adds the items <i>Local Weather</i>, <i>Local Weather Tiles</i> and <i>Local Weather Config</i> to the <i>Environment</i> menu when Flightgear is up. Most of the basic functionality is contained in <i>local_weather.nas</i> which is loaded at startup and identifies itself with a message.<p>
This adds the items <i>Local Weather</i>, <i>Local Weather Tiles</i> and <i>Local Weather Config</i> to the <i>Environment</i> menu when Flightgear is up. Most of the basic functionality is contained in <i>local_weather.nas</i> which is loaded at startup and identifies itself with a message. A compatibility layer (<i>compat_layer.nas</i>) tests for hard-coded support and ensures that, dependent on the version, hard-coded or Nasal-coded fallback functions are used.<p>
Unless asked to do so from the menu, local weather does <b>not</b> run any process in the background. Upon loading, the package does not set any properties already existing, but only generates properties necessary for the menu entries in its own subdirectory <i>/local-weather/</i> in the tree. The package also does a features check on startup if particular functions are available in hard-coded form. If the features are not present, the package will largely still function properly using slower Nasal fallback code.<p>
In order to use the hard-coded terrain presampling routines, it is currently necessary to add the line <b> --prop:/environment/terrain/area[0]/enabled=1</b> to the Flightgear commandline. If this is not done, the system will use the slower fallback routines.<p>
<h2>3. Functionality</h2>
@ -163,7 +164,7 @@ The following pictures show possible results of tile setups 'High-pressure-borde
<h3>Performance settings</h3>
The performance setting menu is available from the main menubar. It controls the allocation of system resources to the various tasks.<p>
The performance setting menu is available from the main menubar. It controls the allocation of system resources to the various tasks, as well as the behaviour of the offline weather system.<p>
<center>
<img src="menu4.jpg">
@ -179,10 +180,16 @@ From this, it is apparent that the two ranges should not be drastically differen
There are additional options to do asymmetric buffering, i.e. to 'cut' out a wedge in the rear of the aircraft in which the tile creation radius or the cloud visibility radius are lower. For example, setting the buffering ratio to 0.2 and the angle to 180 degrees corresponds to a very agressive buffering in which clouds in the rear hemisphere of the aircraft are almost absent and shown only to 20% of the set distance. This may increase performance by 20-30%, but only in straight flight - in fast turns, lots of clouds have to be shuffled from the buffer into the scenery and back, which is actually slower than never trying to cut a wedge at all. Also, agressive asymmetric buffering is not nice in external views as the reference is always the aircraft course.<p>
The last option controls the amout of resources allocated to making clouds drift in the wind if dynamical weather is on. In order to avoid freezes, the weather dynamics system processes only a fixed number of clouds per frame inside the field of view. That means that faraway clouds do not necessarily move even with dynamical weather on. The slider indirectly controls the distance out to which clouds are being processed.<p>
The buffering control can also optionally be tied to a target framerate. In this case, the visible range set with the slider is ignored and a control loop tries to adjust the visible range instead such that a 5-second average of the framerate is within 10% of a specified target framerate. Currently, the subsystem <i>only</i> adjusts the visible range of buffering - asymmetric buffering and/or tile loading range still needs to be specified manually. Also, the system cannot respond to unsolvable problems - if the framerate in the absence of clouds falls below 30, then no setting for the cloud range will bring it to 35. <p>
The next option controls the amout of resources allocated to making clouds drift in the wind if dynamical weather is on. In order to avoid freezes, the weather dynamics system processes only a fixed number of clouds per frame inside the field of view. That means that faraway clouds do not necessarily move even with dynamical weather on. The slider indirectly controls the distance out to which clouds are being processed.<p>
All performance setting menu-options work at runtime, but are processed over time rather than instantaneously, i.e. it takes 10-20 seconds till the new balance between buffered clouds and active clouds is reached after the slider is moved.<p>
The final options, weather pattern scales, deal with the long-range behaviour of the offline weather system. They are not parsed when the tile selection mode is set to <i>METAR</i>. The first slider controls the transition between different airmasses. In the default setting, the typical distance to encounter a different airmass when one flies in a 'High-pressure-core' tile is 200 km. The airmass slider allows to vary this distance between 200 and 800 km. <p>
Inside each tile, there are typically 4-8 different basic cloud patterns (distribution of layers) modelled, with a random pattern selected for each new tile of the given airmass classification. The <i>cloud patterns</i> slider adjusts the probability that the same cloud configuration is kept as long as a tile of the same airmass type is generated. Selecting a large scale in essence means that the theme of clouds will remain similar within each airmass, a small scale allows for more variation.<p>
<h2>4. Cloud models</h2>
The package contains a number of different cloud models, both static ones for Cirrus and Cirrocumulus clouds as well as rotated ones for Altocumulus, Cirrostratus, Cumulus, Cumulonimbus, Stratus and Nimbostratus cloudlet models. Neither the cloud textures, nor the models nor the transformations are perfected, and any aspect can be improved, albeit at the cost of performance consumption.<p>
@ -246,7 +253,7 @@ Effect volumes are always specified between a minimum and a maximum altitude, an
where <i>geometry</i> is a flag (1: circular, 2: elliptical and 3: rectangular), <i>lat</i> and <i>lon</i> are the latitude and longitude, <i>r1</i> and <i>r2</i> are the two size parameters for the elliptic or rectangular shape (for the circular shape, only the first is used), <i>phi</i> is the rotation angle of the shape (not used for circular shape), <i>alt_low</i> and <i>alt_high</i> are the altitude boundaries, <i>vis, rain, snow, turb</i> and <i>lift</i> are weather parameters which are either set to the value they should assume, or to -1 if they are not to be used, or to -2 if a function instead of a parameter is to be used and -3 if a function for wave lift is used. Since thermal lift can be set to negative values in a sink, a separate flag is provided in this case. <i>sat</i> finally determines the light saturation, a parameter between 0 (dark) and 1 (normal light) - it can be used to dim the light beneath cloud layers (which is not done automatically as objects don't cast shades in Flightgear, and given that most cloud models are rotated, their shade would look rather odd on any case).<p>
In version 1.0, thermal lift and wave lift are implemented by function (wave lift is not yet automatically placed, but can be easily from Nasal). There is no easy way to implement any weather parameter by function in an effect volume, as this requires some amount of Nasal coding.<p>
In version 1.1, thermal lift and wave lift are implemented by function (wave lift is not yet automatically placed, but can be easily from Nasal). There is no easy way to implement any weather parameter by function in an effect volume, as this requires some amount of Nasal coding.<p>
Both thermal lift and saturation require a more recent version of Flightgear than 2.0.0 in order to take effect.<p>
@ -362,7 +369,7 @@ With default settings, the local weather package generates a 40x40 km weather ti
<li> Rain and snow may not start properly. For me, rain is only generated when I switch 'Shader effects' on and off in the menu on startup, otherwise neither moving the menu slider nor entering an effect volume generate rain. This seems to be a bug of some Flightgear versions, not of the local weather system.<p>
<li> Especially with multiple overcast layers and weather fronts, loading and unloading weather tiles may take a long time / cause severe drops in framerate. It seems that a dual core processor is very valuable with this particular issue - try switching multiprocessor support on if needed, otherwise please refer to performance tuning to solve such problems. In general, overcast layers and tropical weather tiles do require a system on the high end of the performance scale to render properly.<p>
<li> Especially with multiple overcast layers and weather fronts, loading and unloading weather tiles may take a long time / cause severe drops in framerate. It seems that a dual core processor is very valuable with this particular issue - try switching multiprocessor support on if needed, otherwise please refer to performance tuning to solve such problems. In more recent versions of Flightgear, an activated texture cache improves performance dramatically. In general, overcast layers and tropical weather tiles do require a system on the high end of the performance scale to render properly.<p>
<li> The local weather package is able to occasionally trigger errors like 'Warning:: Picked up error in TriangleIntersect'. These seem to be a problem in the core Flightgear code - the package does nothing but placing normal (rather simple) AC3D models into the scenery.<p>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View file

@ -0,0 +1,106 @@
<PropertyList>
<config>
<asymmetric-buffering-flag type="bool" userarchive="y">0</asymmetric-buffering-flag>
<asymmetric-buffering-reduction type="double" userarchive="y">0.3</asymmetric-buffering-reduction>
<asymmetric-buffering-angle-deg type="double" userarchive="y">90.0</asymmetric-buffering-angle-deg>
<distance-to-load-tile-m type="double" userarchive="y">39000.0</distance-to-load-tile-m>
<distance-to-remove-tile-m type="double" userarchive="y">39500.0</distance-to-remove-tile-m>
<detailed-clouds-flag type="bool" userarchive="y">1</detailed-clouds-flag>
<dynamics-flag type="bool" userarchive="y">0</dynamics-flag>
<thermal-properties type="double" userarchive="y">1.0</thermal-properties>
<wind-model type="string" userarchive="y">constant</wind-model>
<buffer-flag type="bool" userarchive="y">1</buffer-flag>
<asymmetric-reduction type="double" userarchive="y">0.7</asymmetric-reduction>
<clouds-visible-range-m type="double" userarchive="y">30000.0</clouds-visible-range-m>
<clouds-in-dynamics-loop type="int" userarchive="y">250</clouds-in-dynamics-loop>
<debug-output-flag type="bool" userarchive="y">0</debug-output-flag>
<generate-thermal-lift-flag type="bool" userarchive="y">0</generate-thermal-lift-flag>
<dynamical-convection-flag type="bool" userarchive="y">0</dynamical-convection-flag>
<thread-flag type="bool" userarchive="n">1</thread-flag>
<presampling-flag type="bool" userarchive="y">1</presampling-flag>
<fps-control-flag type="bool" userarchive="y">0</fps-control-flag>
<target-framerate type="double" userarchive="y">25.0</target-framerate>
<large-scale-persistence type="double" userarchive="y">1.0</large-scale-persistence>
<small-scale-persistence type="double" userarchive="y">0.0</small-scale-persistence>
</config>
<tmp>
<tile-management type="string" userarchive="y">realistic weather</tile-management>
<tile-type type="string" userarchive="y">High-pressure</tile-type>
<tile-orientation-deg type="double" userarchive="y">260.0</tile-orientation-deg>
<windspeed-kt type="double" userarchive="y">8.0</windspeed-kt>
<gust-frequency-hz type="double" userarchive="n">0.0</gust-frequency-hz>
<gust-relative-strength type="double" userarchive="n">0.0</gust-relative-strength>
<gust-angular-variation-deg type="double" userarchive="n">0.0</gust-angular-variation-deg>
<tile-alt-offset-ft type="double" userarchive="n">0.0</tile-alt-offset-ft>
<asymmetric-tile-loading-flag type="bool" userarchive="y">0</asymmetric-tile-loading-flag>
<FL0-wind-from-heading-deg type="double" userarchive="y">260.0</FL0-wind-from-heading-deg>
<FL0-windspeed-kt type="double" userarchive="y">8.0</FL0-windspeed-kt>
<FL50-wind-from-heading-deg type="double" userarchive="y">262.0</FL50-wind-from-heading-deg>
<FL50-windspeed-kt type="double" userarchive="y">11.0</FL50-windspeed-kt>
<FL100-wind-from-heading-deg type="double" userarchive="y">264.0</FL100-wind-from-heading-deg>
<FL100-windspeed-kt type="double" userarchive="y">16.0</FL100-windspeed-kt>
<FL180-wind-from-heading-deg type="double" userarchive="y">265.0</FL180-wind-from-heading-deg>
<FL180-windspeed-kt type="double" userarchive="y">24.0</FL180-windspeed-kt>
<FL240-wind-from-heading-deg type="double" userarchive="y">269.0</FL240-wind-from-heading-deg>
<FL240-windspeed-kt type="double" userarchive="y">35.0</FL240-windspeed-kt>
<FL300-wind-from-heading-deg type="double" userarchive="y">273.0</FL300-wind-from-heading-deg>
<FL300-windspeed-kt type="double" userarchive="y">45.0</FL300-windspeed-kt>
<FL340-wind-from-heading-deg type="double" userarchive="y">274.0</FL340-wind-from-heading-deg>
<FL340-windspeed-kt type="double" userarchive="y">50.0</FL340-windspeed-kt>
<FL390-wind-from-heading-deg type="double" userarchive="y">273.0</FL390-wind-from-heading-deg>
<FL390-windspeed-kt type="double" userarchive="y">56.0</FL390-windspeed-kt>
<FL450-wind-from-heading-deg type="double" userarchive="y">272.0</FL450-wind-from-heading-deg>
<FL450-windspeed-kt type="double" userarchive="y">65.0</FL450-windspeed-kt>
<cloud-type type="string" userarchive="n">Altocumulus</cloud-type>
<alt type="double" userarchive="n">12000.0</alt>
<nx type="int" userarchive="n">5</nx>
<xoffset type="double" userarchive="n">800.0</xoffset>
<xedge type="double" userarchive="n">0.2</xedge>
<ny type="int" userarchive="n">15</ny>
<yoffset type="double" userarchive="n">800.0</yoffset>
<yedge type="double" userarchive="n">0.2</yedge>
<dir type="double" userarchive="n">0.0</dir>
<tri type="double" userarchive="n">1.0</tri>
<rnd-pos-x type="double" userarchive="n">400.0</rnd-pos-x>
<rnd-pos-y type="double" userarchive="n">400.0</rnd-pos-y>
<rnd-alt type="double" userarchive="n">300.0</rnd-alt>
<conv-strength type="double" userarchive="n">1.0</conv-strength>
<conv-size type="double" userarchive="n">15.0</conv-size>
<conv-alt type="double" userarchive="n">2000.0</conv-alt>
<bar-alt type="double" userarchive="n">3500.0</bar-alt>
<bar-n type="int" userarchive="n">150</bar-n>
<bar-dir type="double" userarchive="n">0.0</bar-dir>
<bar-dist type="double" userarchive="n">5.0</bar-dist>
<bar-size type="double" userarchive="n">10.0</bar-size>
<scloud-type type="string" userarchive="n">Altocumulus</scloud-type>
<scloud-subtype type="string" userarchive="n">small</scloud-subtype>
<scloud-alt type="double" userarchive="n">5000.0</scloud-alt>
<scloud-dir type="double" userarchive="n">0.0</scloud-dir>
<layer-type type="string" userarchive="n">Nimbus</layer-type>
<layer-rx type="double" userarchive="n">10.0</layer-rx>
<layer-ry type="double" userarchive="n">10.0</layer-ry>
<layer-phi type="double" userarchive="n">0.0</layer-phi>
<layer-alt type="double" userarchive="n">3000.0</layer-alt>
<layer-thickness type="double" userarchive="n">500.0</layer-thickness>
<layer-density type="double" userarchive="n">1.0</layer-density>
<layer-edge type="double" userarchive="n">10.0</layer-edge>
<layer-rain-flag type="bool" userarchive="n">1</layer-rain-flag>
<layer-rain-density type="double" userarchive="n">1.0</layer-rain-density>
<box-x-m type="double" userarchive="n">600.0</box-x-m>
<box-y-m type="double" userarchive="n">600.0</box-y-m>
<box-alt-ft type="double" userarchive="n">300.0</box-alt-ft>
<box-n type="int" userarchive="n">10</box-n>
<box-core-fraction type="double" userarchive="n">0.4</box-core-fraction>
<box-core-offset type="double" userarchive="n">0.2</box-core-offset>
<box-core-height type="double" userarchive="n">1.4</box-core-height>
<box-core-n type="int" userarchive="n">3</box-core-n>
<box-bottom-fraction type="double" userarchive="n">0.9</box-bottom-fraction>
<box-bottom-thickness type="double" userarchive="n">0.2</box-bottom-thickness>
<box-bottom-n type="int" userarchive="n">12</box-bottom-n>
</tmp>
</PropertyList>

View file

@ -161,7 +161,7 @@ ________________________________________________________________________________
<desc>Throttle</desc>
<number>
<unix>3</unix>
<mac>2</mac>
<mac>3</mac>
<windows>2</windows>
</number>
<binding>

View file

@ -1,56 +1,190 @@
<?xml version="1.0"?>
<!--
Only a few stick controls have been mapped here:
+ "Rocker" switch: Rudder
+ Top rotary dial: Mixture
+ Bottom rotary dial: Prop Advance
+ Top stick hat: Elevator & Aileron trim
+ Bottom stick hat: View direction
+ Top throttle hat: Flaps & Rudder trim
+ Stick button "A": Gear toggle
+ Stick button "C": Reset view (hackish)
Linux/Windows/Mac Axis Numbers:
0 Roll (positive == right)
1 Pitch (positive == down/back/nose-up)
2/5/5 top "rotary dial" on the throttle (positive == CCW)
3 Rocker switch ("rudder" control) on the throttle (positive == right)
4/2/2 Throttle (positive == back/down/idle)
5/4/4 Bottom "rotary dial" on the throttle (positive == CW)
Strange this axis doesn't seem to exist on Mac OS X!
6/6/6 Lower right hat horizontal axis (positive == right)
7/7/7 Lower right hat vertical axis (positive == down (Mac positive is UP))
This is X52.xml, the joystick config file for the Saitek X52
USB stick and throttle.
Button Numbers (Identical b/w Linux/Windows/Mac):
0 Trigger
1 Stick top "A" switch
2 Stick top "B" switch
3 Stick top "launch/fire" switch
4 Throttle "D" switch
5 Throttle "mouse" switch (tiny black thumb button)
6 Stick "pinkie" switch
7 Stick front "C" switch
8 -+ left position ("M1")
9 +- Throttle "mode" 3-way switch: middle position ("M2")
10 -+ right position ("M3")
11 -+ left position
12 +- Throttle "Aux" 3-way switch: middle position
13 -+ right position
14 Upper left hat in "up" position
15 Upper left hat in "right" position
16 Upper left hat in "down" position
17 Upper left hat in "left" position
18 Throttle forefinger hat in "up/back" position
19 Throttle forefinger hat in "right" position
20 Throttle forefinger hat in "down/forward" position
21 Throttle forefinger hat in "left" position
22 Throttle thumb hat in "up" position
23 Throttle thumb hat in "right" position
24 Throttle thumb hat in "down" position
25 Throttle thumb hat in "left" position
This configuration is meant to be suitable for a generic single-engine
aircraft.
Here are some of the features of a real aircraft that we would like to
implement, and our "preferred" way of assigning them on the X52.
Flight Controls:
Aileron stick L/R
Elevator stick fwd/aft
Rudder stick twist (or pedals!)
Flaps T3/T4
Speedbrakes shift T3/T4
Pitch trim stick upper hat
Rudder trim stick upper hat
Aileron trim throttle rocker
Engine controls:
Throttle throttle
Mixture throttle lower rotary
Propeller RPM throttle thumb slider
Carb heat (alt air) T5/T6
Cowl Flaps shift T5/T6
Fuel tank select **not implemented**
Mag switch keyboard "{" and "}"
Starter keyboard "s"
Other important stuff:
gear handle up/down T1/T2
Overall brakes pinky trigger
L/R toe brakes keyboard dot and comma
Parking brakes keyboard capital-B
Push-to-talk button (A) is a good candidate
also keyboard "space"
Timer reset MultiFunc reset
Timer -> clock MultiFunc function
Autopilot disengage **not implemented**
Autopilot go-around **not implemented**
Electrical:
Master **not implemented**
Radio master **not implemented**
Landing lights **not implemented**
Rotating beacon **not implemented**
Strobes **not implemented**
Cabin lights **not implemented**
Instrument lights **not implemented**
Circuit breakers **not implemented**
Instruments:
Alternate static **not implemented**
Instruments on/off mouse
Instruments tuning mouse or popup dialog
Simulator and view control:
Pan L/R Tilt Up/Dn throttle lower hat
Shift PoV D-shift + throttle lower hat
Restore std view (C) button
Zoom out (B) button
Zoom in D-shift + (B) button
=============================================================
Here are the Unix axes observed by jsd using js_demo, and Windows axes
observed by Satia Lumbar. Mac axes are little more than guesses based
on reports of X45 behavior. An "x" means observed to have no effect
using js_demo. U/M/W means unix/mac/windows:
U/ M/ W Hardware Function Interpretation
======= ================= ==============
0/ 0/ 0 Stick yaw +=R Aileron
1/ 1/ 1 Stick pitch +=aft Elevator
2/ 2/ 2 Throttle +=aft Throttle
3/ 5/ 5 Throttle lower rotary +=cw Mixture (fwd = rich)
4/ 8/ 8x Throttle upper rotary +=cw [unassigned]
5/ 3/ 3 Stick twist +=R Rudder
6/ 4/ 4 Throttle thumb slider +=up Prop (fwd = high RPM)
7/ 6/ 6 Stick lower hat +=R Pan View Left/Right ... or shift
8/ 7/ 7 Stick lower hat +=down Tilt View Up/Down ... or shift
9/ 9/ 9x Green mouse +=up [Mouse???]
10/10/10x Green mouse +=away [Mouse???]
On the Windows platform, the assignment of axes 8, 9, and 10 as
given above is only a hint, suggesting how the axes /should/ be
assigned, if the lower-level implementation ever gets around to
assigning them.
In the meantime, I have maintained cross-platform compatibility by not
assigning any critical functions to axes that don't work on the
Windows platform.
=======================
Now for the buttons. Unix button numbers observed by jsd using
js_demo. (Others rumored to be identical on Unix/Mac/Windows.)
Before 1 Jan 2007, all versions of plib had a bug that affecting bits
32 and 33. The C and C++ language spec says that an out-of-range
shift (such as shifting a 32-bit word 32 or more places) produces an
/undefined/ result. It is really not a good practice to be generating
undefined results.
I observe that on /some/ systems, bit #32 creates a conflict with bit
#0, and bit #33 creates a conflict with bit #1. That is, they "wrap
around" the word boundary. This means that if you roll the gray trim
wheel, it fires the gun! If that weren't bad enough, this behavior is
not guaranteed from compiler to compiler or from hardware to hardware.
Remember, according to the C language spec, an out-of-range shift
produces an "undefined" result, so implementers can do anything they
want with it.
Bit Binary Hardware Function Interpretation
=== ========= ================= ====================
0 = 0000 0001 Trigger (see also #14)
0' (see also #32)
1 = 0000 0002 FIRE Button (guarded)
1' (see also #33)
2 = 0000 0004 (A) Button (should be push-to-talk)
3 = 0000 0008 (B) Button Expand field of view (shift: contract)
4 = 0000 0010 (C) Button Reset View
5 = 0000 0020 Pinky subtrigger Apply brakes
6 = 0000 0040 (D) Button D-Shift, modifies other functions
7 = 0000 0080 (E) Button
8 = 0000 0100 T1 Gear Handle Up
9 = 0000 0200 T2 Gear Handle Down
10 = 0000 0400 T3 Flaps retract 1 notch (shift: speed brakes extend)
11 = 0000 0800 T4 Flaps extend 1 notch (shift: speed brakes retract)
12 = 0000 1000 T5 Carb heat on (shift: cowl flaps close)
13 = 0000 2000 T6 Carb heat off (shift: cowl flaps open)
14 = 0000 4001 More Trigger (==> #0)
15 = 0000 8000 Yoke upper hat Fwd Elevator trim
16 = 0001 0000 Yoke upper hat R Rudder trim
17 = 0002 0000 Yoke upper hat Aft Elevator trim
18 = 0004 0000 Yoke upper hat L Rudder trim
19 = 0008 0000 Throttle rocker aft
20 = 0010 0000 Throttle rocker R Aileron trim
21 = 0020 0000 Throttle rocker fwd
22 = 0040 0000 Throttle rocker L Aileron trim
23 = 0080 0000 Mode Aft (green)
24 = 0100 0000 Mode Mid (pink)
25 = 0200 0000 Mode Fwd (red)
26 = 0400 0000 MultiFunc Function Timer -> clock again
27 = 0800 0000 MultiFunc Start/Stop ** Timer start/stop not implemented **
28 = 1000 0000 MultiFunc Reset Timer reset
29 = 2000 0000 (i) Button
30 = 4000 0000 Green mouse click
31 (not observed)
32 = 1 0000 0000 Gray Roller step fwd (see also bit #0)
33 = 2 0000 0000 Gray Roller step aft (see also bit #1)
== Notes:
*) Note that some joystick configurations specify square-law behavior
for some flight control axes (e.g. ailerons and/or rudder). This is
very unlike the behavior of flight controls on real aircraft.
Aileron authority should be mushy at low airspeeds and crisp at high
airspeeds ... but this should be part of the flight dynamics of the
aircraft. Building the correct behavior into the control stick
configuration is neither possible nor desirable.
*) There are some aircraft in the simulator fleet that have very
little roll damping and very little yaw damping. (You could also say
they have very little damping of the Dutch roll mode, but this is
merely a natural consequence of the roll and yaw issues, not really a
separate issue.)
Such aircraft are vastly easier to fly with auto-coordination turned
on. In my opinion, you want auto-coordination on for flying an ILS
partial panel, i.e. no DG and no AI.
For a crosswind landing, you need to have auto-coordination turned off.
That's why the switch to do that is on the yoke.
*) This configuration does not bind the parking brake to any button on
the joystick (or throttle). Using the keyboard (shift-B) seems
entirely satisfactory and more realistic than putting the /parking/
brake button on the stick.
*) In general, he HOTAS idea (hands on throttle and stick) should
apply to things you need /in flight/.
$Id$
-->
<PropertyList>
<name>Saitek X52</name>
@ -61,99 +195,37 @@ $Id$
<name>Saitek X52 Flight Control System</name>
<name>Saitek Saitek X52</name>
<name>Saitek Saitek X52 Flight Stick (USB)</name>
<name>Saitek Saitek X52 Flight Control Stick </name>
<name>Saitek Saitek X52 Flight Control Stick</name>
<name>Saitek Saitek X52 Flight Control System</name>
<axis n="0">
<axis> <!-- 0/0/0 -->
<desc>Aileron</desc>
<number>
<unix>0</unix>
<mac>0</mac>
<windows>0</windows>
</number>
<binding>
<command>property-scale</command>
<property>/controls/flight/aileron</property>
<squared type="bool">true</squared>
</binding>
</axis>
</axis>
<axis n="1">
<axis> <!-- 1/1/1 -->
<desc>Elevator</desc>
<number>
<unix>1</unix>
<mac>1</mac>
<windows>1</windows>
</number>
<binding>
<command>property-scale</command>
<property>/controls/flight/elevator</property>
<factor type="double">-1.0</factor>
<squared type="bool">true</squared>
</binding>
</axis>
</axis>
<!--<axis n="3">
<desc>Rudder</desc>
<binding>
<command>property-scale</command>
<property>/controls/flight/rudder</property>
</binding>
<binding>
<command>nasal</command>
<script><![CDATA[
# In mode 3 (taxiing), map the wheelbrakes
if(getprop("/input/joysticks/js[0]/saitek-x45-mode") == 3) {
val = cmdarg().getNode("setting").getValue();
setprop("/controls/gear/brake-left", 0);
setprop("/controls/gear/brake-right", 0);
if(val > 0) { setprop("/controls/gear/brake-right", val); }
else { setprop("/controls/gear/brake-left", -val); }
}
]]></script>
</binding>
</axis>-->
<!-- View Direction Hat -->
<axis n="6">
<number>
<unix>7</unix>
<mac>6</mac>
<windows>6</windows>
</number>
<desc>View Direction</desc>
<low>
<repeatable>true</repeatable>
<binding>
<command>nasal</command>
<script>view.panViewDir(1)</script>
</binding>
</low>
<high>
<repeatable>true</repeatable>
<binding>
<command>nasal</command>
<script>view.panViewDir(-1)</script>
</binding>
</high>
</axis>
<axis>
<desc>View Elevation</desc>
<number>
<unix>8</unix>
<mac>7</mac>
<windows>7</windows>
</number>
<low>
<repeatable>true</repeatable>
<binding>
<command>nasal</command>
<script>view.panViewPitch(1)</script>
</binding>
</low>
<high>
<repeatable>true</repeatable>
<binding>
<command>nasal</command>
<script>view.panViewPitch(-1)</script>
</binding>
</high>
</axis>
<axis>
<axis> <!-- 2/2/2 -->
<desc>Throttle</desc>
<number>
<unix>2</unix>
@ -164,9 +236,9 @@ $Id$
<command>nasal</command>
<script>controls.throttleAxis()</script>
</binding>
</axis>
</axis>
<axis>
<axis> <!-- 3/5/5 -->
<desc>Mixture</desc>
<number>
<unix>3</unix>
@ -175,14 +247,45 @@ $Id$
</number>
<binding>
<command>nasal</command>
<script>controls.mixtureAxis()</script>
<script>controls.mixtureAxis(-1)</script>
</binding>
</axis>
</axis>
<axis>
<desc>Propeller Advance</desc>
<!-- Alternate Prop RPM :: throttle upper rotary -->
<axis> <!-- 4/8/8 -->
<desc>unassigned (was: Propeller RPM)</desc>
<number>
<unix>4</unix>
<mac>8</mac>
<windows>8</windows>
</number>
<binding>
<command>nasal</command>
<script>
####controls.propellerAxis(-1)
</script>
</binding>
</axis>
<!-- Rudder :: stick twist -->
<axis> <!-- 5/3/3 -->
<desc>Rudder</desc>
<number>
<unix>5</unix>
<mac>3</mac>
<windows>3</windows>
</number>
<binding>
<command>property-scale</command>
<property>/controls/flight/rudder</property>
</binding>
</axis>
<!-- Propeller RPM :: throttle thumb slider -->
<axis> <!-- 6/4/4 -->
<desc>Propeller RPM</desc>
<number>
<unix>6</unix>
<mac>4</mac>
<windows>4</windows>
</number>
@ -190,18 +293,132 @@ $Id$
<command>nasal</command>
<script>controls.propellerAxis(-1)</script>
</binding>
</axis>
</axis>
<button n="4">
<desc>Reset View</desc>
<!-- View Direction :: stick lower hat -->
<axis> <!-- 7/6/6 -->
<desc>View Pan Left/Right (D-shift: move PoV)</desc>
<number>
<unix>7</unix>
<mac>6</mac>
<windows>6</windows>
</number>
<low>
<repeatable>true</repeatable>
<binding>
<command>nasal</command>
<script>
if (getprop("/sim/gui/d-button")){
setprop("/sim/current-view/x-offset-m",
-0.01 + getprop("/sim/current-view/x-offset-m"));
} else {
view.panViewDir(1)
}
</script>
</binding>
</low>
<high>
<repeatable>true</repeatable>
<binding>
<command>nasal</command>
<script>
if (getprop("/sim/gui/d-button")){
setprop("/sim/current-view/x-offset-m",
0.01 + getprop("/sim/current-view/x-offset-m"));
} else {
view.panViewDir(-1)
}
</script>
</binding>
</high>
</axis>
<axis> <!-- 8/7/7 -->
<desc>View Tilt Up/Down (D-shift: move PoV)</desc>
<number>
<unix>8</unix>
<mac>7</mac>
<windows>7</windows>
</number>
<low>
<repeatable>true</repeatable>
<binding>
<command>nasal</command>
<script>
if (getprop("/sim/gui/d-button")){
setprop("/sim/current-view/y-offset-m",
0.01 + getprop("/sim/current-view/y-offset-m"));
} else {
view.panViewPitch(1)
}
</script>
</binding>
</low>
<high>
<repeatable>true</repeatable>
<binding>
<command>nasal</command>
<script>
if (getprop("/sim/gui/d-button")){
setprop("/sim/current-view/y-offset-m",
-0.01 + getprop("/sim/current-view/y-offset-m"));
} else {
view.panViewPitch(-1)
}
</script>
</binding>
</high>
</axis>
<!-- End of axes; now on to buttons -->
<button n="1">
<desc>(FIRE) : Auto-Coordination off (D-shift: on)</desc>
<binding>
<command>nasal</command>
<script>
setprop("/sim/auto-coordination", ! !getprop("/sim/gui/d-button"));
</script>
</binding>
</button>
<button n="3">
<desc>(B) : Zoom out i.e. increase field of view (D-shift: zoom in)</desc>
<repeatable type="bool">true</repeatable>
<binding>
<command>nasal</command>
<script>
if ( getprop("/sim/gui/d-button") ) {
view.decrease(0.5) # zoom in
} else {
view.increase(0.5) # zoom out
}
</script>
</binding>
</button>
<button n="4">
<desc>(C) : Reset View</desc>
<binding>
<command>nasal</command>
<script>view.resetView()</script>
<script>
view.resetView(); # only resets tilt/pan/zoom:
# must reset x/y/z view point separately
vn = getprop("/sim/current-view/view-number");
conf = sprintf("/sim/view[%d]/config", vn);
foreach (parm ; ["x-offset-m", "y-offset-m", "z-offset-m"]) {
setprop("/sim/current-view/", parm, getprop(conf, parm));
}
</script>
</binding>
</button>
</button>
<!-- <button n="0">
<desc>Brakes</desc>
<!-- Main brakes (not parking brakes) :: pinky subtrigger -->
<button n="5">
<desc>(Pinky) : Brakes</desc>
<binding>
<command>nasal</command>
<script>controls.applyBrakes(1)</script>
@ -212,183 +429,266 @@ $Id$
<script>controls.applyBrakes(0)</script>
</binding>
</mod-up>
</button> -->
</button>
<!-- Gear down on button T2 -->
<button n="9">
<desc>Landing Gear Down</desc>
<!-- Shift :: (D) button -->
<button n="6">
<desc>(D) : Shift Key</desc>
<binding>
<command>nasal</command>
<script>controls.gearDown(1)</script>
<script>
setprop("/sim/gui/d-button", 1);
</script>
</binding>
<mod-up>
<binding>
<command>nasal</command>
<script>controls.gearDown(0)</script>
<script>
setprop("/sim/gui/d-button", 0);
</script>
</binding>
</mod-up>
</button>
</button>
<!-- Gear up on button T1 -->
<button n="8">
<desc>Landing Gear Up</desc>
<binding>
<command>nasal</command>
<script>controls.gearDown(-1)</script>
</binding>
<mod-up>
<binding>
<command>nasal</command>
<script>controls.gearDown(0)</script>
</binding>
</mod-up>
</button>
<!-- gear handle up/down :: button T1/T2 -->
<button n="8">
<desc>(T1) : Landing Gear Handle Up</desc>
<binding>
<command>nasal</command>
<script>
controls.gearDown(-1)
</script>
</binding>
</button>
<button n="9">
<desc>(T2) : Landing Gear Handle Down</desc>
<binding>
<command>nasal</command>
<script>
controls.gearDown(1)
</script>
</binding>
</button>
<!-- mode switch (buttons 23-25) -->
<button n="23">
<desc>Mode 1</desc>
<binding>
<command>nasal</command>
<script>setprop("/input/joysticks/js[0]/saitek-x52-mode", 1)</script>
</binding>
</button>
<button n="24">
<desc>Mode 2</desc>
<binding>
<command>nasal</command>
<script>setprop("/input/joysticks/js[0]/saitek-x52-mode", 2)</script>
</binding>
</button>
<button n="25">
<desc>Mode 3</desc>
<binding>
<command>nasal</command>
<script>setprop("/input/joysticks/js[0]/saitek-x52-mode", 3)</script>
</binding>
</button>
<!-- Trim (upper) hat on the stick -->
<button n="15">
<!-- Pitch trim :: stick upper hat Up/Dn -->
<button n="15">
<desc>Elevator trim down</desc>
<repeatable type="bool">true</repeatable>
<binding>
<command>nasal</command>
<script>controls.elevatorTrim(0.5)</script>
<script>controls.elevatorTrim(0.6)</script>
</binding>
</button>
</button>
<button n="17">
<desc>Elevator trim up</desc>
<repeatable type="bool">true</repeatable>
<binding>
<command>nasal</command>
<script>controls.elevatorTrim(-0.6)</script>
</binding>
</button>
<button n="16">
<!-- Rudder trim :: stick upper hat L/R -->
<button n="16">
<desc>(Throttle Rocker) : Rudder trim right</desc>
<repeatable type="bool">true</repeatable>
<binding>
<command>nasal</command>
<script>controls.rudderTrim(1)</script>
</binding>
</button>
<button n="18">
<desc>(Throttle Rocker) : Rudder trim left</desc>
<repeatable type="bool">true</repeatable>
<binding>
<command>nasal</command>
<script>controls.rudderTrim(-1)</script>
</binding>
</button>
<!-- Flaps (shift: Speed Brakes) :: T3/T4 -->
<button n="10">
<desc>(T3) : Decrease flaps (shift: Speed Brakes extend)</desc>
<binding>
<command>nasal</command>
<script>
if ( getprop("/sim/gui/d-button") ) {
setprop("/controls/flight/speedbrake", 1);
} else {
controls.flapsDown(-1)
}
</script>
</binding>
<mod-up>
<binding>
<command>nasal</command>
<script>
if ( getprop("/sim/gui/d-button") ) {
} else {
controls.flapsDown(0)
}
</script>
</binding>
</mod-up>
</button>
<button n="11">
<desc>(T4) : Increase flaps (shift: Speed Brakes retract)</desc>
<binding>
<command>nasal</command>
<script>
if ( getprop("/sim/gui/d-button") ) {
setprop("/controls/flight/speedbrake", 0);
} else {
controls.flapsDown(1)
}
</script>
</binding>
<mod-up>
<binding>
<command>nasal</command>
<script>
if ( getprop("/sim/gui/d-button") ) {
} else {
controls.flapsDown(0)
}
</script>
</binding>
</mod-up>
</button>
<!-- Carb Heat (shift: Cowl Flaps) :: T6/T5 -->
<button n="12">
<desc>(T5) : Carb Heat On (shift: Cowl Flaps Close)</desc>
<binding>
<command>nasal</command>
<script>
if ( getprop("/sim/gui/d-button") ) {
props.setAll("/controls/engines/engine", "cowl-flaps-norm", 1);
} else {
props.setAll("/controls/engines/engine", "carb-heat", 0);
}
</script>
</binding>
</button>
<button n="13">
<desc>(T6) : Carb Heat Off (shift: Cowl Flaps Open)</desc>
<binding>
<command>nasal</command>
<script>
if ( getprop("/sim/gui/d-button") ) {
props.setAll("/controls/engines/engine", "cowl-flaps-norm", 0);
} else {
props.setAll("/controls/engines/engine", "carb-heat", 1);
}
</script>
</binding>
</button>
<!-- Aileron trim :: throttle rocker -->
<button n="20">
<desc>Aileron trim right</desc>
<repeatable type="bool">true</repeatable>
<binding>
<command>nasal</command>
<script>controls.aileronTrim(0.5)</script>
</binding>
</button>
<button n="17">
<desc>Elevator trim up</desc>
<repeatable type="bool">true</repeatable>
<binding>
<command>nasal</command>
<script>controls.elevatorTrim(-0.5)</script>
</binding>
</button>
<button n="18">
</button>
<button n="22">
<desc>Aileron trim left</desc>
<repeatable type="bool">true</repeatable>
<binding>
<command>nasal</command>
<script>controls.aileronTrim(-0.5)</script>
</binding>
</button>
</button>
<!-- Flap control on the T3/T4 -->
<button n="10">
<desc>Decrease flaps</desc>
<!-- Mode roller switch (buttons 23-25). -->
<!-- Just put it in the property tree, -->
<!-- in case somebody wants to look at it. -->
<button n="23">
<desc>Mode 1</desc>
<binding>
<command>nasal</command>
<script>controls.flapsDown(-1)</script>
<script>
setprop("/input/joysticks/js/saitek-x52-mode",1)
</script>
</binding>
<mod-up>
<binding>
</button>
<button n="24">
<desc>Mode 2</desc>
<binding>
<command>nasal</command>
<script>
setprop("/input/joysticks/js/saitek-x52-mode",2)
</script>
</binding>
</button>
<button n="25">
<desc>Mode 3</desc>
<binding>
<command>nasal</command>
<script>
setprop("/input/joysticks/js/saitek-x52-mode",3)
</script>
</binding>
</button>
<button n="26">
<desc>(MFD Func) : Stopwatch timer becomes clock again</desc>
<binding>
<command>nasal</command>
<script>
props.globals.getNode("/instrumentation/clock/offset-sec", 1).setValue(0);
</script>
</binding>
</button>
<button n="28">
<desc>(MFD Reset) : Stopwatch timer reset</desc>
<binding>
<command>nasal</command>
<script>
<!-- Note that the "indicated-sec" variable is a large number,
probably seconds since midnight ... *not* modulo 60. -->
ttt = props.globals.getNode("/instrumentation/clock/indicated-sec", 1).getValue();
node = props.globals.getNode("/instrumentation/clock/offset-sec", 1);
off = node.getValue();
node.setValue(off-ttt);
</script>
</binding>
</button>
<!-- (i) button :: unbound key -->
<!-- just put it in the property tree -->
<button n="29">
<desc>Mode 1</desc>
<binding>
<command>nasal</command>
<script>controls.flapsDown(0)</script>
</binding>
</mod-up>
</button>
<button n="11">
<desc>Increase flaps</desc>
<binding>
<command>nasal</command>
<script>controls.flapsDown(1)</script>
<script>
setprop("/input/joysticks/js/saitek-x52-i",1)
</script>
</binding>
<mod-up>
<binding>
<mod-up><binding>
<command>nasal</command>
<script>controls.flapsDown(0)</script>
</binding>
</mod-up>
</button>
<script>
setprop("/input/joysticks/js/saitek-x52-i",0)
</script>
</binding></mod-up>
</button>
<!-- Rudder trim on the flap hat -->
<button n="20">
<desc>Rudder trim right</desc>
<repeatable type="bool">true</repeatable>
<binding>
<command>nasal</command>
<script>controls.rudderTrim(1)</script>
</binding>
</button>
<button n="22">
<desc>Rudder trim left</desc>
<repeatable type="bool">true</repeatable>
<binding>
<command>nasal</command>
<script>controls.rudderTrim(-1)</script>
</binding>
</button>
<!-- Fire button -->
<button n="0">
<!-- Parking brake :: unbound function -->
<button n="666">
<desc>Toggle parking brake on or off</desc>
<binding>
<!--<command>nasal</command>
<script>controls.applyParkingBrake4444(1)</script>-->
<command>property-toggle</command>
<property>/controls/gear/brake-parking</property>
</binding>
</button>
<!-- Speed brake control on the T6/T5 -->
<button n="13">
<desc>Decrease speedbrake</desc>
<binding>
<command>property-assign</command>
<property>/controls/flight/speedbrake</property>
<value>0</value>
</binding>
</button>
<button n="12">
<desc>Increase speedbrake</desc>
<binding>
<command>property-assign</command>
<property>/controls/flight/speedbrake</property>
<value>1</value>
</binding>
</button>
</button>
</PropertyList>

View file

@ -0,0 +1,168 @@
<?xml version="1.0"?>
<!--
Bindings for THRUSTMASTER T.Flight Stick X based on presets from the constructor.
by Joffrey Paris
-->
<PropertyList>
<name type="string">T.Flight Stick X</name>
<axis n="0">
<desc>Aileron</desc>
<binding>
<command>property-scale</command>
<property>/controls/flight/aileron</property>
<squared type="bool">true</squared>
</binding>
</axis>
<axis n="1">
<desc>Elevator</desc>
<binding>
<command>property-scale</command>
<property>/controls/flight/elevator</property>
<factor type="double">-1.0</factor>
<squared type="bool">true</squared>
</binding>
</axis>
<axis n="2">
<desc>Increase/Reduce Throttle</desc>
<binding>
<command>nasal</command>
<script>controls.throttleAxis()</script>
</binding>
</axis>
<axis n="3">
<desc>Rudder Left/Right</desc>
<binding>
<command>property-scale</command>
<property>/controls/flight/rudder</property>
<factor type="double">1.0</factor>
</binding>
</axis>
<axis n="6">
<desc>View Direction</desc>
<low>
<repeatable>true</repeatable>
<binding>
<command>property-adjust</command>
<property>/sim/current-view/goal-heading-offset-deg</property>
<step type="double">2.0</step>
</binding>
</low>
<high>
<repeatable>true</repeatable>
<binding>
<command>property-adjust</command>
<property>/sim/current-view/goal-heading-offset-deg</property>
<step type="double">-2.0</step>
</binding>
</high>
</axis>
<axis n="7">
<desc>View Elevation</desc>
<low>
<repeatable>true</repeatable>
<binding>
<command>property-adjust</command>
<property>/sim/current-view/goal-pitch-offset-deg</property>
<step type="double">-2.0</step>
</binding>
</low>
<high>
<repeatable>true</repeatable>
<binding>
<command>property-adjust</command>
<property>/sim/current-view/goal-pitch-offset-deg</property>
<step type="double">2.0</step>
</binding>
</high>
</axis>
<button n="0">
<desc>Brakes</desc>
<binding>
<command>nasal</command>
<script>controls.applyBrakes(1)</script>
</binding>
<mod-up>
<binding>
<command>nasal</command>
<script>controls.applyBrakes(0)</script>
</binding>
</mod-up>
</button>
<button n="1">
<desc>Change View</desc>
<binding>
<command>nasal</command>
<script>view.stepView(1)</script>
</binding>
</button>
<button n="2">
<desc>Trim Nose Up</desc>
<repeatable type="bool">true</repeatable>
<binding>
<command>nasal</command>
<script>controls.elevatorTrim(1)</script>
</binding>
</button>
<button n="3">
<desc>Trim Nose Down</desc>
<repeatable type="bool">true</repeatable>
<binding>
<command>nasal</command>
<script>controls.elevatorTrim(-1)</script>
</binding>
</button>
<button n="4">
<desc>Extend Flaps Incrementally</desc>
<repeatable>false</repeatable>
<binding>
<command>nasal</command>
<script>controls.flapsDown(1)</script>
</binding>
<mod-up>
<binding>
<command>nasal</command>
<script>controls.flapsDown(0)</script>
</binding>
</mod-up>
</button>
<button n="5">
<desc>Retract Flaps Incrementally</desc>
<repeatable>false</repeatable>
<binding>
<command>nasal</command>
<script>controls.flapsDown(-1)</script>
</binding>
<mod-up>
<binding>
<command>nasal</command>
<script>controls.flapsDown(0)</script>
</binding>
</mod-up>
</button>
<button n="7">
<desc>Landing gear Up/Down</desc>
<repeatable>false</repeatable>
<binding>
<command>nasal</command>
<script>controls.gearToggle()</script>
</binding>
</button>
</PropertyList>
<!-- end of T.Flight Stick X.xml -->

View file

@ -28,6 +28,7 @@
READ ALLOW $FG_ROOT/*
READ ALLOW $FG_HOME/*
READ ALLOW $FG_AIRCRAFT/*
READ ALLOW $FG_SCENERY/*
WRITE ALLOW /tmp/*.xml
WRITE ALLOW $FG_HOME/*.sav

View file

@ -17,8 +17,8 @@ _setlistener("/sim/signals/fdm-initialized", func {
var callsign = tanker.getNode("callsign").getValue();
if( callsign == nil ) continue;
if( string.match(callsign,"ballon*") ) {
tanker.getNode("position/latitude-deg",1).setDoubleValue( position.lat() );
tanker.getNode("position/longitude-deg",1).setDoubleValue( position.lon() );
tanker.getNode("position/latitude-deg",1).setDoubleValue( position.lat() - 0.002 );
tanker.getNode("position/longitude-deg",1).setDoubleValue( position.lon() - 0.002 );
tanker.getNode("position/altitude-ft", 1 ).setDoubleValue( position.alt() );
}
}

View file

@ -1254,3 +1254,15 @@ var common_aircraft_keys = {
{ name: "Shift-F8", desc: "scroll 2D panel right" },
],
};
_setlistener("/sim/signals/screenshot", func {
var path = getprop("/sim/paths/screenshot-last");
var button = { button: { legend: "Ok", default: 1, binding: { command: "dialog-close" }}};
var success= getprop("/sim/signals/screenshot");
if (success) {
popupTip("Screenshot written to '" ~ path ~ "'", 3);
} else {
popupTip("Error writing screenshot '" ~ path ~ "'", 600, button);
}
});

View file

@ -81,6 +81,33 @@ var read_properties = func(path, target = nil) {
return fgcommand("loadxml", args) ? ret : nil;
}
# Load XML file in FlightGear's native <PropertyList> format.
# file will be located in the airport-scenery directories according to
# ICAO and filename, i,e in Airports/I/C/A/ICAO.filename.xml
# If the second, optional target parameter is set, then the properties
# are loaded to this node in the global property tree. Otherwise they
# are returned as a separate props.Node tree. Returns the data as a
# props.Node on success or nil on error.
#
# Usage: io.read_airport_properties(<icao>, <filename> [, <props.Node or property-path>]);
#
# Examples:
#
# var data = io.read_properties("KSFO", "rwyuse");
#
var read_airport_properties = func(icao, fname, target = nil) {
var args = props.Node.new({ filename: fname, icao:icao });
if (target == nil) {
var ret = args.getNode("data", 1);
} elsif (isa(target, props.Node)) {
args.getNode("targetnode", 1).setValue(target.getPath());
var ret = target;
} else {
args.getNode("targetnode", 1).setValue(target);
var ret = props.globals.getNode(target, 1);
}
return fgcommand("loadxml", args) ? ret : nil;
}
# Write XML file in FlightGear's native <PropertyList> format.
# Returns the filename on success or nil on error. If the source
@ -245,6 +272,14 @@ _setlistener("/sim/signals/nasal-dir-initialized", func {
pattern = c.getValue() ~ "/" ~ p;
append(rules, [pattern, allow]);
printlog("info", "IORules: appending ", pattern);
}
} elsif (substr(pattern, 0, 12) == "$FG_SCENERY/") {
var p = substr(pattern, 12);
var sim = props.globals.getNode("/sim");
foreach (var c; sim.getChildren("fg-scenery")) {
pattern = c.getValue() ~ "/" ~ p;
append(rules, [pattern, allow]);
printlog("info", "IORules: appending ", pattern);
}
} else {
if (substr(pattern, 0, 9) == "$FG_ROOT/")

View file

@ -415,8 +415,6 @@ return f_slow;
var interpolation_loop = func {
var iNode = props.globals.getNode(lw~"interpolation", 1);
var cNode = props.globals.getNode(lw~"current", 1);
var viewpos = geo.aircraft_position();
var sum_alt = 0.0;
@ -428,6 +426,15 @@ var sum_norm = 0.0;
var vis_before = getprop(lwi~"visibility-m");
# if applicable, do some work for fps sampling
if (fps_control_flag == 1)
{
fps_samples = fps_samples +1;
fps_sum = fps_sum + getprop("/sim/frame-rate");
}
# determine at which distance we no longer keep an interpolation point, needs to be larger for METAR since points are more scarce
if (metar_flag == 1)
@ -512,9 +519,9 @@ var alt1 = weather_dynamics.tile_convective_altitude[current_tile_index -1];
var alt2 = alt1 + 1500.0;
var inc1 = 0.2;
var inc1 = 0.1;
var inc2 = 5.0;
var inc3 = 1.0;
var inc3 = 0.5;
var alt_above_mean = altitude - current_mean_terrain_elevation;
@ -547,41 +554,58 @@ setprop(lwi~"turbulence",0.0);
# now check if an effect volume writes the property and set only if not
flag = props.globals.getNode("local-weather/effect-volumes/number-active-vis").getValue();
if ((flag ==0) and (vis > 0.0))
#flag = props.globals.getNode("local-weather/effect-volumes/number-active-vis").getValue();
flag = getprop("local-weather/effect-volumes/number-active-vis");
if ((flag ==0) and (vis > 0.0) and (getprop(lw~"lift-loop-flag") == 0))
{
cNode.getNode("visibility-m").setValue(vis);
#cNode.getNode("visibility-m").setValue(vis);
setprop(lw~"current/visibility-m",vis);
compat_layer.setVisibility(vis);
}
flag = props.globals.getNode("local-weather/effect-volumes/number-active-turb").getValue();
#flag = props.globals.getNode("local-weather/effect-volumes/number-active-turb").getValue();
flag = getprop("local-weather/effect-volumes/number-active-turb");
if ((flag ==0))
{
cNode.getNode("turbulence").setValue(0.0);
#cNode.getNode("turbulence").setValue(0.0);
setprop(lw~"current/turbulence",0.0);
compat_layer.setTurbulence(0.0);
}
flag = props.globals.getNode("local-weather/effect-volumes/number-active-lift").getValue();
#flag = props.globals.getNode("local-weather/effect-volumes/number-active-lift").getValue();
flag = getprop("local-weather/effect-volumes/number-active-lift");
if (flag ==0)
{
cNode.getNode("thermal-lift").setValue(0.0);
#cNode.getNode("thermal-lift").setValue(0.0);
setprop(lw~"current/thermal-lift",0.0);
}
# no need to check for these, as they are not modelled in effect volumes
cNode.getNode("temperature-degc",1).setValue(T);
#cNode.getNode("temperature-degc",1).setValue(T);
setprop(lw~"current/temperature-degc",T);
compat_layer.setTemperature(T);
cNode.getNode("dewpoint-degc",1).setValue(D);
#cNode.getNode("dewpoint-degc",1).setValue(D);
setprop(lw~"current/dewpoint-degc", D);
compat_layer.setDewpoint(D);
if (p>0.0) {cNode.getNode("pressure-sea-level-inhg",1).setValue(p); compat_layer.setPressure(p);}
if (p>0.0)
{
#cNode.getNode("pressure-sea-level-inhg",1).setValue(p);
setprop(lw~"current/pressure-sea-level-inhg",p);
compat_layer.setPressure(p);
}
# now determine the local wind
var tile_index = props.globals.getNode(lw~"tiles").getChild("tile",4).getNode("tile-index").getValue();
#var tile_index = props.globals.getNode(lw~"tiles").getChild("tile",4).getNode("tile-index").getValue();
var tile_index = getprop(lw~"tiles/tile[4]/tile-index");
if (wind_model_flag ==1) # constant
{
@ -669,21 +693,33 @@ if (gust_frequency > 0.0)
var gust_relative_strength = getprop(lw~"tmp/gust-relative-strength");
var gust_angvar = getprop(lw~"tmp/gust-angular-variation-deg");
var winddir_last = getprop(lwi~"wind-from-heading-deg");
var alt_scaling_factor = 1.2 * windspeed / 10.0;
if (alt_scaling_factor < 1.0) {alt_scaling_factor = 1.0;}
# expected mean number of gusts in time interval (should be < 1)
var p_gust = gust_frequency * interpolation_loop_time;
winddir_change = 0.0;
if (rand() < p_gust) # we change the offsets for windspeed and direction
{
var alt_fact = 1.0 - altitude_agl/(boundary_alt * alt_scaling_factor);
if (alt_fact < 0.0) {alt_fact = 0.0};
windspeed_multiplier = (1.0 + ((rand()) * gust_relative_strength * alt_fact));
winddir_change = alt_fact * (1.0 - 2.0 * rand() * gust_angvar);
winddir_change = alt_fact * (1.0 - 2.0 * rand()) * gust_angvar;
winddir_change = winddir_change * 0.2; # Markov chain parameter, max. change per frame is 1/5
# if the Markov chain reaches the boundary, reflect
#print("Winddir: ", winddir, " winddir_last: ", winddir_last, " winddir_change: ", winddir_change);
if (weather_tile_management.relangle(winddir_last + winddir_change, winddir) > gust_angvar)
{winddir_change = -winddir_change;}
}
windspeed_current = windspeed_current * windspeed_multiplier;
winddir = winddir + winddir_change;
winddir = winddir_last + winddir_change;
}
@ -692,13 +728,17 @@ if (gust_frequency > 0.0)
compat_layer.setWindSmoothly(winddir, windspeed_current);
iNode.getNode("wind-from-heading-deg").setValue(winddir);
iNode.getNode("wind-speed-kt").setValue(windspeed_current);
setprop(lwi~"wind-from-heading-deg", winddir);
setprop(lwi~"wind-speed-kt",windspeed_current);
cNode.getNode("wind-from-heading-deg").setValue(winddir);
cNode.getNode("wind-speed-kt").setValue(windspeed_current);
setprop(lw~"current/wind-from-heading-deg",winddir);
setprop(lw~"current/wind-speed-kt",windspeed_current);
#iNode.getNode("wind-from-heading-deg").setValue(winddir);
#iNode.getNode("wind-speed-kt").setValue(windspeed_current);
#cNode.getNode("wind-from-heading-deg").setValue(winddir);
#cNode.getNode("wind-speed-kt").setValue(windspeed_current);
if (getprop(lw~"interpolation-loop-flag") ==1) {settimer(interpolation_loop, interpolation_loop_time);}
@ -777,6 +817,26 @@ if (getprop(lw~"wave-loop-flag") ==1)
lift = lift + getprop(lw~"current/wave-lift");
}
# compute a reduction in visibility when entering the cloudbase
var vis = getprop(lw~"interpolation/visibility-m");
if (alt > 0.9 * thermal.height)
{
var visibility_reduction = math.pow((alt - 0.9 * thermal.height)/(0.2 * thermal.height),0.1);
visibility_reduction = visibility_reduction * (1.0 - math.pow(d/(0.8*thermal.radius),14));
if (visibility_reduction > 1.0) {visibility_reduction = 1.0;} # this shouldn't ever happen
if (visibility_reduction < 0.0) {visibility_reduction = 0.0;}
vis = vis * (1.0 - 0.98 * visibility_reduction);
}
setprop(lw~"current/visibility-m",vis);
compat_layer.setVisibility(vis);
setprop(lw~"current/thermal-lift",lift);
compat_layer.setLift(lift);
@ -1732,8 +1792,13 @@ settimer ( func {
setprop(lw~"tmp/presampling-status", "idle");
# reset the random store
weather_tiles.rnd_store = rand();
# indicate that we are no longer running
local_weather_running_flag = 0;
}
@ -1846,6 +1911,8 @@ var create_cumosys = func (blat, blon, balt, nc, size) {
if (detailed_clouds_flag == 1)
{nc = int(0.7 * nc);}
nc = int(nc / cumulus_efficiency_factor);
if (thread_flag == 1)
{setprop(lw~"tmp/convective-status", "computing");
cumulus_loop(blat, blon, balt, nc, size);}
@ -1861,7 +1928,7 @@ else
var cumulus_loop = func (blat, blon, balt, nc, size) {
var n = 25;
var n = int(25/cumulus_efficiency_factor);
if (nc < 0)
{
@ -1951,7 +2018,7 @@ while (i < nc) {
# then decide if the thermal energy at the spot generates an updraft and a cloud
if (rand() < p) # we decide to place a cloud at this spot
if (rand() < (p * cumulus_efficiency_factor)) # we decide to place a cloud at this spot
{
strength = (1.5 * rand() + (2.0 * p)) * t_factor2; # the strength of thermal activity at the spot
if (strength > 1.0)
@ -2105,7 +2172,7 @@ while (i < nc) {
# check if to place a cloud with weight sqrt(p), the lifetime gets another sqrt(p) factor
if (rand() > math.sqrt(p))
if (rand() > math.sqrt(p * cumulus_efficiency_factor))
{i=i+1; continue;}
@ -3168,8 +3235,8 @@ var set_wind_ipoint_metar = func (lat, lon, d0, v0) {
if (lat >0.0) {var dsign = -1.0;} else {var dsign = 1.0;}
var v1 = v0 * (1.0 + rand() * 0.2);
var d1 = d0 + dsign * 3.0 * rand();
var v1 = v0 * (1.0 + rand() * 0.1);
var d1 = d0 + dsign * 2.0 * rand();
var v2 = v0 * (1.2 + rand() * 0.2);
var d2 = d0 + dsign * (3.0 * rand() + 2.0);
@ -3225,11 +3292,11 @@ if (getprop(lw~"config/generate-thermal-lift-flag") ==1) {generate_thermal_lift_
thread_flag = getprop(lw~"config/thread-flag");
dynamics_flag = getprop(lw~"config/dynamics-flag");
presampling_flag = getprop(lw~"tmp/presampling-flag");
presampling_flag = getprop(lw~"config/presampling-flag");
detailed_clouds_flag = getprop(lw~"config/detailed-clouds-flag");
dynamical_convection_flag = getprop(lw~"config/dynamical-convection-flag");
debug_output_flag = getprop(lw~"config/debug-output-flag");
fps_control_flag = getprop(lw~"config/fps-control-flag");
}
@ -3825,8 +3892,12 @@ setprop(lw~"METAR/layer[3]/cover-oct",0);
setprop(lw~"METAR/layer[3]/alt-agl-ft", 20000.0);
setprop(lw~"METAR/available-flag",1);
# set initial value for stored random number for small-scale cloud patterns
# set listener for worker threads
weather_tiles.rnd_store = rand();
# set listeners
setlistener(lw~"tmp/thread-status", func {var s = size(clouds_path); compat_layer.create_cloud_array(s, clouds_path, clouds_lat, clouds_lon, clouds_alt, clouds_orientation); });
setlistener(lw~"tmp/convective-status", func {var s = size(clouds_path); compat_layer.create_cloud_array(s, clouds_path, clouds_lat, clouds_lon, clouds_alt, clouds_orientation); });
@ -3840,6 +3911,12 @@ setlistener(lw~"config/clouds-in-dynamics-loop", func {weather_dynamics.max_clou
setlistener(lw~"config/clouds-visible-range-m", func {weather_tile_management.cloud_view_distance = getprop(lw~"config/clouds-visible-range-m");});
setlistener(lw~"config/distance-to-load-tile-m", func {setprop(lw~"config/distance-to-remove-tile-m",getprop(lw~"config/distance-to-load-tile-m") + 500.0);});
setlistener(lw~"config/fps-control-flag", func {fps_control_flag = getprop(lw~"config/fps-control-flag");});
setlistener(lw~"config/target-framerate", func {target_framerate = getprop(lw~"config/target-framerate");});
setlistener(lw~"config/small-scale-persistence", func {weather_tiles.small_scale_persistence = getprop(lw~"config/small-scale-persistence");});
}
@ -4152,12 +4229,10 @@ var windIpointArray = [];
var wind_model_flag = 1;
# a global determining the relative amount of different textures in detailed convective clouds
# globals governing properties of the Cumulus system
var convective_texture_mix = 0.0;
# a global keeping track of the mean cloud altitude when building a Cumulus from individual cloudlets
var cumulus_efficiency_factor = 1.0;
var cloud_mean_altitude = 0.0;
# globals keeping track of the lifetime when building a Cumulus from individual cloudlets
@ -4181,69 +4256,76 @@ var dynamical_convection_flag = 1;
var debug_output_flag = 1;
var metar_flag = 0;
var local_weather_running_flag = 0;
var fps_control_flag = 1;
# globals for framerate controlled cloud management
var fps_average = 0.0;
var fps_samples = 0;
var fps_sum = 0.0;
var target_framerate = 25.0;
# set all sorts of default properties for the menu
setprop(lw~"tmp/cloud-type", "Altocumulus");
setprop(lw~"tmp/alt", 12000.0);
setprop(lw~"tmp/nx",5);
setprop(lw~"tmp/xoffset",800.0);
setprop(lw~"tmp/xedge", 0.2);
setprop(lw~"tmp/ny",15);
setprop(lw~"tmp/yoffset",800.0);
setprop(lw~"tmp/yedge", 0.2);
setprop(lw~"tmp/dir",0.0);
setprop(lw~"tmp/tri", 1.0);
setprop(lw~"tmp/rnd-pos-x",400.0);
setprop(lw~"tmp/rnd-pos-y",400.0);
setprop(lw~"tmp/rnd-alt", 300.0);
setprop(lw~"tmp/conv-strength", 1);
setprop(lw~"tmp/conv-size", 15.0);
setprop(lw~"tmp/conv-alt", 2000.0);
setprop(lw~"tmp/bar-alt", 3500.0);
setprop(lw~"tmp/bar-n", 150.0);
setprop(lw~"tmp/bar-dir", 0.0);
setprop(lw~"tmp/bar-dist", 5.0);
setprop(lw~"tmp/bar-size", 10.0);
setprop(lw~"tmp/scloud-type", "Altocumulus");
setprop(lw~"tmp/scloud-subtype", "small");
# setprop(lw~"tmp/cloud-type", "Altocumulus");
# setprop(lw~"tmp/alt", 12000.0);
# setprop(lw~"tmp/nx",5);
# setprop(lw~"tmp/xoffset",800.0);
# setprop(lw~"tmp/xedge", 0.2);
# setprop(lw~"tmp/ny",15);
# setprop(lw~"tmp/yoffset",800.0);
# setprop(lw~"tmp/yedge", 0.2);
# setprop(lw~"tmp/dir",0.0);
# setprop(lw~"tmp/tri", 1.0);
# setprop(lw~"tmp/rnd-pos-x",400.0);
# setprop(lw~"tmp/rnd-pos-y",400.0);
# setprop(lw~"tmp/rnd-alt", 300.0);
# setprop(lw~"tmp/conv-strength", 1);
# setprop(lw~"tmp/conv-size", 15.0);
# setprop(lw~"tmp/conv-alt", 2000.0);
# setprop(lw~"tmp/bar-alt", 3500.0);
# setprop(lw~"tmp/bar-n", 150.0);
# setprop(lw~"tmp/bar-dir", 0.0);
# setprop(lw~"tmp/bar-dist", 5.0);
# setprop(lw~"tmp/bar-size", 10.0);
# setprop(lw~"tmp/scloud-type", "Altocumulus");
# setprop(lw~"tmp/scloud-subtype", "small");
setprop(lw~"tmp/scloud-lat",getprop("position/latitude-deg"));
setprop(lw~"tmp/scloud-lon",getprop("position/longitude-deg"));
setprop(lw~"tmp/scloud-alt", 5000.0);
setprop(lw~"tmp/scloud-dir", 0.0);
setprop(lw~"tmp/layer-type","Nimbus");
setprop(lw~"tmp/layer-rx",10.0);
setprop(lw~"tmp/layer-ry",10.0);
setprop(lw~"tmp/layer-phi",0.0);
setprop(lw~"tmp/layer-alt",3000.0);
setprop(lw~"tmp/layer-thickness",500.0);
setprop(lw~"tmp/layer-density",1.0);
setprop(lw~"tmp/layer-edge",0.2);
setprop(lw~"tmp/layer-rain-flag",1);
setprop(lw~"tmp/layer-rain-density",1.0);
setprop(lw~"tmp/box-x-m",600.0);
setprop(lw~"tmp/box-y-m",600.0);
setprop(lw~"tmp/box-alt-ft",300.0);
setprop(lw~"tmp/box-n",10);
setprop(lw~"tmp/box-core-fraction",0.4);
setprop(lw~"tmp/box-core-offset",0.2);
setprop(lw~"tmp/box-core-height",1.4);
setprop(lw~"tmp/box-core-n",3);
setprop(lw~"tmp/box-bottom-fraction",0.9);
setprop(lw~"tmp/box-bottom-thickness",0.5);
setprop(lw~"tmp/box-bottom-n",12);
setprop(lw~"tmp/tile-type", "High-pressure");
setprop(lw~"tmp/tile-orientation-deg", 260.0);
setprop(lw~"tmp/windspeed-kt", 8.0);
setprop(lw~"tmp/gust-frequency-hz", 0.0);
setprop(lw~"tmp/gust-relative-strength",0.0);
setprop(lw~"tmp/gust-angular-variation-deg",0.0);
setprop(lw~"tmp/tile-alt-offset-ft", 0.0);
# setprop(lw~"tmp/scloud-alt", 5000.0);
# setprop(lw~"tmp/scloud-dir", 0.0);
# setprop(lw~"tmp/layer-type","Nimbus");
# setprop(lw~"tmp/layer-rx",10.0);
# setprop(lw~"tmp/layer-ry",10.0);
# setprop(lw~"tmp/layer-phi",0.0);
# setprop(lw~"tmp/layer-alt",3000.0);
# setprop(lw~"tmp/layer-thickness",500.0);
# setprop(lw~"tmp/layer-density",1.0);
# setprop(lw~"tmp/layer-edge",0.2);
# setprop(lw~"tmp/layer-rain-flag",1);
# setprop(lw~"tmp/layer-rain-density",1.0);
# setprop(lw~"tmp/box-x-m",600.0);
# setprop(lw~"tmp/box-y-m",600.0);
# setprop(lw~"tmp/box-alt-ft",300.0);
# setprop(lw~"tmp/box-n",10);
# setprop(lw~"tmp/box-core-fraction",0.4);
# setprop(lw~"tmp/box-core-offset",0.2);
# setprop(lw~"tmp/box-core-height",1.4);
# setprop(lw~"tmp/box-core-n",3);
# setprop(lw~"tmp/box-bottom-fraction",0.9);
# setprop(lw~"tmp/box-bottom-thickness",0.5);
# setprop(lw~"tmp/box-bottom-n",12);
# setprop(lw~"tmp/tile-type", "High-pressure");
# setprop(lw~"tmp/tile-orientation-deg", 260.0);
# setprop(lw~"tmp/windspeed-kt", 8.0);
# setprop(lw~"tmp/gust-frequency-hz", 0.0);
# setprop(lw~"tmp/gust-relative-strength",0.0);
# setprop(lw~"tmp/gust-angular-variation-deg",0.0);
# setprop(lw~"tmp/tile-alt-offset-ft", 0.0);
setprop(lw~"tmp/tile-alt-median-ft",0.0);
setprop(lw~"tmp/tile-alt-min-ft",0.0);
setprop(lw~"tmp/tile-management", "realistic weather");
setprop(lw~"tmp/presampling-flag", 1);
setprop(lw~"tmp/asymmetric-tile-loading-flag", 0);
# setprop(lw~"tmp/tile-management", "realistic weather");
# setprop(lw~"tmp/asymmetric-tile-loading-flag", 0);
setprop(lw~"tmp/last-reading-pos-del",0);
setprop(lw~"tmp/last-reading-pos-mod",0);
setprop(lw~"tmp/thread-status", "idle");
@ -4251,47 +4333,48 @@ setprop(lw~"tmp/convective-status", "idle");
setprop(lw~"tmp/presampling-status", "idle");
setprop(lw~"tmp/buffer-status", "idle");
setprop(lw~"tmp/buffer-tile-index", 0);
setprop(lw~"tmp/FL0-wind-from-heading-deg",260.0);
setprop(lw~"tmp/FL0-windspeed-kt",8.0);
setprop(lw~"tmp/FL50-wind-from-heading-deg",262.0);
setprop(lw~"tmp/FL50-windspeed-kt",11.0);
setprop(lw~"tmp/FL100-wind-from-heading-deg",264.0);
setprop(lw~"tmp/FL100-windspeed-kt",16.0);
setprop(lw~"tmp/FL180-wind-from-heading-deg",265.0);
setprop(lw~"tmp/FL180-windspeed-kt",24.0);
setprop(lw~"tmp/FL240-wind-from-heading-deg",269.0);
setprop(lw~"tmp/FL240-windspeed-kt",35.0);
setprop(lw~"tmp/FL300-wind-from-heading-deg",273.0);
setprop(lw~"tmp/FL300-windspeed-kt",45.0);
setprop(lw~"tmp/FL340-wind-from-heading-deg",274.0);
setprop(lw~"tmp/FL340-windspeed-kt",50.0);
setprop(lw~"tmp/FL390-wind-from-heading-deg",273.0);
setprop(lw~"tmp/FL390-windspeed-kt",56.0);
setprop(lw~"tmp/FL450-wind-from-heading-deg",272.0);
setprop(lw~"tmp/FL450-windspeed-kt",65.0);
#setprop(lw~"tmp/FL0-wind-from-heading-deg",260.0);
#setprop(lw~"tmp/FL0-windspeed-kt",8.0);
#setprop(lw~"tmp/FL50-wind-from-heading-deg",262.0);
#setprop(lw~"tmp/FL50-windspeed-kt",11.0);
#setprop(lw~"tmp/FL100-wind-from-heading-deg",264.0);
#setprop(lw~"tmp/FL100-windspeed-kt",16.0);
#setprop(lw~"tmp/FL180-wind-from-heading-deg",265.0);
#setprop(lw~"tmp/FL180-windspeed-kt",24.0);
#setprop(lw~"tmp/FL240-wind-from-heading-deg",269.0);
#setprop(lw~"tmp/FL240-windspeed-kt",35.0);
#setprop(lw~"tmp/FL300-wind-from-heading-deg",273.0);
#setprop(lw~"tmp/FL300-windspeed-kt",45.0);
#setprop(lw~"tmp/FL340-wind-from-heading-deg",274.0);
#setprop(lw~"tmp/FL340-windspeed-kt",50.0);
#setprop(lw~"tmp/FL390-wind-from-heading-deg",273.0);
#setprop(lw~"tmp/FL390-windspeed-kt",56.0);
#setprop(lw~"tmp/FL450-wind-from-heading-deg",272.0);
#setprop(lw~"tmp/FL450-windspeed-kt",65.0);
setprop(lw~"tmp/ipoint-latitude-deg",getprop("position/latitude-deg"));
setprop(lw~"tmp/ipoint-longitude-deg",getprop("position/longitude-deg"));
# set config values
setprop(lw~"config/distance-to-load-tile-m",39000.0);
setprop(lw~"config/distance-to-remove-tile-m",39500.0);
setprop(lw~"config/detailed-clouds-flag",1);
setprop(lw~"config/dynamics-flag",0);
setprop(lw~"config/thermal-properties",1.0);
setprop(lw~"config/wind-model","constant");
setprop(lw~"config/buffer-flag",1);
setprop(lw~"config/asymmetric-reduction",0.7);
setprop(lw~"config/clouds-visible-range-m",30000.0);
setprop(lw~"config/asymmetric-buffering-flag",0);
setprop(lw~"config/asymmetric-buffering-reduction",0.3);
setprop(lw~"config/asymmetric-buffering-angle-deg",90.0);
setprop(lw~"config/clouds-in-dynamics-loop",250);
setprop(lw~"config/debug-output-flag",0);
setprop(lw~"config/generate-thermal-lift-flag", 0);
setprop(lw~"config/dynamical-convection-flag", 0);
setprop(lw~"config/thread-flag", 1);
# setprop(lw~"config/distance-to-load-tile-m",39000.0);
# setprop(lw~"config/distance-to-remove-tile-m",39500.0);
# setprop(lw~"config/detailed-clouds-flag",1);
# setprop(lw~"config/dynamics-flag",0);
# setprop(lw~"config/thermal-properties",1.0);
# setprop(lw~"config/wind-model","constant");
# setprop(lw~"config/buffer-flag",1);
# setprop(lw~"config/asymmetric-reduction",0.7);
# setprop(lw~"config/clouds-visible-range-m",30000.0);
# setprop(lw~"config/asymmetric-buffering-flag",0);
# setprop(lw~"config/asymmetric-buffering-reduction",0.3);
# setprop(lw~"config/asymmetric-buffering-angle-deg",90.0);
# setprop(lw~"config/clouds-in-dynamics-loop",250);
# setprop(lw~"config/debug-output-flag",0);
# setprop(lw~"config/generate-thermal-lift-flag", 0);
# setprop(lw~"config/dynamical-convection-flag", 0);
# setprop(lw~"config/thread-flag", 1);
# setprop(lw~"config/presampling-flag", 1);
# set the default loop flags to loops inactive

View file

@ -62,6 +62,35 @@ if ((local_weather.metar_flag == 1) and (getprop(lw~"METAR/station-id") != getpr
weather_tiles.set_METAR_weather_station();
}
# compute the averaged framerate and see if cloud visibility needs to be adjusted
if (local_weather.fps_control_flag == 1)
{
local_weather.fps_average = local_weather.fps_sum/local_weather.fps_samples;
# print("Average framerate: ", local_weather.fps_average);
local_weather.fps_sum = 0.0;
local_weather.fps_samples = 0;
if (local_weather.fps_average > 1.1 * local_weather.target_framerate)
{
var target_cloud_view_distance = cloud_view_distance * 1.1;
if (target_cloud_view_distance > 45000.0)
{target_cloud_view_distance = 45000.0;}
setprop(lw~"config/clouds-visible-range-m", target_cloud_view_distance);
}
if (local_weather.fps_average < 0.9 * local_weather.target_framerate)
{
var target_cloud_view_distance = cloud_view_distance * 0.9;
if (target_cloud_view_distance < 15000.0)
{target_cloud_view_distance = 15000.0;}
setprop(lw~"config/clouds-visible-range-m", target_cloud_view_distance);
}
}
foreach (var t; tNode) {
@ -441,7 +470,7 @@ if (getprop(lw~"tmp/tile-management") == "repeat tile")
else if (code == "cold_sector") {weather_tiles.set_cold_sector_tile();}
else if (code == "warm_sector") {weather_tiles.set_warm_sector_tile();}
else if (code == "tropical_weather") {weather_tiles.set_tropical_weather_tile();}
#else if (code == "test") {weather_tiles.set_4_8_stratus_tile;}
else if (code == "test") {weather_tiles.set_4_8_stratus_tile();}
else
{
print("Repeat tile not implemented with this tile type!");
@ -450,50 +479,50 @@ if (getprop(lw~"tmp/tile-management") == "repeat tile")
}
else if (getprop(lw~"tmp/tile-management") == "realistic weather")
{
var rn = rand();
var rn = rand() * getprop(lw~"config/large-scale-persistence");
if (code == "low_pressure_core")
{
if (rn > 0.2) {weather_tiles.set_low_pressure_core_tile();}
if (rn > 0.1) {weather_tiles.set_low_pressure_core_tile();}
else {weather_tiles.set_low_pressure_tile();}
}
else if (code == "low_pressure")
{
if (rn > 0.2) {weather_tiles.set_low_pressure_tile();}
else if (rn > 0.1) {weather_tiles.set_low_pressure_core_tile();}
if (rn > 0.1) {weather_tiles.set_low_pressure_tile();}
else if (rn > 0.05) {weather_tiles.set_low_pressure_core_tile();}
else {weather_tiles.set_low_pressure_border_tile();}
}
else if (code == "low_pressure_border")
{
if (rn > 0.4) {weather_tiles.set_low_pressure_border_tile();}
else if (rn > 0.3) {weather_tiles.set_cold_sector_tile();}
else if (rn > 0.2) {weather_tiles.set_warm_sector_tile();}
else if (rn > 0.1) {weather_tiles.set_low_pressure_tile();}
if (rn > 0.2) {weather_tiles.set_low_pressure_border_tile();}
else if (rn > 0.15) {weather_tiles.set_cold_sector_tile();}
else if (rn > 0.1) {weather_tiles.set_warm_sector_tile();}
else if (rn > 0.05) {weather_tiles.set_low_pressure_tile();}
else {weather_tiles.set_high_pressure_border_tile();}
}
else if (code == "high_pressure_border")
{
if (rn > 0.4) {weather_tiles.set_high_pressure_border_tile();}
else if (rn > 0.3) {weather_tiles.set_cold_sector_tile();}
else if (rn > 0.2) {weather_tiles.set_warm_sector_tile();}
else if (rn > 0.1) {weather_tiles.set_high_pressure_tile();}
if (rn > 0.2) {weather_tiles.set_high_pressure_border_tile();}
else if (rn > 0.15) {weather_tiles.set_cold_sector_tile();}
else if (rn > 0.1) {weather_tiles.set_warm_sector_tile();}
else if (rn > 0.05) {weather_tiles.set_high_pressure_tile();}
else {weather_tiles.set_low_pressure_border_tile();}
}
else if (code == "high_pressure")
{
if (rn > 0.2) {weather_tiles.set_high_pressure_tile();}
else if (rn > 0.1) {weather_tiles.set_high_pressure_border_tile();}
if (rn > 0.1) {weather_tiles.set_high_pressure_tile();}
else if (rn > 0.05) {weather_tiles.set_high_pressure_border_tile();}
else {weather_tiles.set_high_pressure_core_tile();}
}
else if (code == "high_pressure_core")
{
if (rn > 0.2) {weather_tiles.set_high_pressure_core_tile();}
if (rn > 0.1) {weather_tiles.set_high_pressure_core_tile();}
else {weather_tiles.set_high_pressure_tile();}
}
else if (code == "cold_sector")
{
if (rn > 0.3) {weather_tiles.set_cold_sector_tile();}
else if (rn > 0.2)
if (rn > 0.15) {weather_tiles.set_cold_sector_tile();}
else if (rn > 0.1)
{
if ((dir_index ==0) or (dir_index ==1) or (dir_index==2))
{weather_tiles.set_warmfront1_tile();}
@ -502,13 +531,13 @@ else if (getprop(lw~"tmp/tile-management") == "realistic weather")
else if ((dir_index ==6) or (dir_index ==7) or (dir_index==8))
{weather_tiles.set_coldfront_tile();}
}
else if (rn > 0.1) {weather_tiles.set_low_pressure_border_tile();}
else if (rn > 0.05) {weather_tiles.set_low_pressure_border_tile();}
else {weather_tiles.set_high_pressure_border_tile();}
}
else if (code == "warm_sector")
{
if (rn > 0.3) {weather_tiles.set_warm_sector_tile();}
else if (rn > 0.2)
if (rn > 0.15) {weather_tiles.set_warm_sector_tile();}
else if (rn > 0.1)
{
if ((dir_index ==0) or (dir_index ==1) or (dir_index==2))
{weather_tiles.set_coldfront_tile();}
@ -517,7 +546,7 @@ else if (getprop(lw~"tmp/tile-management") == "realistic weather")
else if ((dir_index ==6) or (dir_index ==7) or (dir_index==8))
{weather_tiles.set_warmfront4_tile();}
}
else if (rn > 0.1) {weather_tiles.set_low_pressure_border_tile();}
else if (rn > 0.05) {weather_tiles.set_low_pressure_border_tile();}
else {weather_tiles.set_high_pressure_border_tile();}
}
else if (code == "warmfront1")
@ -525,7 +554,12 @@ else if (getprop(lw~"tmp/tile-management") == "realistic weather")
if ((dir_index ==0) or (dir_index ==1) or (dir_index==2))
{weather_tiles.set_warmfront2_tile();}
else if ((dir_index ==3) or (dir_index ==5))
{weather_tiles.set_warmfront1_tile();}
{
if (rand() > 0.15)
{weather_tiles.set_warmfront1_tile();}
else
{weather_tiles.set_high_pressure_border_tile();}
}
else if ((dir_index ==6) or (dir_index ==7) or (dir_index==8))
{weather_tiles.set_cold_sector_tile();}
}
@ -534,7 +568,12 @@ else if (getprop(lw~"tmp/tile-management") == "realistic weather")
if ((dir_index ==0) or (dir_index ==1) or (dir_index==2))
{weather_tiles.set_warmfront3_tile();}
if ((dir_index ==3) or (dir_index ==5))
{weather_tiles.set_warmfront2_tile();}
{
if (rand() > 0.15)
{weather_tiles.set_warmfront2_tile();}
else
{weather_tiles.set_high_pressure_border_tile();}
}
if ((dir_index ==6) or (dir_index ==7) or (dir_index==8))
{weather_tiles.set_warmfront1_tile();}
}
@ -543,7 +582,12 @@ else if (getprop(lw~"tmp/tile-management") == "realistic weather")
if ((dir_index ==0) or (dir_index ==1) or (dir_index==2))
{weather_tiles.set_warmfront4_tile();}
if ((dir_index ==3) or (dir_index ==5))
{weather_tiles.set_warmfront3_tile();}
{
if (rand() > 0.15)
{weather_tiles.set_warmfront3_tile();}
else
{weather_tiles.set_low_pressure_border_tile();}
}
if ((dir_index ==6) or (dir_index ==7) or (dir_index==8))
{weather_tiles.set_warmfront2_tile();}
}
@ -552,7 +596,12 @@ else if (getprop(lw~"tmp/tile-management") == "realistic weather")
if ((dir_index ==0) or (dir_index ==1) or (dir_index==2))
{weather_tiles.set_warm_sector_tile();}
if ((dir_index ==3) or (dir_index ==5))
{weather_tiles.set_warmfront4_tile();}
{
if (rand() > 0.15)
{weather_tiles.set_warmfront4_tile();}
else
{weather_tiles.set_low_pressure_tile();}
}
if ((dir_index ==6) or (dir_index ==7) or (dir_index==8))
{weather_tiles.set_warmfront3_tile();}
}
@ -561,7 +610,12 @@ else if (getprop(lw~"tmp/tile-management") == "realistic weather")
if ((dir_index ==0) or (dir_index ==1) or (dir_index==2))
{weather_tiles.set_cold_sector_tile();}
else if ((dir_index ==3) or (dir_index ==5))
{weather_tiles.set_coldfront_tile();}
{
if (rand() > 0.15)
{weather_tiles.set_coldfront_tile();}
else
{weather_tiles.set_high_pressure_border_tile();}
}
else if ((dir_index ==6) or (dir_index ==7) or (dir_index==8))
{weather_tiles.set_warm_sector_tile();}
}
@ -1379,8 +1433,7 @@ var lon_to_m = 0.0; #local_weather.lon_to_m;
var m_to_lon = 0.0; # local_weather.m_to_lon;
var lw = "/local-weather/";
var cloud_view_distance = 20000.0;
var cloud_view_distance = getprop(lw~"config/clouds-visible-range-m");
var modelArrays = [];
var active_tile_list = [];

View file

@ -29,7 +29,10 @@ var current_code = getprop(lw~"tiles/code");
var dir_index = getprop(lw~"tiles/tmp/dir-index");
props.globals.getNode(lw~"tiles").getChild("tile",dir_index).getNode("code").setValue(current_code);
#print(current_code, getprop(lw~"tiles/tmp/code"));
if (current_code != getprop(lw~"tiles/tmp/code"))
{weather_tiles.rnd_store = rand();}
# generate a handling array for models
@ -95,7 +98,7 @@ calc_geo(blat);
local_weather.set_weather_station(blat, blon, alt_offset, 20000.0, 14.0, 12.0, 29.78);
create_8_8_nimbus_var3(blat, blon, 2000.0 + alt_offset+local_weather.cloud_vertical_size_map["Nimbus"] * 0.5 * m_to_ft, 0.0);
# create_8_8_nimbus_var3(blat, blon, 2000.0 + alt_offset+local_weather.cloud_vertical_size_map["Nimbus"] * 0.5 * m_to_ft, 0.0);
#create_2_8_sstratus_streak(blat, blon,5000.0,0.0);
@ -105,7 +108,7 @@ create_8_8_nimbus_var3(blat, blon, 2000.0 + alt_offset+local_weather.cloud_verti
# create_2_8_cirrocumulus(blat, blon, 6000.0, 0.0);
#create_detailed_stratocumulus_bank(blat, blon,5000.0+alt_offset,0.0);
create_detailed_small_stratocumulus_bank(blat, blon,3000.0+alt_offset,0.0);
#create_4_8_altocumulus_perlucidus(blat, blon, 10000.0, 0.0);
@ -151,7 +154,7 @@ calc_geo(blat);
# get probabilistic values for the weather parameters
var vis = 35000.0 + rand() * 20000.0;
var vis = 30000.0 + rand() * 15000.0;
var T = 20.0 + rand() * 10.0;
var spread = 5.0 + 3.0 * rand();
var D = T - spread;
@ -164,11 +167,16 @@ local_weather.set_weather_station(blat, blon, alt_offset, vis, T, D, p * hp_to_i
var alt = spread * 1000;
var strength = 0.0;
var rn = rand();
if (rand() < small_scale_persistence)
{rn = rnd_store;}
else
{rnd_store = rn;}
if (rn > 0.66)
if (rn > 0.8)
{
# cloud scenario 1: weak cumulus development and blue thermals
@ -186,7 +194,7 @@ if (rn > 0.66)
}
}
else if (rn > 0.33)
else if (rn > 0.6)
{
# cloud scenario 2: some Cirrocumulus patches
@ -194,8 +202,10 @@ else if (rn > 0.33)
local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
create_2_8_cirrocumulus(blat, blon, alt + alt_offset + 5000.0, alpha);
create_2_8_cirrus(blat, blon, alt + alt_offset + 35000.0, alpha);
}
else if (rn > 0.0)
else if (rn > 0.4)
{
# cloud scenario 3: Cirrostratus undulatus over weak cumulus
@ -204,6 +214,27 @@ else if (rn > 0.0)
create_4_8_cirrostratus_undulatus(blat, blon, alt + alt_offset + 32000.0, alpha);
}
else if (rn > 0.2)
{
# cloud scenario 4: Cirrostratus undulatus streak
strength = rand() * 0.03;
local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
create_1_8_cirrostratus_undulatus(blat, blon, alt + alt_offset + 32000.0, alpha);
}
else if (rn > 0.0)
{
# cloud scenario 5: Cirrus
create_2_8_cirrus(blat, blon, alt + alt_offset + 35000.0, alpha);
create_1_8_cirrostratus_undulatus(blat, blon, alt + alt_offset + 28000.0, alpha);
create_1_8_cirrostratus_undulatus(blat, blon, alt + alt_offset + 28000.0, alpha);
}
# store convective altitude and strength
@ -261,9 +292,14 @@ var strength = 0.0;
var rn = rand();
if (rand() < small_scale_persistence)
{rn = rnd_store;}
else
{rnd_store = rn;}
# rn = 0.1;
if (rn > 0.75)
if (rn > 0.8)
{
# cloud scenario 1: possible Cirrus over Cumulus
strength = 0.2 + rand() * 0.4;
@ -285,7 +321,7 @@ if (rn > 0.75)
}
}
else if (rn > 0.5)
else if (rn > 0.6)
{
# cloud scenario 2: Cirrostratus over weak Cumulus
@ -295,7 +331,7 @@ else if (rn > 0.5)
create_2_8_cirrostratus(blat, blon, alt+alt_offset+25000.0, alpha);
}
else if (rn > 0.25)
else if (rn > 0.4)
{
# cloud scenario 3: Cirrocumulus sheet over Cumulus
@ -310,7 +346,7 @@ else if (rn > 0.25)
compat_layer.create_cloud(path, blat + get_lat(x,y,phi), blon+get_lon(x,y,phi), alt + alt_offset +24000,alpha);
}
else if (rn > 0.0)
else if (rn > 0.2)
{
# cloud scenario 4: Cirrostratus undulatus over weak Cumulus
@ -319,6 +355,17 @@ else if (rn > 0.0)
create_4_8_cirrostratus_undulatus(blat, blon, alt + alt_offset + 25000.0, alpha);
}
else if (rn > 0.0)
{
# cloud scenario 5: some scattered Altocumuli over Cumulus
strength = 0.25 + rand() * 0.1;
local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
create_1_8_altocumulus_scattered(blat, blon, alt+alt_offset+10000.0, alpha);
create_1_8_cirrostratus_undulatus(blat, blon, alt + alt_offset + 25000.0, alpha);
}
# store convective altitude and strength
@ -375,6 +422,10 @@ var strength = 0.0;
var rn = rand();
if (rand() < small_scale_persistence)
{rn = rnd_store;}
else
{rnd_store = rn;}
if (rn > 0.875)
{
@ -476,6 +527,7 @@ else if (rn > 0.0)
create_4_8_altocumulus_perlucidus(blat, blon, alt + 10000.0 + alt_offset, alpha);
create_2_8_cirrus(blat, blon, alt + 30000.0 + alt_offset, alpha);
}
@ -507,10 +559,8 @@ var lon = 0.0;
var alpha = getprop(lw~"tmp/tile-orientation-deg");
var phi = alpha * math.pi/180.0;
if (getprop(lw~"tmp/presampling-flag") == 0)
{var alt_offset = getprop(lw~"tmp/tile-alt-offset-ft");}
else
{var alt_offset = getprop(lw~"tmp/tile-alt-layered-ft");}
var alt_offset = getprop(lw~"tmp/tile-alt-offset-ft");
# get tile center coordinates
@ -538,76 +588,87 @@ var strength = 0.0;
var rn = rand();
if (rn > 0.875)
{
# cloud scenario 1: a low 4/8 stratus patches, thin patches above
if (rand() < small_scale_persistence)
{rn = rnd_store;}
else
{rnd_store = rn;}
alt = alt + local_weather.cloud_vertical_size_map["Stratus"] * 0.5 * m_to_ft;
create_4_8_stratus_patches(blat, blon, alt+alt_offset,alpha);
create_4_8_tstratus_patches(blat, blon, alt+alt_offset+6000,alpha);
}
else if (rn > 0.75)
{
# cloud scenario 2: a low 4/8 undulatus, thin patches above
# rn = 0.1;
alt = alt + local_weather.cloud_vertical_size_map["Stratus"] * 0.5 * m_to_ft;
create_4_8_sstratus_undulatus(blat, blon, alt+alt_offset,alpha);
create_2_8_tstratus(blat, blon, alt+alt_offset+7000,alpha);
}
else if (rn > 0.625)
if (rn > 0.857)
{
# cloud scenario 3: low Stratocumulus
# cloud scenario 1: low Stratocumulus, thin streaks above
strength = 0.05 + rand() * 0.1;
local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
# alt = alt + local_weather.cloud_vertical_size_map["Cumulus"] * 0.5 * m_to_ft;
create_detailed_stratocumulus_bank(blat, blon, alt+alt_offset,alpha);
create_2_8_sstratus(blat, blon, alt+alt_offset+6000,alpha);
create_2_8_tstratus(blat, blon, alt+alt_offset+9000,alpha);
}
else if (rn > 0.5)
{
# cloud scenario 4: dense low Stratocumulus
# alt = alt + local_weather.cloud_vertical_size_map["Cumulus"] * 0.5 * m_to_ft;
create_detailed_stratocumulus_bank(blat, blon, alt+alt_offset,alpha);
create_detailed_stratocumulus_bank(blat, blon, alt+alt_offset,alpha);
create_2_8_sstratus(blat, blon, alt+alt_offset+8000,alpha);
create_4_8_alttstratus_streaks(blat, blon, alt+alt_offset+4000.0,alpha);
}
else if (rn > 375)
else if (rn > 0.714)
{
# cloud scenario 5: Cirrocumulus over 4/8 Stratus
# cloud scenario 2: weak Cumulus, Stratus undulatus above
strength = 0.15 + rand() * 0.15;
local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
create_6_8_tstratus_undulatus(blat, blon, alt+alt_offset+4000.0,alpha);
create_2_8_alttstratus(blat, blon, alt+alt_offset+7000.0,alpha);
}
else if (rn > 0.571)
{
# cloud scenario 3: Stratocumulus banks with patches above
create_detailed_stratocumulus_bank(blat, blon, alt+alt_offset,alpha);
create_detailed_small_stratocumulus_bank(blat, blon, alt+alt_offset,alpha);
create_4_8_alttstratus_patches(blat, blon, alt+alt_offset+4000.0,alpha);
}
else if (rn > 0.428)
{
# cloud scenario 4: structured Stratus
alt = alt + local_weather.cloud_vertical_size_map["Stratus"] * 0.5 * m_to_ft;
create_4_8_sstratus_patches(blat, blon, alt+alt_offset,alpha);
create_4_8_cirrocumulus_bank(blat, blon, alt+alt_offset + 12000.0, alpha);
create_2_8_alttstratus(blat, blon, alt+alt_offset+7000.0,alpha);
}
else if (rn > 0.250)
else if (rn > 0.285)
{
# cloud scenario 6: Cirrostratus over 4/8 Stratus undulatus
# cloud scenario 5: Stratus blending with Cumulus with Cirrocumulus above
strength = 0.1 + rand() * 0.1;
local_weather.create_cumosys(blat,blon, alt + alt_offset, get_n(strength), 20000.0);
alt = alt + local_weather.cloud_vertical_size_map["Stratus"] * 0.5 * m_to_ft;
create_6_8_stratus_undulatus(blat, blon, alt+alt_offset,alpha);
create_4_8_cirrostratus_undulatus(blat, blon, alt+alt_offset+24000,alpha);
create_4_8_tstratus_patches(blat, blon, alt+alt_offset,alpha);
create_4_8_cirrocumulus_undulatus(blat, blon, alt+alt_offset + 12000.0,alpha);
}
else if (rn > 0.125)
else if (rn > 0.142)
{
# cloud scenario 7: thin stratus
# cloud scenario 6: small Stratocumulus banks
create_4_8_alttstratus_streaks(blat, blon, alt+alt_offset,alpha);
create_detailed_small_stratocumulus_bank(blat, blon, alt+alt_offset,alpha);
create_detailed_small_stratocumulus_bank(blat, blon, alt+alt_offset,alpha);
create_2_8_sstratus(blat, blon, alt+alt_offset+6000,alpha);
create_4_8_tstratus_patches(blat, blon, alt+alt_offset,alpha);
create_2_8_cirrostratus(blat, blon, alt+alt_offset + 25000.0,alpha);
}
else if (rn > 0.0)
else
{
# cloud scenario 8: thin stratus
create_4_8_alttstratus_patches(blat, blon, alt+alt_offset,alpha);
# cloud scenario 7: blended structured and unstructured Stratiform clouds
create_4_8_cirrostratus_undulatus(blat, blon, alt+alt_offset+25000,alpha);
create_4_8_tstratus_patches(blat, blon, alt+alt_offset,alpha);
create_4_8_sstratus_patches(blat, blon, alt+alt_offset,alpha);
create_2_8_cirrostratus(blat, blon, alt+alt_offset + 25000.0,alpha);
}
# store convective altitude and strength
append(weather_dynamics.tile_convective_altitude,alt);
@ -666,7 +727,10 @@ var strength = 0.0;
var rn = rand();
if (rand() < small_scale_persistence)
{rn = rnd_store;}
else
{rnd_store = rn;}
if (rn > 0.75)
{
@ -784,18 +848,23 @@ var alt = spread * 1000.0 + local_weather.cloud_vertical_size_map["Nimbus"] * 0.
var strength = 0.0;
create_8_8_nimbus(blat, blon, alt+alt_offset, alpha);
create_8_8_nimbus_rain(blat, blon, alt+alt_offset, alpha,0.4 + rand()*0.2);
# and a precipitation layer below, more rain in the center of the tile
local_weather.create_effect_volume(3, blat, blon, 20000.0, 20000.0, alpha, 0.0, alt + alt_offset, 3000.0, 0.3, -1, -1, -1,0 ,0.95);
local_weather.create_effect_volume(3, blat , blon, 16000.0, 16000.0, alpha, 0.0, alt + alt_offset - 300.0, 1500.0, 0.5, -1, -1, -1,0 ,0.8);
#local_weather.create_effect_volume(3, blat, blon, 20000.0, 20000.0, alpha, 0.0, alt + alt_offset, 3000.0, 0.3, -1, -1, -1,0 ,0.95);
#local_weather.create_effect_volume(3, blat , blon, 16000.0, 16000.0, alpha, 0.0, alt + alt_offset - 300.0, 1500.0, 0.5, -1, -1, -1,0 ,0.8);
# and some broken Stratus cover above
var rn = rand();
if (rand() < small_scale_persistence)
{rn = rnd_store;}
else
{rnd_store = rn;}
if (rn > 0.5){create_4_8_stratus_patches(blat, blon, alt+alt_offset+3000.0, alpha);}
else {create_4_8_stratus(blat, blon, alt+alt_offset+3000.0, alpha);}
@ -851,6 +920,11 @@ var strength = 0.0;
var rn = rand();
if (rand() < small_scale_persistence)
{rn = rnd_store;}
else
{rnd_store = rn;}
#rn = 0.1;
if (rn > 0.5)
@ -935,6 +1009,10 @@ var strength = 0.0;
var rn = rand();
if (rand() < small_scale_persistence)
{rn = rnd_store;}
else
{rnd_store = rn;}
if (rn > 0.8)
{
@ -1054,6 +1132,7 @@ var t_factor = 0.5 * (1.0-math.cos((t * sec_to_rad)-0.9));
var rn = rand();
if (rn > (t_factor * t_factor * t_factor * t_factor)) # call a normal convective cloud system
{
strength = 1.0 + rand() * 0.2;
@ -1067,6 +1146,11 @@ else
rn = rand();
if (rand() < small_scale_persistence)
{rn = rnd_store;}
else
{rnd_store = rn;}
if (rn > 0.2)
{
# cloud scenario 1: 1-2 medium sized storms
@ -2142,10 +2226,10 @@ var set_METAR_weather_station = func {
var gust_angvar = 0.5 * weather_tile_management.relangle(wind_range_from, wind_range_to);
if (gust_strength > 0.0)
if ((gust_strength > 0.0) or (gust_angvar > 0.0))
{
var gust_relative_strength = (gust_strength - windspeed)/windspeed;
setprop(lw~"tmp/gust-frequency-hz", 1.0);
setprop(lw~"tmp/gust-frequency-hz", 0.2 + rand()*0.8);
}
else
{
@ -2436,12 +2520,16 @@ var create_4_8_tstratus_patches = func (lat, lon, alt, alpha) {
var phi = alpha * math.pi/180.0;
for (var i=0; i<16; i=i+1)
for (var i=0; i<22; i=i+1)
{
var x = 2.0 * (rand()-0.5) * 18000;
var y = 2.0 * (rand()-0.5) * 18000;
var beta = (rand() -0.5) * 180.0;
local_weather.create_streak("Stratus (thin)",lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt,300.0,4,950.0,0.2,500.0,6,950.0,0.2,500.0,alpha+beta,1.0);
var m = int(3 + rand() * 3);
var n = int(3 + rand() * 5);
local_weather.create_streak("Stratus (thin)",lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt,300.0,m,1000.0,0.2,500.0,n,1000.0,0.2,500.0,alpha+beta,1.0);
}
@ -2452,12 +2540,14 @@ var create_4_8_sstratus_patches = func (lat, lon, alt, alpha) {
var phi = alpha * math.pi/180.0;
for (var i=0; i<16; i=i+1)
for (var i=0; i<22; i=i+1)
{
var x = 2.0 * (rand()-0.5) * 18000;
var y = 2.0 * (rand()-0.5) * 18000;
var beta = (rand() -0.5) * 180.0;
local_weather.create_streak("Stratus (structured)",lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt,300.0,4,950.0,0.2,500.0,6,950.0,0.2,500.0,alpha+beta,1.0);
var m = int(3 + rand() * 5);
var n = int(3 + rand() * 5);
local_weather.create_streak("Stratus (structured)",lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt,300.0,m,1000.0,0.2,500.0,n,1000.0,0.2,500.0,alpha+beta,1.0);
}
@ -2726,6 +2816,17 @@ for (var i=0; i<25; i=i+1)
}
var create_2_8_cirrus = func (lat, lon, alt, alpha) {
var phi = alpha * math.pi/180.0;
var x = 2.0 * (rand()-0.5) * 3000;
var y = 2.0 * (rand()-0.5) * 3000;
local_weather.create_streak("Cirrus",lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt,1500.0,3,12000.0,0.0, 4000.0, 3,12000.0,0.0,4000.0,alpha,1.0);
}
var create_2_8_alttstratus = func (lat, lon, alt, alpha) {
@ -2757,6 +2858,25 @@ for (var i=0; i<2; i=i+1)
}
var create_1_8_altocumulus_scattered = func (lat, lon, alt, alpha) {
var phi = alpha * math.pi/180.0;
local_weather.create_streak("Altocumulus",lat, lon, alt,1500.0,15,0.0,0.2,19000.0,15,0.0,0.2,19000.0,alpha ,0.0);
for (var i=0; i<6; i=i+1)
{
var x = 2.0 * (rand()-0.5) * 14000;
var y = 2.0 * (rand()-0.5) * 14000;
var tri = 1.0 + rand();
local_weather.create_streak("Altocumulus",lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt,1500.0,10,750.0,0.1,800.0,4,550.0,0.1,500.0,alpha ,tri);
}
}
var create_1_8_cirrocumulus = func (lat, lon, alt, alpha) {
var phi = alpha * math.pi/180.0;
@ -2777,6 +2897,12 @@ for (var i = 0; i < 2; i = i + 1)
}
var create_1_8_cirrostratus_undulatus = func (lat, lon, alt, alpha) {
local_weather.create_undulatus("Cirrostratus",lat, lon, alt,300.0,1,8000.0,0.0,400.0,40,1000.0,0.1,100.0, 1500.0, alpha,1.0);
}
var create_1_8_contrails = func (lat, lon, alt, alpha) {
@ -2854,16 +2980,44 @@ var y = 2.0 * (rand()-0.5) * 6000;
var tri = 1.5 + 1.5*rand();
var beta = (rand() -0.5) * 60.0;
var m = int(7 + rand() * 7);
var n = int(9 + rand() * 7);
var alt_offset = 0.5 * local_weather.cloud_vertical_size_map["Cumulus"] * ft_to_m;
local_weather.create_streak("Stratocumulus",lat+get_lat(x,y+7500,phi), lon+get_lon(x,y+7500,phi), alt + alt_offset,500.0,12,1000.0,0.1,400.0,15,1000.0,0.1,400.0,alpha+90.0+beta,tri);
local_weather.create_streak("Stratocumulus",lat+get_lat(x,y+7500,phi), lon+get_lon(x,y+7500,phi), alt + alt_offset,500.0,m,1100.0,0.1,400.0,n,1100.0,0.1,400.0,alpha+90.0+beta,tri);
local_weather.create_streak("Stratocumulus",lat+get_lat(x,y-7500,phi), lon+get_lon(x,y-7500,phi), alt + alt_offset,500.0,12,1000.0,0.1,400.0,15,1000.0,0.1,400.0,alpha+270.0+beta,tri);
local_weather.create_streak("Stratocumulus",lat+get_lat(x,y-7500,phi), lon+get_lon(x,y-7500,phi), alt + alt_offset,500.0,m,1100.0,0.1,400.0,n,1100.0,0.1,400.0,alpha+270.0+beta,tri);
local_weather.create_streak("Stratocumulus bottom",lat+get_lat(x,y+5250,phi), lon+get_lon(x,y+5250,phi), alt,0.0,10,700.0,0.2,400.0,15,700.0,0.0,400.0,alpha+90.0+beta,tri);
local_weather.create_streak("Stratocumulus bottom",lat+get_lat(x,y+5250,phi), lon+get_lon(x,y+5250,phi), alt,0.0,m+1,700.0,0.2,400.0,n+1,700.0,0.0,400.0,alpha+90.0+beta,tri);
local_weather.create_streak("Stratocumulus bottom",lat+get_lat(x,y-5250,phi), lon+get_lon(x,y-5250,phi), alt,0.0,10,700.0,0.2,400.0,15,700.0,0.0,400.0,alpha+270.0+beta,tri);
local_weather.create_streak("Stratocumulus bottom",lat+get_lat(x,y-5250,phi), lon+get_lon(x,y-5250,phi), alt,0.0,m+1,700.0,0.2,400.0,n+1,700.0,0.0,400.0,alpha+270.0+beta,tri);
}
var create_detailed_small_stratocumulus_bank = func (lat, lon, alt, alpha) {
var phi = alpha * math.pi/180.0;
var x = 2.0 * (rand()-0.5) * 12000;
var y = 2.0 * (rand()-0.5) * 12000;
var tri = 1.5 + 1.5*rand();
var beta = (rand() -0.5) * 60.0;
var m = int(5 + rand() * 5);
var n = int(6 + rand() * 5);
var alt_offset = 0.5 * local_weather.cloud_vertical_size_map["Cumulus"] * ft_to_m;
local_weather.create_streak("Stratocumulus",lat+get_lat(x,y+7500,phi), lon+get_lon(x,y+7500,phi), alt + alt_offset,500.0,m,1100.0,0.12,400.0,n,1100.0,0.12,400.0,alpha+90.0+beta,tri);
local_weather.create_streak("Stratocumulus",lat+get_lat(x,y-7500,phi), lon+get_lon(x,y-7500,phi), alt + alt_offset,500.0,m,1100.0,0.12,400.0,n,1100.0,0.12,400.0,alpha+270.0+beta,tri);
local_weather.create_streak("Stratocumulus bottom",lat+get_lat(x,y+7050,phi), lon+get_lon(x,y+7050,phi), alt,0.0,m,700.0,0.2,400.0,n,700.0,0.0,400.0,alpha+90.0+beta,tri);
local_weather.create_streak("Stratocumulus bottom",lat+get_lat(x,y-7050,phi), lon+get_lon(x,y-7050,phi), alt,0.0,m,700.0,0.2,400.0,n,700.0,0.0,400.0,alpha+270.0+beta,tri);
}
@ -3012,6 +3166,9 @@ var lon_to_m = 0.0; # needs to be calculated dynamically
var m_to_lon = 0.0; # we do this on startup
var lw = "/local-weather/";
var small_scale_persistence = getprop(lw~"config/small-scale-persistence");
var rnd_store = 0.0;
var elat = [];
var elon = [];
var erad = [];

View file

@ -10,6 +10,8 @@
<modal>false</modal>
<text>
<x>10</x>
<y>570</y>
@ -62,7 +64,7 @@
<x>0</x>
<y>525</y>
<combo>
<x>10</x>
<y>0</y>
@ -101,7 +103,7 @@
<command>dialog-apply</command>
</binding>
</combo>
<input>
<x>203</x>
@ -231,7 +233,7 @@
<x>0</x>
<y>440</y>
<combo>
<x>10</x>
<y>0</y>
@ -426,7 +428,7 @@
<x>165</x>
<y>0</y>
<label>alt (ft)</label>
</text>
</text>
<input>
<x>245</x>
@ -440,7 +442,7 @@
<x>320</x>
<y>0</y>
<label>size (km)</label>
</text>
</text>
<input>
<x>410</x>
@ -649,7 +651,7 @@
<x>0</x>
<y>195</y>
<combo>
<x>10</x>
<y>0</y>

View file

@ -2,7 +2,7 @@
<PropertyList>
<!-- Weather tiles -->
<!-- Weather config -->
<name>local_weather_config</name>
<width>400</width>
@ -18,19 +18,19 @@
<text>
<x>60</x>
<y>340</y>
<y>345</y>
<label>loading distance</label>
</text>
<text>
<x>10</x>
<y>320</y>
<y>325</y>
<label>25 km</label>
</text>
<slider>
<x>60</x>
<y>320</y>
<y>325</y>
<width>100</width>
<height>20</height>
<min>29000.0</min>
@ -43,14 +43,14 @@
<text>
<x>170</x>
<y>320</y>
<y>325</y>
<label>55 km</label>
</text>
<checkbox>
<x>250</x>
<y>350</y>
<y>355</y>
<width>15</width>
<height>15</height>
<label>asymmetric range</label>
@ -62,13 +62,13 @@
<text>
<x>220</x>
<y>320</y>
<y>325</y>
<label>0.5</label>
</text>
<slider>
<x>250</x>
<y>320</y>
<y>325</y>
<width>100</width>
<height>20</height>
<min>0.5</min>
@ -81,32 +81,32 @@
<text>
<x>360</x>
<y>320</y>
<y>325</y>
<label>1.0</label>
</text>
<text>
<x>5</x>
<y>280</y>
<y>285</y>
<label>Cloud buffering settings</label>
</text>
<text>
<x>60</x>
<y>260</y>
<y>265</y>
<label>visible range</label>
</text>
<text>
<x>10</x>
<y>240</y>
<y>245</y>
<label>15 km</label>
</text>
<slider>
<x>60</x>
<y>240</y>
<y>245</y>
<width>100</width>
<height>20</height>
<min>15000.0</min>
@ -119,14 +119,14 @@
<text>
<x>170</x>
<y>240</y>
<y>245</y>
<label>45 km</label>
</text>
<checkbox>
<x>250</x>
<y>270</y>
<y>275</y>
<width>15</width>
<height>15</height>
<label>asymmetric buffering</label>
@ -138,13 +138,13 @@
<text>
<x>220</x>
<y>240</y>
<y>245</y>
<label>0.2</label>
</text>
<slider>
<x>250</x>
<y>240</y>
<y>245</y>
<width>100</width>
<height>20</height>
<min>0.2</min>
@ -157,26 +157,26 @@
<text>
<x>360</x>
<y>240</y>
<y>245</y>
<label>1.0</label>
</text>
<text>
<x>170</x>
<y>210</y>
<y>215</y>
<label>angle:</label>
</text>
<text>
<x>220</x>
<y>210</y>
<y>215</y>
<label>0.0</label>
</text>
<slider>
<x>250</x>
<y>210</y>
<y>215</y>
<width>100</width>
<height>20</height>
<min>0.0</min>
@ -189,35 +189,71 @@
<text>
<x>360</x>
<y>210</y>
<y>215</y>
<label>180</label>
</text>
<checkbox>
<x>30</x>
<y>185</y>
<width>15</width>
<height>15</height>
<label>tie range to framerate</label>
<property>/local-weather/config/fps-control-flag</property>
<binding>
<command>dialog-apply</command>
</binding>
</checkbox>
<text>
<x>200</x>
<y>180</y>
<label>10 fps</label>
</text>
<slider>
<x>250</x>
<y>180</y>
<width>100</width>
<height>20</height>
<min>10.0</min>
<max>40.0</max>
<property>/local-weather/config/target-framerate</property>
<binding>
<command>dialog-apply</command>
</binding>
</slider>
<text>
<x>355</x>
<y>180</y>
<label>40 fps</label>
</text>
<text>
<x>5</x>
<y>160</y>
<y>150</y>
<label>Weather dynamics settings</label>
</text>
<text>
<x>60</x>
<y>140</y>
<x>55</x>
<y>130</y>
<label>max. clouds in loop</label>
</text>
<text>
<x>10</x>
<y>120</y>
<y>110</y>
<label>100</label>
</text>
<slider>
<x>60</x>
<y>120</y>
<y>110</y>
<width>100</width>
<height>20</height>
<min>100</min>
@ -230,12 +266,80 @@
<text>
<x>170</x>
<y>120</y>
<y>110</y>
<label>400</label>
</text>
<text>
<x>5</x>
<y>80</y>
<label>Weather pattern scales</label>
</text>
<text>
<x>15</x>
<y>45</y>
<label>small</label>
</text>
<text>
<x>78</x>
<y>60</y>
<label>airmass</label>
</text>
<slider>
<x>60</x>
<y>45</y>
<width>100</width>
<height>20</height>
<min>0.5</min>
<max>2.0</max>
<property>/local-weather/config/large-scale-persistence</property>
<binding>
<command>dialog-apply</command>
</binding>
</slider>
<text>
<x>165</x>
<y>45</y>
<label>large</label>
</text>
<text>
<x>205</x>
<y>45</y>
<label>small</label>
</text>
<text>
<x>257</x>
<y>60</y>
<label>cloud patterns</label>
</text>
<slider>
<x>250</x>
<y>45</y>
<width>100</width>
<height>20</height>
<min>0.0</min>
<max>1.0</max>
<property>/local-weather/config/small-scale-persistence</property>
<binding>
<command>dialog-apply</command>
</binding>
</slider>
<text>
<x>355</x>
<y>45</y>
<label>large</label>
</text>
<group>
<x>10</x>

View file

@ -35,10 +35,18 @@
<value>Coldfront</value>
<value>Warmfront</value>
<value>Tropical</value>
<!--<value>Test tile</value>-->
<value>Test tile</value>
<binding>
<command>dialog-apply</command>
</binding>
<!--<enable>
<not>
<equals>
<property>/local-weather/tmp/tile-management</property>
<value type="string">METAR</value>
</equals>
</not>
</enable>-->
</combo>
<text>
@ -100,7 +108,7 @@
<width>50</width>
<height>20</height>
<min>0.0</min>
<max>1.0</max>
<max>2.0</max>
<property>/local-weather/tmp/gust-frequency-hz</property>
<binding>
<command>dialog-apply</command>
@ -205,7 +213,7 @@
<width>15</width>
<height>15</height>
<label>terrain presampling</label>
<property>/local-weather/tmp/presampling-flag</property>
<property>/local-weather/config/presampling-flag</property>
<binding>
<command>dialog-apply</command>
</binding>
@ -330,7 +338,7 @@
<y>0</y>
<legend>Clear / End</legend>
<!--<default>true</default>-->
<equal>true</equal>
<!--<equal>true</equal>-->
<binding>
<command>nasal</command>
<script>local_weather.clear_all()</script>
@ -341,7 +349,7 @@
<x>135</x>
<y>0</y>
<legend>Close</legend>
<equal>true</equal>
<!--<equal>true</equal>-->
<key>Esc</key>
<binding>
<command>dialog-close</command>
@ -352,7 +360,7 @@
<x>200</x>
<y>0</y>
<legend>Show winds</legend>
<equal>true</equal>
<!--<equal>true</equal>-->
<binding>
<command>dialog-show</command>
<dialog-name>local_weather_winds</dialog-name>

View file

@ -57,8 +57,12 @@ command interface /autopilot/route-manager/input:
<!-- sidebar -->
<group>
<layout>vbox</layout>
<button>
<legend>Fixes</legend>
<text>
<label>Display:</label>
</text>
<checkbox>
<label>Fixes</label>
<pref-width>100</pref-width>
<property>/gui/map/draw-fixes</property>
<live>true</live>
@ -68,10 +72,10 @@ command interface /autopilot/route-manager/input:
<binding>
<command>property-toggle</command>
</binding>
</button>
</checkbox>
<button>
<legend>Navaids</legend>
<checkbox>
<label>Navaids</label>
<pref-width>100</pref-width>
<property>/gui/map/draw-navaids</property>
<live>true</live>
@ -81,7 +85,7 @@ command interface /autopilot/route-manager/input:
<binding>
<command>property-toggle</command>
</binding>
</button>
</checkbox>
<!--
<button>
<legend>Airways</legend>
@ -89,8 +93,8 @@ command interface /autopilot/route-manager/input:
</button>
-->
<button>
<legend>Traffic</legend>
<checkbox>
<label>Traffic</label>
<pref-width>100</pref-width>
<property>/gui/map/draw-traffic</property>
<live>true</live>
@ -100,7 +104,7 @@ command interface /autopilot/route-manager/input:
<binding>
<command>property-toggle</command>
</binding>
</button>
</checkbox>
<!--
<button>
@ -109,8 +113,8 @@ command interface /autopilot/route-manager/input:
</button>
-->
<button>
<legend>Data</legend>
<checkbox>
<label>Data</label>
<pref-width>100</pref-width>
<property>/gui/map/draw-data</property>
<live>true</live>
@ -120,12 +124,12 @@ command interface /autopilot/route-manager/input:
<binding>
<command>property-toggle</command>
</binding>
</button>
</checkbox>
<empty><stretch>true</stretch></empty>
<button>
<legend>Center on Acft</legend>
<checkbox>
<label>Center on Acft</label>
<pref-width>100</pref-width>
<property>/gui/map/centre-on-aircraft</property>
<live>true</live>
@ -135,10 +139,10 @@ command interface /autopilot/route-manager/input:
<binding>
<command>property-toggle</command>
</binding>
</button>
</checkbox>
<button>
<legend>Acft Hdg Up</legend>
<checkbox>
<label>Aircraft Hdg Up</label>
<pref-width>100</pref-width>
<property>/gui/map/aircraft-heading-up</property>
<live>true</live>
@ -148,10 +152,10 @@ command interface /autopilot/route-manager/input:
<binding>
<command>property-toggle</command>
</binding>
</button>
</checkbox>
<button>
<legend>Magnetic Hdgs</legend>
<checkbox>
<label>Magnetic Hdgs</label>
<pref-width>100</pref-width>
<property>/gui/map/magnetic-headings</property>
<live>true</live>
@ -161,7 +165,7 @@ command interface /autopilot/route-manager/input:
<binding>
<command>property-toggle</command>
</binding>
</button>
</checkbox>
<empty><stretch>true</stretch></empty>

View file

@ -87,6 +87,15 @@
</binding>
</combo>
<checkbox>
<row>2</row><col>1</col>
<halign>left</halign>
<property>/sim/replay/looped</property>
<label>Looped replay</label>
<binding>
<command>dialog-apply</command>
</binding>
</checkbox>
</group>
<hrule/>

View file

@ -951,20 +951,7 @@ top down before the key bindings are parsed.
<name>p</name>
<desc>Toggle the pause state of the sim</desc>
<binding>
<command>property-toggle</command>
<property>/sim/freeze/master</property>
</binding>
<binding>
<command>property-toggle</command>
<property>/sim/freeze/clock</property>
</binding>
<binding>
<condition>
<property>/sim/freeze/replay-state</property>
</condition>
<command>property-assign</command>
<property>/sim/replay/disable</property>
<value type="bool">true</value>
<command>pause</command>
</binding>
</key>
@ -1119,20 +1106,7 @@ top down before the key bindings are parsed.
<name>F3</name>
<desc>Capture screen</desc>
<binding>
<command>nasal</command>
<script>
var success = fgcommand("screen-capture");
var path = getprop("/sim/paths/screenshot-last");
var threading = getprop("/sim/rendering/multithreading-mode");
var button = { button: { legend: "Ok", default: 1, binding: { command: "dialog-close" }}};
if (threading and threading != "SingleThreaded") {
gui.popupTip("Threading model must be SingleThreaded (or not defined) for snapshots to work.", 600, button);
} elsif (success) {
gui.popupTip("Screenshot written to '" ~ path ~ "'", 2);
} else {
gui.popupTip("Error writing screenshot '" ~ path ~ "'", 600, button);
}
</script>
<command>screen-capture</command>
</binding>
<mod-shift>
<desc>Load panel</desc>

View file

@ -10,6 +10,8 @@ Started September 2000 by David Megginson, david@megginson.com
<PropertyList>
<local-weather include="Environment/local-weather-defaults.xml"/>
<!-- General simulation preferences -->
<sim>
<!-- show-aircraft option: show ALL aircraft regardless by default -->
@ -674,6 +676,7 @@ Started September 2000 by David Megginson, david@megginson.com
<replay>
<duration type="double">90</duration>
<view type="int">1</view>
<looped type="bool" userarchive="y">true</looped>
</replay>
<airport>