Board index FlightGear Development Nasal

Any help? :)

Nasal is the scripting language of FlightGear.

Any help? :)

Postby legoboyvdlp » Tue Dec 08, 2015 7:22 pm

Code: Select all
<group>
      <layout>hbox</layout>
      
      <checkbox>
         <label>Pitot Tube Frozen</label>
         <binding>
            <command>nasal</command>
            <script>
            setprop("fbw/active-law", ALTERNATE LAW);
            setprop("instrumentation/airspeed-indicator/serviceable", false);
            setprop("flight-management/control/ap1-master", off);
            setprop("flight-management/control/ap2-master", off);
            setprop("flight-management/control/a-thrust", off);
            setprop("flight-management/control/fd", false);
            </script>
         </binding>
      </checkbox>
   </group>


I'm trying to model the effects of the Pitot Tube freezing in the Airbus A330 (alternate law, no airspeed, no autopilot, no autothrust, no flight director, no altitude). This is what I have so far.
The silly thing refuses to work.
It is simply an addition to an old file; not a new file.
Any ideas why it will not work?

Console output:
Code: Select all
Nasal parse error: parse error in /sim/bindings/gui/binding[6], line 2
Failed to execute command nasal
User avatar
legoboyvdlp
 
Posts: 7981
Joined: Sat Jul 26, 2014 2:28 am
Location: Northern Ireland
Callsign: G-LEGO
Version: next
OS: Windows 10 HP

Re: Any help? :)

Postby sanhozay » Tue Dec 08, 2015 9:02 pm

I don't know what ALTERNATE LAW is but it shouldn't have a space in it. Underscore perhaps? Where is it defined?
sanhozay
 
Posts: 1207
Joined: Thu Dec 26, 2013 12:57 pm
Location: EGNM
Callsign: G-SHOZ
Version: Git
OS: Ubuntu 16.04

Re: Any help? :)

Postby legoboyvdlp » Tue Dec 08, 2015 9:13 pm

ALTERNATE LAW does not have a space in it.
It is part of Airbus Fly By Wire and is defined in fbw.nas.

Code: Select all
##################################
## AIRBUS FLY-BY-WIRE SYSTEM    ##
##################################
## Written by Narendran and Jon ##
##################################

# FLIGHT CONTROL LAWS -
## Normal Law
## Alternate Law
## Abnormal Alternate Law
## Direct Law
## Mechanical Backup

# CONSTANTS

var RAD2DEG = 57.2957795;
var DEG2RAD = 0.0174532925;

# PATHS

var fcs = "/fdm/jsbsim/fcs/";
var input = "/controls/flight/";
var deg = "/orientation/";

