Terrain Detection
In Flightgear 2017.2.1 a new Nasal method was introduced by Richard Harrison.
It works like geo.elevation but in a more general way such that one would define an arbitrary line and the method will return any terrain detection along that line.
Definition
get_cart_ground_intersection() returns where the given position in the specified direction will intersect with the ground. Returns whether or not a certain position and direction pair intersect with the ground, and if so the intersection point.
Useful for radars, terrain avoidance (GPWS), etc.
Input parameters: (geocentric coordinate system)
1. hash {"x","y","z"} position
2. hash {"x","y","z"} direction
Returns nil or geod hash {lat:deg,lon:deg,elevation:Meters} intersection
Time till impact with terrain
This example could be used in terrain detection systems that warn about impending collision with terrain.
if (getprop("velocities/speed-east-fps") != 0 or getprop("velocities/speed-north-fps") != 0) {
var start = geo.aircraft_position();
var speed_down_fps = getprop("velocities/speed-down-fps");
var speed_east_fps = getprop("velocities/speed-east-fps");
var speed_north_fps = getprop("velocities/speed-north-fps");
var speed_horz_fps = math.sqrt((speed_east_fps*speed_east_fps)+(speed_north_fps*speed_north_fps));
var speed_fps = math.sqrt((speed_horz_fps*speed_horz_fps)+(speed_down_fps*speed_down_fps));
var heading = 0;
if (speed_north_fps >= 0) {
heading -= math.acos(speed_east_fps/speed_horz_fps)*R2D - 90;
} else {
heading -= -math.acos(speed_east_fps/speed_horz_fps)*R2D - 90;
}
heading = geo.normdeg(heading);
var end = geo.Coord.new(start);
end.apply_course_distance(heading, speed_horz_fps*FT2M);
end.set_alt(end.alt()-speed_down_fps*FT2M);
var dir_x = end.x()-start.x();
var dir_y = end.y()-start.y();
var dir_z = end.z()-start.z();
var xyz = {"x":start.x(), "y":start.y(), "z":start.z()};
var dir = {"x":dir_x, "y":dir_y, "z":dir_z};
var geod = get_cart_ground_intersection(xyz, dir);
if (geod != nil) {
end.set_latlon(geod.lat, geod.lon, geod.elevation);
var dist = start.direct_distance_to(end)*M2FT;
var time = dist / speed_fps;
setprop("/sim/model/radar/time-until-impact", time);
} else {
setprop("/sim/model/radar/time-until-impact", -1);
}
}
Check for terrain between 2 aircraft
This example is typically for radar use.
var myPos = geo.aircraft_position();
var otherPos = geo.aircraft_position().apply_course_distance(100, 20000);# another plane 20 Km out, bearing (true) 100
# Check for terrain between own aircraft and other:
v = get_cart_ground_intersection({"x":myPos.x(), "y":myPos.y(), "z":myPos.z()}, {"x":otherPos.x()-myPos.x(), "y":otherPos.y()-myPos.y(), "z":otherPos.z()-myPos.z()});
if (v == nil) {
print("No terrain, planes has clear view of each other");
} else {
var terrain = geo.Coord.new();
terrain.set_latlon(v.lat,v.lon,v.elevation);
var maxDist = myPos.direct_distance_to(otherPos);
var terrainDist = myPos.direct_distance_to(terrain);
if (terrainDist < maxDist) {
print("terrain found between the planes");
} else {
print("The planes has clear view of each other");
}
}