AI Systems: Difference between revisions

Jump to navigation Jump to search
534 bytes added ,  20 November 2015
Some cleanup, but needs some more work.
m (Related content: Status of AI in FlightGear)
(Some cleanup, but needs some more work.)
Line 1: Line 1:
{{Out of date}}
{{Out of date}}
{{-}}
[[FlightGear]] has a number of more or less independently operating systems for simulating semi-intelligent interaction with the environment, so called '''AI Systems'''. Because there often times exists some confusion regarding to which system does what, one should take notice of the differences between them: The major distinction is that between an older ATC/AI system, and a newer AIModels system. The AIModels system can, in turn, be controlled in at least three different ways; directly, using a script, through the multiplayer system, and through a subsystem known as the traffic manager.


[[FlightGear]] has a number of more or less independently operating systems for simulating semi- intelligent interaction with the environment, so called '''AI Systems'''. Because there often times exists some confusion regarding to which system does what, one should take notice of the differences between them: The major distinction is that between an older ATC/AI system, and a newer AIModels system. The AIModels system can, in turn, be controlled in at least three different ways; directly, using a script, through the multiplayer system, and through a subsystem known as the traffic manager.
To enable/disable the AI traffic system:
 
* FlightGear 2.2.0 and above
To enable/disable the AI traffic system:
** Use <code>--enable-ai-traffic</code> and <code>--disable-ai-traffic</code>
** use <tt>--enable-ai-traffic</tt> / <tt>--disable-ai-traffic</tt> for FlightGear >= 2.2.0
* Flightgear 2.0.0 and older
** ( use <tt>--prop:/sim/ai-traffic/enabled=[1|0]</tt> for FlightGear 2.0.0 and older )
** <code>--prop:/sim/ai-traffic/enabled=[1|0]</code>
To enable/disable the AIModels system: use <tt>--prop:/sim/ai/enabled=[1|0]</tt>
To enable/disable the AIModels system, use <code>--prop:/sim/ai/enabled=[1|0]</code>


== ATC/AI ==
== ATC/AI ==
'''The ATC/AI system was removed with FlightGear 2.2.0. It was replaced by a new module, see [[Interactive Traffic]]'''
{{Note|The ATC/AI system was removed with FlightGear 2.2.0. It was replaced by a new module: [[Interactive Traffic]].}}


The  [[Air traffic control|Air Traffic Control]] system simulates interaction between the user and a number of AI controlled cessna  and piper aircraft. This system can be controlled using the GUI from within FlightGear. The ATC/AI system is no longer maintained and marked for deprecation. Recent reports have indicated that the ATC/AI system may be causing numerical computation problems in some cases, resulting in a flurry of NaN warning messages on the FlightGear console. If you experience this, you might consider shutting down the ATC/AI system  
The  [[Air traffic control|Air Traffic Control]] system simulates interaction between the user and a number of AI controlled cessna  and piper aircraft. This system can be controlled using the GUI from within FlightGear. The ATC/AI system is no longer maintained and marked for deprecation. Recent reports have indicated that the ATC/AI system may be causing numerical computation problems in some cases, resulting in a flurry of NaN warning messages on the FlightGear console. If you experience this, you might consider shutting down the ATC/AI system  
Line 22: Line 24:


== AI Models ==
== AI Models ==
Starting with FlightGear version 0.9.4 you can place AI objects in the "FlightGear world". In version 0.9.4 the AI objects can be defined in the preferences.xml file, or in an airplane's *-set.xml file. In later versions they are defined in a "scenario file" only. The types of AI objects you can have are airplanes, ships, thunderstorms, thermals/sinks, static and ballistic objects. AI objects have some things in common: The have a location in the "FlightGear world", they can have an associated exterior 3D model, and they can move according to an internal [[Flight Dynamics Model|FDM]] (flight dynamics model). As of now, these objects are created at simulator start-up by adding some XML code to a scenario file. The scenario file must be in the data/AI directory. You select which scenario files you want to use by naming it in the preferences.xml file. The preferences.xml file has an entry that looks like this (FlightGear versions newer than 0.9.4, including Git):  
Starting with FlightGear version 0.9.4 you can place AI objects in the "FlightGear world". In version 0.9.4 the AI objects can be defined in the preferences.xml file, or in an [[aircraft-set.xml]] file. In later versions they are defined in a "scenario file" only. The types of AI objects you can have are airplanes, ships, thunderstorms, thermals/sinks, static and ballistic objects. AI objects have some things in common: The have a location in the "FlightGear world", they can have an associated exterior 3D model, and they can move according to an internal [[Flight Dynamics Model|FDM]] (flight dynamics model). As of now, these objects are created at simulator start-up by adding some XML code to a scenario file. The scenario file must be in the data/AI directory. You select which scenario files you want to use by naming it in the preferences.xml file. The preferences.xml file has an entry that looks like this (in FlightGear versions newer than 0.9.4, including [[Git]]):  
 