var fbw_loop = {   
   init : func {
      me.UPDATE_INTERVAL = 0.001;
      me.loopid = 0;

      # fbw.reset();

      ## Initialize Control Surfaces

      setprop("/fdm/jsbsim/fcs/aileron-fbw-output", 0);
      setprop("/fdm/jsbsim/fcs/rudder-fbw-output", 0);
      setprop("/fdm/jsbsim/fcs/elevator-fbw-output", 0);
      
      ## Flight envelope

      setprop("/limits/fbw/max-bank-soft", '33' );
      setprop("/limits/fbw/max-bank-hard", '67' );   
      setprop("/limits/fbw/max-roll-speed", '0.261799387'); # max 0.261799387 rad_sec, 15 deg_sec
      setprop("/limits/fbw/alpha-prot", '19');
      setprop("/limits/fbw/alpha-floor", '25');
      setprop("/limits/fbw/alpha-max", '30');
      setprop("/limits/fbw/alpha-min", '-15');

      setprop("/fbw/pitch-limit",30);
      setprop("/fbw/bank-limit",33);
      setprop("/fbw/bank-manual", 67);
      
      setprop("/fbw/max-pitch-rate", 15);
      setprop("/fbw/max-roll-rate", 15);
      
      setprop("/fbw/active-law", "NORMAL LAW");
      setprop("/fbw/flight-phase", "Ground Mode");
      
      # This should be moved to 'failures.nas' but as I haven't written it yet, we'll just keep the systems working fine at all times. (0 - all working | 1 - moderate failures | 2 - major failures | 3 - elec/hyd failure)
      
      setprop("/systems/condition", 0);
            
      # Servo Control Modes (0 - direct | 1 - fbw)
      # Servo Protection Modes (0 - off | 1 - protect)
      # Servo Working (0 - not working/use mech backup | 1 - working)
      
      props.globals.initNode("/fbw/stable/elevator", 0);
      props.globals.initNode("/fbw/stable/aileron", 0);
      
      # The Stabilizer (Trimmers) are used to maintain pitch and/or bank angle when the control stick is brought to the center. The active fbw controls "try" to maintain 0 pitch-rate/roll-rate/1g but if by any chance (for example during turbulence) the attitude's changed, the stabilizer can get it back to the original attitude
      
      # Stabilizer works ONLY in NORMAL LAW Flight Mode

      me.reset();
   },  #Init Function end


   get_state : func{
      #me.law = "NORMAL LAW";
      me.condition = getprop("/systems/condition");
      me.pitch = getprop("/orientation/pitch-deg");
      me.bank = getprop("/orientation/roll-deg");
      me.phase = getprop("/fbw/flight-phase");
      me.agl = getprop("/position/altitude-agl-ft");

      me.law = getprop("/fbw/active-law");
      me.mode = getprop("/fbw/flight-phase");
      me.pitch_limit = getprop("/fbw/pitch-limit");
      me.bank_limit = getprop("/fbw/bank-limit");
      me.manual_bank = getprop("/fbw/bank-manual");
      
      me.stick_pitch = getprop(input~ "elevator");
      me.stick_roll = getprop(input~ "aileron");
        if(fmgc.fmgc_loop.alpha_floor_mode)
            me.pitch_limit = 0;

   },
   get_alpha_prot : func{
      if (me.pitch <=  me.alpha_min) return 'alpha_min';
      else if (me.pitch >= me.alpha_prot and me.pitch < me.alpha_floor) return 'alpha_prot';
      else if (me.pitch >= me.alpha_floor and me.pitch < me.alpha_max) return 'alpha_floor';
      else if (me.pitch >= me.alpha_max) return 'alpha_max';
   },

   #get_aircraft : func {

   #},
   airbus_law : func {

      # Decide which law to use according to system condition
      
      if (me.condition == 1)
         me.law = "ALTERNATE LAW";
      elsif (me.condition == 2)
         me.law = "DIRECT LAW";
      elsif (me.condition == 3)
         me.law = "MECH BACKUP";
         
      ## Check for abnormal attitude


      
      if ((me.pitch >= 60) or (me.pitch <= -30) or (math.abs(me.bank) >= 80))
         me.law = "ABNORMAL ALTERNATE LAW";
         
      setprop("/fbw/active-law", me.law);

   },
   flight_phase : func {

      # Find out the current flight phase (Ground/Flight/Flare)
      
            
      if (me.agl > 35)
         setprop("/fbw/flight-phase", "Flight Mode");
         
   #   if ((me.phase == "Flight Mode") and (me.agl <= 50))
   #      setprop("/fbw/flight-phase", "Flare Mode");
         
      if (getprop("/gear/gear/wow"))
         setprop("/fbw/flight-phase", "Ground Mode");

   },
   law_normal : func {
      # Protection
      
      if ((me.pitch > me.pitch_limit) or (me.pitch < -0.5 * me.pitch_limit) or (math.abs(me.bank) > me.bank_limit)) {
      
         setprop("/fbw/control/aileron", 0);
         setprop("/fbw/control/elevator", 0);
         
         setprop("/fbw/protect-mode", 1);
            setprop("/fbw/stable/elevator", 0);
            setprop("/fbw/stable/aileron", 0);
      
      } else {
      
            setprop("/fbw/protect-mode", 0);

         # Ground Mode
   
         if (me.mode == "Ground Mode") {
      
            setprop("/fbw/control/aileron", 0);
            setprop("/fbw/control/elevator", 0);
      
         # Flight Mode
      
         } elsif (me.mode == "Flight Mode") {
         
            setprop("/fbw/control/elevator", 1);
            setprop("/fbw/control/aileron", 1);
         
            if ((math.abs(me.stick_pitch) >= 0.02) or (me.mode == "Ground Mode") or (me.law != "NORMAL LAW") or (getprop("/flight-management/control/ap1-master") == "eng") or (getprop("/flight-management/control/ap2-master") == "eng")) {
            
               # setprop("/fbw/control/elevator", 1);
               setprop("/fbw/stable/elevator", 0);
            
            } else {
            
               if (getprop("/fbw/stable/elevator") != 1) {
               
                  setprop("/fbw/stable/pitch-deg", me.pitch);
                  
                  # setprop("/fbw/control/elevator", 0);
                  setprop("/fbw/stable/elevator", 1);
               
               }
               
            }
            
            if ((math.abs(me.stick_roll) >= 0.02) or (getprop("/flight-management/control/ap1-master") == "eng") or (getprop("/flight-management/control/ap2-master") == "eng")) {
            
               # setprop("/fbw/control/aileron", 1);
               setprop("/fbw/stable/aileron", 0);
               
            } else {
            
               if (getprop("/fbw/stable/aileron") == 0) {
               
                  setprop("/fbw/stable/bank-deg", me.bank);
                  
                  # setprop("/fbw/control/aileron", 0);
                  setprop("/fbw/stable/aileron", 1);
               
               }
                           
            }
         
         # Flare Mode
         
         } else {
         
            # STILL HAVE SOME WORK HERE. Atm, we'll just shift to direct control.
            
            setprop("/fbw/control/aileron", 0);
            setprop("/fbw/control/elevator", 0);
         
         }
      
      }
   },
   law_direct : func {
      setprop("/fbw/control/aileron", 0);
      setprop("/fbw/control/elevator", 0);
   },
   law_alternate : func {
      ## Flight Envelope Protection is NOT offered
   
      # Ground Mode
      if (me.mode == "Ground Mode") {
      
         setprop("/fbw/control/aileron", 0);
         setprop("/fbw/control/elevator", 0);

      # Flight Mode
      } elsif (me.mode == "Flight Mode") {
      
         # Load Factor Control if gears are retracted, else direct control
      
         if (getprop("controls/gear/gear-down")) {
      
            setprop("/fbw/control/aileron", 0);
            setprop("/fbw/control/elevator", 0);
         
         } else {
      
            setprop("/fbw/control/aileron", 1);
            setprop("/fbw/control/elevator", 1);
      
         }


      # Flare Mode
      } else {
      
         # STILL HAVE SOME WORK HERE. Atm, we'll just shift to direct control.
         
         setprop("/fbw/control/aileron", 0);
         setprop("/fbw/control/elevator", 0);
      }
   
   },
   law_abnormal_alternate : func {

      # Ground Mode
      if (me.mode == "Ground Mode") {
      
         setprop("/fbw/control/elevator", 0);
   

      # Flight Mode
      } elsif (me.mode == "Flight Mode") {
      
         # Load Factor Control if gears are retracted, else direct control
      
         if (getprop("controls/gear/gear-down")) {
      
            setprop("/fbw/control/elevator", 0);
         
         } else {
      
            setprop("/fbw/control/elevator", 1);
      
         }
      }
               
      setprop("/fbw/control/aileron", 0);
   },
   
   neutralize_trim : func(stab) {
   
      var trim_prop = "/controls/flight/" ~ stab ~ "-trim";
      
      var trim = getprop(trim_prop);
      
      if (trim > 0.005)
         setprop(trim_prop, trim - 0.01);
      elsif (trim < -0.005)
         setprop(trim_prop, trim + 0.01);
   
   },

   update : func {

      # Update vars from property tree
      me.get_state();

      # Decide which law to use according to system condition
      me.airbus_law();
      
      # Find out the current flight phase (Ground/Flight/Flare)
      me.flight_phase();

      # Bring Stabilizers to 0 gradually when stabilizer mode is turned off
                #print("FBW UPD");
      
      if ((getprop("/fbw/stable/elevator") != 1) and (me.mode == "Flight Mode") and (me.law == "NORMAL LAW"))
         me.neutralize_trim("elevator");
         
      if (getprop("/fbw/stable/aileron") != 1)
         me.neutralize_trim("aileron");

      ########################### PRECAUTIONS #############################

      # Reset Stabilizers when out of NORMAL LAW Flight Mode
      
      if ((me.law != "NORMAL LAW") or (me.mode != "Flight Mode")) {
      
         setprop("/controls/flight/aileron-trim", 0);
      
      }
      
      #if ((me.law != "NORMAL LAW") or (me.mode != "Flight Mode")) {
      
      #   setprop("/controls/flight/elevator-trim", 0);
      
      #}
      
      #####################################################################

      if (me.law == "NORMAL LAW") me.law_normal();
      elsif (me.law == "ALTERNATE LAW") me.law_alternate();
      elsif (me.law == "ABNORMAL ALTERNATE LAW") me.law_abnormal_alternate();
      elsif (me.law == "DIRECT LAW") law_direct();
      elsif (me.law == "MECHANICAL BACKUP") law_mechanical_backup();
            


      # Load Limit and Flight Envelope Protection
      if (getprop("/fbw/protect-mode")) {
      
          # PITCH AXIS
         
          if ((me.pitch > me.pitch_limit) and (me.stick_pitch <= 0)) {
         
             setprop("/fbw/target-pitch", me.pitch_limit);
            setprop("/fbw/pitch-hold", 1);
         
          } elsif ((me.pitch < -0.5 * me.pitch_limit) and (me.stick_pitch >= 0)) {
         
             setprop("/fbw/target-pitch", -0.5 * me.pitch_limit);
            setprop("/fbw/pitch-hold", 1);
         
          } else
             
             setprop("/fbw/pitch-hold", 0);
         
          # ROLL AXIS
         
          if ((me.stick_roll >= 0.5) and (me.bank > me.manual_bank)) {
         
             setprop("/fbw/target-bank", me.manual_bank);
            setprop("/fbw/bank-hold", 1);
         
          } elsif ((me.stick_roll <= -0.5) and (me.bank < -1 * me.manual_bank)) {
         
             setprop("/fbw/target-bank", -1 * me.manual_bank);
            setprop("/fbw/bank-hold", 1);
         
          } elsif ((me.stick_roll < 0.5) and (me.stick_roll >= 0) and (me.bank > me.bank_limit)) {
         
             setprop("/fbw/target-bank", me.bank_limit);
            setprop("/fbw/bank-hold", 1);
         
          } elsif ((me.stick_roll > -0.5) and (me.stick_roll <= 0) and (me.bank < -1 * me.bank_limit)) {
         
             setprop("/fbw/target-bank", -1 * me.bank_limit);
            setprop("/fbw/bank-hold", 1);
         
          } else
         
             setprop("/fbw/bank-hold", 0);
      
      } else {
            setprop("/fbw/pitch-hold", 0);
        }
      
#####################################################################

      # DIRECT Servo Control (just simple copying)
      
      if (getprop("/fbw/control/aileron") == 0)
            
         setprop("/fdm/jsbsim/fcs/aileron-fbw-output", getprop("/controls/flight/aileron"));
         
      if (getprop("/fbw/control/elevator") == 0)
      
         setprop("/fdm/jsbsim/fcs/elevator-fbw-output", getprop("/controls/flight/elevator"));
      
#####################################################################

      # FLY-BY-WIRE Servo Control

      # Convert Stick Position into target G-Force
      
      ## Pitch Rate Control
      
      me.pitch_gforce = (me.stick_pitch * -1.75) + 1;
      
      me.pitch_rate = (me.stick_pitch * -1 * getprop("/fbw/max-pitch-rate"));
      
      ## Roll Rate Control
      
      me.roll_rate = (me.stick_roll * getprop("/fbw/max-roll-rate"));
      
      ## Set G-forces to properties for xml to read
      
      setprop("/fbw/target-pitch-gforce", me.pitch_gforce);
      setprop("/fbw/target-roll-rate", me.roll_rate);
      setprop("/fbw/target-pitch-rate", me.pitch_rate);
      
      if (getprop("/fbw/control/elevator")) {
      
         # Load Factor over 210 kts
      
      # LOAD FACTOR COMMENTED OUT FOR TESTING
      #   
      #   if (getprop("/velocities/airspeed-kt") > 210) {
      #      
      #      setprop("/fbw/elevator/pitch-rate", 0);
      #      setprop("/fbw/elevator/load-factor", 1);
      #      
      #   } else {
      #   
            setprop("/fbw/elevator/pitch-rate", 1);
            setprop("/fbw/elevator/load-factor", 0);
         
      #   }
      
      }

   }, # Update Fuction end

   reset : func {
      me.loopid += 1;
      me._loop_(me.loopid);
   },

   _loop_ : func(id) {
      id == me.loopid or return;
      me.update();
      settimer(func { me._loop_(id); }, me.UPDATE_INTERVAL);
   }

};
###
# END fwb_loop var
###

