Project Lua Script Helicopters!

Can anyone tell me where this variable "G0" comes from?
Is it the acceleration of gravity?

C++:
local set_feature = {}

function set_feature.set_contact_points()

    local travel = 0.1
    local stiffness_value = ((empty_mass+main_fuel_tank_max)*G0)/travel
 
Can anyone tell me where this variable "G0" comes from?
Is it the acceleration of gravity?

C++:
local set_feature = {}

function set_feature.set_contact_points()

    local travel = 0.1
    local stiffness_value = ((empty_mass+main_fuel_tank_max)*G0)/travel
It's a global constant available from Orbiter.

 
It would be better to add Lua support to UACS instead of having to port a vessel to C++ to be able to do so.
I've had a look at UACS but the architecture looks incompatible because Cargo/Astronauts derive from VESSEL4 and you cannot dynamically add a base class to an existing object in C++.
 
So it is possible to take the LUa script and replace the mesh? and make it work as a new vessel? I know the animations will not work. But not sure how to do that.
 
Thankyou @Thunder Chicken for the introduction to LUA! Slowly getting to grips with your code. Have resolved most issues;)
Haven't been able to solve the extern light savestate issue though.
The new R4 floats very well, very smooth transition! Testing so far the new code seems more stable, no engine errors on reloading?
Got pretty much everything working, also added strobes, animated flight sticks. Trying to figure an autohover? and then maybe sound support.
Basic (WIP) cocpit:
0009.jpg
But I'm still unsure about engine specs/flight model:
Wasn't sure how to adjust for two blades so I reduced the prop_area from 0.25 to 0.15.
I take it max_air_flow is in kg/s, in which case stats say it should be 1.5, I've reduced to 0.5 and it still seems overpowered?

Beta with sources attached for assessment.

Now I understand/appreciate your pushing for more lua support. No dependencies, no compiling (@ anyone who's been struggling with a C++ compiler stuff you've got almost complete access to the Orbiter API with instant feedback with LUA).
Haven't had this much fun since programming in Basic!:)
 

Attachments

Thankyou @Thunder Chicken for the introduction to LUA! Slowly getting to grips with your code. Have resolved most issues;)
Haven't been able to solve the extern light savestate issue though.

But I'm still unsure about engine specs/flight model:
Wasn't sure how to adjust for two blades so I reduced the prop_area from 0.25 to 0.15.
It's an actuator disk model for the rotors, there is no accounting for any number of blades. You should use the actual rotor area as there are other things that can cause problems with the thrust. If you attempt to put the engine power into a smaller area of air flow the thrust could very well be too high because of this.
I take it max_air_flow is in kg/s, in which case stats say it should be 1.5, I've reduced to 0.5 and it still seems overpowered?
Set this to the spec value, same with the rotor diameter. I have modeled several vessels with these engines and propellers and if you use accurate inputs you will get good results.
Now I understand/appreciate your pushing for more lua support. No dependencies, no compiling (@ anyone who's been struggling with a C++ compiler stuff you've got almost complete access to the Orbiter API with instant feedback with LUA).
Haven't had this much fun since programming in Basic!:)
I like that aspect too, that I can just tweak a line of code, save it, restart Orbiter, and test that code in seconds. It really lets you rapidly iterate improvements. You don't have to recompile a module every time you want to tweak your code. You can pick it up for a few minutes and do minor little improvements here and there and test them as you go.

I use VS Code with a Lua language extension and that works pretty nicely for catching syntax errors. I just save the workspaces for my various projects in a folder on my desktop for easy access.
 
Last edited:
I have another question:
In the engine_spec table, there is no field named "rp."

I'm referring primarily to the function:

Code:
function get_engine.brayton_efficiency(engine_spec)


local rp = engine_spec.rp

local k = 1.2 --specific heat ratio for air (can tweak based on engine size to account for heat losses)


local efficiency = 1 - (1/((rp)^((k-1)/k))) -- Brayton cycle efficiency


return efficiency


end

Does the function refer to r = 5.20?

Code:
engine_spec =


 {

 r = 5.20, --compression ratio

 rc = 1, --cut-off ratio, 1 for Otto cycle, >1 for Diesel

 displacement = 6.82e-3, --engine displacement in cubic meters

 max_rpm = 2050, --maximum engine speed (rpm)

 min_rpm = 750, --idle engine speed (rpm)

 n_stroke = 4, --2 if 2-stroke, 4 if 4-stroke

 HV = 43e6, --lower heating value of fuel (J/kg) (~43 MJ/kg for typical liquid fuels)

 AF = 14.6, --air fuel ratio (mass air/mass fuel) (stochiometric ~14.6:1 for typical liquid fuels)

 }
 
I have another question:
In the engine_spec table, there is no field named "rp."

I'm referring primarily to the function:

Code:
function get_engine.brayton_efficiency(engine_spec)


local rp = engine_spec.rp

local k = 1.2 --specific heat ratio for air (can tweak based on engine size to account for heat losses)


local efficiency = 1 - (1/((rp)^((k-1)/k))) -- Brayton cycle efficiency


return efficiency