<syntaxhighlight lang="xml">
<ai>
<ai>
   <enabled type="bool">true</enabled>
   <enabled type="bool">true</enabled>
   <scenario>aircraft_demo</scenario>
   <scenario>aircraft_demo</scenario>
</ai>
</ai>
</syntaxhighlight>


The above bit of XML enables the AI system and selects a scenario file called aircraft_demo.xml.
The above bit of XML enables the AI system and selects a scenario file called aircraft_demo.xml.


''Notes:  
Notes:  
* XML tags are ''case-sensitive''.
* XML tags are case-sensitive.
* Introducing certain characters into the XML file, even as part of a comment, will cause the file to choke.  These include &, <, and --.''
* Introducing certain characters into the XML file, even as part of a comment, will cause the file to choke.  These include &, <, and --.


The scenario file contains one entry for each AI object. The entry specifies what kind of object to create, what its initial conditions will be, and optionally (for aircraft and ships) a flight plan. The entry for a sailboat could look like this:
The scenario file contains one entry for each AI object. The entry specifies what kind of object to create, what its initial conditions will be, and optionally (for aircraft and ships) a flight plan. The entry for a sailboat could look like this:
 
<syntaxhighlight lang="xml">
<entry>
<entry>
   <type>ship</type>
   <type>ship</type>
   <model>models/geometry/sailboat.xml</model>  
   <model>models/geometry/sailboat.xml</model>  
Line 45: Line 48:
   <latitude type="double">37.61667</latitude>
   <latitude type="double">37.61667</latitude>
   <heading type="double">20.0</heading>
   <heading type="double">20.0</heading>
</entry>
</entry>
</syntaxhighlight>


 
Most of the parameters are self-explanatory. The "type" of object can be one of "aircraft", "ship", "carrier", "thunderstorm", "thermal", "ballistic" or "static". The rest of the items give the AI object a model, a starting location, and a starting speed and direction. You use the <model> item to give the object any valid exterior model. You can even make the ship look like an airplane if you want! Note that the speed of the AI object is true airspeed, and since AI aircraft and ships don't feel wind or current then this also the ground speed. The "ship" type can also have a <rudder> value specified, which will cause the ship to move in a circle ({{itip|Use small values, five degrees or less, and right rudder is positive}}). Here is an example of how to create an aircraft AI object:
Most of the parameters are self-explanitory. The "type" of object can be one of "aircraft", "ship", "carrier", "thunderstorm", "thermal", "ballistic" or "static". The rest of the items give the AI object a model, a starting location, and a starting speed and direction. You use the <MODEL> item to give the object any valid exterior model. You can even make the ship look like an airplane if you want! Note that the speed of the AI object is true airspeed, and since AI aircraft and ships don't feel wind or current then this also the ground speed. The "ship" type can also have a <RUDDER> value specified, which will cause the ship to move in a circle (HINT: use small values, five degrees or less, and right rudder is positive). Here is an example of how to create an aircraft AI object:
<syntaxhighlight lang="xml">
 
<!-- puts an A-4 north of KSFO, orbiting at 7000 ft -->   
<!-- puts an A-4 north of KSFO, orbiting at 7000 ft -->   
<entry>
<entry>
   <type>aircraft</type>
   <type>aircraft</type>
   <class>light</class>  
   <class>light</class>  
Line 61: Line 64:
   <heading type="double">210.0</heading>  
   <heading type="double">210.0</heading>  
   <bank type="double">-15.0</bank>
   <bank type="double">-15.0</bank>
</entry>
</entry>
</syntaxhighlight>