fbw_loop.init();
print("Airbus Fly-by-wire Initialized");
User avatar
legoboyvdlp
 
Posts: 7981
Joined: Sat Jul 26, 2014 2:28 am
Location: Northern Ireland
Callsign: G-LEGO
Version: next
OS: Windows 10 HP

Re: Any help? :)

Postby sanhozay » Tue Dec 08, 2015 9:20 pm

Ah, ok. It needs double quotes around it. It's just a string rather than a variable.

Variables can't have spaces in their names. Strings are enclosed in quotes.
sanhozay
 
Posts: 1207
Joined: Thu Dec 26, 2013 12:57 pm
Location: EGNM
Callsign: G-SHOZ
Version: Git
OS: Ubuntu 16.04

Re: Any help? :)

Postby legoboyvdlp » Tue Dec 08, 2015 9:52 pm

Oh! Let me test :D
User avatar
legoboyvdlp
 
Posts: 7981
Joined: Sat Jul 26, 2014 2:28 am
Location: Northern Ireland
Callsign: G-LEGO
Version: next
OS: Windows 10 HP

Re: Any help? :)

Postby legoboyvdlp » Tue Dec 08, 2015 10:05 pm

Got her to go into ALTN LAW but did not like "false".... will try doing it in quotes too

Edit

