Board index FlightGear Development Nasal

How to deal with exceptions in Nasal?

Nasal is the scripting language of FlightGear.

How to deal with exceptions in Nasal?

Postby eatdirt » Sun Feb 02, 2020 12:01 am

Hi there,
I've discovered Nasal last week for a little project and I needed to add some methods into geo.nas to calculate distances to great circles. That works, but I am trying to make it safe, and there is one error case I need to deal with, see below (TO BE FIXED). What are the standard way in nasal, and more precisely here, in geo.nas, to deal with exceptions/errors?

Thanks, and sorry for the rookie's question!
chris.


Code: Select all
# arc distance on an earth sphere to the great circle passing by A and B; doesn't consider altitude
   greatcircle_distance_to: func(destA, destB) {
      me._pupdate();
      destA._pupdate();
      destB._pupdate();

      # AB is not a circle but a point
      if (destA._lat == destB._lat and destA._lon == destB._lon)
          return me.distance_to(destA);

      # AB is undertermined; a great circle should be defined with non-collinear vectors
############################ TO BE FIXED #############################
      if (destA._lat == -destB._lat and destA._lon == math.pi - destB._lon) {
          return -1.0;
      }
###################################################################
      var ca1 = math.cos(destA._lon);
      var cd1 = math.cos(destA._lat);   
      var sa1 = math.sin(destA._lon);
      var sd1 = math.sin(destA._lat);   

      var ca2 = math.cos(destB._lon);
      var cd2 = math.cos(destB._lat);   
      var sa2 = math.sin(destB._lon);
      var sd2 = math.sin(destB._lat);   

      var sa12 = math.sin(destA._lon - destB._lon);
      
          var ca3 = math.cos(me._lon);
      var cd3 = math.cos(me._lat);   
      var sa3 = math.sin(me._lon);
      var sd3 = math.sin(me._lat);   

      # this is sin(greatcircle_dist) * sin(arcAB)
                var sDsAB = cd3 * sa3 * (ca2 * cd2 * sd1 - ca1 * cd1 * sd2 )
          + ca3 * cd3 * ( cd1 * sa1 * sd2 - cd2 * sa2 * sd1 )
          - cd1 * cd2 * sd3 * sa12;
      
      # direct calculation of sin(arcAB) to not call sin(arcsin(distance_to))   
      var a = math.sin((destA._lat - destB._lat) * 0.5);
      var o = math.sin((destA._lon - destB._lon) * 0.5);

      var hs12 = a * a + cd1 * cd2 * o * o;
      var hc12 = 1.0 - hs12;      
         
      return ERAD * math.abs( math.asin( 0.5 * sDsAB / math.sqrt( hs12 * hc12 ) ) );
   },
   # arc distance on an earth sphere to the horizon   
        horizon: func() {
           me._pupdate();
      return ERAD*math.acos(ERAD/(ERAD+me._alt));      
   },
eatdirt
 
Posts: 1012
Joined: Wed Aug 15, 2018 3:06 pm

Re: How to deal with exceptions in Nasal?

Postby Hooray » Sun Feb 02, 2020 9:34 am

Yes, you would explicitly call the corresponding function using the call() API while passing an empty vector for any error handling, once the call() completes you can check the size() of the previously empty vector to see if any errors occurred.

http://wiki.flightgear.org/index.php?ti ... call.28.29

Basically (untested, see the wiki article for working examples):
Code: Select all

var exception = func() {
die("oops ...");
}

var errors = [];
call(exception, [],nil,nil,errors);

if (size(errors)) {
foreach (var e; errors) {
 debug.dump(e);
 }
}

Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 12707
Joined: Tue Mar 25, 2008 9:40 am
Pronouns: THOU

Re: How to deal with exceptions in Nasal?

Postby eatdirt » Mon Feb 03, 2020 8:14 am

Thanks perfect. Your answer made me discover the function die()... It is all I need here, and then, the error can be caught the way you show.

Thanks,
Chris.
eatdirt
 
Posts: 1012
Joined: Wed Aug 15, 2018 3:06 pm


Return to Nasal

Who is online

Users browsing this forum: No registered users and 5 guests