1
0
Fork 0

Computing gun sight code with USAAF K-14A sight.

This commit is contained in:
Hal V. Engel 2013-12-17 22:28:21 +00:00
parent 0f3788d1b0
commit 408ec1b334
20 changed files with 70880 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,266 @@
<?xml version="1.0"?>
<PropertyList>
<path>K-14A-pipper.ac</path>
<animation>
<type>range</type>
<min-m>0</min-m>
<max-m>15</max-m>
</animation>
<animation>
<type>translate</type>
<object-name>diamondTop</object-name>
<property>/controls/armament/gunsight/rangeRingSize</property>
<axis>
<x>0</x>
<y>0</y>
<z>1</z>
</axis>
</animation>
<animation>
<type>translate</type>
<object-name>diamondBottom</object-name>
<property>/controls/armament/gunsight/rangeRingSize</property>
<axis>
<x>0</x>
<y>0</y>
<z>-1</z>
</axis>
</animation>
<animation>
<type>translate</type>
<object-name>diamondUR</object-name>
<property>/controls/armament/gunsight/rangeRingSize</property>
<axis>
<x>0</x>
<y>0.866025</y>
<z>0.5</z>
</axis>
</animation>
<animation>
<type>translate</type>
<object-name>diamondUL</object-name>
<property>/controls/armament/gunsight/rangeRingSize</property>
<axis>
<x>0</x>
<y>-0.866025</y>
<z>0.5</z>
</axis>
</animation>
<animation>
<type>translate</type>
<object-name>diamondLL</object-name>
<property>/controls/armament/gunsight/rangeRingSize</property>
<axis>
<x>0</x>
<y>-0.866025</y>
<z>-0.5</z>
</axis>
</animation>
<animation>
<type>translate</type>
<object-name>diamondLR</object-name>
<property>/controls/armament/gunsight/rangeRingSize</property>
<axis>
<x>0</x>
<y>0.866025</y>
<z>-0.5</z>
</axis>
</animation>
<!-- sight on/off -->
<animation>
<type>select</type>
<object-name>gyro-pipper</object-name>
<condition>
<property>/controls/armament/gunsight/pipperVisibility</property>
</condition>
</animation>
<animation>
<type>select</type>
<object-name>diamondTop</object-name>
<condition>
<property>/controls/armament/gunsight/diamondTopVisibility</property>
</condition>
</animation>
<animation>
<type>select</type>
<object-name>diamondBottom</object-name>
<condition>
<property>/controls/armament/gunsight/diamondBottomVisibility</property>
</condition>
</animation>
<animation>
<type>select</type>
<object-name>diamondUL</object-name>
<condition>
<property>/controls/armament/gunsight/diamondULVisibility</property>
</condition>
</animation>
<animation>
<type>select</type>
<object-name>diamondUR</object-name>
<condition>
<property>/controls/armament/gunsight/diamondURVisibility</property>
</condition>
</animation>
<animation>
<type>select</type>
<object-name>diamondLL</object-name>
<condition>
<property>/controls/armament/gunsight/diamondLLVisibility</property>
</condition>
</animation>
<animation>
<type>select</type>
<object-name>diamondLR</object-name>
<condition>
<property>/controls/armament/gunsight/diamondLRVisibility</property>
</condition>
</animation>
<animation>
<type>select</type>
<object-name>cross</object-name>
<condition>
<property>/controls/armament/gunsight/fixedReticleOn</property>
</condition>
</animation>
<animation>
<type>select</type>
<object-name>fixedRing</object-name>
<condition>
<and>
<property>/controls/armament/gunsight/mask-off</property>
<property>/controls/armament/gunsight/fixedReticleOn</property>
</and>
</condition>
</animation>
<animation>
<type>select</type>
<object-name>rocketLadder</object-name>
<condition>
<and>
<property>/controls/armament/gunsight/mask-off</property>
<property>/controls/armament/gunsight/rocketLadder</property>
<property>/controls/armament/gunsight/fixedReticleOn</property>
</and>
</condition>
</animation>
<!-- gyro sight brightness -->
<animation>
<name>everything</name>
<object-name>gyro-pipper</object-name>
<object-name>diamondBottom</object-name>
<object-name>diamondTop</object-name>
<object-name>diamondUL</object-name>
<object-name>diamondUR</object-name>
<object-name>diamondLR</object-name>
<object-name>diamondLL</object-name>
<object-name>fixedRing</object-name>
<object-name>rocketLadder</object-name>
<object-name>cross</object-name>
</animation>
<animation>
<type>material</type>
<object-name>everything</object-name>
<interpolation>
<entry>
<ind>1</ind>
<dep>1.0</dep>
</entry>
<entry>
<ind>0</ind>
<dep>0.05</dep>
</entry>
</interpolation>
<emission>
<red>1.0</red>
<green>0.5</green>
<blue>0.9</blue>
<factor-prop>/controls/armament/gunsight/intensity</factor-prop>
</emission>
</animation>
<animation>
<type>transparency</type>
<object-name>everything</object-name>
<alpha-prop>/controls/armament/gunsight/intensity</alpha-prop>
<interpolation>
<entry>
<ind>1</ind>
<dep>0.8</dep>
</entry>
<entry>
<ind>0</ind>
<dep>0.0</dep>
</entry>
</interpolation>
</animation>
<animation>
<type>blend</type>
<object-name>everything</object-name>
<alpha-prop>/controls/armament/gunsight/intensity</alpha-prop>
<factor>0.8</factor>
<min>0</min>
<max>1.0</max>
</animation>
<animation>
<name>gyro-group</name>
<object-name>gyro-pipper</object-name>
<object-name>diamondBottom</object-name>
<object-name>diamondTop</object-name>
<object-name>diamondUL</object-name>
<object-name>diamondUR</object-name>
<object-name>diamondLR</object-name>
<object-name>diamondLL</object-name>
</animation>
<!-- gyro sight elevation movement -->
<animation>
<type>translate</type>
<object-name>gyro-group</object-name>
<property>/controls/armament/gunsight/elevation</property>
<factor>0.185</factor>
<axis>
<x>0</x>
<y>0</y>
<z>1</z>
</axis>
</animation>
<!-- gyro sight azimuth movement -->
<animation>
<type>translate</type>
<object-name>gyro-group</object-name>
<property>/controls/armament/gunsight/azimuth</property>
<factor>0.185</factor>
<axis>
<x>0</x>
<y>1</y>
<z>0</z>
</axis>
</animation>
</PropertyList>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,350 @@
<?xml version="1.0"?>
<PropertyList>
<path>K14-sight.ac</path>
<animation>
<type>range</type>
<min-m>0</min-m>
<max-m>40</max-m>
</animation>
<animation>
<type>material</type>
<emission>
<factor-prop>controls/lighting/cabin-norm</factor-prop>
<red>0.25</red>
<green>0.12</green>
<blue>0.12</blue>
</emission>
</animation>
<animation>
<type>rotate</type>
<object-name>sunShield</object-name>
<object-name>sunShieldGlass</object-name>
<factor>95</factor>
<property>/controls/armament/gunsight/sunScreenDown</property>
<center>
<x-m>-0.0673</x-m>
<y-m>0</y-m>
<z-m>0.0416</z-m>
</center>
<axis>
<x>0</x>
<y>-1</y>
<z>0</z>
</axis>
</animation>
<animation>
<type>rotate</type>
<object-name>sunShadeControlLever</object-name>
<factor>75</factor>
<property>/controls/armament/gunsight/sunScreenDown</property>
<center>
<x-m>-0.0239</x-m>
<y-m>0</y-m>
<z-m>0.0172</z-m>
</center>
<axis>
<x>0</x>
<y>1</y>
<z>0</z>
</axis>
</animation>
<animation>
<type>pick</type>
<object-name>sunShadeControlLever</object-name>
<action>
<button>0</button>
<repeatable>false</repeatable>
<binding>
<command>property-toggle</command>
<property>/controls/armament/gunsight/sunScreenDown</property>
</binding>
</action>
</animation>
<animation>
<type>rotate</type>
<object-name>mask-knob</object-name>
<object-name>mask-lever</object-name>
<property>/controls/armament/gunsight/mask-off</property>
<interpolation>
<entry>
<ind>0</ind>
<dep>45</dep>
</entry>
<entry>
<ind>1</ind>
<dep>0</dep>
</entry>
</interpolation>
<center>
<x-m>-0.052</x-m>
<y-m>-0.067911</y-m>
<z-m>0.0112</z-m>
</center>
<axis>
<x>0</x>
<y>1</y>
<z>0</z>
</axis>
</animation>
<animation>
<type>pick</type>
<object-name>mask-knob</object-name>
<action>
<button>0</button>
<repeatable>false</repeatable>
<binding>
<command>property-toggle</command>
<property>/controls/armament/gunsight/mask-off</property>
</binding>
</action>
</animation>
<animation>
<type>rotate</type>
<object-name>span-lever</object-name>
<property>/controls/armament/gunsight/span</property>
<interpolation>
<entry>
<ind>30</ind>
<dep>-56.0</dep>
</entry>
<entry>
<ind>40</ind>
<dep>-34.0</dep>
</entry>
<entry>
<ind>50</ind>
<dep>-13.0</dep>
</entry>
<entry>
<ind>60</ind>
<dep>0.0</dep>
</entry>
<entry>
<ind>70</ind>
<dep>12.0</dep>
</entry>
<entry>
<ind>80</ind>
<dep>24.0</dep>
</entry>
<entry>
<ind>90</ind>
<dep>34.0</dep>
</entry>
<entry>
<ind>100</ind>
<dep>42.0</dep>
</entry>
<entry>
<ind>110</ind>
<dep>50.0</dep>
</entry>
<entry>
<ind>120</ind>
<dep>56.0</dep>
</entry>
</interpolation>
<center>
<x-m>-0.0002</x-m>
<y-m>0.0005</y-m>
<z-m>-0.0105</z-m>
</center>
<axis>
<x>0.75</x>
<y>0</y>
<z>-0.25</z>
</axis>
</animation>
<animation>
<type>pick</type>
<object-name>span-scale</object-name>
<action>
<button>1</button>
<repeatable>true</repeatable>
<binding>
<command>property-adjust</command>
<property>/controls/armament/gunsight/span</property>
<step>-1</step>
<min>30</min>
<max>120</max>
</binding>
</action>
</animation>
<animation>
<type>pick</type>
<object-name>span-scale</object-name>
<action>
<button>0</button>
<repeatable>true</repeatable>
<binding>
<command>property-adjust</command>
<property>/controls/armament/gunsight/span</property>
<step>1</step>
<min>30</min>
<max>120</max>
</binding>
</action>
</animation>
<animation>
<type>rotate</type>
<object-name>rangeDial</object-name>
<property>/controls/armament/gunsight/range</property>
<interpolation>
<entry>
<ind>600</ind>
<dep>0</dep>
</entry>
<entry>
<ind>650</ind>
<dep>26</dep>
</entry>
<entry>
<ind>700</ind>
<dep>49</dep>
</entry>
<entry>
<ind>750</ind>
<dep>70.5</dep>
</entry>
<entry>
<ind>800</ind>
<dep>90</dep>
</entry>
<entry>
<ind>850</ind>
<dep>107</dep>
</entry>
<entry>
<ind>900</ind>
<dep>123</dep>
</entry>
<entry>
<ind>950</ind>
<dep>140</dep>
</entry>
<entry>
<ind>1000</ind>
<dep>154</dep>
</entry>
<entry>
<ind>1100</ind>
<dep>168</dep>
</entry>
<entry>
<ind>1200</ind>
<dep>182</dep>
</entry>
<entry>
<ind>1300</ind>
<dep>194</dep>
</entry>
<entry>
<ind>1400</ind>
<dep>206</dep>
</entry>
<entry>
<ind>1500</ind>
<dep>217</dep>
</entry>
<entry>
<ind>1600</ind>
<dep>228</dep>
</entry>
<entry>
<ind>1700</ind>
<dep>240.5</dep>
</entry>
<entry>
<ind>1800</ind>
<dep>252</dep>
</entry>
<entry>
<ind>1900</ind>
<dep>261</dep>
</entry>
<entry>
<ind>2000</ind>
<dep>270</dep>
</entry>
<entry>
<ind>2100</ind>
<dep>282</dep>
</entry>
<entry>
<ind>2200</ind>
<dep>294</dep>
</entry>
<entry>
<ind>2300</ind>
<dep>305</dep>
</entry>
<entry>
<ind>2400</ind>
<dep>315</dep>
</entry>
</interpolation>
<center>
<x-m>-0.0485</x-m>
<y-m>-0.0762</y-m>
<z-m>-0.05053</z-m>
</center>
<axis>
<x>0</x>
<y>-1</y>
<z>0</z>
</axis>
</animation>
<animation>
<type>pick</type>
<object-name>rangeDial</object-name>
<action>
<button>1</button>
<repeatable>true</repeatable>
<binding>
<command>property-adjust</command>
<property>/controls/armament/gunsight/range</property>
<step>30</step>
<min>600</min>
<max>2400</max>
</binding>
</action>
</animation>
<animation>
<type>pick</type>
<object-name>rangeDial</object-name>
<action>
<button>0</button>
<repeatable>true</repeatable>
<binding>
<command>property-adjust</command>
<property>/controls/armament/gunsight/range</property>
<step>-30</step>
<min>600</min>
<max>2400</max>
</binding>
</action>
</animation>
<effect>
<inherits-from>Effects/model-transparent</inherits-from>
<condition>
<property>/sim/rendering/rembrandt/enabled</property>
</condition>
<object-name>reflector-plate</object-name>
</effect>
</PropertyList>

