Moved the RAF Mk.9 bubble sextant to Aircraft/Instruments-3d.
This commit is contained in:
parent
22466ada61
commit
fa65993dc6
8 changed files with 11641 additions and 0 deletions
Binary file not shown.
After Width: | Height: | Size: 41 KiB |
10434
Aircraft/Instruments-3d/RAF_Mk9_bubble_sextant/RAF_Mk9_bubble_sextant.ac
Normal file
10434
Aircraft/Instruments-3d/RAF_Mk9_bubble_sextant/RAF_Mk9_bubble_sextant.ac
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,477 @@
|
|||
###############################################################################
|
||||
##
|
||||
## RAF mk9 bubble sextant.
|
||||
##
|
||||
## Copyright (C) 2007 - 2010 Anders Gidenstam (anders(at)gidenstam.org)
|
||||
## This file is licensed under the GPL license version 2 or later.
|
||||
##
|
||||
###############################################################################
|
||||
|
||||
## NOTE: This module MUST be loaded as RAFmk9sextant;
|
||||
|
||||
## You can override these parameters when loading this file.
|
||||
# Field of view when looking through the sextant
|
||||
var FOV = 25;
|
||||
# Distance from the eye to the sextant when looking through the sextant.
|
||||
var VIEW_DISTANCE = 0.15;
|
||||
# The view in which the sextant will be used.
|
||||
var VIEW_NAME = "Cockpit View";
|
||||
# The storage location and orientation.
|
||||
# The location is relative to the default center for the view.
|
||||
var STOWED = { position : {x:-0.3, y: 0.0, z: -0.2},
|
||||
orientation : {heading : 320.0,
|
||||
pitch : -45.0,
|
||||
roll : 0.0}
|
||||
};
|
||||
|
||||
## Interface functions.
|
||||
var pick_up = func {
|
||||
if (handling.lookthrough) return;
|
||||
|
||||
handling.toggle();
|
||||
if (handling.enabled) {
|
||||
handling.view_angle.setValue(-90.0);
|
||||
handling.view_distance.setValue(2.0*VIEW_DISTANCE);
|
||||
}
|
||||
}
|
||||
|
||||
var toggle_look_through = func {
|
||||
handling.toggle_look_through();
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Bindings for mouse X and Y movements. Install these to the appropriate
|
||||
# mouse mode and axes, e.g. in the -set file.
|
||||
var mouseX = func {
|
||||
if (!handling.enabled) return;
|
||||
if(__kbd.alt.getValue()) {
|
||||
var delta = 3*cmdarg().getNode("offset").getValue();
|
||||
if(__kbd.shift.getValue() and handling.enabled) {
|
||||
# Roll adjustment
|
||||
var orient = sextant.get_orientation();
|
||||
var roll = orient[2] - delta;
|
||||
if(roll < -180) roll = -180;
|
||||
if(roll > 180) roll = 180;
|
||||
sextant.set_orientation(orient[0], orient[1], roll);
|
||||
} else {
|
||||
var view = "/sim/current-view/heading-offset-deg";
|
||||
var val = getprop(view) - delta;
|
||||
if(val < 0) val = 0;
|
||||
if(val > 360) val = 360;
|
||||
setprop(view, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var mouseY = func {
|
||||
if (!handling.enabled) return;
|
||||
if(__kbd.alt.getValue()) {
|
||||
var delta = 3*cmdarg().getNode("offset").getValue();
|
||||
if(__kbd.shift.getValue() and handling.enabled) {
|
||||
# Altitude adjustment
|
||||
sextant.adjust_altitude_fine(delta);
|
||||
} else {
|
||||
var view = "/sim/current-view/pitch-offset-deg";
|
||||
var val = getprop(view) - delta;
|
||||
if(val < -90) val = -90;
|
||||
if(val > 90) val = 90;
|
||||
setprop(view, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var RAD = math.pi/180;
|
||||
var DEG = 180/math.pi;
|
||||
|
||||
###############################################################################
|
||||
# Class for managing one RAF mk9 bubble sextant instrument.
|
||||
var sextant = {
|
||||
##################################################
|
||||
init : func (n=0) {
|
||||
me.UPDATE_INTERVAL = 0.0;
|
||||
me.loopid = 0;
|
||||
me.base =
|
||||
props.globals.getNode("instrumentation/sextant["~ n ~"]/", 1);
|
||||
|
||||
## Instrument properties
|
||||
me.pitch_err = me.base.getNode("pitch-error-deg", 1);
|
||||
me.pitch_err.setDoubleValue(0);
|
||||
me.roll_err = me.base.getNode("roll-error-deg", 1);
|
||||
me.roll_err.setDoubleValue(0);
|
||||
me.setting_min = me.base.getNode("setting/min", 1);
|
||||
me.setting_min.setDoubleValue(0);
|
||||
me.setting_deg1 = me.base.getNode("setting/deg1", 1);
|
||||
me.setting_deg1.setDoubleValue(0); # 0 - 10 deg fractional.
|
||||
me.setting_deg10 = me.base.getNode("setting/deg10", 1);
|
||||
me.setting_deg10.setDoubleValue(0);
|
||||
me.bubble = me.base.getNode("bubble-norm", 1);
|
||||
me.bubble.setDoubleValue(0);
|
||||
me.serviceable = me.base.getNode("serviceable", 1);
|
||||
me.serviceable.setBoolValue(1);
|
||||
|
||||
## The instrument's orientation in the aircraft frame
|
||||
## and position offset relative its initial position.
|
||||
me.position = [me.base.getNode("offsets/x-m", 1),
|
||||
me.base.getNode("offsets/y-m", 1),
|
||||
me.base.getNode("offsets/z-m", 1)];
|
||||
me.heading = me.base.getNode("offsets/heading-deg", 1);
|
||||
me.pitch = me.base.getNode("offsets/pitch-deg", 1);
|
||||
me.roll = me.base.getNode("offsets/roll-deg", 1);
|
||||
|
||||
me.position[0].setValue(0);
|
||||
me.position[1].setValue(0);
|
||||
me.position[2].setValue(0);
|
||||
me.heading.setValue(0);
|
||||
me.pitch.setValue(0);
|
||||
me.roll.setValue(0);
|
||||
|
||||
me.reset();
|
||||
|
||||
print("RAF Mk9 bubble sextant ... initialized");
|
||||
},
|
||||
##################################################
|
||||
set_position : func (x, y ,z) {
|
||||
me.position[0].setValue(x);
|
||||
me.position[1].setValue(y);
|
||||
me.position[2].setValue(z);
|
||||
},
|
||||
##################################################
|
||||
get_position : func (x, y ,z) {
|
||||
return [me.position[0].getValue(),
|
||||
me.position[1].getValue(),
|
||||
me.position[2].getValue()];
|
||||
},
|
||||
##################################################
|
||||
set_orientation : func (heading, pitch, roll) {
|
||||
me.heading.setValue(heading);
|
||||
me.pitch.setValue(pitch);
|
||||
me.roll.setValue(roll);
|
||||
},
|
||||
##################################################
|
||||
get_orientation : func () {
|
||||
return [me.heading.getValue(),
|
||||
me.pitch.getValue(),
|
||||
me.roll.getValue()];
|
||||
},
|
||||
##################################################
|
||||
step_10deg_knob : func (d) {
|
||||
var val = me.setting_deg10.getValue() + (d < 0 ? -1 : 1);
|
||||
if(val < 0) val = 0;
|
||||
if(val > 8) val = 8;
|
||||
me.setting_deg10.setValue(val);
|
||||
},
|
||||
##################################################
|
||||
step_5deg_knob : func (d) {
|
||||
var val = me.setting_deg1.getValue();
|
||||
var new = val;
|
||||
if (d <= 0 and val >= 5.0) new -= 5.0;
|
||||
if (d >= 0 and val < 5.0) new += 5.0;
|
||||
if(new < 0.0) new = 0;
|
||||
if(new > 10.0) new = 10;
|
||||
me.setting_deg1.setValue(new);
|
||||
},
|
||||
##################################################
|
||||
step_bubble_knob : func (d) {
|
||||
var val = me.bubble.getValue() + d;
|
||||
if(val < 0) val = 0;
|
||||
if(val > 1) val = 1;
|
||||
me.bubble.setValue(val);
|
||||
},
|
||||
##################################################
|
||||
adjust_altitude_fine : func (d) {
|
||||
var val = me.setting_deg1.getValue() - d;
|
||||
if(val < 0) val = 0;
|
||||
if(val > 10) val = 10;
|
||||
|
||||
me.setting_deg1.setValue(val);
|
||||
me.setting_min.setValue(60.0*val - 60*int(val));
|
||||
},
|
||||
##################################################
|
||||
get_altitude : func {
|
||||
return 10.0 * me.setting_deg10.getValue() + me.setting_deg1.getValue();
|
||||
},
|
||||
##################################################
|
||||
reset : func {
|
||||
me.loopid += 1;
|
||||
me._loop_(me.loopid);
|
||||
},
|
||||
##################################################
|
||||
update : func {
|
||||
## State data we need.
|
||||
var heading_ac = getprop("/orientation/heading-deg") * RAD;
|
||||
var pitch_ac = getprop("/orientation/pitch-deg") * RAD;
|
||||
var roll_ac = getprop("/orientation/roll-deg") * RAD;
|
||||
|
||||
var yaw_v = me.heading.getValue() * RAD;
|
||||
var pitch_v = me.pitch.getValue() * RAD;
|
||||
var roll_v = me.roll.getValue() * RAD;
|
||||
|
||||
## Compute local aircraft axes vectors in the local frame
|
||||
## Account for aircraft orientation. (x/y/z = front/left/up)
|
||||
var T_ac = mulMM(mulMM(rotateZ(heading_ac), rotateY(pitch_ac)),
|
||||
rotateX(roll_ac));
|
||||
## Account for view orientation and sextant settings.
|
||||
## The sextant frame is assumed to coincide with the view frame
|
||||
## except that it is pitched down altitude deg around its local
|
||||
## Y axis.
|
||||
var T_bs = mulMM(mulMM(mulMM(mulMM(
|
||||
T_ac,
|
||||
rotateZ(yaw_v)),
|
||||
rotateY(pitch_v)),
|
||||
rotateX(roll_v)),
|
||||
rotateY(-me.get_altitude() * RAD));
|
||||
|
||||
var X_bs = mulMv(T_bs, X);
|
||||
var Y_bs = mulMv(T_bs, Y);
|
||||
var Z_bs = mulMv(T_bs, Z);
|
||||
|
||||
## Transform up in the local frame to the sextant frame.
|
||||
var Up = mulMv([X_bs, Y_bs, Z_bs], Z);
|
||||
var Up_xz = [Up[0], 0, Up[2]];
|
||||
var Up_yz = [0, Up[1], Up[2]];
|
||||
|
||||
## Compute interesting angles in the sextant frame.
|
||||
var p_err = angleV(Z, Up_xz);
|
||||
if (scalar(Up_xz, X) < 0.0) {
|
||||
p_err *= -1;
|
||||
}
|
||||
me.pitch_err.setValue(p_err*DEG);
|
||||
|
||||
var r_err = angleV(Z, Up_yz);
|
||||
if (scalar(Up_yz, Y) < 0.0) {
|
||||
r_err *= -1;
|
||||
}
|
||||
me.roll_err.setValue(r_err*DEG);
|
||||
},
|
||||
##################################################
|
||||
_loop_ : func(id) {
|
||||
id == me.loopid or return;
|
||||
me.update();
|
||||
settimer(func { me._loop_(id); }, me.UPDATE_INTERVAL, 1);
|
||||
}
|
||||
};
|
||||
|
||||
###############################################################################
|
||||
## Singleton class for handling (i.e. moving / rotating) a sextant.
|
||||
var handling = {
|
||||
enabled : 0,
|
||||
##################################################
|
||||
init : func (n=0) {
|
||||
me.UPDATE_INTERVAL = 0.0;
|
||||
me.loopid = 0;
|
||||
me.lookthrough = 0;
|
||||
|
||||
me.base =
|
||||
props.globals.getNode("instrumentation/sextant["~ n ~"]/", 1);
|
||||
|
||||
## Instrument properties
|
||||
me.altitude_deg = me.base.getNode("altitude-deg", 1);
|
||||
me.altitude_deg.setDoubleValue(0);
|
||||
|
||||
## 3d model position properties
|
||||
me.source_view = view.views[view.indexof(VIEW_NAME)];
|
||||
var src = me.source_view.getNode("config");
|
||||
me.offset = {x: src.getNode("z-offset-m").getValue(),
|
||||
y: src.getNode("x-offset-m").getValue(),
|
||||
z: src.getNode("y-offset-m").getValue()};
|
||||
|
||||
me.view_distance = me.base.getNode("view-distance-m", 1);
|
||||
me.view_distance.setDoubleValue(2.0*VIEW_DISTANCE);
|
||||
me.view_angle = me.base.getNode("view-angle-deg", 1);
|
||||
me.view_angle.setDoubleValue(0.0);
|
||||
|
||||
sextant.init();
|
||||
sextant.set_position
|
||||
(STOWED.position.x,
|
||||
STOWED.position.y,
|
||||
STOWED.position.z);
|
||||
sextant.set_orientation
|
||||
(STOWED.orientation.heading,
|
||||
STOWED.orientation.pitch,
|
||||
STOWED.orientation.roll);
|
||||
|
||||
## Instrument "display"
|
||||
me.display = screen.display.new(20, 10);
|
||||
me.display.add(me.altitude_deg,
|
||||
props.globals.getNode("/sim/time/gmt"));
|
||||
|
||||
me.disable();
|
||||
|
||||
print("RAF Mk9 bubble sextant handling ... initialized");
|
||||
},
|
||||
##################################################
|
||||
toggle : func {
|
||||
if (me.enabled) {
|
||||
me.disable();
|
||||
} else {
|
||||
me.enable();
|
||||
}
|
||||
},
|
||||
##################################################
|
||||
enable : func {
|
||||
me.enabled = 1;
|
||||
me.display.toggle();
|
||||
|
||||
me.loopid += 1;
|
||||
me._loop_(me.loopid);
|
||||
},
|
||||
##################################################
|
||||
toggle_look_through : func {
|
||||
if (!me.enabled) return;
|
||||
if (!me.lookthrough) {
|
||||
me.lookthrough = 1;
|
||||
|
||||
me.view_distance.setDoubleValue(VIEW_DISTANCE);
|
||||
me.view_angle.setValue(0.0);
|
||||
|
||||
me.old_view = view.point.save();
|
||||
setprop("/sim/current-view/field-of-view", FOV);
|
||||
} else {
|
||||
me.lookthrough = 0;
|
||||
setprop("/sim/current-view/field-of-view",
|
||||
me.old_view.getChild("field-of-view").getValue());
|
||||
# view.point.restore();
|
||||
me.view_angle.setValue(-90.0);
|
||||
me.view_distance.setValue(2.0*VIEW_DISTANCE);
|
||||
}
|
||||
},
|
||||
##################################################
|
||||
disable : func {
|
||||
me.enabled = 0;
|
||||
me.lookthrough = 0;
|
||||
me.display.toggle();
|
||||
|
||||
sextant.set_position
|
||||
(STOWED.position.x,
|
||||
STOWED.position.y,
|
||||
STOWED.position.z);
|
||||
sextant.set_orientation
|
||||
(STOWED.orientation.heading,
|
||||
STOWED.orientation.pitch,
|
||||
STOWED.orientation.roll);
|
||||
me.view_distance.setDoubleValue(0.0);
|
||||
me.view_angle.setValue(0.0);
|
||||
|
||||
if (me.lookthrough) {
|
||||
me.toggle_look_through();
|
||||
}
|
||||
},
|
||||
##################################################
|
||||
update : func {
|
||||
## Move the 3d model.
|
||||
if (view.current == me.source_view) {
|
||||
var src = props.globals.getNode("/sim/current-view");
|
||||
sextant.set_position
|
||||
(src.getNode("z-offset-m").getValue() - me.offset.x,
|
||||
src.getNode("x-offset-m").getValue() - me.offset.y,
|
||||
src.getNode("y-offset-m").getValue() - me.offset.z);
|
||||
var old = sextant.get_orientation();
|
||||
sextant.set_orientation
|
||||
(getprop("/sim/current-view/heading-offset-deg"),
|
||||
getprop("/sim/current-view/pitch-offset-deg"),
|
||||
old[2]);
|
||||
me.altitude_deg.setValue(sextant.get_altitude());
|
||||
}
|
||||
},
|
||||
##################################################
|
||||
_loop_ : func(id) {
|
||||
id == me.loopid and me.enabled or return;
|
||||
me.update();
|
||||
settimer(func { me._loop_(id); }, me.UPDATE_INTERVAL, 1);
|
||||
}
|
||||
};
|
||||
|
||||
###############################################################################
|
||||
setlistener("/sim/signals/fdm-initialized", func {
|
||||
handling.init();
|
||||
});
|
||||
|
||||
###############################################################################
|
||||
## Ugly matrix math as needed.
|
||||
## Probably horribly inefficient matrix representation:
|
||||
## M[row][col] = [[row1], [row2], [row3]]
|
||||
## v[row] = [x, y, z]
|
||||
|
||||
var X = [1, 0, 0];
|
||||
var Y = [0, 1, 0];
|
||||
var Z = [0, 0, 1];
|
||||
var id = [X, Y, Z];
|
||||
|
||||
var mulMv = func(M, v) {
|
||||
return [M[0][0]*v[0] + M[0][1]*v[1] + M[0][2]*v[2],
|
||||
M[1][0]*v[0] + M[1][1]*v[1] + M[1][2]*v[2],
|
||||
M[2][0]*v[0] + M[2][1]*v[1] + M[2][2]*v[2]];
|
||||
}
|
||||
|
||||
var mulMM = func(A, B) {
|
||||
return [[A[0][0]*B[0][0] + A[0][1]*B[1][0] + A[0][2]*B[2][0],
|
||||
A[0][0]*B[0][1] + A[0][1]*B[1][1] + A[0][2]*B[2][1],
|
||||
A[0][0]*B[0][2] + A[0][1]*B[1][2] + A[0][2]*B[2][2]],
|
||||
[A[1][0]*B[0][0] + A[1][1]*B[1][0] + A[1][2]*B[2][0],
|
||||
A[1][0]*B[0][1] + A[1][1]*B[1][1] + A[1][2]*B[2][1],
|
||||
A[1][0]*B[0][2] + A[1][1]*B[1][2] + A[1][2]*B[2][2]],
|
||||
[A[2][0]*B[0][0] + A[2][1]*B[1][0] + A[2][2]*B[2][0],
|
||||
A[2][0]*B[0][1] + A[2][1]*B[1][1] + A[2][2]*B[2][1],
|
||||
A[2][0]*B[0][2] + A[2][1]*B[1][2] + A[2][2]*B[2][2]]];
|
||||
}
|
||||
|
||||
var scalar = func(a, b) {
|
||||
return a[0]*b[0] + a[1]*b[1] + a[2]*b[2];
|
||||
}
|
||||
|
||||
var absV = func(a) {
|
||||
return math.sqrt(scalar(a, a));
|
||||
}
|
||||
|
||||
var crossV = func(a, b) {
|
||||
return [a[1]*b[2] - a[2]*b[1],
|
||||
a[2]*b[0] - a[0]*b[2],
|
||||
a[0]*b[1] - a[1]*b[0]];
|
||||
}
|
||||
|
||||
var rotateX = func (r) {
|
||||
return [[1, 0, 0],
|
||||
[0, math.cos(-r), -math.sin(-r)],
|
||||
[0, math.sin(-r), math.cos(-r)]];
|
||||
}
|
||||
|
||||
var rotateY = func (r) {
|
||||
return [[math.cos(-r), 0, math.sin(-r)],
|
||||
[0, 1, 0],
|
||||
[-math.sin(-r), 0, math.cos(-r)]];
|
||||
}
|
||||
|
||||
var rotateZ = func (r) {
|
||||
return [[math.cos(r), -math.sin(r), 0],
|
||||
[math.sin(r), math.cos(r), 0],
|
||||
[0, 0, 1]];
|
||||
}
|
||||
|
||||
var printMat = func (m) {
|
||||
foreach (var e; m) {
|
||||
if (typeof(e) == "scalar") {
|
||||
print(" " ~ e);
|
||||
} else {
|
||||
var line = "";
|
||||
foreach (var ee; e) {
|
||||
line = line ~ " " ~ ee;
|
||||
}
|
||||
print(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var angleV = func (a, b) {
|
||||
return math.acos(math.abs(scalar(a,b)) / (absV(a) * absV(b)));
|
||||
}
|
||||
|
||||
#print("id*id=");
|
||||
#printMat(mulMM(id,id));
|
||||
|
||||
#print("X=");
|
||||
#printMat(X);
|
||||
|
||||
#print("RotY(45)*X=");
|
||||
#printMat(mulMv(rotateY(45*math.pi/180),X));
|
||||
|
||||
#print("Y*X= " ~scalar(Y,X));
|
|
@ -0,0 +1,520 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
RAF Mk9 bubble sextant.
|
||||
|
||||
Copyright (C) 2008 - 2010 Anders Gidenstam (anders(at)gidenstam.org)
|
||||
This file is licensed under the GPL license version 2 or later.
|
||||
-->
|
||||
<PropertyList>
|
||||
|
||||
<path>RAF_Mk9_bubble_sextant.ac</path>
|
||||
<!-- x/y/z == back/right/up -->
|
||||
|
||||
<!-- =========================================================================
|
||||
Instrument function animations.
|
||||
===================================================================== -->
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- Bubble movement -->
|
||||
<animation>
|
||||
<type>translate</type>
|
||||
<object-name>bubble</object-name>
|
||||
<property>instrumentation/sextant/roll-error-deg</property>
|
||||
<axis>
|
||||
<x>0</x>
|
||||
<y>1</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
<interpolation>
|
||||
<entry>
|
||||
<ind>-4</ind>
|
||||
<dep>0.008</dep>
|
||||
</entry>
|
||||
<entry>
|
||||
<ind>0</ind>
|
||||
<dep>0</dep>
|
||||
</entry>
|
||||
<entry>
|
||||
<ind>4</ind>
|
||||
<dep>-0.008</dep>
|
||||
</entry>
|
||||
</interpolation>
|
||||
</animation>
|
||||
<animation>
|
||||
<type>translate</type>
|
||||
<object-name>bubble</object-name>
|
||||
<property>instrumentation/sextant/pitch-error-deg</property>
|
||||
<axis>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<z>1</z>
|
||||
</axis>
|
||||
<interpolation>
|
||||
<entry>
|
||||
<ind>-4</ind>
|
||||
<dep>0.008</dep>
|
||||
</entry>
|
||||
<entry>
|
||||
<ind>0</ind>
|
||||
<dep>0</dep>
|
||||
</entry>
|
||||
<entry>
|
||||
<ind>4</ind>
|
||||
<dep>-0.008</dep>
|
||||
</entry>
|
||||
</interpolation>
|
||||
</animation>
|
||||
<animation>
|
||||
<type>scale</type>
|
||||
<object-name>bubble</object-name>
|
||||
<property>instrumentation/sextant/bubble-norm</property>
|
||||
<x-factor>0.0</x-factor>
|
||||
<x-offset>1.0</x-offset>
|
||||
<y-factor>1.0</y-factor>
|
||||
<y-offset>0.0</y-offset>
|
||||
<z-factor>1.0</z-factor>
|
||||
<z-offset>0.0</z-offset>
|
||||
<center>
|
||||
<x-m> -0.060 </x-m>
|
||||
<y-m> 0.000 </y-m>
|
||||
<z-m> 0.000 </z-m>
|
||||
</center>
|
||||
</animation>
|
||||
|
||||
<!-- If the bubble is gone the instrument is unserviceable. -->
|
||||
<animation>
|
||||
<type>select</type>
|
||||
<object-name>bubble</object-name>
|
||||
<condition>
|
||||
<property>instrumentation/sextant/serviceable</property>
|
||||
</condition>
|
||||
</animation>
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- 10 deg setting knob -->
|
||||
<animation>
|
||||
<type>rotate</type>
|
||||
<object-name>10_setting_knob</object-name>
|
||||
<property>instrumentation/sextant/setting/deg10</property>
|
||||
<factor>5.0</factor>
|
||||
<offset-deg>-15.0</offset-deg>
|
||||
<center>
|
||||
<x-m> -0.057 </x-m>
|
||||
<y-m> 0.035 </y-m>
|
||||
<z-m> 0.038 </z-m>
|
||||
</center>
|
||||
<axis>
|
||||
<x> 0.0 </x>
|
||||
<y> 1.0 </y>
|
||||
<z> 0.0 </z>
|
||||
</axis>
|
||||
</animation>
|
||||
<animation>
|
||||
<type>rotate</type>
|
||||
<object-name>10_setting_knob_scale</object-name>
|
||||
<property>instrumentation/sextant/setting/deg10</property>
|
||||
<factor>5.0</factor>
|
||||
<offset-deg>-15.0</offset-deg>
|
||||
<center>
|
||||
<x-m> -0.057 </x-m>
|
||||
<y-m> 0.035 </y-m>
|
||||
<z-m> 0.038 </z-m>
|
||||
</center>
|
||||
<axis>
|
||||
<x> 0.0 </x>
|
||||
<y> 1.0 </y>
|
||||
<z> 0.0 </z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- Degree drum -->
|
||||
<animation>
|
||||
<type>rotate</type>
|
||||
<object-name>degree_drum</object-name>
|
||||
<property>instrumentation/sextant/setting/deg1</property>
|
||||
<factor>36.0</factor>
|
||||
<offset-deg>18</offset-deg>
|
||||
<center>
|
||||
<x-m> -0.1110 </x-m>
|
||||
<y-m> 0.0150 </y-m>
|
||||
<z-m> -0.0450 </z-m>
|
||||
</center>
|
||||
<axis>
|
||||
<x> 1.0 </x>
|
||||
<y> 0.0 </y>
|
||||
<z> 0.0 </z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- Minute drum -->
|
||||
<animation>
|
||||
<type>rotate</type>
|
||||
<object-name>minute_drum</object-name>
|
||||
<property>instrumentation/sextant/setting/min</property>
|
||||
<factor>6.0</factor>
|
||||
<offset-deg>30.0</offset-deg>
|
||||
<center>
|
||||
<x-m> -0.1270 </x-m>
|
||||
<y-m> 0.0040 </y-m>
|
||||
<z-m> -0.0315 </z-m>
|
||||
</center>
|
||||
<axis>
|
||||
<x>-1.0 </x>
|
||||
<y> 0.0 </y>
|
||||
<z> 0.0 </z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<animation>
|
||||
<type>rotate</type>
|
||||
<object-name>slow_motion_knob</object-name>
|
||||
<property>instrumentation/sextant/setting/deg1</property>
|
||||
<factor>120.0</factor>
|
||||
<offset-deg>0</offset-deg>
|
||||
<center>
|
||||
<x-m> -0.0680 </x-m>
|
||||
<y-m> 0.0230 </y-m>
|
||||
<z-m> 0.0090 </z-m>
|
||||
</center>
|
||||
<axis>
|
||||
<x> 0.0 </x>
|
||||
<y> 1.0 </y>
|
||||
<z> 0.0 </z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<animation>
|
||||
<type>rotate</type>
|
||||
<object-name>bubble_knob</object-name>
|
||||
<property>instrumentation/sextant/bubble-norm</property>
|
||||
<factor>360.0</factor>
|
||||
<offset-deg>0</offset-deg>
|
||||
<center>
|
||||
<x-m> -0.0350 </x-m>
|
||||
<y-m> -0.0230 </y-m>
|
||||
<z-m> 0.0390 </z-m>
|
||||
</center>
|
||||
<axis>
|
||||
<x> 0.0 </x>
|
||||
<y> 1.0 </y>
|
||||
<z> 0.0 </z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- Instrument control pick animations. -->
|
||||
<animation>
|
||||
<type>pick</type>
|
||||
<object-name>10_setting_knob</object-name>
|
||||
<action>
|
||||
<button>0</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>
|
||||
RAFmk9sextant.sextant.step_10deg_knob(1);
|
||||
</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>1</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>
|
||||
RAFmk9sextant.sextant.step_10deg_knob(-1);
|
||||
</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>3</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>
|
||||
RAFmk9sextant.sextant.step_10deg_knob(-1);
|
||||
</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>4</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>
|
||||
RAFmk9sextant.sextant.step_10deg_knob(1);
|
||||
</script>
|
||||
</binding>
|
||||
</action>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>pick</type>
|
||||
<object-name>slow_motion_knob</object-name>
|
||||
<action>
|
||||
<button>0</button>
|
||||
<repeatable>true</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>
|
||||
RAFmk9sextant.sextant.adjust_altitude_fine(0.01667);
|
||||
</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>1</button>
|
||||
<repeatable>true</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>
|
||||
RAFmk9sextant.sextant.adjust_altitude_fine(-0.01667);
|
||||
</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>3</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>
|
||||
RAFmk9sextant.sextant.adjust_altitude_fine(-0.01667);
|
||||
</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>4</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>
|
||||
RAFmk9sextant.sextant.adjust_altitude_fine(0.01667);
|
||||
</script>
|
||||
</binding>
|
||||
</action>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>pick</type>
|
||||
<object-name>5_deg_knob</object-name>
|
||||
<action>
|
||||
<button>0</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>
|
||||
RAFmk9sextant.sextant.step_5deg_knob(0);
|
||||
</script>
|
||||
</binding>
|
||||
</action>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>pick</type>
|
||||
<object-name>bubble_knob</object-name>
|
||||
<action>
|
||||
<button>0</button>
|
||||
<repeatable>true</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>
|
||||
RAFmk9sextant.sextant.step_bubble_knob(0.01);
|
||||
</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>1</button>
|
||||
<repeatable>true</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>
|
||||
RAFmk9sextant.sextant.step_bubble_knob(-0.01);
|
||||
</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>3</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>
|
||||
RAFmk9sextant.sextant.step_bubble_knob(-0.01);
|
||||
</script>
|
||||
</binding>
|
||||
</action>
|
||||
<action>
|
||||
<button>4</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>
|
||||
RAFmk9sextant.sextant.step_bubble_knob(0.01);
|
||||
</script>
|
||||
</binding>
|
||||
</action>
|
||||
</animation>
|
||||
|
||||
<!-- =========================================================================
|
||||
Instrument handling animations.
|
||||
===================================================================== -->
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<animation>
|
||||
<type>rotate</type>
|
||||
<property>instrumentation/sextant/view-angle-deg</property>
|
||||
<factor>1.0</factor>
|
||||
<center>
|
||||
<x-m> -0.10 </x-m>
|
||||
<y-m> 0.00 </y-m>
|
||||
<z-m> 0.00 </z-m>
|
||||
</center>
|
||||
<axis>
|
||||
<x> 0.0 </x>
|
||||
<y> 0.3 </y>
|
||||
<z> 1.0 </z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- Offset from eye position -->
|
||||
<animation>
|
||||
<type>translate</type>
|
||||
<property>instrumentation/sextant/view-distance-m</property>
|
||||
<axis>
|
||||
<x>-1.0 </x>
|
||||
<y> 0.0 </y>
|
||||
<z> 0.0 </z>
|
||||
</axis>
|
||||
<factor>1.0</factor>
|
||||
</animation>
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<animation>
|
||||
<type>rotate</type>
|
||||
<property>instrumentation/sextant/offsets/roll-deg</property>
|
||||
<factor>1.0</factor>
|
||||
<center>
|
||||
<x-m> 0.00 </x-m>
|
||||
<y-m> 0.00 </y-m>
|
||||
<z-m> 0.00 </z-m>
|
||||
</center>
|
||||
<axis>
|
||||
<x> 1.0 </x>
|
||||
<y> 0.0 </y>
|
||||
<z> 0.0 </z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>rotate</type>
|
||||
<property>instrumentation/sextant/offsets/pitch-deg</property>
|
||||
<factor>1.0</factor>
|
||||
<center>
|
||||
<x-m> 0.00 </x-m>
|
||||
<y-m> 0.00 </y-m>
|
||||
<z-m> 0.00 </z-m>
|
||||
</center>
|
||||
<axis>
|
||||
<x> 0.0 </x>
|
||||
<y> 1.0 </y>
|
||||
<z> 0.0 </z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<animation>
|
||||
<type>rotate</type>
|
||||
<property>instrumentation/sextant/offsets/heading-deg</property>
|
||||
<factor>1.0</factor>
|
||||
<center>
|
||||
<x-m> 0.00 </x-m>
|
||||
<y-m> 0.00 </y-m>
|
||||
<z-m> 0.00 </z-m>
|
||||
</center>
|
||||
<axis>
|
||||
<x> 0.0 </x>
|
||||
<y> 0.0 </y>
|
||||
<z> 1.0 </z>
|
||||
</axis>
|
||||
</animation>
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- Translations for user's view. -->
|
||||
<animation>
|
||||
<type>translate</type>
|
||||
<property>instrumentation/sextant/offsets/x-m</property>
|
||||
<axis>
|
||||
<x>1</x>
|
||||
<y>0</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
<factor>1.0</factor>
|
||||
</animation>
|
||||
<animation>
|
||||
<type>translate</type>
|
||||
<property>instrumentation/sextant/offsets/y-m</property>
|
||||
<axis>
|
||||
<x>0</x>
|
||||
<y>1</y>
|
||||
<z>0</z>
|
||||
</axis>
|
||||
<factor>1.0</factor>
|
||||
</animation>
|
||||
<animation>
|
||||
<type>translate</type>
|
||||
<property>instrumentation/sextant/offsets/z-m</property>
|
||||
<axis>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<z>1</z>
|
||||
</axis>
|
||||
<factor>1.0</factor>
|
||||
</animation>
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<animation>
|
||||
<type>pick</type>
|
||||
<object-name>eye_piece</object-name>
|
||||
<action>
|
||||
<button>0</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>
|
||||
RAFmk9sextant.toggle_look_through();
|
||||
</script>
|
||||
</binding>
|
||||
</action>
|
||||
</animation>
|
||||
<animation>
|
||||
<type>pick</type>
|
||||
<object-name>left_handle</object-name>
|
||||
<action>
|
||||
<button>0</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>
|
||||
RAFmk9sextant.pick_up();
|
||||
</script>
|
||||
</binding>
|
||||
</action>
|
||||
</animation>
|
||||
<animation>
|
||||
<type>pick</type>
|
||||
<object-name>right_handle</object-name>
|
||||
<action>
|
||||
<button>0</button>
|
||||
<repeatable>false</repeatable>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>
|
||||
RAFmk9sextant.pick_up();
|
||||
</script>
|
||||
</binding>
|
||||
</action>
|
||||
</animation>
|
||||
|
||||
</PropertyList>
|
210
Aircraft/Instruments-3d/RAF_Mk9_bubble_sextant/README
Normal file
210
Aircraft/Instruments-3d/RAF_Mk9_bubble_sextant/README
Normal file
|
@ -0,0 +1,210 @@
|
|||
|
||||
Bubble sextant for Celestial Navigation in FlightGear
|
||||
-----------------------------------------------------
|
||||
|
||||
Copyright 2007 - 2010 Anders Gidenstam
|
||||
|
||||
* These programs are free software; you can redistribute them and/or modify
|
||||
* them under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Yes, the stars on the night sky in FlightGear can be used for navigation.
|
||||
This short text gives a hint to how it is done. The references explain it
|
||||
much better, though, so have a look there both for introduction and more
|
||||
advanced topics.
|
||||
|
||||
|
||||
Part 0 - Installing the tools: 3d bubble sextant model for FlightGear
|
||||
---------------------------------------------------------------------
|
||||
|
||||
- The bubble sextant 3d model RAF_Mk9_bubble_sextant.xml need to be
|
||||
loaded from the aircraft 3d model file and placed at the center of
|
||||
the view it is intended to be used from. For example for a view located
|
||||
2.5 meter behind and 2.0 meter above the aircraft origin:
|
||||
(Note that any offsets of the main 3d model needs to be accounted for
|
||||
in translating the view position to a 3d model position and that the
|
||||
axes order differs.)
|
||||
|
||||
<!-- Star observer's instruments -->
|
||||
<model>
|
||||
<name>Bubble_sextant</name>
|
||||
<path>Aircraft/Short_Empire/Instruments/BubbleSextant/RAF_Mk9_bubble_sextant.xml</path>
|
||||
<offsets>
|
||||
<x-m> 2.50 </x-m>
|
||||
<y-m> 0.50 </y-m>
|
||||
<z-m> 2.00 </z-m>
|
||||
</offsets>
|
||||
</model>
|
||||
|
||||
- The Nasal module needs to be loaded from the main aircraft -set file.
|
||||
The name of the view in which the sextant will be used and
|
||||
the stowed (= inactive) location of the instrument needs to be set.
|
||||
The stored location is specified in a frame axis parallel with the
|
||||
aircraft frame but centered at the location given for the sextant
|
||||
3d model in the 3d model file.
|
||||
For example:
|
||||
<nasal>
|
||||
<RAFmk9sextant>
|
||||
<file>Aircraft/Short_Empire/Instruments/BubbleSextant/RAF_Mk9_bubble_sextant.nas</file>
|
||||
<script>
|
||||
var VIEW_NAME = "Star Observation View";
|
||||
var STOWED = { position : {x:-0.3, y: 0.0, z: -0.2},
|
||||
orientation : {heading : 320.0,
|
||||
pitch : -45.0,
|
||||
roll : 0.0}
|
||||
};
|
||||
</script>
|
||||
</RAFmk9sextant>
|
||||
</nasal>
|
||||
|
||||
- To allow fine control of the sextant using the mouse add the following
|
||||
XML snippet to the aircraft's -set file.
|
||||
It binds moves movements in mode 0/pointer mode to the sextant.
|
||||
alt + move mouse - precision movement of view direction.
|
||||
alt + shift + move mouse - up/down changes the altitude setting of the
|
||||
sextant.
|
||||
- left/right tilts the sextant to align with
|
||||
the horizon.
|
||||
|
||||
<input>
|
||||
<!-- Install the sextant controls in mouse mode 0. -->
|
||||
<mice n="0">
|
||||
<mouse n="0">
|
||||
<mode n="0">
|
||||
<x-axis>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>
|
||||
RAFmk9sextant.mouseX();
|
||||
</script>
|
||||
</binding>
|
||||
</x-axis>
|
||||
<y-axis>
|
||||
<binding>
|
||||
<command>nasal</command>
|
||||
<script>
|
||||
RAFmk9sextant.mouseY();
|
||||
</script>
|
||||
</binding>
|
||||
</y-axis>
|
||||
</mode>
|
||||
</mouse>
|
||||
</mice>
|
||||
</input>
|
||||
|
||||
|
||||
To correctly measure the altitude of a heavenly body the instrument
|
||||
must be level, i.e. the bubble must be centered.
|
||||
The instrument is configured for an aim-then-level method, i.e.
|
||||
one first center the view on the desired object then change the altitude
|
||||
and tilt settings until the instrument is level. (I.e. changing altitude
|
||||
behaves as if the user changes the setting and rotates the instrument so
|
||||
that it remains aimed in the same direction).
|
||||
|
||||
NOTE: Tilting of the instrument might still be somewhat buggy.
|
||||
|
||||
|
||||
Part 1 - Taking sextant sights in FlightGear
|
||||
-------------------------------------
|
||||
|
||||
What is needed?
|
||||
- The celestial altitude (~angle from the horizon) for some (at least 2)
|
||||
stars and the precise time of observation.
|
||||
|
||||
How?
|
||||
|
||||
- Pick up the sextant by clicking on either of its handles.
|
||||
|
||||
- Enter the sextant view by clicking on the sextant eye piece.
|
||||
|
||||
- Obtain a bubble by turning the bubble knob on the left side of
|
||||
the instrument. It is possible to reach the bubble knob while in
|
||||
sextant view.
|
||||
|
||||
- Aim the center of the view on the star. Alt + move mouse in pointer mode
|
||||
enables high precision view rotation.
|
||||
|
||||
- Level the instrument. This is done by changing the altitude setting,
|
||||
first in 10 degree steps by the coarse motion knob on the right side
|
||||
of the instrument (reachable also while in sextant view) and then
|
||||
with the slow motion knob (or alt+shift+move mouse up/down).
|
||||
Tilt the instrument (alt+shift+move mouse right/left) as needed to
|
||||
center the bubble.
|
||||
|
||||
- Time + celestial altitude constitutes a sighting. Make sure that
|
||||
the instrument is level and aimed at the star when you note the time
|
||||
and altitude.
|
||||
|
||||
|
||||
But where are those bl**dy stars?
|
||||
|
||||
- I use the star charts around page 256 in "The American Practical Navigator",
|
||||
http://www.nga.mil/MSISiteContent/StaticFiles/NAV_PUBS/APN/pub9.zip
|
||||
to find some. For me the ones in Ursa Major was easiest to find (though
|
||||
one should use a wider spread).
|
||||
|
||||
Suggestion (northern hemisphere):
|
||||
* Dubhe (Right upper corner star of the Ursa Major "wagon".)
|
||||
* Alkaid (Third and last (leftmost) star in the Ursa Major "wagon" handle.)
|
||||
* Arcturus (Brightest star found to the "left" of Alkaid just below the
|
||||
extended line between Alkaid and the star immediately to the
|
||||
right in the Ursa Major "wagon" handle.
|
||||
See star chart in [Bowditch] page 256.)
|
||||
|
||||
|
||||
Part 2 - Computing a position
|
||||
-----------------------------
|
||||
|
||||
The Intercept method
|
||||
|
||||
- Assume a position. It should be close to ones actual position - usually one
|
||||
has a dead reckoning position to start from. (The assumed position need
|
||||
not be equal to the DR one - one can choose a more convenient one e.g.
|
||||
when using tables.)
|
||||
|
||||
- Compute the expected locations of the observed stars for
|
||||
that position.
|
||||
Use a program/website, like http://www.tecepe.com.br/cgi-win/cgiasvis.exe ,
|
||||
or a Nautical Almenac + tables.
|
||||
- Compare the observed star locations with the computed ones.
|
||||
This gives a position line for each star. Plot the position
|
||||
lines to (hopefully) get a fix.
|
||||
Further info and plotting sheets: http://www.efalk.org/Navigation/
|
||||
|
||||
|
||||
References
|
||||
----------
|
||||
|
||||
http://www.celestialnavigation.net/
|
||||
Good place to start.
|
||||
|
||||
http://www.efalk.org/Navigation/
|
||||
Intercept method tutorial and downloadable plot sheets.
|
||||
|
||||
http://www.ludd.luth.se/users/kavli/peck_celestial/space.html
|
||||
Longer tutorial and description. Focuses on the use of tables for sight
|
||||
reductions.
|
||||
|
||||
http://www.tecepe.com.br/cgi-win/cgiasvis.exe
|
||||
Computes star locations. Use instead of tables.
|
||||
|
||||
[Bowditch]
|
||||
"The American Practical Navigator",
|
||||
http://www.nga.mil/MSISiteContent/StaticFiles/NAV_PUBS/APN/pub9.zip
|
||||
For those that really really want to learn it all :)
|
||||
|
||||
RAF Mk9 bubble sextant manuals and more information
|
||||
http://www.users.bigpond.com/bgrobler/sextant/RAF_Mk9_manual.pdf
|
||||
http://www.users.bigpond.com/bgrobler/sextant/sextant.html
|
||||
http://www.physics.uq.edu.au/physics_museum/bblsex.html
|
||||
|
BIN
Aircraft/Instruments-3d/RAF_Mk9_bubble_sextant/degree_drum.png
Normal file
BIN
Aircraft/Instruments-3d/RAF_Mk9_bubble_sextant/degree_drum.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.8 KiB |
BIN
Aircraft/Instruments-3d/RAF_Mk9_bubble_sextant/leatherette.png
Normal file
BIN
Aircraft/Instruments-3d/RAF_Mk9_bubble_sextant/leatherette.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 61 KiB |
BIN
Aircraft/Instruments-3d/RAF_Mk9_bubble_sextant/minute_drum.png
Normal file
BIN
Aircraft/Instruments-3d/RAF_Mk9_bubble_sextant/minute_drum.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
Loading…
Add table
Reference in a new issue