end
The Brayton cycle is a model of a gas turbine engine like used on the Bell 206. That engine type has different parameters from reciprocating gasoline and Diesel engines. I think I left examples of these in the module get_engine.lua. If not, this is what you need to provide for gas turbine engines (with correct values, of course):

Code:
-- sample_gas_turbine_engine_spec =
-- {
--     rp = 20,                --pressure ratio
--     max_rpm = 3600,         --maximum engine speed (rpm)
--     min_rpm = 1000,         --idle engine speed (rpm)
--     max_air_flow = 69.4,    --mass air flow at max rpm
--     HV = 43e6,              --lower heating value of fuel (J/kg) (~43 MJ/kg for typical liquid fuels)
--     AF = 77.1               --air fuel ratio (mass air/mass fuel) (stochiometric ~14.6:1 for typical liquid fuels)
-- }

The heating value HV and air/fuel ration AF should be OK for most gas turbine engines, but the remaining parameters are important

Does the function refer to r = 5.20?
No. r is the compression ratio for reciprocating engines. rp is the pressure ratio for a gas turbine engine. Different specs for different types of engine.
Code:
engine_spec =


 {

 r = 5.20, --compression ratio

 rc = 1, --cut-off ratio, 1 for Otto cycle, >1 for Diesel

 displacement = 6.82e-3, --engine displacement in cubic meters

 max_rpm = 2050, --maximum engine speed (rpm)

 min_rpm = 750, --idle engine speed (rpm)

 n_stroke = 4, --2 if 2-stroke, 4 if 4-stroke

 HV = 43e6, --lower heating value of fuel (J/kg) (~43 MJ/kg for typical liquid fuels)

 AF = 14.6, --air fuel ratio (mass air/mass fuel) (stochiometric ~14.6:1 for typical liquid fuels)

 }
You don't want to use this engine spec table as it was created for the R-4 which had a reciprocating gasoline engine. Use the spec table for gas turbines.
 
The Brayton cycle is a model of a gas turbine engine like used on the Bell 206. That engine type has different parameters from reciprocating gasoline and Diesel engines. I think I left examples of these in the module get_engine.lua. If not, this is what you need to provide for gas turbine engines (with correct values, of course):

Code:
-- sample_gas_turbine_engine_spec =
-- {
--     rp = 20,                --pressure ratio
--     max_rpm = 3600,         --maximum engine speed (rpm)
--     min_rpm = 1000,         --idle engine speed (rpm)
--     max_air_flow = 69.4,    --mass air flow at max rpm
--     HV = 43e6,              --lower heating value of fuel (J/kg) (~43 MJ/kg for typical liquid fuels)
--     AF = 77.1               --air fuel ratio (mass air/mass fuel) (stochiometric ~14.6:1 for typical liquid fuels)
-- }

The heating value HV and air/fuel ration AF should be OK for most gas turbine engines, but the remaining parameters are important


No. r is the compression ratio for reciprocating engines. rp is the pressure ratio for a gas turbine engine. Different specs for different types of engine.

You don't want to use this engine spec table as it was created for the R-4 which had a reciprocating gasoline engine. Use the spec table for gas turbines.
Thank you very much.
By the way, your code is incredibly detailed. It's a work of art.
 
It's an actuator disk model for the rotors, there is no accounting for any number of blades. You should use the actual rotor area as there are other things that can cause problems with the thrust. If you attempt to put the engine power into a smaller area of air flow the thrust could very well be too high because of this.
Set this to the spec value, same with the rotor diameter. I have modeled several vessels with these engines and propellers and if you use accurate inputs you will get good results.
Ok, good to know what to mess with;)
Only changed the stats after unexpected results, maybe I'm missing something major? Although the engine and flight model work great, just a little more overpowered than expected?
I use VS Code with a Lua language extension and that works pretty nicely for catching syntax errors. I just save the workspaces for my various projects in a folder on my desktop for easy access.
Thanks for the tip, I'm using Notepad++ currently.

I've resolved the engine error on reload bug, it's persistant in the latest iteration of the R4 too. To reproduce the error just start a default .scn, start the engines (still ground contact), close Orbiter and then reload.
The engine code has an "else" that should cover it but it throws a null value? Declaring "power = 0" at the beginning of the main code solves the problem.

@Matias Saibene There is a "no fuel" bug in the gas turbine code, the other engine has the correct code, I copied over/updated the engine file. see attach. above.

Also fuel consumption seems high? I'll add a low fuel indicater. Console update:0010.jpg
 
Ok, good to know what to mess with;)
Only changed the stats after unexpected results, maybe I'm missing something major? Although the engine and flight model work great, just a little more overpowered than expected?
Don't confuse feels with reals. Modern turboshaft engine helicopter engines have a lot more power than the old R-4. The Warner engine in the R-4 gave 165 hp, the turboshaft engine on the Bell 206 is about 250 hp. The Bell 222 is downright scary powerful with two engines with a combined 1200 hp.

You can check the power output of the engine in horsepower if you put the following in your code in clbk_prestep() after the engine module is called:

Code:
oapi.dbg_out(string.format("%.1f hp", power/745.7))