View file

@ -0,0 +1,4 @@
AC3Db
MATERIAL "DefaultWhite" rgb 1 1 1 amb 1 1 1 emis 0 0 0 spec 0.5 0.5 0.5 shi 64 trans 0
OBJECT world
kids 0

View file

@ -0,0 +1,168 @@
# ==============================================================================
# K14 Reticle
# ==============================================================================
var propertyTreeRoot = "/controls/armament/gunsight/";
var sideEdge = 0.08;
var zCenterLine = getprop(propertyTreeRoot, "zCenterLine");
var topEdge = zCenterLine + 0.04;
var pipperVisibility = func()
{
if (getprop(propertyTreeRoot, "reticleSelectorPos") < 2 and
getprop(propertyTreeRoot, "power-on") != 0 and
getprop("/controls/engines/engine/master-bat") == 1)
{
setprop(propertyTreeRoot, "fixedReticleOn", 1);
}
else
{
setprop(propertyTreeRoot, "fixedReticleOn", 0);
}
if (getprop(propertyTreeRoot, "computer-on") == 1 and
getprop(propertyTreeRoot, "reticleSelectorPos") > 0 and
getprop(propertyTreeRoot, "power-on") != 0 and
getprop("/controls/engines/engine/master-bat") == 1)
{
var elevation = call(func getprop(propertyTreeRoot, "elevation"), var err = []);
if (!size(err))
{
elevation = elevation * 0.401885 + zCenterLine;
var azimuth = call(func getprop(propertyTreeRoot, "azimuth"), var err1 = []);
if (!size(err1))
{
azimuth = azimuth * 0.401885;
var ringSize = call(func getprop(propertyTreeRoot, "rangeRingSize"), var err2 = []);
if (!size(err2))
{
if (elevation + ringSize > topEdge
or (azimuth > 0 and azimuth > sideEdge)
or (azimuth < 0 and azimuth < -sideEdge))
{
setprop(propertyTreeRoot, "diamondTopVisibility", 0);
}
else
{
setprop(propertyTreeRoot, "diamondTopVisibility", 1);
}
if (elevation - ringSize > topEdge
or (azimuth > 0 and azimuth > sideEdge)
or (azimuth < 0 and azimuth < -sideEdge))
{
setprop(propertyTreeRoot, "diamondBottomVisibility", 0);
}
else
{
setprop(propertyTreeRoot, "diamondBottomVisibility", 1);
}
if (elevation + (0.5 * ringSize) > topEdge
or (azimuth > 0 and azimuth + (0.866025 * ringSize) > sideEdge)
or (azimuth < 0 and azimuth + (0.866025 * ringSize) < -sideEdge))
{
setprop(propertyTreeRoot, "diamondURVisibility", 0);
}
else
{
setprop(propertyTreeRoot, "diamondURVisibility", 1);
}
if (elevation + (0.5 * ringSize) > topEdge
or (azimuth < 0 and azimuth - (0.866025 * ringSize) < -sideEdge)
or (azimuth > 0 and azimuth - (0.866025 * ringSize) > sideEdge))
{
setprop(propertyTreeRoot, "diamondULVisibility", 0);
}
else
{
setprop(propertyTreeRoot, "diamondULVisibility", 1);
}
if (elevation - (0.5 * ringSize) > topEdge
or (azimuth > 0 and azimuth + (0.866025 * ringSize) > sideEdge)
or (azimuth < 0 and azimuth + (0.866025 * ringSize) < -sideEdge))
{
setprop(propertyTreeRoot, "diamondLRVisibility", 0);
}
else
{
setprop(propertyTreeRoot, "diamondLRVisibility", 1);
}
if (elevation - (0.5 * ringSize) > topEdge
or (azimuth < 0 and azimuth - (0.866025 * ringSize) < -sideEdge)
or (azimuth > 0 and azimuth - (0.866025 * ringSize) > sideEdge))
{
setprop(propertyTreeRoot, "diamondLLVisibility", 0);
}
else
{
setprop(propertyTreeRoot, "diamondLLVisibility", 1);
}
if (elevation > topEdge
or (azimuth > 0 and azimuth > sideEdge)
or (azimuth < 0 and azimuth < -sideEdge))
{
setprop(propertyTreeRoot, "pipperVisibility", 0);
}
else
{
setprop(propertyTreeRoot, "pipperVisibility", 1);
}
}
}
}
}
else
{
setprop(propertyTreeRoot, "diamondTopVisibility", 0);
setprop(propertyTreeRoot, "diamondBottomVisibility", 0);
setprop(propertyTreeRoot, "diamondURVisibility", 0);
setprop(propertyTreeRoot, "diamondULVisibility", 0);
setprop(propertyTreeRoot, "diamondLRVisibility", 0);
setprop(propertyTreeRoot, "diamondLLVisibility", 0);
setprop(propertyTreeRoot, "pipperVisibility", 0);
}
}
var scaleRangeFindingReticle = func()
{
if (getprop(propertyTreeRoot, "gunsightComputerInitialized") == 1)
{
var span = getprop(propertyTreeRoot, "span");
if (span < 30)
{
setprop(propertyTreeRoot, "span", 30);
}
else if (span > 120)
{
setprop(propertyTreeRoot, "span", 120);
}
var range = getprop(propertyTreeRoot, "range");
if (range < 600)
{
setprop(propertyTreeRoot, "range", 600);
}
else if (range > 2400)
{
setprop(propertyTreeRoot, "range", 2400);
}
var mils = 1000 * (span / range);
setprop(propertyTreeRoot, "mils", mils);
var newRangeRingSize = 0.00019 * mils; # scale mils to meters
setprop(propertyTreeRoot, "rangeRingSize", newRangeRingSize);
}
}
setlistener("/controls/armament/gunsight/gunsightComputerInitialized", scaleRangeFindingReticle, 1, 0);
setlistener("/controls/armament/gunsight/span", scaleRangeFindingReticle, 1, 0);
setlistener("/controls/armament/gunsight/range", scaleRangeFindingReticle, 1, 0);
setlistener("/controls/armament/gunsight/elevation", pipperVisibility, 1, 0);
setlistener("/controls/armament/gunsight/gunsightComputerInitialized", pipperVisibility, 1, 0);
setlistener("/controls/armament/gunsight/reticleSelectorPos", pipperVisibility, 1, 0);
setlistener("/controls/armament/gunsight/power-on", pipperVisibility, 1, 0);

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

