Jump to content
The simFlight Network Forums

Recommended Posts

I want to create a plug-in that will monitor the airspeed, and when it reaches a preset value, triggers a wav file. I can't seem to find the right event handler, and not sure what format the preset airspeed should be in.  Anyone able to shed some light on a script that would handle this type of need?  

Thanks,

Steve

Share this post


Link to post
Share on other sites
3 hours ago, srd said:

I want to create a plug-in that will monitor the airspeed, and when it reaches a preset value, triggers a wav file. I can't seem to find the right event handler, and not sure what format the preset airspeed should be in.  Anyone able to shed some light on a script that would handle this type of need?  

Use event.offset for the airspeed offset. You can find the offset details and format in the Offsets Status list included in your FSUIPC Documents folder.

Take a look also at the supplied Lua plug-in examples, especially "record to csv" which reads a lot of offsets, but uses a timer event to do this at regular intervals instead of when they change.

Pete

 

Share this post


Link to post
Share on other sites

Thanks Pete,

Unfortunately I'm just not getting it. The Offset Status list shows: Offset 02BC, 4 bits, IAS as knots * 128.
I don't know what to do with the "record to csv" other then to try and use the timer event once I get the basic script working how I invasion it.
I've tried working with a few other scripts, modifying them, learning how they do what they do. I'm missing so much when it comes to watching 
the IAS and setting a value which when "true" will then play a sound file. What I would like to do
is to: as part of a check list, when on the runway and on the takeoff roll, trigger a voice file ( i can do that) 
when the airspeed comes alive (say at 10 knots) and then another one when rotation speed is reached.
If you can point me in some direction as to or where to learn how to do that, it would be much appreciated. I do tend to learn best by example.

Thanks for the help,

Steve

Share this post


Link to post
Share on other sites
3 hours ago, srd said:

Unfortunately I'm just not getting it. The Offset Status list shows: Offset 02BC, 4 bits, IAS as knots * 128.
I don't know what to do with the "record to csv" other then to try and use the timer event once I get the basic script working how I invasion it.

Er, 4 BYTES not BITS. 4 bits is half a byte, capacity only 0-16.

Best to run it on a timer. You don't want the code called every time there's a minute change in the IAS. Smpling every half to one second should do. So, just have a function called, say, "checkIAS", thus:

function checkIAS()
   ias = ipc.readUD(0x02bc)/128 -- gives IAS in knots
  -- do what you want with the ias here
end
event.timer(500, "checkIAS")

There are lots of examples of different ways of using Lua to do things. And the Library document shows you the syntax of the functions provided, built-in to FSUIPC.

What I would like to do
is to: as part of a check list, when on the runway and on the takeoff roll, trigger a voice file ( i can do that) 
when the airspeed comes alive (say at 10 knots) and then another one when rotation speed is reached.

Quote

What I would like to do is to: as part of a check list, when on the runway and on the takeoff roll, trigger a voice file ( i can do that) when the airspeed comes alive (say at 10 knots) and then another one when rotation speed is reached.

You can read the ground flag to check that it is on the gound, but there's no easy way to check if it is on the runway. Programs that do that use a database of airports and exact runway dimensions and positions and use the Lat/Lon coordinates to work it out. A rather ambitious task. 10 knots is going to occur during taxi as well. You'd need to work out some other way.

But certainly higher speeds would be a way. 

Pete

 

Share this post


Link to post
Share on other sites

Thank you Pete.

I did try the ground flag and that worked as it should, but then again with the checklist being a list of items that must be confirmed to move to the next item, you have to be on the ground to use this list so I may or may not need to check this condition.  As far as knowing when I'm on the runway, one or two checklist items right before the takeoff roll would require the plane to be on the center line ready to go. 

So if I use something like  (with the right format) :  if ias = =( >=10 knots)

                                                                                          then play sound (airspeed alive)

                                                                                          else loop --until true

this should trigger  the event ?

Steve

 

 

 

 

Quote

 

 

Share this post


Link to post
Share on other sites
12 hours ago, srd said:

So if I use something like  (with the right format) :  if ias = =( >=10 knots)

                                                                                          then play sound (airspeed alive)

                                                                                          else loop --until true

this should trigger  the event ?

As I said before, use event.timer to call a function to read the IAS at intervals THEN test for > 10 knots and do whatever it is you want to do. Do NOT use a "loop until true" method.

To make sure you do it only once and not every time the speed is >= 10 knots, have a variable defined outside of the function, say "DoneAlive = false" which you set to true when you play the sound, and test DoneAlive ("if not DoneAlive then ...") before testing for >= 10 knots. Do this as well as testing that you are on the ground.

You will want this to happen on the next take off roll too, so you need to also reset "DoneAlive" back to false when you detect you are off the ground.

You could make all this more efficient and simpler by having an event.offset for the ground flag offset, and setting an "OnHGround" variable in the function that calls. Then you don't need to read and test the ground offset value every time in the main tmer function, and that OnGround setting function can also reset all other things back to fase when your aircraft does leave the ground.

