Jump to content
The simFlight Network Forums

Reading LVARs repeatedly


Recommended Posts

Thanks to the thread today, I started poking into FSUIPC's capability for reading local panel variables, and I think it's going to solve a long-standing problem I've had about reading payware autopilot states.

 

Pete, what is the best practice for reading several LVARs continuously (say, every 100-500ms)?

 

Right now I'm doing a three-step shuffle of writes to 0xD6C and 0xD70 followed by a read from my specified offset, all wrapped around a single FSUIPC_Process() call. However, if I need to do a Process() for every LVAR, that strikes me as rather inefficient and problematic. Ideally, I'd like to register an LVAR->offset mapping and then have FSUIPC handle it all in the background when it changes. That way I can batch my Reads like I already do. Is there a way to do this?

 

Cheers!

Luke

 

 

Link to comment
Share on other sites

what is the best practice for reading several LVARs continuously (say, every 100-500ms)?

You don't need to. Best to use the appropriate event, where FSUIPC reads it and calls you when it changes.

Right now I'm doing a three-step shuffle of writes to 0xD6C and 0xD70 followed by a read from my specified offset, all wrapped around a single FSUIPC_Process() call.

Oh, you mean from a program, not a Lua plug-in. Sorry.

However, if I need to do a Process() for every LVAR, that strikes me as rather inefficient and problematic. Ideally, I'd like to register an LVAR->offset mapping and then have FSUIPC handle it all in the background when it changes. That way I can batch my Reads like I already do. Is there a way to do this?

No, not at present. Obviously it's possible, because that's pretty much what the Lua event is doing. But there's nothing like that for external programs. There's really nothing like it to base it on, either, so it it was implemented it would be all new code.

When you say "rather inefficient and problematic", what's the problem part of it? And how many Lvars are you talking about? All at 100 mSEc intervals? Are these critically changing values?

Pete

Link to comment
Share on other sites

No, not at present. Obviously it's possible, because that's pretty much what the Lua event is doing. But there's nothing like that for external programs. There's really nothing like it to base it on, either, so it it was implemented it would be all new code. When you say "rather inefficient and problematic", what's the problem part of it? And how many Lvars are you talking about? All at 100 mSEc intervals? Are these critically changing values?

 

It's around a dozen, but it depends -- all on the PMDG747X MCP. I'm trying to be somewhat intelligent in my reading to only check autopilot and auto-throttle states when the AT is armed and one of the CMD buttons is selected, but that means between 2 and 4 reads at a minimum.

 

I've thrown together a prototype that should give me some ideas as to what the performance penalty is like; I'll take a look and see what the performance penalty is.

 

Cheers!

Luke

Link to comment
Share on other sites

Out of curiosity, what is the format of the string going into 0xD70? I'm passing in ":MCP_CMD_L_Switch" as ASCII bytes and null-terminated, but I'm consistently getting back a zero. Is there something obvious I'm missing? This is what the LUA logging returns:

 

776012 LUA.0: L:MCP_CMD_L_Switch_var=1
776292 LUA.0: L:MCP_CMD_L_Switch_var=2
 
Cheers!
 
Luke
Link to comment
Share on other sites

I'm not at home now till Monday--answering this on my iPhone. No access to my dev tools, nor documents, but it is as documented. Put the offset for the result to the place first.

 

 

Enjoy your weekend! So I don't forget, here's where I've gotten thus far.

 

I think I'm making an error in the format of the LVar name. I've tried several different options, with the resulting offset being 0x6D88. Here's the logging:

 
7758523 WRITE0[7296]  0D6C,   4 bytes: 88 6D 00 00                                      .m..
7758523 WRITE0[7296]  0D70,  23 bytes: 3A 4D 43 50 5F 41 54 5F 41 52 4D 5F 53 77 69 74  :MCP_AT_ARM_Swit
7758523                           63 68 5F 76 61 72 00                             ch_var.
 
I've tried the following strings for the LVar name:
 
":L:MCP_AT_ARM_Switch_var"
"L:MCP_AT_ARM_Switch_var"
":MCP_AT_ARM_Switch_var"
"L:MCP_AT_ARM_Switch"
":L:MCP_AT_ARM_Switch"
 
And they all seem to return 0. Is there an example snippet for the use of this offset for reading LVars?
 
FWIW, it seems like every write/write/read/process iteration (to read the LVar) is around 5-10ms on my i4770K using FSX.
 
Cheers!

Luke

Link to comment
Share on other sites

Update - when in doubt, assume the programmer is missing something important.

 

Pete, it looks like you definitely are enforcing some limitations on the output offset, just like your documentation suggests! :) Once I started using 0x66C8 rather than 0x6D88, I started getting back some data. The form ":MCP_AT_ARM_Switch_var" seems to work fine.

 

Hope this helps someone else down the line - now to see what the performance impact is!

 

Cheers!

Luke

Link to comment
Share on other sites

Yes, the offset must be one of those assigned for general user usage. Without access to my system at home I can't check whether 6D88/8 is aleady assigned, but even if not it might be one day. I'm trying to ensure no conflicts except those the user can resolve himself.

Pete

Link to comment
Share on other sites

FWIW, it seems like every write/write/read/process iteration (to read the LVar) is around 5-10ms on my i4770K using FSX.

Sounds about right. Process switch, queuing on FS's message list, forwarding to a thread in FSUIPC, message to the gauges system in FS to get the variable ID and then another to get the value.