It looks much the same as the ship AI code. There are two differences, the <class> item and the <bank> item. If the class is set to "tanker" the airplane will allow you to refuel if you can get close behind it.  The bank is of course similar to the ship's rudder. In the above example the A-4 will be orbiting to the left at 15 degrees of bank. You can also create a ship or airplane with a flight plan. In this case the object will follow the flight plan, and then delete itself when it reaches the end. The flight plans are kept in data/Data/AI/FlightPlans. To create an airplane with a flightplan do this:
It looks much the same as the ship AI code. There are two differences, the <class> item and the <bank> item. If the class is set to "tanker" the airplane will allow you to refuel if you can get close behind it.  The bank is of course similar to the ship's rudder. In the above example the A-4 will be orbiting to the left at 15 degrees of bank. You can also create a ship or airplane with a flight plan. In this case the object will follow the flight plan, and then delete itself when it reaches the end. The flight plans are kept in {{fgdata file|AI/FlightPlans}}. To create an airplane with a flightplan do this:
 
<syntaxhighlight lang="xml">
<entry>
<entry>
   <type>aircraft</type>  
   <type>aircraft</type>  
   <class>jet-transport</class>
   <class>jet-transport</class>
   <model>Aircraft/737/Models/737.xml</model>
   <model>Aircraft/737/Models/737.xml</model>
   <flightplan>ksfo_ils28l.xml</flightplan>  
   <flightplan>ksfo_ils28l.xml</flightplan>  
</entry>
</entry>
</syntaxhighlight>


To make a thunderstorm, use this:
To make a thunderstorm, use this:
 
<syntaxhighlight lang="xml">
<!-- puts a thunderstorm overhead OSI (Woodside VOR) -->
<!-- puts a thunderstorm overhead OSI (Woodside VOR) -->
<entry>
<entry>
   <type>storm</type>
   <type>storm</type>
   <model>Models/Geometry/thunderstorm.xml</model>  
   <model>Models/Geometry/thunderstorm.xml</model>  
Line 84: Line 89:
   <heading type="double">90</heading>
   <heading type="double">90</heading>
  </entry>
  </entry>
</syntaxhighlight>


There's not much to it. No, they don't turn :) To create a thermal, use this:
There's not much to it. No, they don't turn :) To create a thermal, use this:
 
<syntaxhighlight lang="xml">
<entry>
<entry>
   <type>thermal</type>
   <type>thermal</type>
   <latitude type="double">37.61633</latitude>  
   <latitude type="double">37.61633</latitude>  
Line 95: Line 101:
   <height-msl>6000</height-msl>
   <height-msl>6000</height-msl>
   <model>Models/Geometry/thermalcap.xml</model>
   <model>Models/Geometry/thermalcap.xml</model>
</entry>
</entry>
</syntaxhighlight>


The AI thermals don't move, they are invisible, and they don't "lean" downwind. The <strength-fps> defines the maximum vertical velocity of the airmass at the center of the thermal. The strength decreases to zero at the thermal's edge.  A
The AI thermals don't move, they are invisible, and they don't "lean" downwind. The <strength-fps> defines the maximum vertical velocity of the airmass at the center of the thermal. The strength decreases to zero at the thermal's edge.  A
Line 101: Line 108:


A ballistic AI object starts with an initial azimuth, elevation and speed, then follows a ballistic path from there (with air resistance and wind included). Try this:
A ballistic AI object starts with an initial azimuth, elevation and speed, then follows a ballistic path from there (with air resistance and wind included). Try this:
 
<syntaxhighlight lang="xml">
<entry>
<entry>
   <type>ballistic</type>  
   <type>ballistic</type>  
   <model>Models/Geometry/rocket.xml</model>
   <model>Models/Geometry/rocket.xml</model>
Line 112: Line 119:
   <azimuth type="double">70.0</azimuth>  
   <azimuth type="double">70.0</azimuth>  
   <elevation type="double">45.0</elevation>  
   <elevation type="double">45.0</elevation>  
</entry>
</entry>
 
</syntaxhighlight>


Note that the speed is now in feet per second.
Note that the speed is now in feet per second.


The AI storm objects can be displayed on weather radar. See the Aircraft/Instruments/wxradar.xml file for details. The AI aircraft objects can be displayed on radar. See the Aircraft/Instruments/radar.xml file for details.  
The AI storm objects can be displayed on weather radar. See {{fgdata file|Aircraft/Instruments/wxradar.xml}} for details. The AI aircraft objects can be displayed on radar. See {{fgdata file|Aircraft/Instruments/radar.xml}} for details.  