View file

@ -0,0 +1,195 @@
<?xml version="1.0"?>
<PropertyList>
<path>Aircraft/Instruments-3d/computing-gun-sights/K14/K14-controller.ac</path>
<animation>
<type>range</type>
<min-m>0</min-m>
<max-m>45</max-m>
</animation>
<animation>
<type>material</type>
<object-name>GS-gyro-fixed</object-name>
<object-name>GS-brightness</object-name>
<object-name>GS-power</object-name>
<object-name>GS-body</object-name>
<object-name>Switch</object-name>
<object-name>switchGuard</object-name>
<object-name>switchCase</object-name>
<object-name>switchNut</object-name>
<object-name>upperSwitchPlate</object-name>
<emission>
<factor-prop>/controls/lighting/cabin-norm</factor-prop>
<red>0.2</red>
<green>0.1</green>
<blue>0.1</blue>
</emission>
</animation>
<animation>
<type>rotate</type>
<object-name>GS-brightness</object-name>
<property>/controls/armament/gunsight/intensity</property>
<interpolation>
<entry>
<ind>0</ind>
<dep>140.0</dep>
</entry>
<entry>
<ind>0.5</ind>
<dep>0</dep>
</entry>
<entry>
<ind>1.0</ind>
<dep>-140.0</dep>
</entry>
</interpolation>
<center>
<x-m>0.0475</x-m>
<y-m>-0.00006</y-m>
<z-m>0.0</z-m>
</center>
<axis>
<x>0</x>
<y>0</y>
<z>1</z>
</axis>
</animation>
<animation>
<type>rotate</type>
<object-name>GS-gyro-fixed</object-name>
<property>/controls/armament/gunsight/reticleSelectorPos</property>
<interpolation>
<entry>
<ind>0</ind>
<dep>90.0</dep>
</entry>
<entry>
<ind>1</ind>
<dep>0</dep>
</entry>
<entry>
<ind>2</ind>
<dep>-90.0</dep>
</entry>
</interpolation>
<center>
<x-m>-0.0474</x-m>
<y-m>0.000032</y-m>
<z-m>0.</z-m>
</center>
<axis>
<x>0</x>
<y>0</y>
<z>1</z>
</axis>
</animation>
<animation>
<type>rotate</type>
<object-name>Switch</object-name>
<property>/controls/armament/gunsight/computer-on</property>
<interpolation>
<entry>
<ind>0</ind>
<dep>0</dep>
</entry>
<entry>
<ind>1</ind>
<dep>-60</dep>
</entry>
</interpolation>
<center>
<x-m>0.000056</x-m>
<y-m>0.01</y-m>
<z-m>0.0082</z-m>
</center>
<axis>
<x>1</x>
<y>0</y>
<z>0</z>
</axis>
</animation>
<animation>
<type>pick</type>
<object-name>Switch</object-name>
<action>
<button>0</button>
<binding>
<command>property-toggle</command>
<property>/controls/armament/gunsight/computer-on</property>
</binding>
</action>
</animation>
<animation>
<type>pick</type>
<object-name>GS-brightness</object-name>
<action>
<button>1</button>
<repeatable>true</repeatable>
<binding>
<command>property-adjust</command>
<property>/controls/armament/gunsight/intensity</property>
<step>0.01</step>
<min>0</min>
<max>1</max>
</binding>
</action>
</animation>
<animation>
<type>pick</type>
<object-name>GS-brightness</object-name>
<action>
<button>0</button>
<repeatable>true</repeatable>
<binding>
<command>property-adjust</command>
<property>/controls/armament/gunsight/intensity</property>
<step>-0.01</step>
<min>0</min>
<max>1</max>
</binding>
</action>
</animation>
<animation>
<type>pick</type>
<object-name>GS-gyro-fixed</object-name>
<action>
<button>1</button>
<repeatable>false</repeatable>
<binding>
<command>property-adjust</command>
<property>/controls/armament/gunsight/reticleSelectorPos</property>
<step>1</step>
<min>0</min>
<max>2</max>
</binding>
</action>
</animation>
<animation>
<type>pick</type>
<object-name>GS-gyro-fixed</object-name>
<action>
<button>0</button>
<repeatable>false</repeatable>
<binding>
<command>property-adjust</command>
<property>/controls/armament/gunsight/reticleSelectorPos</property>
<step>-1</step>
<min>0</min>
<max>2</max>
</binding>
</action>
</animation>
</PropertyList>