Worked absolutely perfectly.


What I would like is for it to automatically freeze if pitot tube heating is OFF, TAT is below a certain level, and the air is humid (thus, condensation and icing).

Also, for the autopilot property to be checked once per second, and be turned back off, if turned on again. Currently, when turned back on again, it acts as normal.

Finally, a random failure of probe heating would be interesting.
User avatar
legoboyvdlp
 
Posts: 7981
Joined: Sat Jul 26, 2014 2:28 am
Location: Northern Ireland
Callsign: G-LEGO
Version: next
OS: Windows 10 HP

Re: Any help? :)

Postby sanhozay » Tue Dec 08, 2015 11:30 pm

legoboyvdlp wrote in Tue Dec 08, 2015 10:05 pm:What I would like is for it to automatically freeze if pitot tube heating is OFF, TAT is below a certain level, and the air is humid (thus, condensation and icing).

You'd need some sort of timed loop that gradually changes the temperature of the pitot tube based on the TAT. Things don't cool instantly, the heater doesn't thaw it instantly, and it thaws on it's own if the TAT gets above freezing. You'd probably capture the ambient temperature when the engine starts, use that as the start temperature of the tube and move it up and down based on TAT. When it goes below freezing, you need another timed loop for ice build up.

There must be examples around - I think Torsten's Seneca II has a pitot icing simulation for example.
sanhozay
 
