Nasal Help

14 Dec 2020 09:47 - 14 Dec 2020 10:53 #49210 by ScottBouch
Hi guys,

Can someone please cast their eye over this attached Nasal script and tell me where I'm going wrong?

It does not generate the root /hydraulics branch in the property tree, and has a parse error at the actual script part. All I have done is copy methods form other scripts, I mush have introduced a mistake, but can't spot it.

The actual functional script is very early days (please almost ignore it), I really just need help in getting the basics working of generating the branch of the property tree and some properties, and I can go from there.

This is for the FGUK Lightning currently on GitLab, I've been debugging a little over the last few months (so there are some recent updates), and thought it was about time to model the hydraulic systems.

Many thanks, Scott.
Attachments:

Please Log in or Create an account to join the conversation.

14 Dec 2020 10:59 #49211 by ScottBouch
SCRAP that.. I commented out all ofmy half scripting, and the basics now work!

Turned out that a parse error further down the script caused the initial basics to break.

I now have the hydraulics systems and properties in the property tree! Hooray!

Now to figure out how to correctly script it...

Please Log in or Create an account to join the conversation.

14 Dec 2020 11:04 #49212 by ScottBouch
Ok, why does this throw a parse error?

I'm just trying to set two local variables "engine1_rpm" and "engine 2_rpm" to contain the same data as the global rpm's. This is because I'll be using the rpm's a few times in my code.
var main_loop = func {
	var engine1_rpm.setValue(props.globals.getValue("/engines/engine/rpm"));
	var engine2_rpm.setValue(props.globals.getValue("/engines/engine[1]/rpm"));
}

Please Log in or Create an account to join the conversation.

14 Dec 2020 13:06 #49213 by Warty
Maybe try something like this?
# It is assumed the aircraft last flew / ran a few hours ago, and retains minimum services pressure to operate canopy and wheelbrakes only.

var hydraulics_loop = func { # Main Loop

	var engine1_rpm = getprop("/engines/engine/rpm");
	var engine2_rpm = getprop("/engines/engine[1]/rpm");

	# Generate a pressure following engine %rpm
	var serv_pump1_press_psi_raw = engine1_rpm * (3000/100);

	# Clamp to low limit of 1700psi
	if (serv_pump1_press_psi_raw > 1700) {
		serv_pump1_press_psi_raw = 1700 ;
	}
	# then do something, like ... .
	setprop("/hydraulics/services/serv_pump1_press_psi", serv_pump1_press_psi_raw);
	setprop("/hydraulics/services/serv_pump2_press_psi", serv_pump1_press_psi_raw);

	settimer(hydraulics_loop, update_period);
}

setlistener("/sim/signals/fdm-initialized", func { # ====================== initialization

	# Settings & Defaults
	var update_period = 0.25;			# Loop Frequency

	# Services pumps:
	setprop("/hydraulics/services/serv_pump1_press_psi", 0);
	setprop("/hydraulics/services/serv_pump2_press_psi", 0);

	# Controls pumps:
	setprop("/hydraulics/controls/cont_pump1_press_psi", 0);
	setprop("/hydraulics/controls/cont_pump2_press_psi", 0);

	# Controls pumps pressure switches:
	setprop("/hydraulics/controls/cont_pump1_low_pressure_switch", 0);
	setprop("/hydraulics/controls/cont_pump2_low_pressure_switch", 0); # switches only exist on the controls side

	# Services pressure, common to both pumps:
	setprop("/hydraulics/services/serv_press_psi", 0);

	# Wheelbrake pressure (downstream of NRV):
	setprop("/hydraulics/services/wheelbrake_press_psi", 1700);
	
	hydraulics_loop();
	
})

Mac 10.14.1 Mojave, FG 2020.4.0

Please Log in or Create an account to join the conversation.

14 Dec 2020 15:00 - 14 Dec 2020 16:17 #49214 by ScottBouch
Thank you so much for that help, I'd not use getprop before.

so, it worked in that I could generate the properties and set values, thank you.

I have corrected a few other errors, but I have one question now, I need to declare a variable, and have done so as just:
var serv_pumps_hss_press_psi;
But it's throwing another parse error at this line, I have not set it to equal anything, this may be the issue, but I want to IF statement to set it's value..

var main_loop = func {

# Engine speeds:
	var engine1_rpm = getprop("/engines/engine/rpm");
	var engine2_rpm = getprop("/engines/engine[1]/rpm");


# Services:
	# Generate a pressure following engine %rpm
	var serv_pump1_press_raw_psi = engine1_rpm * (3000/100);
	var serv_pump2_press_raw_psi = engine2_rpm * (3000/100);
	var serv_pumps_hss_press_psi;

	# Rail pressure = highest pump pressure
	if (serv_pump1_press_raw_psi >= serv_pump2_press_raw_psi) {
	serv_pumps_hss_press_psi = serv_pump1_press_raw_psi ;
	}
	if (serv_pump2_press_raw_psi > serv_pump1_press_raw_psi) {
	serv_rail_hss_press_psi = serv_pump2_press_raw_psi ;
	}

	setprop("/hydraulics/services/serv_pump1_press_psi", serv_pump1_press_raw_psi);
	setprop("/hydraulics/services/serv_pump2_press_psi", serv_pump2_press_raw_psi);
	setprop("/hydraulics/services/wheelbrake_press_psi", serv_rail_hss_press_psi);
}