(This is all more difficult to explain in words than to simply write the lua code, but you seem to want it in a sort of non-lua pseudo code judging by your message) 

Pete

 

Share this post


Link to post
Share on other sites

Thanks Pete,

I'll try to incorporate your suggestions. My real issue is the lack of lua coding knowledge, which causes me to fall back to what little coding I did do way back when. I would  very much like to simply write the lua code, but you don't always get what you want. So I'll keep trying, learning, and asking for help.

Thanks again Pete,

Steve

Share this post


Link to post
Share on other sites
5 hours ago, srd said:

I would  very much like to simply write the lua code, but you don't always get what you want.

There are lots of examples supplied, and more I think in the User Contributions subforum. and it is easy to debug them as you simply check the log for errors, make a change and immediately test again. It's a quick process, and trial and error is not a bad way to learn in such an environment (something not possible in my original programming environment where jobs were submitted for overnight tests in a Bureau type operation!

Pete

 

Share this post


Link to post
Share on other sites

Hi Pete, I've made progress ( for me) in my little project. The items I've been working on all work the way I'd hope them to by themselves. When I put them in succession though, the first 2 functions are bypassed and only the last function runs. Clearly I'm missing something. Any thoughts?

Thanks,

Steve

 

function checkAlive()
    ias = ipc.readUD(0X02BC)/128
    ipc.lineDisplay("Airspeed="..ias)
    if ias >= 25 then
        sound.play("F:\\FSX\\Sound\\wavefiles\\senecaII\\Airspeed alive.wav")
        ipc.lineDisplay("Airspeed alive")
        event.cancel("checkAlive")
    end
end
 event.timer(500, "checkAlive")

function checkIAS()
    ias = ipc.readUD(0X02BC)/128
    ipc.lineDisplay("Airspeed= "..ias)
    if ias >= 60 then
         sound.play("F:\\FSX\\Sound\\wavefiles\\senecaII\\70 knots rotate.wav")
         ipc.lineDisplay("Rotate")
        event.cancel("checkIAS")
    end
end
 event.timer(500, "checkIAS")

function checkRALT()
   radio_alt = (3.281/65536)*ipc.readUD (0x31E4)
   radio_alt = math.floor(radio_alt + 0.5)
   ipc.lineDisplay("AGL= "..radio_alt)
   if radio_alt >= 200 then
        sound.play("F:\\FSX\\Sound\\wavefiles\\senecaII\\Positive climb rate gear up.wav")
        ipc.lineDisplay("Positive climb rate")
        event.cancel("checkRALT")
   end
end
event.timer(500, "checkRALT")
 

Share this post


Link to post
Share on other sites

From the lua docs on event.timer:

Quote

Note that each Lua plug-in is restricted to one timer. If you
specify another it replaces the previous one.

So you must either:

1. Break these out into three separate plugins

or

2. setup one timer to call a single function e.g. "doChecks()" and either put all the checks in there, or have it call each of your functions in turn.

For 2 however, you can't just cancel the event when the action is done. You'll need to setup variables (true/false) to know when each action has completed, has check those each time.

Paul

Share this post


Link to post
Share on other sites

Hi Paul, 

Thanks for the response. I was thinking that the first function would run until it was true which then stopped the event.timer for that function, then move to the next function until true, stop that event.timer and move to the last function until true.

It seemed I needed to stop the event timer each time or the sound file kept looping. I'm not understanding why replacing the previous event.timer is a bad thing. Is there a way to check that the sound file has played and if true, move to the next function? I'm trying to make these functions and more part of a single checklist type script.

Could I have the first function call the second function and then it would call the third function?

Any doChecks() examples you know of or can point to? or other thoughts? 

Thanks,

Steve

 

Share this post


Link to post
Share on other sites
Quote

I was thinking that the first function would run until it was true which then stopped the event.timer for that function, then move to the next function until true, stop that event.timer and move to the last function until true.

No, that's not how the events work. When the event.timer() line is reached the script does not start the timer and wait until it stops. The timer is started and then the script continues to execute. 

So your current script does this:

1. Creates a function in memory called checkAlive().

2. Starts a timer that calls that function every 500ms.

3. Creates a function called checkIAS()

4. Reprograms the timer to call checkIAS() every 500ms.

5. Creates a function called checkRALT()

6. Reprograms the timer to call checkRALT() every 500ms

Note that all of this happens in a few milliseconds, before the timer has ticked for the first time.

Quote

I'm not understanding why replacing the previous event.timer is a bad thing.

Because there is only 1 timer per script. The script does stop at each timer line. It carries on and overwrites the previous timer settings.

Quote

It seemed I needed to stop the event timer each time or the sound file kept looping.

Yes because the function (e.g. checkAlive()) is called every 500ms and the conditions that play the sound still exist 500ms later. In that case of checkAlive you are looking for IAS >= 25 kts. You play the sound at 25kts, but 500ms later the IAS is still >= 25kts so it plays it again. It will play every 500ms until the IAS comes below 25kts.