You can make your own AI scenario file, called say my_scenario.xml, and cut/paste entries from the other scenario files to build an AI scenario as complicated as you like.
You can make your own AI scenario file, called say my_scenario.xml, and cut/paste entries from the other scenario files to build an AI scenario as complicated as you like.
Line 130: Line 137:
For example; relating flap extension to airspeed of an AI model. Typically an aircraft will extend flaps on final approach to control Indicated Airspeed (IAS) and stall speed to affect a low speed controlled landing. Upon touchdown the extra lift efficiency introduced by the flaps is no longer required or desirable, hence the flaps will be retracted ASAP after touch down.  
For example; relating flap extension to airspeed of an AI model. Typically an aircraft will extend flaps on final approach to control Indicated Airspeed (IAS) and stall speed to affect a low speed controlled landing. Upon touchdown the extra lift efficiency introduced by the flaps is no longer required or desirable, hence the flaps will be retracted ASAP after touch down.  


This is relatively simple in a sim aircraft as the /surface-positions/flap-pos-norm property is a normalised indicator of the flap setting chosen by the pilot.
This is relatively simple in a sim aircraft as the <code>/surface-positions/flap-pos-norm</code> property is a normalised indicator of the flap setting chosen by the pilot.


AI aircraft have no pilots to control flaps nor does the flight plan <flaps-down>true/false</flaps-down> parameter effect the /AI property tree parameter, a relationship to the IAS is the next best choice.
AI aircraft have no pilots to control flaps nor does the flight plan <code><flaps-down>true/false</flaps-down></code> parameter effect the /AI property tree parameter, a relationship to the IAS is the next best choice.


To effect this relationship (IAS/flap-position) using factors/offsets and min/max would be quite difficult and non-intuitive. Using interpolation tables allows the following scenario to be setup very easily and intuitively:
To effect this relationship (IAS/flap-position) using factors/offsets and min/max would be quite difficult and non-intuitive. Using interpolation tables allows the following scenario to be setup very easily and intuitively:


: '''C172P'''
{| class="wikitable"
{| border="1"
|+ C172p
|-
! scope="row" | Max
| Max
| 123 KIAS
| 123 KIAS
|-
|-
| Cruise
! scope="row" | Cruise
| 90 KIAS
| 90 KIAS
|-
|-
| Stall (no flaps)
! scope="row" | Stall (no flaps)
| 50 KIAS
| 50 KIAS
|-
|-
| Flaps
! scope="row" | Flaps
| 0, 10, 20, 30 deg.
| 0, 10, 20, 30 deg
|-
|-
| Approach
! scope="row" | Approach
| 90 KIAS
| 90 KIAS
|-
|-
| 10° flaps
! scope="row" | 10° flaps
| 90 KIAS
| 90 KIAS
|-
|-
| 20° flaps
! scope="row" | 20° flaps
| 70 KIAS
| 70 KIAS
|-
|-
| 30° flaps
! scope="row" | 30° flaps
| 60 KIAS
| 60 KIAS
|-
|-
| Flare & touch down
! scope="row" | Flare & touch down
| 50 KIAS
| 50 KIAS
|-
|-
| Brake
! scope="row" | Brake
| 45 KIAS
| 45 KIAS
|-
|-
| Retract flaps
! scope="row" | Retract flaps
| 45 KIAS
| 45 KIAS
|}
|}


'''Table IAS/flap extension'''
{| class="wikitable"
{| border="2"
|+ IAS/flap extension
|+
! IAS (kt) !! Flaps
| IAS (kt) || Flaps
|-
|-
| 90
| 90 || 0
| 0
|-
|-
| 70 - 89
| 70-89 || 10
| 10
|-
|-
| 60-69
| 60-69 || 20
| 20
|-
|-
| 45-59
| 45-59 || 30
| 30
|-
|-
| < 45
| less than 45 || 0
| 0
|}
|}


Line 205: Line 205:
# Apply the min/max values
# Apply the min/max values


e.g.
For example:
  factor=60
  factor = 60
  offset= -30
  offset = -30
  min=-10
  min   = -10
  max+10
  max   = 10
 
these figures are nonsense but are used to illustrate a point:


  flaps retracted(0°) = 0 x 60 = 0, (offset=-30) = -30, (min= -10) = -10