Posts: 1207
Joined: Thu Dec 26, 2013 12:57 pm
Location: EGNM
Callsign: G-SHOZ
Version: Git
OS: Ubuntu 16.04

Re: Any help? :)

Postby legoboyvdlp » Tue Dec 08, 2015 11:32 pm

Alright.
I'll take a look at his code.

By the way, Torsten, hope you don't mind me using it!
User avatar
legoboyvdlp
 
Posts: 7981
Joined: Sat Jul 26, 2014 2:28 am
Location: Northern Ireland
Callsign: G-LEGO
Version: next
OS: Windows 10 HP

Re: Any help? :)

Postby legoboyvdlp » Tue Dec 15, 2015 3:18 pm

'nother little question:

Any idea why this gives 'illegal character line 2' message in the console?

Code: Select all
<binding>
            <command>nasal</command>
            <script>
               if (var condition = (getprop ("failures/pitot-tube-frozen”) == “true” and getprop("controls/anti-ice/pitot-heat”) == "true")); {
               setprop("fbw/active-law", "NORMAL LAW");
               setprop("instrumentation/airspeed-indicator/serviceable", 1);
               setprop("instrumentation/altimiter/serviceable", 1);
               setprop("flight-management/control/ap1-master", "off");
               setprop("flight-management/control/ap2-master", "off");
               setprop("flight-management/control/a-thrust", "off");
               setprop("flight-management/control/fd", 1);
               setprop("instrumentation/altimeter/serviceable", 1);
               print("No Ice Detected");
               screen.log.write("Ice Removed! Turn on AutoFlight Systems.", 0, 0.584, 1);
               } else {
               print("Unable to unfreeze Pitot Heat
               }
            </script>
         </binding>
User avatar
legoboyvdlp
 
Posts: 7981
Joined: Sat Jul 26, 2014 2:28 am
Location: Northern Ireland
Callsign: G-LEGO
Version: next
OS: Windows 10 HP

Re: Any help? :)