View file

@ -0,0 +1,342 @@
#****************************************************************************
#
# Derived from
# A Digital Lead Computing Optical Sight Model
# Anthony L. Leatham, et al
# Air Force Academy
# Sept. 1974
# http://www.dtic.mil/dtic/tr/fulltext/u2/786464.pdf
#
# Appendex D Air Force Avionics Laboratory digital LCOS
# Contains FORTRAN code that is used here converted into Nasal code.
#
# Original source for equations and code was from:
#
# Air-to-Air Gun Fire Control Equations for Digital Lead Computing Optical Sights
# R.A. Manske
# AFAL-TM-74-8-NVE-1
# April 1974
# Air Force Avionics Laboratory
# Wring-Patterson AFB, Ohio
#
# Document location unknown.
#
# non-static inputs
#
# range in feet
# rangeRate range rate in ft/sec
# P angular pitch rate of aircraft body axis in radians/second
# Q angular yaw rate of aircraft body axis in radians/second
# R angular roll rate of aircraft body axis in radians/second
# normalAcceleration normal acceleration in ft/sec/sec (-32.17 straight and level)
# alpha angle of attack radians
# trueAirSpeed true airspeed - feet per second
# RHO air density in slugs per cubic foot
#
#********************************************************************************
# ================================ Initalize ======================================
# Make sure all needed properties are present and accounted
# for, and that they have sane default values.
# print("gunsight-computer.nas started");
var propertyTreeRoot = "/controls/armament/gunsight/";
var z_offset = 0;
var y_offset = 0;
var gunElevationRadians = 0;
var ballisticCoefficienct = 0;
var muzzleVelocity = 0;
var harmonizationRange = 0;
var range = 0;
# constants
var timeStep = 0.1;
# sight damping factor
var SIG = 0.4;
var KSIG = 1.0 / (1.0 + SIG);
var seaLevelAirDensity = 0.00238;
var radiansPerDrgree = 0.0174532925;
# Ballistic coefficient divided by sea level air density
var KBRHO = 0;
var cosGunElevation = 0;
var sinGunElevation = 0;
# Reciprocal of gun harmonization range
var RRH = 0;
var SQRV = 0;
var RHO = 0;
var RDC = 0;
var LA = 0;
var LE = 0;
var VLS = 0;
var rangeRate = 0;
var VOS = 0;
var VCM = 0;
var VMC = 0;
var rangeRateArray = [0, 0, 0, 0];
var rRAindex = 0;
var P = 0;
var Q = 0;
var R = 0;
var normalAcceleration = -32.17;
var maxElevation = getprop(propertyTreeRoot, "maxElevation");
var maxAzimuth = getprop(propertyTreeRoot, "maxAzimuth");
var initSightComputer = func()
{
# print("gunsite-computer.nas init()");
# Get aircraft/sight specific info
# Offset of gun in feet from sight line
z_offset = getprop(propertyTreeRoot, "z-offsetFeet");
y_offset = getprop(propertyTreeRoot, "y-offsetFeet");
# Elevation of gun(s) above alpha
gunElevationRadians = getprop(propertyTreeRoot, "gunElevationDegrees") * 0.0174532925;
# Projectile ballistic Coefficient and muzzle velocity in feet per second
ballisticCoefficienct = getprop(propertyTreeRoot, "ballisticCoefficienct");
muzzleVelocity = getprop(propertyTreeRoot, "muzzleVelocity");
# Range where the sight line is = the guns bore line
harmonizationRange = getprop(propertyTreeRoot, "gunHarminizationRangeFeet");
# range to target usually from an onboard radar system or a
# manual system controlled by the aircraft crew
range = getprop(propertyTreeRoot, "range");
var seaLevelAirDensity = 0.00238;
# Ballistic coefficient divided by sea level air density
KBRHO = ballisticCoefficienct / seaLevelAirDensity;
cosGunElevation = math.cos(gunElevationRadians);
sinGunElevation = math.sin(gunElevationRadians);
# Reciprocal of gun harmonization range
RRH = 1.0 / harmonizationRange;
SQRV = math.sqrt(muzzleVelocity);
RHO = getprop("/environment/density-slugft3");
VLS = KBRHO * RHO * SQRV * range;
rangeRate = 0;
VOS = muzzleVelocity + VLS + rangeRate;
VCM = math.sqrt(VOS * VOS - 4.0 * (rangeRate) * VLS);
VMC = math.sqrt(VOS * VOS - 4.0 * (rangeRate) * VLS);
# print("gunsite-computer.nas initialization done");
}
var getRangeRate = func()
{
# print("gunsite-computer.nas getRangeRate");
var oldRange = range;
range = getprop(propertyTreeRoot, "range");
rangeRateArray[rRAindex] = (oldRange - range) / timeStep;
rRAindex = rRAindex + 1;
if (rRAindex > 3)
{
rRAindex = 0;
}
var rangeRateSum = 0;
forindex(i; rangeRateArray)
{
rangeRateSum = rangeRateSum + rangeRateArray[i];
}
var rangeRateAve = rangeRateSum / 4;
setprop("/controls/armament/gunsight/rangeRate", rangeRateAve);
return -1.0 * rangeRateAve;
}
var getAccelerationData = func()
{
# print("gunsite-computer.nas getAccelerationData()");
P = getprop("/orientation/p-body");
Q = getprop("/orientation/q-body");
R = getprop("/orientation/r-body");
normalAcceleration = getprop("/accelerations/pilot/z-accel-fps_sec");
}
var getTrueAirSpeed = func()
{
# print("gunsite-computer.nas getTrueAirspeed()");
# from http://en.wikipedia.org/wiki/True_airspeed
# TASKnots = A0 * M * sqrt(T/T0)
# where A0 = speed of sound a standard sea level (661.47 Kts)
# M = MACH speed of aircraft
# T = static air temperature in Kelvin at aircraft position
# T0 = temperature a standard sea level (288.15 K)
var ambientTemperatureKelvin = getprop("/environment/temperature-degc") + 273.15;
var MACH = getprop("/velocities/mach");
var TASKnots = 661.47 * MACH * math.sqrt(ambientTemperatureKelvin / 288.15);
# print("true airspeed = ", TASKnots);
# return TAS in feet per second.
return TASKnots * 1.68781;
}
var getAzimuthAndElevation = func()
{
# print("gunsite-computer.nas getAzimuthAndElevation");
getAccelerationData();
# print("normalAcceleration = ", normalAcceleration);
rangeRate = getRangeRate();
range = getprop(propertyTreeRoot, "range");
var alpha = getprop("/orientation/alpha-deg") * radiansPerDrgree;
var trueAirSpeed = getTrueAirSpeed();
var totalInitialVelocity = trueAirSpeed + muzzleVelocity;
var SQRV = math.sqrt(trueAirSpeed + totalInitialVelocity);
var RHO = getprop("/environment/density-slugft3");
var SLA = LA * (1.0 - 0.16667 * LA * LA);
var SLE = LE * (1.0 - 0.16667 * LE * LE);
var CLE = 1.0 - (LE * LE)/2;
var CLA = 1.0 - (LA * LA)/2;
var RCOS = 1.0/(CLA * CLE);
var RDE = (-rangeRate - RDC * SLE) * RCOS;
var RE = range * RCOS;
# Approximation used for sqrt
# If y=approx. square root of x, then SQTR(x) = 0.5 * (y + x/y) is very close
SQRV = 0.5 * (SQRV + (trueAirSpeed + totalInitialVelocity)/SQRV);
VLS = KBRHO * RHO * RE * SQRV;
VOS = totalInitialVelocity - RDE - VLS;
# Approximation used for sqrt
# RDE = -rangeRate makes this calculation identical to other LCOSS
RDE = -rangeRate;
VCM = 0.5 * (VCM + (VOS * VOS - 4.0 * (trueAirSpeed + RDE) * VLS) / VCM);
var VE = 0.5 * (VOS + VCM);
var recipricalTimeOfFlight = VE / RE;
var averageRelativeVelocity = VE + RDE;
var rRange = 1.0 / range;
var KH = 1.0 - range * RRH;
var VN = averageRelativeVelocity - SIG * RDE * VLS * (averageRelativeVelocity + trueAirSpeed)/(VCM * averageRelativeVelocity);
var PG = P * cosGunElevation - R * sinGunElevation;
var RG = P * sinGunElevation + R * cosGunElevation;
RDC = trueAirSpeed * (alpha + gunElevationRadians) *
(totalInitialVelocity - averageRelativeVelocity) /
(trueAirSpeed + totalInitialVelocity) +
0.5 * normalAcceleration / recipricalTimeOfFlight;
# WJ and WK are computed sight line angular rates
var WK = (KH * y_offset * CLA * recipricalTimeOfFlight - VN * SLA) * rRange;
var WJ = ((RDC - KH * z_offset * recipricalTimeOfFlight) * CLE - VN * CLA * SLE) * rRange;
var LED = (WJ + SLA * PG - CLA * Q) * KSIG;
var LAD = ((WK - SLE * (CLA * PG + SLA * Q)) / CLE -RG) * KSIG;
LA = LA + LAD * timeStep;
LE = LE + LED * timeStep;
}
var gunSightMain = func()
{
# print("gunSightMain()");
if (getprop(propertyTreeRoot, "computer-on") == 1)
{
getAzimuthAndElevation();
# LA and LE are azimuth and elevation angles of the computed sight line
# LA and LE are in radians.
# Compute PLA and PLE as negative mills
# var PLA = -1000.0 * LA;
# var PLE = -1000.0 * LE;
# update reticle position
# Under extreme conditions such as a spin the algorithm
# can generate invalid results and return NaN for LA
# and LE which causes the whole thing to break down.
# If that happens set them to 0 (reinitialize LA and LE)
# and continue on.
# clamp LA and LE to max deflection values for the sight
var tempLA = LA;
var tempLE = LE;
if (LA > maxAzimuth/1000)
{
tempLA = maxAzimuth/1000;
}
else if (LA < -maxAzimuth/1000)
{
tempLA = -maxAzimuth/1000;
}
if (LE > maxElevation/1000)
{
tempLE = maxElevation/1000;
}
else if (LE < -maxElevation/1000)
{
tempLE = -maxElevation/1000;
}
call(func setprop(propertyTreeRoot, "azimuth", tempLA), nil, var LEerr = []);
if (size(LEerr))
{
tempLA = 0;
setprop(propertyTreeRoot, "azimuth", tempLA);
}
call (func setprop(propertyTreeRoot, "elevation", tempLE), nil, var LAerr = []);
if (size(LAerr))
{
tempLE = 0;
setprop(propertyTreeRoot, "elevation", tempLE)
}
# print("gunSightMain loop");
# print("LA (azimuth) = ", LA);
# print("LE (elevation)= ", LE);
# wait a while and do this again
settimer(gunSightMain, timeStep);
}
}
# listener for the the sight computer/gyro to be powered up or down.
# Will start gunSightMain process when the gun sight computer/gyro is powered on.
var listenGunSightGyroPower = func(i)
{
if (getprop(propertyTreeRoot, "computer-on") == 1)
{
initSightComputer();
setprop(propertyTreeRoot, "gunsightComputerInitialized", 1);
# print("gunsite-computer.nas power switched");
gunSightMain();
}
else
{
setprop(propertyTreeRoot, "gunsightComputerInitialized", 0);
}
}
setprop("/controls/armament/gunsight/gunsightComputerInitialized", 0);
var L1 = setlistener("/sim/signals/fdm-initialized", func(i)
{
var L = setlistener("/controls/armament/gunsight/computer-on", listenGunSightGyroPower, 1, 0);
}, 1, 0);