(HSS = High Signal Select).

Thank you, Scott.

Please Log in or Create an account to join the conversation.

14 Dec 2020 16:22 #49215 by Warty
Yes, assign a value when you declare it - even if it is only . . .

var serv_pumps_hss_press_psi = 0 ;
if(....){ serv_pumps_hss_press_psi = 10; }

etc

Mac 10.14.1 Mojave, FG 2020.4.0

Please Log in or Create an account to join the conversation.

15 Dec 2020 14:38 #49216 by ScottBouch
Excellent advice, thank you again.

One question though - this var is now being assigned a value of 0, and then whatever sensible value the IF statement changes it to as the programme progresses...

As both of these assignments are within the main loop, why does the value not get set to zero, then the IF value each time the loop is run? ie: how does Nasal know to ignore the initial "var serv_pumps_hss_press_psi = 0 ;" after the first iteration?

Cheers, Scott.

Please Log in or Create an account to join the conversation.

15 Dec 2020 15:12 #49218 by timi
Usually one would place a definition like that outside the loop
so it would have no effect when the loop starts executing. I
don't do much Nasal but that's what I'd do in other types of
scripting.

Please Log in or Create an account to join the conversation.

15 Dec 2020 16:52 #49219 by Warty
In my defence, I was answering the question of whether a var needed to be assigned a value on declaration. The etc kind of meant "deal with all eventualities" B)
Maybe something like this:
var serv_pumps_hss_press_psi =  serv_pump2_press_raw_psi ;
if (serv_pump1_press_raw_psi >= serv_pump2_press_raw_psi){
	serv_pumps_hss_press_psi =  serv_pump1_press_raw_psi 
}
etc :) ;)

Yes, it could be declared outside of any functions in the body of hydraulics.nas just once and could then be changed by any function. If that is what you want. If you want other functions to have access to it that would certainly be preferable. Also, if you want it to "hold" its value until you want to change it for some reason.

But if you are only using it in this loop then there might be some advantage in confining it to this function - so you won't inadvertently change it in another call as the code gets bigger. A classic example of where you could get in a real mess with if it is available to all functions is the
for (var i = 0; i < 2; i += 1)
type construct.

Also, self contained things are more portable. I'm not saying either way is better/preferable. They are just options - your choice.

I think that "as the programme progresses..." is maybe a bit misleading. hydraulics_loop is a little programme that executes, in this case, every 250ms. When it's done it's done. Any vars declared and manipulated within it die at the closing } to be born again 250ms later.

Just a suggestion: maybe don't call things "main_loop" as you could end up with so many of them you can't tell which is which.

Mac 10.14.1 Mojave, FG 2020.4.0

Please Log in or Create an account to join the conversation.

15 Dec 2020 17:45 #49220 by eagle12
For me these are hieroglyphs. I didn't know that you are archaeologists.
How are you Nefertiti ?

Please Log in or Create an account to join the conversation.

15 Dec 2020 17:58 #49221 by ScottBouch
Thank you for these tips...

I like your explanations on how to think about how a program treats variables. I wish I'd studied C or similar in the past just to get more familiar with general programming, which is why I'm doing these project, to learn... as such most of what I'm doing so far is just copying ideas form other scripts, and a relying on a little teaching a friend once gave to me. This help you gave today certainly is useful to building my confidence with programming, thank you.

I had previously been taught it's good practice to keep as many variables within the function as possible, and only to make them"global" if needed for sharing between functions, so had been sticking with what I was taught.

With the hydraulics I had not split it up into separate functions as it's not that complex a system, and also there's no need to call separate parts under different circumstances, so I just stuck it all into one main function in it's own hydraulics .nas file. However, calling the loops more specific names could be helpful as you have suggested, I may do that.

I can't see this script being copied to another aircraft simply because no two aircraft are the same, so wasn't thinking about portability.

I now have a functioning Nasal script and have completed 50% of the hydraulic systems, the rest should be easier now I've got this far, ie: I can copy / paste a lot of what's now done and working. It's now comitted to the FGUK GitLab Lightning.

I have a Lightning wheelbrake pressure indicator on my desk that is working correctly now, driven by this script, via my Arduino, good to get another original indicator working!

Thanks again, Scott.

Please Log in or Create an account to join the conversation.

15 Dec 2020 18:18 #49222 by timi
A function is just a combination of things that
can be done with one call. Or that's how I see
it anyway. And a function can include a loop
for repetitive things.

So the function can still have local variables
which are not in the loop.

Please Log in or Create an account to join the conversation.

16 Dec 2020 20:24 #49226 by sanni
@Warty:

I don't know the internals of Nasal, but
/engines/engine[]
is an array.

That means that
/engines/engine
and
/engines/engine[1]
are the same variable!!?!

Please Log in or Create an account to join the conversation.

16 Dec 2020 20:45 - 16 Dec 2020 21:35 #49227 by Warty
Nasal is a bit different :)
/engines/engine
is a shortcut for
/engines/engine[0]
.. the first engine (very often the only engine).
In my own stuff, I try to use the second "[0]" version

Mac 10.14.1 Mojave, FG 2020.4.0
The following user(s) said Thank You: sanni

Please Log in or Create an account to join the conversation.

Time to create page: 0.474 seconds
Powered by Kunena Forum

Latest Forum Posts

PM Notifications

You are not logged in.

PM Mailbox

You are not logged in.