2013-12-01 20:47:42 +00:00
# == walking functions v4.3 for FlightGear version 1.9-2.0 OSG ==
# == plus coordinates for Bluebird Explorer Hovercraft 10.4 ==
# aircraft specific section:
var hatch_specs = {
z_opening_ft: 6.0,
z_floor_ft: 0, # z-axis offset for walker exit from aircraft origin
# generally floor z-axis converted to ft.
rear_hatch_loc: 5,
out_locations: func (loc) {
if (loc == 0) { # exit but not by hatch
2013-12-09 17:55:38 +00:00
# get default exit coordinates from set file
var defx = getprop ("sim/model/map/default_exit/x-offset-m");
var defy = getprop ("sim/model/map/default_exit/y-offset-m");
# if no exit is specified in set file, start at 0,0
if (defx == nil ) {
defx =0;
}
if (defy == nil ) {
defy =0;
}
var new_coord = xy2LatLonZ(defx,defy);
2013-12-01 20:47:42 +00:00
} elsif (loc == 1) {
var new_coord = xy2LatLonZ(getprop("sim/model/bluebird/crew/walker/x-offset-m"),-4.9);
} elsif (loc == 2) {
var new_coord = xy2LatLonZ(getprop("sim/model/bluebird/crew/walker/x-offset-m"),4.9);
} elsif (loc == 5) {
var new_coord = xy2LatLonZ(11.0,getprop("sim/model/bluebird/crew/walker/y-offset-m"));
} else {
var new_coord = xy2LatLonZ(xViewNode.getValue(),yViewNode.getValue());
}
return new_coord;
}
};
# end aircraft specific
var sin = func(a) { math.sin(a * math.pi / 180.0) } # degrees
var cos = func(a) { math.cos(a * math.pi / 180.0) }
var asin = func(y) { math.atan2(y, math.sqrt(1-y*y)) } # radians
var ERAD = 6378138.12; # Earth radius (m)
var ERAD_deg = 180 / (ERAD * math.pi);
var DEG2RAD = math.pi / 180;
var xViewNode = props.globals.getNode("sim/current-view/z-offset-m", 1);
var yViewNode = props.globals.getNode("sim/current-view/x-offset-m", 1);
var zViewNode = props.globals.getNode("sim/current-view/y-offset-m", 1);
var fps_node = props.globals.getNode("sim/frame-rate", 1);
var falling = 0; # 0/1 = false/true
var last_altitude = 0; # remember last position to detect falling from ground
var exit_time_sec = 0.0;
var parachute_ft = 0.0;
var parachute_deployed_sec = 0.0;
var elapsed_chute_sec = 0.0;
var lat_vector = 0.0;
var lon_vector = 0.0;
var z_vector_mps = 0.0;
var time_to_top_sec = 0.0;
var starting_lat = 0.0;
var starting_lon = 0.0;
var walk_heading = 0;
var walk_watch = 0;
var walk_factor = 1.0;
# debug section
var measure_main_count = 0;
var measure_walk_count = 0; # momentum_walk loops
var measure_extmov_count = 0;
var measure_sec = 0;
var measure_alt = 0;
var last_elapsed_sec = 0;
# ===== functions ======
var normheading = func (a) {
while (a >= 360)
a -= 360;
while (a < 0)
a += 360;
return a;
}
var distFromCraft = func (lat,lon) {
var c_lat = getprop("position/latitude-deg");
var c_lon = getprop("position/longitude-deg");
var a = sin((lat - c_lat) * 0.5);
var b = sin((lon - c_lon) * 0.5);
return 2.0 * ERAD * asin(math.sqrt(a * a + cos(lat) * cos(c_lat) * b * b));
}
var xy2LatLonZ = func (x,y) {
# given the x,y offsets of the cockpit view when walking (in meters)
# or the hatch location upon exit
# translate into lat,lon,z-offset-m for transfer to outside walker
var c_head_rad = getprop("orientation/heading-deg") * DEG2RAD;
var c_lat = getprop("position/latitude-deg");
var c_lon = getprop("position/longitude-deg");
# var c_gnd_pitch = getprop("orientation/ground-pitch");
var c_pitch = getprop("orientation/pitch-deg");
var c_roll = getprop("orientation/roll-deg");
var xZ_factor = math.cos(c_pitch * DEG2RAD);
var x_Zadjust = x * xZ_factor; # adjusted for pitch
var y_Zadjust = y * math.cos(c_roll * DEG2RAD); # adjusted for roll
# print(sprintf("W.xy2 x= %10.6f xZ= %10.6f y= %10.6f yZ= %10.6f",x,x_Zadjust,y,y_Zadjust));
var xy_hyp = math.sqrt((x_Zadjust * x_Zadjust) + (y_Zadjust * y_Zadjust));
var a = (xy_hyp == 0 ? 0 : asin(y_Zadjust / xy_hyp));
if (x > 0) {
a = math.pi - a;
}
var xy_head_rad = c_head_rad + a;
# print(sprintf ("W.xy2 c_head= %6.2f a= %6.2f xy_head= %6.2f",(c_head_rad*180/math.pi),(a*180/math.pi),(xy_head_rad*180/math.pi)));
var xy_lat_m = xy_hyp * math.cos(xy_head_rad);
var xy_lon_m = xy_hyp * math.sin(xy_head_rad);
# print(sprintf ("W.xy2 x= %9.8f y= %9.8f xy_lat_m= %9.8f xy_lon_m= %9.8f",x_Zadjust,y_Zadjust,xy_lat_m,xy_lon_m));
var xy_lat = xy_lat_m * ERAD_deg;
var xy_lon = xy_lon_m * ERAD_deg / cos(c_lat);
# print(sprintf ("W.xy2 position/lat= %9.8f lon= %9.8f xy_lat= %9.8f xy_lon= %9.8f",c_lat,c_lon,xy_lat,xy_lon));
var zxZ_m = -(x * math.sin(c_pitch * DEG2RAD));
var zyZ_m = -(y * math.sin(c_roll * DEG2RAD) * xZ_factor); # goes to zero as pitch to 90
# MARK-pre-10.4: not Perfect yet: z of hatch and height of walker (1.67m) is not adjusted for at angle.
# print (sprintf ("W.xy2 zxZ= %10.6f zyZ= %10.6f z= %10.6f",zxZ_m,zyZ_m,(zxZ_m + zyZ_m)));
return [(c_lat + xy_lat) , (c_lon + xy_lon) , (zxZ_m + zyZ_m)];
}
var calc_heading = func {
var w_forward = getprop("sim/walker/key-triggers/forward");
var w_left = getprop("sim/walker/key-triggers/slide");
var new_head = -999;
var new_walking = 0;
if (w_forward > 0) {
new_walking = 1;
if (w_left < 0) {
new_head = 45;
} elsif (w_left > 0) {
new_head = -45;
} else {
new_head = 0;
}
} elsif (w_forward < 0) {
new_walking = -1;
if (w_left < 0) {
new_head = 135;
} elsif (w_left > 0) {
new_head = -135;
} else {
new_head = 180;
}
} else {
if (w_left < 0) {
new_walking = 4;
new_head = 90;
} elsif (w_left > 0) {
new_walking = 6;
new_head = -90;
} else {
setprop ("sim/walker/walking", 0);
return 0;
}
}
walk_heading = new_head;
setprop ("sim/walker/walking", new_walking);
}
var momentum_walk = func {
measure_walk_count += 1;
if (walk_watch >= 3) {
if (walk_factor < 2.0) { # speed up when holding down key
walk_factor += 0.025;
}
setprop ("sim/walker/walking-momentum", 1);
} elsif (walk_watch >= 2) {
setprop ("sim/walker/walking-momentum", 1);
walk_watch -= 1;
} else {
walk_factor = ((walk_factor - 1.0) * 0.5) + 1.0;
if (walk_factor < 1.1) {
walk_factor = 1.0;
walk_watch = 0;
} else {
setprop ("sim/walker/walking-momentum", 1);
}
}
if (walk_watch) {
settimer(momentum_walk,0.05);
} else {
setprop ("sim/walker/walking-momentum", 0);
}
}
var main_loop = func {
measure_main_count += 1;
var c_view = getprop ("sim/current-view/view-number");
var moved = 0;
if (c_view == 0 and getprop("sim/walker/walking-momentum")) {
# inside aircraft
# bluebird.walk_about_cabin(0.1, walk_heading);
moved = 1;
}
if (getprop("sim/walker/outside")) {
if (falling or getprop("sim/walker/walking-momentum")) {
ext_mov(moved);
}
# check for proximity to hatches for entry after 0.75 sec.
var elapsed_sec = getprop("sim/time/elapsed-sec");
var elapsed_fall_sec = elapsed_sec - exit_time_sec;
if (elapsed_fall_sec > 0.75) {
if (abs(getprop("sim/walker/altitude-ft") - getprop("position/altitude-ft") + hatch_specs.z_opening_ft) < 7) {
# must be within (opening) ft vertically to climb in
var posy = getprop("sim/walker/latitude-deg");
var posx = getprop("sim/walker/longitude-deg");
# the following section is aircraft specific for locations of entry hatches and doors
# if (getprop("sim/model/bluebird/doors/door[0]/position-norm") > 0.73) {
# var door0_ll = xy2LatLonZ(-2.6,-3.42);
# var a0 = sin((door0_ll[0] - posy) * 0.5);
# var b0 = sin((door0_ll[1] - posx) * 0.5);
# doesn't actually check z-axis, mis-alignments in rare orientations
# var d0 = 2.0 * ERAD * asin(math.sqrt(a0 * a0 + cos(door0_ll[0]) * cos(posy) * b0 * b0));
# if (d0 < 1.2) {
# get_in(1);
# }
# }
# if (getprop("sim/model/bluebird/doors/door[1]/position-norm") > 0.73) {
# var door1_ll = xy2LatLonZ(-2.6,3.42);
# var a1 = sin((door1_ll[0] - posy) * 0.5);
# var b1 = sin((door1_ll[1] - posx) * 0.5);
# var d1 = 2.0 * ERAD * asin(math.sqrt(a1 * a1 + cos(door1_ll[0]) * cos(posy) * b1 * b1));
# if (d1 < 1.2) {
# get_in(2);
# }
# }
# if (getprop("sim/model/bluebird/doors/door[5]/position-norm") > 0.78) {
# var door5_ll = xy2LatLonZ(9.0,0);
# var a5 = sin((door5_ll[0] - posy) * 0.5);
# var b5 = sin((door5_ll[1] - posx) * 0.5);
# var d5 = 2.0 * ERAD * asin(math.sqrt(a5 * a5 + cos(door5_ll[0]) * cos(posy) * b5 * b5));
# if (d5 < 1.9) {
# get_in(5);
# }
# }
# end aircraft specific
}
}
} elsif (!moved and getprop("sim/walker/walking-momentum")) {
# bluebird.walk_about_cabin(0.1, walk_heading);
}
if (getprop("logging/walker-debug") and getprop("sim/walker/outside")) {
var elapsed_sec = getprop("sim/time/elapsed-sec");
var t = elapsed_sec - measure_sec;
if (t >= 0.991) {
var posz1 = getprop("sim/walker/altitude-ft");
print(sprintf("========= at %6.2f : %3i %3i %3i : Z-axis %6.2f ft / %6.4f sec = %6.2f mps",elapsed_sec,measure_main_count,measure_walk_count,measure_extmov_count,(measure_alt-posz1),t,((measure_alt-posz1)*0.3028/t)));
measure_alt = posz1;
measure_sec = elapsed_sec;
measure_main_count = 0;
measure_walk_count = 0;
measure_extmov_count = 0;
}
}
settimer(main_loop, 0.01)
}
2014-04-26 17:29:16 +00:00
var walker_model = {
index: 0,
add: func {
if (getprop("sim/model/crew/walker/visible")) {
if (getprop("logging/walker-position")) {
print("walker_model.add");
}
var manager = props.globals.getNode("/models", 1);
var i = 0;
for (; 1; i += 1)
if (manager.getChild("model", i, 0) == nil)
break;
props.globals.getNode("models/model[" ~ i ~ "]/path", 1);
props.globals.getNode("models/model[" ~ i ~ "]/longitude-deg-prop", 1);
props.globals.getNode("models/model[" ~ i ~ "]/latitude-deg-prop", 1);
props.globals.getNode("models/model[" ~ i ~ "]/elevation-ft-prop", 1);
props.globals.getNode("models/model[" ~ i ~ "]/heading-deg-prop", 1);
setprop ("models/model[" ~ i ~ "]/path", "Aircraft/Generic/Human/Models/walker.xml");
setprop ("models/model[" ~ i ~ "]/longitude-deg-prop", "sim/walker/longitude-deg");
setprop ("models/model[" ~ i ~ "]/latitude-deg-prop", "sim/walker/latitude-deg");
setprop ("models/model[" ~ i ~ "]/elevation-ft-prop", "sim/walker/altitude-ft");
setprop ("models/model[" ~ i ~ "]/heading-deg-prop", "sim/walker/model-heading-deg");
props.globals.getNode("models/model[" ~ i ~ "]/load", 1);
me.index = i;
}
},
remove: func {
if (getprop("logging/walker-position")) {
print("walker_model.remove");
}
props.globals.getNode("/models", 1).removeChild("model", me.index);
walker_model.reset_fall();
},
2013-12-01 20:47:42 +00:00
reset_fall: func {
falling = 0;
walk_factor = 1.0;
setprop("sim/walker/airborne", 0);
setprop("sim/walker/parachute-opened-altitude-ft", 0);
parachute_deployed_sec = 0;
setprop("sim/walker/parachute-opened-sec", 0);
setprop("sim/walker/starting-trajectory-lat", 0.0);
setprop("sim/walker/starting-trajectory-lon", 0.0);
setprop("sim/walker/starting-trajectory-z-mps", 0.0);
setprop("sim/walker/time-to-zero-z-sec", 0.0);
},
land: func (lon,lat,alt) {
walker_model.reset_fall();
setprop("sim/walker/latitude-deg", lat);
setprop("sim/walker/longitude-deg", lon);
setprop("sim/walker/altitude-ft", alt);
last_altitude = alt;
},
};
var open_chute = func {
if (getprop("sim/walker/airborne") and exit_time_sec and !parachute_ft and getprop("sim/walker/parachute-equipped")) {
setprop("sim/walker/parachute-opened-altitude-ft", getprop("sim/walker/altitude-ft"));
parachute_deployed_sec = getprop("sim/time/elapsed-sec");
setprop("sim/walker/parachute-opened-sec", 0);
}
}
setlistener("sim/walker/walking", func(n) {
var wdir = n.getValue();
if (wdir) { # repetitive input or bug in mod-up keeps triggering
walk_dir = wdir; # remember current direction
if (walk_watch == 0) {
walk_watch = 3; # start or reset timer for countdown
momentum_walk(); # starting from rest, start new loop
} else {
walk_watch = 3; # reset watcher
}
} else {
# last heard was zero
walk_watch -= 1;
if (walk_watch < 0) {
walk_watch = 0;
}
}
});
setlistener("sim/walker/key-triggers/outside-toggle", func {
var c_view = getprop ("sim/current-view/view-number");
if (c_view == 0) {
if (getprop("sim/walker/outside")) {
setprop("sim/current-view/view-number", view.indexof("Walk View"));
} else {
get_out(0);
}
} elsif (c_view == view.indexof("Walk View")) {
get_in(0);
} else {
if (getprop("sim/walker/outside")) {
get_in(0);
} else {
get_out(0);
}
}
});
var ext_mov = func (moved) {
measure_extmov_count += 1;
var c_view = getprop("sim/current-view/view-number");
if (c_view == view.indexof("Walker Orbit View")) {
var head_v = 360 - getprop("sim/walker/model-heading-deg");
} else {
var head_v = getprop("sim/current-view/heading-offset-deg");
}
var c_head_deg = getprop("orientation/heading-deg");
var posy1 = getprop("sim/walker/latitude-deg");
var posx1 = getprop("sim/walker/longitude-deg");
var posz1 = getprop("sim/walker/altitude-ft");
var posx2 = posx1; # new after calculations
var posy2 = posy1;
var posz2 = posz1;
var check_movement = 1;
var fps = fps_node.getValue();
fps = (fps < 10 ? 10 : fps); # only realistic above 10fps. Slow down below that so that walker pauses instead of jumping.
var speed = getprop("sim/walker/key-triggers/speed") * walk_factor / fps;
if (c_view >= 1 and c_view <=3) {
head_v = normheading(360 - c_head_deg + head_v);
} elsif (c_view == 5) {
head_v = normheading(c_head_deg + head_v + 90);
}
var head_w = normheading(head_v + walk_heading);
if (!moved) {
setprop("sim/walker/model-heading-deg" , 360 - head_v);
}
var elapsed_sec = getprop("sim/time/elapsed-sec");
if (falling) {
var elapsed_fall_sec = elapsed_sec - exit_time_sec;
if (elapsed_fall_sec > 0.1) {
check_movement = 0;
}
}
if (check_movement and !moved) {
var lat_m = speed * cos(head_w);
var lon_m = speed * sin(head_w);
var lat3 = lat_m * ERAD_deg;
var lon3 = lon_m * ERAD_deg / cos(posy1);
posx2 = posx1 - lon3; # heading is offset or reversed west to east
2013-12-16 20:12:30 +00:00
# if (posy1 < 0 ) {
# posy2 = posy1 + lat3;
# print (" South");
# } else {
# posy2 = posy1 + lat3;
# print (" North");
# }
posy2 = posy1 + lat3;
# posy2 = (posy1 < 0 ? posy1 - lat3 : posy1 + lat3);
2013-12-01 20:47:42 +00:00
# southern or northern hemisphere
}
if (falling) { # add movement from aircraft upon jumping
var parabola = 0;
var parachute_drag = 0;
var zero_xy_sec = (elapsed_fall_sec < 10 ? elapsed_fall_sec : 10.0);
if (parachute_ft) { # chute open
setprop("sim/walker/parachute-opened-sec", (elapsed_sec - parachute_deployed_sec - 1.0));
# chute starts to add drag at 1 second, fully open at 3 sec. Slows to 17 ft/sec
if (elapsed_chute_sec >= 3.0) {
parachute_drag = 0.9;
} elsif (elapsed_chute_sec >= 0.0) { # 1 second delay for chute to deploy
parachute_drag = sin(elapsed_chute_sec * 30) * 0.9; # 0 to 0.9 in 3 sec.
}
}
if (parachute_drag) {
zero_xy_sec = parachute_deployed_sec - exit_time_sec + 1.0;
if (zero_xy_sec > 10.0) {
zero_xy_sec = 10.0;
}
}
parabola = sin(90 - zero_xy_sec ) * zero_xy_sec - (0.096 * zero_xy_sec * zero_xy_sec / 2);
if (parachute_drag and zero_xy_sec < 7) {
posy2 = starting_lat + (lat_vector * parabola) + (lat_vector * parachute_drag);
posx2 = starting_lon + (lon_vector * parabola) + (lon_vector * parachute_drag);
} else {
posy2 = starting_lat + (lat_vector * parabola);
posx2 = starting_lon + (lon_vector * parabola);
}
}
var posz_geo = geo.elevation(posy2, posx2, ((posz1 * 0.3048) + 2));
if (posz_geo == nil) {
posz_geo = geo.elevation(posy2, posx2); # underground? try without current walker altitude
if (posz_geo == nil) {
posz_geo = 0;
print(sprintf("Error. Attempting to move to latitude %13.8f longitude %13.8f",posy2,posx2));
}
}
posz_geo = posz_geo / 0.3048; # convert to ft
# if (getprop("logging/walker-debug")) {
# print(sprintf("walker_lat= , %9.8f , lon= , %9.8f , groundDistanceFromAircraft= , %6.3f , geo.elev= , %8.3f , altitude= , %8.3f",posy2,posx2,distFromCraft(posy2,posx2),posz_geo,posz2));
# }
if (falling) { # 13,000 to 12,000 ft = 10 sec. 12,000 - 4,000 = 44 sec.
# 5.5 sec to cover each 1000 ft at terminal velocity (ignoring altitude density and surface area)
var dist_traveled_z = 0; # feet
if (posz_geo < posz1) { # ground is below walker
dist_traveled_z = -32.185 * time_to_top_sec * time_to_top_sec / 2; # upward half of arc
var elapsed1 = elapsed_fall_sec - time_to_top_sec;
# excludes wind resistance and cross section of projectile. Assume negligible for now.
if (elapsed_fall_sec > time_to_top_sec) { # past zero_z and falling
# drag constant is actually 0.515 kg/s for spread eagle, and 0.067 for feet first.
# I am ignoring these distinctions for now, until a more complex formula can be made,
# to go along with the new walker model visibility.
# also needs to be improved is loss of acceleration due to drag forces
if (elapsed_fall_sec > (time_to_top_sec + 5.358)) { # time to reach terminal velocity
dist_traveled_z += 461.99 + ((elapsed1 - 5.358) * 172);
} else { # 9.81m/s/s up to terminal velocity 172ft/s 54m/s spread eagle
dist_traveled_z += 32.185 * elapsed1 * elapsed1 / 2;
}
} else { # started going up, arch to zero_z before falling
dist_traveled_z += 32.185 * elapsed1 * elapsed1 / 2;
if (getprop("logging/walker-debug")) {
print(sprintf("time_to_top_sec= %6.2f elapsed1= %6.2f dist_traveled_z_ft = %8.3f z_vector_mps= %6.2f exit_alt= %9.3f posz1= %9.3f posz2= %9.3f" , time_to_top_sec,elapsed1,dist_traveled_z,z_vector_mps,getprop("sim/walker/altitude-at-exit-ft"),posz1,(getprop("sim/walker/altitude-at-exit-ft")-posz1)));
}
}
if (parachute_ft) { # chute open
# need to better model deceleration due to opening of chute, change in surface area.
var subtract_z = 0;
if (elapsed_chute_sec >= 5.0) {
subtract_z = 363.14 + ((elapsed_chute_sec - 5.0) * 155);
} elsif (elapsed_chute_sec >= 2.0) {
subtract_z = 32.15 * parachute_drag * elapsed_chute_sec * elapsed_chute_sec / 2;
} elsif (elapsed_chute_sec >= 0.0) {
subtract_z = 32.15 * parachute_drag * elapsed_chute_sec * elapsed_chute_sec / 2;
}
dist_traveled_z -= subtract_z;
}
posz2 = getprop("sim/walker/altitude-at-exit-ft") - dist_traveled_z;
if (posz2 < posz_geo) { # below ground
if ((parachute_drag < 0.7) and (dist_traveled_z > 20)) {
print(sprintf("OUCH! You fell %9.2f ft from an exit at %10.2f ft. Parachute was Not deployed.",dist_traveled_z,getprop("sim/walker/altitude-at-exit-ft")));
if (getprop("sim/current-view/view-number") == view.indexof("Walk View")) {
setprop("sim/current-view/pitch-offset-deg", -80);
}
setprop("sim/model/bluebird/position/landing-wow", 1);
setprop("sim/walker/crashed", 1);
setprop("sim/walker/airborne", 0);
}
posz2 = posz_geo;
walker_model.land(posx2,posy2,posz_geo);
} else {
if (getprop("logging/walker-position")) {
print(sprintf("falling_lat= %11.8f lon= %13.8f altitude= %9.2f elapsed_fall_sec= %5.2f speed_ft/s= %7.2f chute_drag= %4.2f",posy2,posx2,posz1,elapsed_fall_sec,((measure_alt-posz2)/(elapsed_sec - last_elapsed_sec)),parachute_drag));
measure_alt = posz2;
last_elapsed_sec = elapsed_sec;
}
}
} else {
walker_model.land(posx2,posy2,posz_geo);
posz2 = posz_geo;
}
} else { # not falling
# check for sudden change in ground elevation
if ((abs(posz1 - last_altitude) > 1.6) or ((posz_geo + 1.6) < posz1)) {
setprop("sim/walker/time-of-exit-sec", getprop("sim/time/elapsed-sec"));
setprop("sim/walker/altitude-at-exit-ft", last_altitude);
# add "forward" momentum upon step out and down
var lat_m = getprop("sim/walker/key-triggers/speed") * walk_factor * cos(head_w);
var lon_m = getprop("sim/walker/key-triggers/speed") * walk_factor * (0 - sin(head_w));
var lat3 = lat_m * ERAD_deg;
var lon3 = lon_m * ERAD_deg / cos(posy1);
posy3 = posy1 + lat3;
posx3 = posx1 + lon3;
setprop("sim/walker/starting-trajectory-lat", lat3);
setprop("sim/walker/starting-trajectory-lon", lon3);
setprop("sim/walker/starting-lat", posy2);
setprop("sim/walker/starting-lon", posx2);
setprop("sim/walker/latitude-deg", posy3);
setprop("sim/walker/longitude-deg", posx3);
setprop("sim/walker/starting-trajectory-z-mps", 0.0);
falling = 1;
if ((posz1 - posz_geo) > 50) {
setprop("sim/walker/airborne", 1);
setprop("sim/walker/parachute-equipped", 0);
}
}
if (!falling) {
if (posz_geo < (posz1 + 5)) { # walking, ground within 10 ft below walker
var posz3_geo = geo.elevation(posy2, posx2, ((posz1 * 0.3048) + 2));
if (posz3_geo == nil) {
posz3_geo = 0;
}
posz3_geo = posz3_geo / 0.3048; # convert to ft
var posz_geodiff = abs(posz_geo - posz1);
if ((posz3_geo - posz_geo) > 1.5 and posz_geodiff < 7 and posz_geodiff > 1.5) { # under object and nearly hitting head
print(sprintf ("Stopped by overhead obstruction, has height %6.2f ft above your position.", posz_geodiff));
posx2 -= (5 * (posx2 - posx1));
posy2 -= (5 * (posy2 - posy1)); # fall backward and reload ground level
posz_geo = geo.elevation(posy2, posx2, ((posz1 * 0.3048) + 1));
if (posz_geo == nil) {
posz_geo = 0;
}
posz_geo = posz_geo / 0.3048; # convert to ft
}
if ((posz1+0.3) > posz_geo or (posz1-0.3) < posz_geo) { # smoothen stride
interpolate ("sim/walker/altitude-ft", posz_geo, 0.25, 0.3);
posz2 = getprop("sim/walker/altitude-ft");
}
if (getprop("logging/walker-position")) {
print(sprintf("walker_lat= %12.8f lon= %11.8f altitude= %9.2f heading= %6.2f speed= %4.2f walk_factor= %4.2f groundDistanceFromAircraft= %3.2f geo.elev= %8.3f",posy2,posx2,posz2,head_v,speed,walk_factor,distFromCraft(posy2,posx2),posz_geo));
}
} else {
print(sprintf ("Stopped by wall, has height %6.2f ft above your position.",(posz1-posz_geo)));
posx2 -= (5 * (posx2 - posx1));
posy2 -= (5 * (posy2 - posy1));
}
}
}
setprop("sim/walker/latitude-deg", posy2);
setprop("sim/walker/longitude-deg", posx2);
last_altitude = posz2;
setprop("sim/walker/altitude-ft", posz2);
}
setlistener("sim/current-view/heading-offset-deg", func(n) {
var c_view = getprop("sim/current-view/view-number");
if (c_view == 0) {
var head_v = n.getValue();
setprop("sim/model/bluebird/crew/walker/head-offset-deg" , head_v);
} elsif (c_view == view.indexof("Walk View")) {
var head_v = n.getValue();
setprop("sim/walker/model-heading-deg" , 360 - head_v);
# } elsif (c_view == view.indexof("Walker Orbit View")) {
# var head_v = getprop("sim/current-view/heading-offset-deg");
}
});
var get_out = func (loc) {
var c_view = getprop("sim/current-view/view-number");
var head_add = 0;
if (c_view == 0) { # remember point of exit
setprop("sim/walker/keep-inside-offset-x", getprop("sim/current-view/x-offset-m"));
setprop("sim/walker/keep-inside-offset-y", getprop("sim/current-view/y-offset-m"));
setprop("sim/walker/keep-inside-offset-z", getprop("sim/current-view/z-offset-m"));
setprop("sim/walker/keep-pitch-offset-deg", getprop("sim/current-view/pitch-offset-deg"));
setprop("sim/view[110]/enabled",1);
setprop("sim/view[111]/enabled",1);
head_add = getprop("sim/current-view/heading-offset-deg");
}
var c_airspeed_mps = getprop("velocities/airspeed-kt") * 0.51444444;
var walk_dir = getprop("sim/walker/walking");
if (walk_dir and loc == hatch_specs.rear_hatch_loc) {
if (c_airspeed_mps > 0) {
c_airspeed_mps -= 1; # add momentum toward rear
} else {
c_airspeed_mps += 1;
}
}
var c_head_deg = getprop("orientation/heading-deg");
var c_pitch = getprop("orientation/pitch-deg");
# for powered ejections, add to the next line the rocket thrust
var c_z_vector_mps = sin(c_pitch) * c_airspeed_mps;
# x and y are in meters, but z axis needs to be in feet once it enters altitude calculations
setprop("sim/walker/starting-trajectory-z-mps", c_z_vector_mps);
if (c_airspeed_mps < 0) {
c_airspeed_mps = abs(c_airspeed_mps);
c_head_deg = normheading(c_head_deg + 180);
}
var c_head_rad = c_head_deg * 0.01745329252;
var c_lat = getprop("position/latitude-deg");
var c_lon = getprop("position/longitude-deg");
var xy_Z_factor = math.cos(c_pitch * 0.01745329252); # factor to zero when pitch = +- 90
var xy_lat_m = c_airspeed_mps * math.cos(c_head_rad) * xy_Z_factor;
var xy_lon_m = c_airspeed_mps * math.sin(c_head_rad) * xy_Z_factor;
var xy_lat = xy_lat_m * ERAD_deg;
var xy_lon = xy_lon_m * ERAD_deg / cos(c_lat);
setprop("sim/walker/starting-trajectory-lat", xy_lat);
setprop("sim/walker/starting-trajectory-lon", xy_lon);
var c_time0z_sec = math.sqrt(c_z_vector_mps * c_z_vector_mps / 9.81 / 9.81); # time to top of arc
if (c_z_vector_mps < 0) { # going down
c_time0z_sec = 0 - c_time0z_sec;
}
setprop("sim/walker/time-to-zero-z-sec", c_time0z_sec);
if (getprop("logging/walker-debug")) {
print(sprintf("get_out: traj-lat= %12.8f traj-lon= %12.8f c_z_vector_mps= %12.8f",xy_lat,xy_lon,c_z_vector_mps));
}
var new_coord = hatch_specs.out_locations(loc);
var head = normheading(abs(getprop("orientation/heading-deg") -360.00) + head_add);
setprop("sim/walker/latitude-deg" , (getprop("position/latitude-deg")));
setprop("sim/walker/longitude-deg" , (getprop("position/longitude-deg")));
setprop("sim/walker/roll-deg" , (getprop("orientation/roll-deg")));
setprop("sim/walker/pitch-deg" , (getprop("orientation/pitch-deg")));
setprop("sim/walker/heading-deg" , (getprop("orientation/heading-deg")));
# setprop("sim/view[100]/enabled", 1);
# setprop("sim/view[101]/enabled", 1);
var posy = new_coord[0];
var posx = new_coord[1];
var posz_ft = new_coord[2] * globals.M2FT;
setprop("sim/walker/outside", 1);
if (c_view == 0) {
setprop("sim/current-view/view-number", view.indexof("Walk View"));
setprop("sim/current-view/pitch-offset-deg", getprop("sim/walker/keep-pitch-offset-deg"));
setprop("sim/current-view/roll-offset-deg", 0);
setprop("sim/current-view/heading-offset-deg", head);
}
setprop("sim/walker/heading-deg", 0);
setprop("sim/walker/roll-deg", 0);
setprop("sim/walker/pitch-deg", 0);
setprop("sim/walker/latitude-deg", new_coord[0]);
setprop("sim/walker/longitude-deg", new_coord[1]);
falling = 1;
setprop("sim/walker/time-of-exit-sec", getprop("sim/time/elapsed-sec"));
var alt1 = getprop("position/altitude-ft") + posz_ft + hatch_specs.z_floor_ft;
setprop("sim/walker/altitude-at-exit-ft", alt1);
setprop("sim/walker/altitude-ft" , alt1);
measure_alt = alt1;
if ((alt1 - getprop("position/ground-elev-ft")) > 20) {
setprop("sim/walker/airborne", 1);
setprop("sim/walker/parachute-equipped", 1);
}
setprop("sim/walker/starting-lat", new_coord[0]);
setprop("sim/walker/starting-lon", new_coord[1]);
walk_factor = 1.0;
walker_model.add();
}
var get_in = func (loc) {
walker_model.remove();
# var c_view = getprop("sim/current-view/view-number");
# the following section is aircraft specific for locations of entry hatches and doors
# var new_pos = 4;
# var c_pos = getprop("sim/model/bluebird/crew/cockpit-position");
# if (c_view > 0) {
# if (loc == 0) { # find open hatch
# loc = 1;
# setprop("sim/model/bluebird/crew/cockpit-position", 4);
# c_pos = 5;
# } elsif (getprop("sim/model/bluebird/doors/door[1]/position-norm") > 0.2) {
# loc = 2;
# setprop("sim/model/bluebird/crew/cockpit-position", 4);
# c_pos = 5;
# } elsif (getprop("sim/model/bluebird/doors/door[5]/position-norm") > 0.2) {
# loc = 5;
# setprop("sim/model/bluebird/crew/cockpit-position", 4);
# c_pos = 5;
# }
# }
# if (loc >= 1) {
# if (c_pos == 5) {
# var new_walker_x = (loc == 1 ? -2.55 : (loc == 2 ? -2.55 : 10.0));
# var new_walker_y = (loc == 1 ? -2.8 : (loc == 2 ? 2.8 : 0));
# } else {
# if (loc == 1) {
# var new_walker_x = -2.55;
# var new_walker_y = -1.9;
# } elsif (loc == 2) {
# var new_walker_x = -2.55;
# var new_walker_y = 1.9;
# } else {
# var new_walker_x = getprop("sim/model/bluebird/crew/walker/x-offset-m");
# var new_walker_y = getprop("sim/model/bluebird/crew/walker/y-offset-m");
# if (new_walker_x < 9) {
# new_walker_x = 10.4;
# }
# if (new_walker_y < -1.6) {
# new_walker_y = -1.6;
# } elsif (new_walker_y > 1.6) {
# new_walker_y = 1.6;
# }
# }
# }
# var c_head_deg = getprop("orientation/heading-deg");
# c_pos = 5;
# var new_walker_h = normheading(getprop("sim/current-view/heading-offset-deg") + c_head_deg);
# } else {
# var new_walker_x = bluebird.cockpit_locations[c_pos].x;
# var new_walker_y = bluebird.cockpit_locations[c_pos].y;
# var new_walker_h = bluebird.cockpit_locations[c_pos].h;
# }
# var new_walker_z = bluebird.cockpit_locations[c_pos].z[0];
# var new_walker_p = bluebird.cockpit_locations[c_pos].p;
# var new_walker_fov = bluebird.cockpit_locations[c_pos].fov;
# end aircraft specific
# if (c_view == view.indexof("Walk View")) {
# setprop("sim/current-view/view-number", 0);
# setprop("sim/current-view/z-offset-m", new_walker_x);
# setprop("sim/current-view/x-offset-m", new_walker_y);
# setprop("sim/current-view/y-offset-m", new_walker_z);
# setprop("sim/current-view/goal-heading-offset-deg", new_walker_h);
# setprop("sim/current-view/heading-offset-deg", new_walker_h);
# setprop("sim/current-view/goal-pitch-offset-deg", new_walker_p);
# setprop("sim/current-view/pitch-offset-deg", new_walker_p);
# setprop("sim/current-view/field-of-view", new_walker_fov);
# }
# setprop("sim/model/bluebird/crew/walker/x-offset-m", new_walker_x);
# setprop("sim/model/bluebird/crew/walker/y-offset-m", new_walker_y);
#}
setprop("sim/current-view/view-number", 0);
setprop("sim/walker/crashed", 0);
setprop("sim/walker/airborne", 0);
setprop("sim/walker/outside", 0);
setprop("sim/walker/parachute-opened-altitude-ft", 0);
parachute_deployed_sec = 0;
setprop("sim/walker/parachute-opened-sec", 0);
setprop("sim/view[110]/enabled", 0);
setprop("sim/view[111]/enabled", 0);
}
var reinit_walker = func {
setprop("sim/walker/outside", 0);
setprop("sim/view[100]/enabled",0);
setprop("sim/view[101]/enabled",0);
setprop("sim/walker/crashed", 0);
setprop("sim/walker/airborne", 0);
falling = 0;
walk_factor = 1.0;
setprop("sim/walker/parachute-opened-altitude-ft", 0);
parachute_deployed_sec = 0;
setprop("sim/walker/parachute-opened-sec", 0);
2015-08-10 08:12:09 +00:00
#setprop("sim/walker/key-triggers/outside-toggle",1);
2013-12-16 20:12:30 +00:00
walker_model.remove();
2013-12-01 20:47:42 +00:00
}
var init_common = func {
setlistener("sim/walker/time-of-exit-sec", func(n) exit_time_sec = n.getValue());
setlistener("sim/walker/parachute-opened-altitude-ft", func(n) parachute_ft = n.getValue());
setlistener("sim/walker/parachute-opened-sec", func(n) elapsed_chute_sec = n.getValue());
setlistener("sim/walker/starting-trajectory-lat", func(n) lat_vector = n.getValue());
setlistener("sim/walker/starting-trajectory-lon", func(n) lon_vector = n.getValue());
setlistener("sim/walker/starting-trajectory-z-mps", func(n) z_vector_mps = n.getValue());
setlistener("sim/walker/time-to-zero-z-sec", func(n) time_to_top_sec = n.getValue());
setlistener("sim/walker/starting-lat", func(n) starting_lat = n.getValue());
setlistener("sim/walker/starting-lon", func(n) starting_lon = n.getValue());
setlistener("sim/walker/key-triggers/forward", func {
calc_heading();
});
setlistener("sim/walker/key-triggers/slide", func {
calc_heading();
});
setlistener("sim/model/bluebird/crew/walker/visible", func(n) {
if (n.getValue()) {
if (getprop("sim/walker/outside")) {
walker_model.add();
}
} else {
walker_model.remove();
}
});
setlistener("sim/current-view/view-number", func(n) {
if (n.getValue() == view.indexof("Walk View")) {
yViewNode.setValue(0);
zViewNode.setValue(1.67); # matches person height when inside due to aircraft offsets
xViewNode.setValue(0);
}
});
setlistener("sim/signals/reinit", func {
reinit_walker();
});
setlistener("sim/signals/fdm-initialized", func {
reinit_walker();
});
}
settimer(init_common,0);
var theme_dialog = gui.OverlaySelector.new("Select Theme", "Aircraft/Generic/Human/Models/Themes", "sim/walker/theme-name", nil, "sim/multiplay/generic/string[10]");
2014-04-26 17:29:16 +00:00
var equip_dialog = gui.OverlaySelector.new("Select Equipment", "Aircraft/Generic/Human/Models/equipment/Themes", "sim/walker/equipment-name", nil, "sim/multiplay/generic/string[11]");
2013-12-01 20:47:42 +00:00