View file

@ -0,0 +1,64 @@
To enable full functionality of the K14 gun sight there are several things
that need to be done.
First change the <nasal> section of your *set.xml file so that it looks like the
following.
<nasal>
<!-- your other nasal files -->
<!-- the following three lines must be exactly like this -->
<K14>
<file>Aircraft/Instruments-3d/computing-gun-sights/Nasal/lead-computer.nas</file>
</K14>
</nasal>
Animation:
For dark conditions when cabin/cockpit illumination is used all of the K14 sight
is illuminated in response to
<property>/controls/lighting/cabin-norm</property>
If you are using a different property for your cabin/cockpit lights you will need to map your
lighting property to /controls/lighting/cabin-norm.
Aircraft Specific Properties:
The following properties will need to be set to configure the site for an aircraft.
The following five values can be found in the submodels.xnl configuration file.
/controls/armament/gunsight/z-gunOffsetFeet = Gun position on z axis relative to the sight line in feet.
Will = <z-offset>offset value</z-offset> + distance from
aircraft center line to sight line height.
/controls/armament/gunsight/y-gunOffsetFeet = Gun position on y axis relative to the sight line in feet.
Will = <y-offset>abs value</y-offset>
/controls/armament/gunsight/gunElevationDegrees = <pitch-offset>gun pitch setting</pitch-offset>
/controls/armament/gunsight/ballisticCoefficienct = <eda>xxxxx</eda>
/controls/armament/gunsight/muzzleVelocity = <speed>xxxxx</speed> = In feet per second
/controls/armament/gunsight/gunHarminizationRangeFeet = Range where the sight and the bullet
path cross is level flight in feet.
Below is an example from the P-51D using the K14A sight which needs some additional
settings to control power and lighting for the sight.
<controls>
<armament>
<gunsight>
<power-on type="int">0</power-on>
<intensity type="float">1.0</intensity>
<z-offsetFeet type="float">-4.0</z-offsetFeet>
<y-offsetFeet type="float">0.0</y-offsetFeet>
<scale type="float">0.6</scale>
<gunElevationDegrees type="float">3.8</gunElevationDegrees>
<ballisticCoefficienct type="float">0.00136354</ballisticCoefficienct>
<muzzleVelocity type="float">2900.0</muzzleVelocity>
<gunHarminizationRangeFeet type="float">900.0</gunHarminizationRangeFeet>
<range type="float">900.0</range> <!-- startup default -->
</gunsight>
</armament>
...
</controls>