Postby Philosopher » Tue Dec 15, 2015 3:26 pm

See these?
Code: Select all
“true”

There are curly quotes – good for your papers for school, bad for code ;)
There's four of them I can spot. Just replace them with straight quotes, like so:
Code: Select all
"true"


P.S. You need to finish this statement too ;):
Code: Select all
               print("Unable to unfreeze Pitot Heat
Philosopher
 
Posts: 1593
Joined: Sun Aug 12, 2012 7:29 pm

Re: Any help? :)

Postby legoboyvdlp » Tue Dec 15, 2015 3:33 pm

Thanks! Ha!
Righto, I'll do that.
(Oops!)
And I managed -- at last -- to get it to work. Silly me; I forgot that when I'm turning something on, [i]it is not on yet![i/] Of course "controls/anti-ice/pitot-heat" is not going to show on when off...

Thank's for replying :)
User avatar
legoboyvdlp
 
Posts: 7981
Joined: Sat Jul 26, 2014 2:28 am
Location: Northern Ireland
Callsign: G-LEGO
Version: next
OS: Windows 10 HP

Re: Any help? :)

Postby Thorsten » Tue Dec 15, 2015 4:53 pm

Dependent on how much detail you want... the Space Shuttle has a pretty detailed simulation of the thermal environment.

It's based on a network of connected thermal masses with heat transfer links, radiative heat transfer and sources/sinks and solves real physics - which means it gives you realistic heating and cooling curves when you switch on thermal sources or sinks. For instance, if you switch on one APU, you'll sooner or later see the temperature also increase in the other APU sensors because the running APU acts as a heat source for the whole aft fuselage and heat slowly diffuses through it.

The code is a fairly generic physics solver, agnostic of the particulars - you just define elements and links with their sources and sinks and let it run.

Admittedly it's a slight overkill to determine freezing of a single element - but you may or may not need more.
Thorsten
 
Posts: 12490
Joined: Mon Nov 02, 2009 9:33 am

Re: Any help? :)

Postby legoboyvdlp » Tue Dec 15, 2015 5:24 pm

Oh. My. So. Much. Detail.
That Space Shuttle is one amazing bird.
No, I don't think the Airbus needs so much detail... but thanks anyway :)
User avatar
legoboyvdlp
 
Posts: 7981
Joined: Sat Jul 26, 2014 2:28 am
Location: Northern Ireland
Callsign: G-LEGO
Version: next
OS: Windows 10 HP

Re: Any help? :)

Postby Octal450 » Wed Apr 27, 2016 4:39 am

@legoboyvdlp, do you still need help on this?

Regards,
Skillset: JSBsim Flight Dynamics, Systems, Canvas, Autoflight/Control, Instrumentation, Animations
Aircraft: A320-family, MD-11, MD-80, Contribs in a few others

Octal450's GitHub|Launcher Catalog
|Airbus Dev Discord|Octal450 Hangar Dev Discord
User avatar
Octal450
 
Posts: 5583
Joined: Tue Oct 06, 2015 1:51 pm
Location: Huntsville, AL
Callsign: WTF411
Version: next
OS: Windows 11

Re: Any help? :)

Postby legoboyvdlp » Wed Apr 27, 2016 1:43 pm

Well, no -- as far as I know it is all present in branch 'dev' of the A330 :)
User avatar
legoboyvdlp
 
Posts: 7981
Joined: Sat Jul 26, 2014 2:28 am
Location: Northern Ireland
Callsign: G-LEGO
Version: next
OS: Windows 10 HP


Return to Nasal

Who is online

Users browsing this forum: No registered users and 2 guests

cron