No reason why you shouldn't do multiple write write read sequences before the process, just use separate offsets each time. Didn't you try that? Would save multiple process swiches. As documented, the read is processed before continuing, it's not asynchronous.

Pete

Link to comment
Share on other sites

No reason why you shouldn't do multiple write write read sequences before the process, just use separate offsets each time. Didn't you try that? Would save multiple process swiches. As documented, the read is processed before continuing, it's not asynchronous.

 

I'd forgotten about that - so I can do multiple write/write operations to D6C and D70 before a single Process()? That would be ideal because it means that I can read everything in a single Process() call like I do with everything else (I read different offsets with the PMDG737, PMDG737X and PMDG777X).

 

I'm wrapping up a trans-Atlantic leg in the 744 but I'll see if I can test this out later today. I guess I'll need to find 96 free bytes. :) Thanks again Pete!

 

Cheers!

Luke

Link to comment
Share on other sites

I'd forgotten about that - so I can do multiple write/write operations to D6C and D70 before a single Process()?

Well, a single read before the Process.

I guess I'll need to find 96 free bytes.

Ah, you can't. It will only work on the user-assigned offsets, 6C00-6CFF, so 64 bytes.

BUT it would be dead easy for me to add a facility to read/write values or different sizes and types, doing the double float conversion internally. For instance, if you know a value is an integer then provide it or ask for it as such.

I can use the high word of the offset value for this in 0D6C. So, use the offset 0x0nnnn as now for the full 8-byte double, or:

0x1nnnn for 32-bit float

0x2nnnn for 32-bit signed integer (SD)

0x3nnnn for 32-bit unsigned integer (UD)

0x4nnnn for 16-bit signed integer (SW)

0x5nnnn for 16-bit unsigned integer (UW)

0x6nnnn for 8-bit signed integer (SB)

0x7nnnn for 8-bit unsigned integer (UB)

Then you could fit up to 64 values in, depending on their types.

Pete

Link to comment
Share on other sites

Ah, you can't. It will only work on the user-assigned offsets, 6C00-6CFF, so 64 bytes. BUT it would be dead easy for me to add a facility to read/write values or different sizes and types, doing the double float conversion internally. For instance, if you know a value in an integer then provide it or ask for it as such.

Then you could fit up to 64 values in, depending on their types.

 

That would be wonderful! All of my values are currently 8-bit values but this would be a handy feature for down the road.

 

Cheers!

Luke

Link to comment
Share on other sites

That would be wonderful! All of my values are currently 8-bit values but this would be a handy feature for down the

Well if they are all 8 bit then you would be able to read 64 of them in one go. Mind you, do check for performance impact on FS. The requests to the Gauges system have to be made in the main thread.

Or did you mean that they all need 8-byte (64 bit) floating point accuracy? Surely not. The two you showed earlier were for a switch position, no?

Anyway, I'll put it in when I'm home -- Monday or Tuesday. It'll be in interim update 4.952.

Pete

Link to comment
Share on other sites

On 5/14/2016 at 3:41 PM, Pete Dowson said:

Anyway, I'll put it in when I'm home -- Monday or Tuesday. It'll be in interim update 4.952.
 

Okay, it's done. 4.952 will soon be available in the Download Links subforum.

[LATER]

Something's wrong with the Forum at present, and I don't seem to be able to change the Download Links. I'll keep trying ... but meanwhile it's attached instead.

Pete

 

Attachment revised a bit later, next day:

 

FSUIPC4952.zip

Link to comment
Share on other sites

On 5/14/2016 at 10:41 AM, Pete Dowson said:

Well if they are all 8 bit then you would be able to read 64 of them in one go. Mind you, do check for performance impact on FS. The requests to the Gauges system have to be made in the main thread.

Or did you mean that they all need 8-byte (64 bit) floating point accuracy? Surely not. The two you showed earlier were for a switch position, no?

Anyway, I'll put it in when I'm home -- Monday or Tuesday. It'll be in interim update 4.952.

Pete

Thank you! I've tweaked my code to use the encoded data size and I'll test things out in a little bit. You are correct, by the way, I just need a single byte per call.

I'm not too worried about performance; I already did a test with the PMDG 747 reading a dozen LVARs regularly without any noticeable performance impact, and that was using multiple Process() calls since I could only read LVARs at a time, but I'll confirm.

Thanks again!

Luke

Link to comment
Share on other sites

Pete, how do LVAR writes work? I started looking at doing writes, and I'm assuming that nothing has changed and that they are all FLT64 values When running the LUA log lvar script, when I write to LVAR foo I see a "foo_value" and a "foo_set", but the variable doesn't appear to change.

Cheers!

Luke

Link to comment
Share on other sites

20 minutes ago, Luke Kolin said:

Pete, how do LVAR writes work? I started looking at doing writes, and I'm assuming that nothing has changed and that they are all FLT64 values When running the LUA log lvar script, when I write to LVAR foo I see a "foo_value" and a "foo_set", but the variable doesn't appear to change.

No, the new facility for any format data works both ways. It would be very remiss of me to do it asymmetrically! And surely if I did so it would say so clearly in my write-up!

You can use FLT64's, but then the upper part of the offset value in 0D6C must be zero.

 

What's "foo_value" and "foo-set"? Strange names!

Pete

 

Link to comment
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
×
×
  • Create New...

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.