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:
var 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");
}
}