These figures are nonsense but are used to illustrate a point:
  flaps extended(10°) = 0.33 x 60 = 20, (offset=-30) = -10, (min= -10) = -10
  flaps retracted (0°) = 0 * 60 + -30 = -30;
  flaps extended(20°) = 0.66 x 60 = 40, (offset=-30) = 10, (min= -10/max=10) = 10
  min = -10, so = -10
  flaps extended(30°) = 1.00 x 60 = 60, (offset=-30) = 30, (max=10) = 10
  flaps extended (10°) = 0.33 * 60 + -30 = -10.2;
  min = -10, so = -10
  flaps extended (20°) = 0.66 * 60 + -30 = 9.6
  flaps extended (30°) = 1.00 * 60 + -30 = 30;
  max = 10, so = 10


more realistically, offset and min max are not used for flaps, only a factor.
More realistically, offset and min/max are not used for flaps, only a factor.
 
say 27°, this represents the maximum rotation of the 3-D component in the model around its defined axis.


Say 27°, this represents the maximum rotation of the 3D component in the model around its defined axis.
  flaps retracted(0°) = 0 x 27 = 0
  flaps retracted(0°) = 0 x 27 = 0
  flaps extended(10°) = 0.33 x 27 = 9
  flaps extended(10°) = 0.33 x 27 = 9
Line 227: Line 228:
  flaps extended(30°) = 1.00 x 27 = 27
  flaps extended(30°) = 1.00 x 27 = 27


from this it can be seen that the 3-D object will be rotated 0°, 9°, 18° & 27° to represent the 0°, 10°, 20° & 30° deployment of the flaps.
From this it can be seen that the 3D object will be rotated 0°, 9°, 18° & 27° to represent the 0°, 10°, 20° & 30° deployment of the flaps.


Relating this back to the speeds above:
Relating this back to the speeds above:
 
{| class="wikitable"
{| border="1"
! IAS (kt) !! <rotate> value
|+
| IAS (kt)
| <rotate> value
|-
|-
| 0
| 0 || 0
| 0
|-
|-
| 44
| 44 || 0
| 0
|-
|-
| 45
| 45 || 27
| 27
|-
|-
| 59
| 59 || 27
| 27
|-
|-
| 60
| 60 || 18
| 18
|-
|-
| 69
| 69 || 18
| 18
|-
|-
| 70
| 70 || 9
| 9
|-
|-
| 89
| 89 || 9
| 9
|-
|-
| 90
| 90 || 0
| 0
|-
|-
| 100
| 100 || 0
| 0
|}
|}


this gives a stepped effect, where the movement is limited to 1knt of airspeed. That is the 3-D object will linearly move from 9° to 18° while the aircraft looses speed from 70 knots to 69 knots. This behaviour will make the need for an upper and lower limit of a stepped value obvious.
This gives a stepped effect, where the movement is limited to 1 kt of airspeed. That is the 3-D object will linearly move from 9° to 18° while the aircraft looses speed from 70 knots to 69 knots. This behaviour will make the need for an upper and lower limit of a stepped value obvious.


a simplified table of:
A simplified table:
 
{| class="wikitable"
{| border="1"
! IAS (kt) !! <rotate> value
|+
| IAS (kt)
| <rotate> value
|-
|-
| 0
| 0 || 0
| 0
|-
|-
| 45
| 45 || 27
| 27
|-
|-
| 60
| 60 || 18
| 18
|-
|-
| 70
| 70 || 9
| 9
|-
|-
| 90
| 90 || 9
| 9
|-
|-
| 100
| 100 || 0
| 0
|}
|}


will cause the flaps to start extending at the rate of 1/45 x 27 degrees per knot of airspeed gained until 45 knots when the rate of change will adjust to the new gradient. This is not how flaps behave, but can be used to good effect with "tail dragger" animations where at a certain IAS the tail starts rising, maybe at an increasing rate, until flying attitude is reached when it stops rising any further. The tail rising is not a stepped function of IAS.
This will cause the flaps to start extending at the rate of 1/45 x 27 degrees per knot of airspeed gained until 45 knots when the rate of change will adjust to the new gradient. This is not how flaps behave, but can be used to good effect with "tail dragger" animations where at a certain IAS the tail starts rising, maybe at an increasing rate, until flying attitude is reached when it stops rising any further. The tail rising is not a stepped function of IAS.