Stopping the timer was a good way of preventing this when you were only doing one thing with the timer. Now you want to do many things with the timer you can't just stop the timer after the first thing happens.

 

Quote

Is there a way to check that the sound file has played and if true, move to the next function? 

You need to keep track of this yourself. You need to setup some boolean variables (true/false) so that you know what checklist items have been done and which haven't. I show this later...

Quote

Any doChecks() examples you know of or can point to? or other thoughts? 

doChecks() was just an example name off the top of my head. The idea is this:

1. Create a single function that you can call with your timer. I came up with the name doChecks().

2. That function will check every item in your list that hasn't already been done.

3. You could put all the code in the one function but it might get very long. It's better to break them out into a function for each check (as you have now) and have doCheck() call each one in turn. (If it needs calling).

4. You must keep track of what's been done and what hasn't.

Here is some code that would be the sort of thing you would do. I don't use LUA so this might not be 100% working, correct LUA, but it shows the basic plan.

I've included the three checks you've given but you can hopefully see the logic and how you would expand this basic structure to add other items.

 

local airspeedAliveCalled = false
local rotateCalled = false
local gearUpCalled = false

function checkAlive()
    ias = ipc.readUD(0X02BC)/128
    ipc.lineDisplay("Airspeed="..ias)
    if ias >= 25 then
        sound.play("F:\\FSX\\Sound\\wavefiles\\senecaII\\Airspeed alive.wav")
        ipc.lineDisplay("Airspeed alive")
        airspeedAliveCalled = true
    end
end

function checkIAS()
    ias = ipc.readUD(0X02BC)/128
    ipc.lineDisplay("Airspeed= "..ias)
    if ias >= 60 then
         sound.play("F:\\FSX\\Sound\\wavefiles\\senecaII\\70 knots rotate.wav")
         ipc.lineDisplay("Rotate")
         rotateCalled = true
    end
end

function checkRALT()
   radio_alt = (3.281/65536)*ipc.readUD (0x31E4)
   radio_alt = math.floor(radio_alt + 0.5)
   ipc.lineDisplay("AGL= "..radio_alt)
   if radio_alt >= 200 then
        sound.play("F:\\FSX\\Sound\\wavefiles\\senecaII\\Positive climb rate gear up.wav")
        ipc.lineDisplay("Positive climb rate")
        gearUpCalled = true
   end
end

function doChecks()
   if not airspeedAliveCalled then
      checkAlive()
   elseif not rotateCalled then
      checkIAS()
   elseif not gearUpCalled then
      checkRALT()
   end
end

-- Only 1 timer!
event.timer(500, "doChecks") 

 

Paul

Share this post


Link to post
Share on other sites
Quote

 

Thanks a bunch Paul, I understand it a lot better now. I was under the assumption that the script didn't start executing the next function until it was finished with the current one. I'll give your input a try , get it to work, learn more and have fun.  

Cheers,

Steve                        

Share this post


Link to post
Share on other sites

Ok Paul, your script worked just great. Thank you!

Now I have an issue with the following script. The log file says "waiting for input" . Nothing happens when I press the 0,1 or 2 key. Any thoughts?

What I'm trying to achieve is to show  a list of different checklists and by selecting the one you want, opens the associated .lua file.

I would really like to be able to mouse over an item and click to go to the specific list. But that's for another time...

Thanks,

Steve

ref = sound.play("F:\\FSX\\Sound\\wavefiles\\senecaII\\Are you ready for the prestart checklist Steve.wav")
ipc.lineDisplay("1. Cancel Checklists", 1)
ipc.lineDisplay("2. Pre-Flight Checks", 2)
ipc.lineDisplay("3. Pre-Start Checks", 3)

function callNew0(keycode, shifts)
   ipc.lineDisplay("Checklist terminated by pilot")
   ipc.sleep(2000)
   ipc.exit()
end

function callNew1(keycode, shifts)
    ipc.runlua("F:\\FSX\\Module\\Listtest.lua")--runs another lua program
end

function callNew2(keycode, shifts)    
    ipc.runlua("F:\\FSX\\Module\\Listtest1.lua")--runs another lua program
end

event.key(48, 8, "callNew0") --key 0 unshifted

event.key(49, 8, "callNew1") --key 1 unshifted

event.key(50, 8, "callNew2") --key 2 unshifted

Share this post


Link to post
Share on other sites

You seem to display a listing actions for 1, 2 and 3, but then wait for keypresses 0, 1 and 2.

Have you used FSUIPC's Key/Button logging to see what it thinks is happening to your keypress. 0, 1 and 2 may be taken previously. I've tested your program but with

 ipc.lineDisplay("callNew1")

etc, in place of the ipc.runlua lines, and it works fine. I've also used it with runlua just to be sure it all will work.

Enable Button/key logging, and maybe also Event logging. The log will show what the Key presses are doing, and Lua programs starting.

Pete

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×

Important Information

By using this site, you agree to our Terms of Use. Guidelines Privacy Policy We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.