Put the engine to full power and see how much power you have, and compare that to the actual Bell 206 engine maximum power. They should agree within about 10%.

Thanks for the tip, I'm using Notepad++ currently.

I've resolved the engine error on reload bug, it's persistant in the latest iteration of the R4 too. To reproduce the error just start a default .scn, start the engines (still ground contact), close Orbiter and then reload.
The engine code has an "else" that should cover it but it throws a null value? Declaring "power = 0" at the beginning of the main code solves the problem.
I'll look into it when I have time. There are some instances when something seems it should be initialized, but isn't for some reason.
@Matias Saibene There is a "no fuel" bug in the gas turbine code, the other engine has the correct code, I copied over/updated the engine file. see attach. above.
I'm not sure what you mean by this?
Also fuel consumption seems high? I'll add a low fuel indicater.
Again, don't confuse feels with reals. Vehicles that must lift the entire aircraft solely on the power of their engines do not sip fuel. The old R-4 got a whopping 130 mile range on a 30 gallon tank of gas, giving it a fuel mileage slightly better than a tank. Modern helicopters do better, but those engines are hungry. You're asking for a lot of power which demands fuel.
 
Last edited:
Don't confuse feels with reals. Modern turboshaft engine helicopter engines have a lot more power than the old R-4. The Warner engine in the R-4 gave 165 hp, the turboshaft engine on the Bell 206 is about 250 hp. The Bell 222 is downright scary powerful with two engines with a combined 1200 hp.
True, true, my reckoning was if they can build one with two engines than with one it would be pretty weak? Two of them would be scary!
You can check the power output of the engine in horsepower if you put the following in your code in clbk_prestep() after the engine module is called:

oapi.dbg_out(string.format("%.1f hp", power/745.7)
Put the engine to full power and see how much power you have, and compare that to the actual Bell 206 engine maximum power. They should agree within about 10%.
This is cool, thanks, now I can check feels against reals!
I'm not sure what you mean by this?
If you run out of fuel it throws an error. This is what I changed:
Code:
        vi:set_propellantmass(fuel_tank_handle, math.max(fuel_level,0))   

        --vi:set_propellantmass(fuel_tank_handle, fuel_level)
Again, don't confuse feels with reals. Vehicles that must lift the entire aircraft solely on the power of their engines do not sip fuel. The old R-4 got a whopping 130 mile range on a 30 gallon tank of gas, giving it a fuel mileage slightly better than a tank. Modern helicopters do better, but those engines are hungry. You're asking for a lot of power which demands fuel.
I know that helicopters generaly only have a couple of hours flight time but this is coming in at about 40min? (full rpm) I got the low fuel warning light working though:D
Further testing/research required:)
 
True, true, my reckoning was if they can build one with two engines than with one it would be pretty weak? Two of them would be scary!

This is cool, thanks, now I can check feels against reals!

If you run out of fuel it throws an error. This is what I changed:
Code:
        vi:set_propellantmass(fuel_tank_handle, math.max(fuel_level,0))  

        --vi:set_propellantmass(fuel_tank_handle, fuel_level)

I know that helicopters generaly only have a couple of hours flight time but this is coming in at about 40min? (full rpm) I got the low fuel warning light working though:D
Further testing/research required:)

The Bell 206 burns 25 gallons per hour in cruise, never mind full power. The fuel consumption of that engine at full power is about 40 gallons per hour.

Can you post your engine spec table? If anything in that is wrong everything will be wrong. You cannot just tweak numbers with this model.
 
All the data that I have is in the attachment above, I only changed the relevant variables (max air flow, rp, and rpm).
And have restored the prop_area values as advised.
 
Code:
{
    rp = 6.2,               --pressure ratio
    max_rpm = 51600,        --maximum engine speed (rpm)
    min_rpm = 6000,         --idle engine speed (rpm)
    max_air_flow = 0.5,     --mass air flow at max rpm -Allison eng. 1.5 kg/s
    HV = 43e6,              --lower heating value of fuel (J/kg) (~43 MJ/kg for typical liquid fuels)
    AF = 14.6               --air fuel ratio (mass air/mass fuel) (stochiometric ~14.6:1 for typical liquid fuels)
}

I see a couple problems:
  1. max_air_flow typo, should be 1.5, not 0.5
  2. AF = 14.6 is for stoichiometric combustion with no residual oxygen in the exhaust. Gas turbines operate at much higher AF ratios.
You can work out the proper AF ratio by taking the data specific fuel consumption and multiplying it by the maximum power to get the fuel mass flow rate, and just divide the max_air_flow value by the fuel mass flow rate to get the AF ratio.
 
max_air_flow typo, should be 1.5, not 0.5
This was the deliberate adjustment I mentioned
  1. AF = 14.6 is for stoichiometric combustion with no residual oxygen in the exhaust. Gas turbines operate at much higher AF ratios.
You can work out the proper AF ratio by taking the data specific fuel consumption and multiplying it by the maximum power to get the fuel mass flow rate, and just divide the max_air_flow value by the fuel mass flow rate to get the AF ratio.
Cool, this is a lead, thanks :)
 
Back
Top