Terrain Detection

From FlightGear wiki
Jump to navigation Jump to search

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.


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);

      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();
 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");