Now we have the basic ideas behind interpolation tables, the question is how are they implemented…answer;…easy ….an example of the stepped flaps animation  above
Now we have the basic ideas behind interpolation tables, the question is how are they implemented…answer;…easy ….an example of the stepped flaps animation  above
<syntaxhighlight lang="xml">
<interpolation>
  <entry><ind>0.000></ind><dep>0.000</dep></entry>
  <entry><ind>44.00></ind><dep>0.000</dep></entry>
  <entry><ind>45.00></ind><dep>27.00</dep></entry>
  <entry><ind>59.00></ind><dep>27.00</dep></entry>
  <entry><ind>59.00></ind><dep>27.00</dep></entry>
  <entry><ind>60.00></ind><dep>18.00</dep></entry>
  <entry><ind>69.00></ind><dep>18.00</dep></entry>
  <entry><ind>70.00></ind><dep>9.000</dep></entry>
  <entry><ind>89.00></ind><dep>9.000</dep></entry>
  <entry><ind>90.00></ind><dep>0.000</dep></entry>
  <entry><ind>100.0></ind><dep>0.000</dep></entry>
</interpolation>
</syntaxhighlight>


<interpolation>
Here endeth Interpolation tables 101
  <entry><ind>0.000></ind><dep>0.000</dep></entry>
  <entry><ind>44.00></ind><dep>0.000</dep></entry>
  <entry><ind>45.00></ind><dep>27.00</dep></entry>
  <entry><ind>59.00></ind><dep>27.00</dep></entry>
  <entry><ind>59.00></ind><dep>27.00</dep></entry>
  <entry><ind>60.00></ind><dep>18.00</dep></entry>
  <entry><ind>69.00></ind><dep>18.00</dep></entry>
  <entry><ind>70.00></ind><dep>9.000</dep></entry>
  <entry><ind>89.00></ind><dep>9.000</dep></entry>
  <entry><ind>90.00></ind><dep>0.000</dep></entry>
  <entry><ind>100.0></ind><dep>0.000</dep></entry>
</interpolation>
 
Here endth Interpolation tables 101
:-Dene
:-Dene


=== Submodels ===
=== Submodels ===
{{main article|Submodels}}
Submodels are AI ballistic objects that emanate from, fall from, or launch from the user aircraft.  They are presently used to model smoke, contrails, flares, tracers, bombs, drop tanks and flight path markers.  
Submodels are AI ballistic objects that emanate from, fall from, or launch from the user aircraft.  They are presently used to model smoke, contrails, flares, tracers, bombs, drop tanks and flight path markers.  


Line 323: Line 304:
As an example examine the submodels file in the Aircraft/737-300 directory.  This file creates two submodels which will become the airplane's left and right engine contrails.  Each contrail needs its own submodel definition because the contrails begin at different locations.  Each contrail consists of a train of individual "puff" models that are released in rapid succession as long as the "trigger" property is true.  We ensure an unlimited supply of puffs by setting the "count" parameter to -1. The individual puffs, being AIBallistic objects, will follow their own ballistic paths once released.  In this case we have used the "bouyancy" parameter to negate gravity in the ballistic path.  The puffs have been given a life span of eight seconds.  At cruising speed the [[Boeing 737|737]] will thus have about 400 puffs behind it at any moment.
As an example examine the submodels file in the Aircraft/737-300 directory.  This file creates two submodels which will become the airplane's left and right engine contrails.  Each contrail needs its own submodel definition because the contrails begin at different locations.  Each contrail consists of a train of individual "puff" models that are released in rapid succession as long as the "trigger" property is true.  We ensure an unlimited supply of puffs by setting the "count" parameter to -1. The individual puffs, being AIBallistic objects, will follow their own ballistic paths once released.  In this case we have used the "bouyancy" parameter to negate gravity in the ballistic path.  The puffs have been given a life span of eight seconds.  At cruising speed the [[Boeing 737|737]] will thus have about 400 puffs behind it at any moment.


* [http://wiki.flightgear.org/images/0/0f/Submodels.txt This annotated submodels.xml file] gives a good idea about how to create submodel files, what parameters are available and how to use them, and also the type of research needed to make sure the information and models are accurate historically.
* See also {{readme file|submodels}}. It gives a good idea about how to create submodel files, what parameters are available and how to use them, and also the type of research needed to make sure the information and models are accurate historically.


=== Multiplayer controlled traffic ===
=== Multiplayer controlled traffic ===

Navigation menu