Jump to content



Photo
* * * * * 9 votes

Pinscape Controller software V2

pinscape

  • Please log in to reply
975 replies to this topic

#481 mjr

mjr

    Pinball Wizard

  • Members
  • PipPipPipPipPip
  • 3,332 posts

  • Flag: United States of America

  • Favorite Pinball: Medieval Madness

Posted 15 November 2017 - 06:04 PM

Just an FYI (as I didn't see it mentioned anywhere, maybe I missed it)

I just picked up a KL25Z and it didn't need any firmware updates to work - just plugged it in and it had the newer firmware on out of the box, so I just ran the tool and installed Pinscape :)

 

That's great news!  I'm guessing this has to do with the period a few months ago where all of the electronics vendors were out of stock on the KL25Z.  It probably means that the warehouse finally ran out of the old inventory with the old firmware, and they had to make up a fresh batch.  It's really good that they updated at the factory - it was getting really hard for people to find XP machines to do the upgrade on.



#482 hlr53

hlr53

    Pinball Fan

  • Gold Supporter
  • 683 posts
  • Location:Kettering OH

  • Flag: United States of America

  • Favorite Pinball: 1964 Williams Palooka Joe

Posted 22 November 2017 - 12:27 PM

If you encounter one of the old ones still out there I've recently read you can disable Windows 10 Storage Services temporarily. Not quite sure how to do that?


Former Cab: 40" Haier, 28" I-INC, i7-6700, 1080 GPU, v3DMD, 4D7 solenoids. Altec-Lansing speakers and sub. Artwork by Stuzza. Printing by Brad Bowman. VR HP reverb


#483 mjr

mjr

    Pinball Wizard

  • Members
  • PipPipPipPipPip
  • 3,332 posts

  • Flag: United States of America

  • Favorite Pinball: Medieval Madness

Posted 22 November 2017 - 05:59 PM

If you encounter one of the old ones still out there I've recently read you can disable Windows 10 Storage Services temporarily. Not quite sure how to do that?

 

Right; the details are included in the instructions that the config tool displays when you go through the new KL25Z setup procedure.



#484 hlr53

hlr53

    Pinball Fan

  • Gold Supporter
  • 683 posts
  • Location:Kettering OH

  • Flag: United States of America

  • Favorite Pinball: 1964 Williams Palooka Joe

Posted 22 November 2017 - 08:18 PM

Oh! My bad. I should read the most current docs. I last flashed the Summer of 2016.


Former Cab: 40" Haier, 28" I-INC, i7-6700, 1080 GPU, v3DMD, 4D7 solenoids. Altec-Lansing speakers and sub. Artwork by Stuzza. Printing by Brad Bowman. VR HP reverb


#485 DJRobX

DJRobX

    Pinball Fan

  • VP Dev Team
  • PipPipPipPip
  • 941 posts
  • Location:Valencia, CA

  • Flag: United States of America

  • Favorite Pinball: F14 Tomcat

Posted 30 November 2017 - 08:14 AM

Hi MJR,

 

My latest obsession has been trying to figure out how to get my nudging and tilt dialed in properly.  I've gone as far as to add code to VP's scripting interface to add visibility to how the virtual tilt bob and sensor readings are actually working, and to allow realtime adjustments into the VP nudge test table.   This way we can observe the sensors when running the shaker. 

 

What I noticed almost immediately is that the oscillating action of the shaker was not being represented by the sensors in VP very well.  I could see the left/right pulses were not smoothly balanced, and it the balls would sometimes react violently the more the shaker ran.     A shaker motor runs up to 3600RPM which is about 60hz which happens to be about the interval that VP will poll the sensor if you're running at 60hz.   So it seemed logical that VP might be missing the oscillating action.  

 

I took a look at the Pinscape sources and see that you've already accounted for this situation, and poll the sensor much more often, and report an averaged sum to the USB controller.   However, it is reporting out at 10ms intervals.    If VP is reading every 16ms (On each 60fps vsync frame), we're dropping quite a bit of the accumulated data. 

I modified your code to wait until 16666 usec instead of 10000 to match my 60hz refresh rate.    The difference is huge.    The virtual tilt bob is now almost rock steady when the shaker is moving, yet I can move it by throwing the cab around.   Maybe it could be an option to change the reporting interval?  


Edited by DJRobX, 30 November 2017 - 08:16 AM.


#486 randr

randr

    I'm just a hardware guy so...

  • VIP
  • 2,650 posts
  • Location:Minnesota

  • Flag: United States of America

  • Favorite Pinball: Twilight Zone

Posted 30 November 2017 - 12:51 PM

This really is a good test table and I hope zeb or Paul will look and use this to make any changes needed in their code too

randr___pinball.png                         


#487 mjr

mjr

    Pinball Wizard

  • Members
  • PipPipPipPipPip
  • 3,332 posts

  • Flag: United States of America

  • Favorite Pinball: Medieval Madness

Posted 30 November 2017 - 07:23 PM

My latest obsession has been trying to figure out how to get my nudging and tilt dialed in properly.  I've gone as far as to add code to VP's scripting interface to add visibility to how the virtual tilt bob and sensor readings are actually working, and to allow realtime adjustments into the VP nudge test table.   This way we can observe the sensors when running the shaker. 

 

What I noticed almost immediately is that the oscillating action of the shaker was not being represented by the sensors in VP very well.  I could see the left/right pulses were not smoothly balanced, and it the balls would sometimes react violently the more the shaker ran.     A shaker motor runs up to 3600RPM which is about 60hz which happens to be about the interval that VP will poll the sensor if you're running at 60hz.   So it seemed logical that VP might be missing the oscillating action.  

 

I took a look at the Pinscape sources and see that you've already accounted for this situation, and poll the sensor much more often, and report an averaged sum to the USB controller.   However, it is reporting out at 10ms intervals.    If VP is reading every 16ms (On each 60fps vsync frame), we're dropping quite a bit of the accumulated data. 

I modified your code to wait until 16666 usec instead of 10000 to match my 60hz refresh rate.    The difference is huge.    The virtual tilt bob is now almost rock steady when the shaker is moving, yet I can move it by throwing the cab around.   Maybe it could be an option to change the reporting interval?  

 

I could certainly add an option for that.  There's a tradeoff in padding out the timing like that, which is that you might start seeing latency on button inputs.  16ms isn't long enough to notice by itself, but it's only one part of the input chain, and everything adds up, particularly the input lag on the TV.

 

Out of curiosity, did you ever try the Nudge Filter option in VP with the old timing?  The point of the nudge filter is basically to interpolate the missing data to smooth out the data VP sees to make it better match reality.

 

You're quite right about the timing in the interface between VP, USB, and the accelerometer being problematic.  In fact, in my opinion, the whole approach VP uses for this is wrong.  I'm glad you were able to get such a big improvement on your machine with such a simple change, but I'd really like to fix the whole approach so that time padding isn't required.  I've been puzzling over this for a couple of years and haven't quite cracked it yet.  

 

The basic problem, as you noticed, is timing.  But it's not purely VP timing.  VP polls for input from DirectInput, and DirectInput in turn polls for input from USB, which in turn polls from the hardware.  The USB hardware polls at 1ms intervals (since all of the known nudge devices have USB 2 electronics), but the Windows USB HID drivers generally poll at 10ms intervals.  VP actually doesn't poll at the video frame rate; it polls at the PHYSICS frame rate, which in VP 10 is approximately 1ms.  ("Approximately" because it depends on how long the actual computations take.  The physics cycle runs synchronously and can't be interrupted.  The actual timing is highly variable because of collision detection; some cycles can take 15-20ms on my machine.)

 

How do DirectInput and VP negotiate this difference in timing?  It's simple but counterintuitive, at least to my way of thinking.   Counterintuitive because I think of this as a stream of input data:  we take reading "A" from the accelerometer, send it to the PC, and VP receives reading A; we take reading "B", send it to the PC, and VP takes reading "B".  But that's not how it works at all!  DirectInput doesn't provide VP with a stream of data.  It only provides it with a "current reading".  Let's take a look at a timeline, using your 16ms timing modification:

 

On the KL25Z side:

0ms:  KL25Z takes reading "A" and sends it to the PC.

16ms:  KL25Z takes reading "B" and sends it to the PC

32ms: KL25Z takes reading "C" and sends it to the PC

...

 

On the PC USB/DirectInput side:

0ms: DirectInput receives reading "A"

16ms: DirectInput receives reading "B"

32ms: DirectInput receives reading "C"

..

 

Visual Pinball 10:

0ms: Read from DirectInput: current sample is "A"; apply "A" acceleration to the ball

3ms: Read from DirectInput: current sample is "A"; apply "A" acceleration to the ball AGAIN

4ms: Read from DirectInput: current sample is "A": apply "A" acceleration YET AGAIN

7ms: Read from DirectInput: current sample is "A": apply "A" one more time

11ms: Read sample "A", apply "A" yet yet yet again

17ms: The current sample is now "B"; apply "B" acceleration

20ms: Read sample "B" again, apply "B" acceleration again

33ms: Reading sample "C", apply sample "C"

 

 

See what I mean about counterintuitive?  VP doesn't get a simple input stream of A, B, C.  It gets A, A, A, A, A, B, B, C...  DirectInput doesn't provide discrete samples the way we humans think about input files.  DirectInput just reports the latest reading, and reports the same lastest reading over and over if you keep asking faster than new samples are coming in.  Which VP is doing.

 

I *think* what you did by slowing down the timing in the KL25Z sending the joystick samples is basically smooth out the effect of the varying physics cycle time in VP.  You'll probably get even smoother results if you keep increasing it further, but obviously you don't really want to do that beyond a certain point (which you've probably already reached) because the longer times also translate to longer latency.

 

The real problem is that VP wants to treat the accelerometer readings as instantaneous, but that's impossible given the constraints of DirectInput.  The real solution here is that we need to change the reporting interface between VP and the accelerometer so that VP receives both acceleration and timing data, somehow.  VP needs to know the true INTEGRAL of the acceleration over the time slice to apply the data accurately.  That's the part I haven't been able to figure out.  



#488 DJRobX

DJRobX

    Pinball Fan

  • VP Dev Team
  • PipPipPipPip
  • 941 posts
  • Location:Valencia, CA

  • Flag: United States of America

  • Favorite Pinball: F14 Tomcat

Posted 30 November 2017 - 09:54 PM

Unfortunately that doesn't appear to be the case when you're using Vsync.   I added some logging in the plumb_update function and ran it, here are the time deltas between each time it's called (after the initial settling period), times are in msec.

 

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 14, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15

 

VP isn't multi-threaded, so if vsync is on, it's going to sit and wait until the next frame.  The physics loop then runs in a tight loop to catch up.     I think this is something that needs addressing in VP, there's got to be a better way for it to make use of time before entering the wait for vsync....  

 

Going off the current behavior, though, this means that the acceleration data may be updated twice in a 14-16ms period while VP is "sleeping".    Figure this means we're losing 3/8ths of the nudge information.   That lost data results in violent movement from a shaker making a "sine wave", much like dropping sound samples results in garbled harsh sound.   I am using the nudge filter, it's even worse without it.

With the PinScape syncrhonized to VP's reads, it's a completely different animal.   I can hammer my shaker and the tilt bob doesn't move much at all but you can see the immediate sensor reads going crazy.    Manual movement of the cab finally has the reaction it should have without being dwarfed by shaker action.   The sensor is clearly able to see the balanced movement properly, it's just a matter of getting it to VP reliably.   :)


Edited by DJRobX, 30 November 2017 - 10:20 PM.


#489 mjr

mjr

    Pinball Wizard

  • Members
  • PipPipPipPipPip
  • 3,332 posts

  • Flag: United States of America

  • Favorite Pinball: Medieval Madness

Posted 30 November 2017 - 10:38 PM

Unfortunately that doesn't appear to be the case when you're using Vsync.   I added some logging in the plumb_update function and ran it, here are the time deltas between each time it's called (after the initial settling period), times are in msec.

 

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0...

 

Indeed, those are the real time deltas.  Internally VP is using its own simulation times on each of those, 1ms apart.  It's that mismatch between real time and physics time that's at the core of this.  VP is sampling on every one of those calls, but it's reading the same data over and over between successive USB updates from the accelerometer.

 

 

With the PinScape syncrhonized to VP's reads, it's a completely different animal.   I can hammer my shaker and the tilt bob doesn't move much at all but you can see the immediate sensor reads going crazy.    Manual movement of the cab finally has the reaction it should have without being dwarfed by shaker action.   The sensor is clearly able to see the balanced movement properly, it's just a matter of getting it to VP reliably.   :)

 

The problem with trying to handle this by padding out the timing is that you can't really synchronize clocks perfectly.  I guess your testing shows that you can get an empirically better results by making the timing closer, so that's something.  So this is a good workaround until we can figure out a real solution, at least if it's not creating additional latency for you.

 

But I'd really like to fix this for real at some point.   Even making the timing closer, you're still going to be missing some inputs, but it's probably down from missing 40% of inputs to missing 5% or something like that.  The bigger problem is the unpredictable number of VP reads each sample.  As you can see in your data, the number of "zero time" reads varies between video frames.  I'm guessing those readings came from a simple test table - if you run a complex table that has some longer video render times and more demanding collision detection, you'll probably see much greater variability.  That causes a lot of randomness in how the accelerometer data are interpreted because each "instantaneous" input is integrated over a different number of physics frames.  That creates a random multiplier for each input - if a sample is applied to the simulation 16 times, it's twice as powerful an effect as if the same input is applied 8 times.



#490 mjr

mjr

    Pinball Wizard

  • Members
  • PipPipPipPipPip
  • 3,332 posts

  • Flag: United States of America

  • Favorite Pinball: Medieval Madness

Posted 30 November 2017 - 10:52 PM

My thinking is that you can't change VP's reading strategy without re-architecting the whole physics engine, so we have to come up with a data format that VP can interpret into the simulation properly.  The approach I have in mind is that you do the integration on the accelerometer side, where you have real-time data, and pass along the integrated results to VP instead of instantaneous results.  VP should then be able to decode the integrated results and turn them back into instantaneous samples for the simulation. 

 

The best thing I've come up with is to report the accelerometer data as a SUM of all readings to far, rather than as instantaneous readings.  VP can then take the difference between the current reading and the last reading each time it samples.  That eliminates the problem of missed samples entirely - if the accelerometer reports five samples between VP readings, it doesn't matter because all of those missed five samples are incorporated into the sum that VP gets when it finally does get around to taking a reading. 

 

But to make this work, I think the accelerometer also has to report a timestamp on each reading.  When VP takes a sample, then, it can determine not only the total amount of input that has accumulated since its last reading, but also the real-time duration of the sample data.  It can then work this backwards to figure out how much of the sample to apply on each frame.

 

The tricky part is that the data fields for reporting the timestamps and acceleration sums have limited precision, so if you keep adding up readings you're going to frequently overflow the field.  But I think that's okay as long as the magnitudes are chosen so that you can fit, say, a hundred or so readings into the sum before you get an overflow.  Then it's all just simple modular arithmetic - as long as VP samples frequently enough that you can only overflow once between successive readings, modular arithmetic still gives you a valid difference.  It's only if you overflow multiple times between successive samples that you start losing data.

 

Anyway, I've been wanting to experiment with something like this for a long time to see if it's workable, but I haven't had the time.  Given how much you've been getting into the VP and Pinscape internals, maybe you want to give it a shot...



#491 DJRobX

DJRobX

    Pinball Fan

  • VP Dev Team
  • PipPipPipPip
  • 941 posts
  • Location:Valencia, CA

  • Flag: United States of America

  • Favorite Pinball: F14 Tomcat

Posted 30 November 2017 - 11:04 PM

But I'd really like to fix this for real at some point.   Even making the timing closer, you're still going to be missing some inputs, but it's probably down from missing 40% of inputs to missing 5% or something like that.  

 

 

Yes, agree 100%.   It's still not perfect, just a lot less nasty in this case. 

 

Have you tried pushing joystick updates at 8ms?   If the Windows polling frequency is 125mhz it ought to be able to keep up with that.    If we did that, we could push the updates twice, but only recalculating the summed accelerometer data every other time.   That would improve the button latency without affecting the accelerometer reads. 

 

If I can figure out a way to at least delay the physics loop to 8ms before entering vsync, it would hugely help not only this issue but also VPM input latency problems.   I had started to look at that before and will get back at it.     I did something similar in VPM last year - adding delays so all the processing is not bunched up at frame update intervals, which allows more opportunities for the virtual machines to see button state changes. 


Edited by DJRobX, 30 November 2017 - 11:15 PM.


#492 mjr

mjr

    Pinball Wizard

  • Members
  • PipPipPipPipPip
  • 3,332 posts

  • Flag: United States of America

  • Favorite Pinball: Medieval Madness

Posted 30 November 2017 - 11:12 PM

Another approach, which might be a lot simpler conceptually, is switch from DirectInput to Raw Input instead.  Microsoft actually has already deprecated DirectInput and suggests replacing it with Raw Input, so it would be a modernization.  But for nudge puposes, the benefit would be that we'd be able to get all of the actual inputs from the joystick in a stream of discrete inputs.  What you'd want to do is set up a background thread whose whole job is to read Raw Input packets from the joystick.  It would record a timestamp (in real time) for each one.  When VP wants to read a sample, it would be able be able to look at the timestamps on successive samples to determine how to apply them to the simulation.  I think there'd be enough information that VP could interpolate the samples into slices that correspond to its internal physics clock - it would basically re-partition the real-time samples from the joystick into physics-time slices.  That way no samples would ever be lost, and no samples would ever be randomly repeated.  Rather than repeating samples, VP would take little slices of each one corresponding to its physics clock.

 

The nice thing about this approach is that it would work with the existing joystick reporting format.  We could easily change Pinscape's reporting format, but I'm sure none of the commercial guys are going to adopt my "integration" scheme.  The downside is that the implementation would be complicated, particularly because Raw Input is a huge PITA for joysticks.  It's completely doable, but the APIs are really low-level and hard to work with.



#493 DJRobX

DJRobX

    Pinball Fan

  • VP Dev Team
  • PipPipPipPip
  • 941 posts
  • Location:Valencia, CA

  • Flag: United States of America

  • Favorite Pinball: F14 Tomcat

Posted 01 December 2017 - 12:16 AM

Yeah, it sounds like RawInput is the way to go here.   From what I can see, it means we can accept the accelerometer data as input packets, rather than "fishing" for data and guessing at when it was last changed.   I'll look into this also,


Edited by DJRobX, 01 December 2017 - 12:16 AM.


#494 mjr

mjr

    Pinball Wizard

  • Members
  • PipPipPipPipPip
  • 3,332 posts

  • Flag: United States of America

  • Favorite Pinball: Medieval Madness

Posted 01 December 2017 - 01:05 AM

Yeah, it sounds like RawInput is the way to go here.   From what I can see, it means we can accept the accelerometer data as input packets, rather than "fishing" for data and guessing at when it was last changed.   I'll look into this also,

 

Exactly.  Raw Input works by delivering the USB packets from the device without any interpretation.  Whenever a USB packet arrives, Raw Input sends a WM_INPUT message to a designated window; the window proc reads the input and picks it apart.  All you get is the raw binary data from the USB wire, so you have to pick it apart yourself.  Well, okay, it's not quite *that* bad; the HID API actually does most of the heavy lifting for interpreting the bytes into joystick control elements.  But it's much more cumbersome than DirectInput's API, which gives you pretty straightforward joystick control values.  Even so, it's much better in that you get every packet and know exactly when it came in.  (Or close enough to exactly, anyway.  WM_INPUT latency is practically zero.  Other gaming developers think this is the main reason that MSFT deprecated DirectInput.  DI uses Raw Input under the covers, and layers its own threading model on top of it, which adds latency and CPU overhead for the thread context switching and mutexes and so on.)  I think WM_INPUT is close enough to real-time that you could timestamp the packets when you read them and not have to do any timestamping at the device level - again, good because it would work with all existing devices without any changes.



#495 DJRobX

DJRobX

    Pinball Fan

  • VP Dev Team
  • PipPipPipPip
  • 941 posts
  • Location:Valencia, CA

  • Flag: United States of America

  • Favorite Pinball: F14 Tomcat

Posted 01 December 2017 - 01:44 AM

Just for fun I tried a quick and dirty hack:

 

  if (cfg.joystickEnabled && jsReportTimer.read_us() > 8333UL)
  {
            // read the accelerometer
            static int xa, ya;
            static int flip = 1;
            if (flip)
                accel.get(xa, ya);
            flip = 1 - flip;

 

Seems to work fine.   So now I'm getting my more desirable nudging behavior without increasing button latency.  

I still can't believe the difference.   I have tilt sensitivity all the way up to 900 and dead zone down to 3.     I can play Walking Dead which has always been a problem table because of its near constant shaker use and it doesn't even blip.   Yet if I bump the cab it's nicely registering "Danger!".    I've never had nudging working anywhere remotely this well before.  This has been a pain point for me for years, so while there's more work to do this is a small victory for me!

BTW MJR, your code is probably the best commented, most easy for me to follow that I've ever seen in my whole life.   Thank you again for making this project open source and all the hard work you've put into it.   

 



#496 mjr

mjr

    Pinball Wizard

  • Members
  • PipPipPipPipPip
  • 3,332 posts

  • Flag: United States of America

  • Favorite Pinball: Medieval Madness

Posted 01 December 2017 - 02:21 AM

Just for fun I tried a quick and dirty hack:

  if (cfg.joystickEnabled && jsReportTimer.read_us() > 8333UL)
  {
            // read the accelerometer
            static int xa, ya;
            static int flip = 1;
            if (flip)
                accel.get(xa, ya);
            flip = 1 - flip;

Seems to work fine.   So now I'm getting my more desirable nudging behavior without increasing button latency.  

 

I'll definitely have to add a setting for the joystick timing, then.  Seems like a great stopgap until VP can be upgraded to deal with the timing issues itself.  If that ever happens; like most stopgaps, it'll probably end up being the permanent solution. :)



#497 mjr

mjr

    Pinball Wizard

  • Members
  • PipPipPipPipPip
  • 3,332 posts

  • Flag: United States of America

  • Favorite Pinball: Medieval Madness

Posted 14 December 2017 - 12:26 AM

I've updated the firmware and config tool with configurable joystick report timing, along the lines that DJRobX experimented with and found helpful.  It lets you set the report interval in milliseconds, and a "stutter" rate for the accelerometer.  The stutter controls how often the accelerometer is sampled: 1 means sample on every joystick report, 2 means sample on every *other* report, and so on.  If you set an interval of 8.333ms and a stutter of 2, it will have the effect of reading the acclerometer every 16.667ms, which should line up closely with the video refresh cycle.

 

This is all discussed above (earlier in the thread), but to summarize, DJRobX found that VP's nudge performance could be greatly improved by timing the accelerometer reports from the KL25Z to match the video refresh timing on the PC.  On most systems, that will be 60Hz, which translates to 16.667ms.  The "stutter" is an additional control that lets you send joystick reports at one rate, and take accelerometer readings at longer intervals.  The reason you might want to do this is to minimize latency for joystick button reporting, by using a fast joystick report rate, while using a slower rate for sampling the accelerometer.

 

DJRobX found the ideal settings on his system are a joystick reporting interval of 8.333ms and a stutter rate of 2.  The optimal settings might vary on different systems, though, because the critical element is VP's input cycle.  If you have VP locked to the video rate, and your video card is set to 60Hz refresh, these settings will probably work best on your system as well.  But you might have to experiment a bit to find the ideal settings.  The thing we're trying to optimize here is nudge performance in VP - specifically, making it uniform and predictable, so that it responds linearly to nudges, rather than seeming random or erratic (overreacting to some nudges, underreacting to others).


Edited by mjr, 14 December 2017 - 12:34 AM.


#498 cenutrio

cenutrio

    Neophyte

  • Members
  • Pip
  • 9 posts

  • Flag: Spain

  • Favorite Pinball: whitewater

  • 360 Gamer Tag: ATRAKAVIEJAS

Posted 27 December 2017 - 10:20 AM

 mjr thanks for the hard work of program pinscape and answer the dudes in the forums.

i  have to read many post by step by step is working my pinscape



#499 xm41907

xm41907

    Neophyte

  • Members
  • Pip
  • 2 posts

  • Flag: ---------

  • Favorite Pinball: addams family

Posted 30 December 2017 - 04:18 PM

Just an FYI (as I didn't see it mentioned anywhere, maybe I missed it)

I just picked up a KL25Z and it didn't need any firmware updates to work - just plugged it in and it had the newer firmware on out of the box, so I just ran the tool and installed Pinscape :)

I just got one through Amazon and it didn't need a firmware update.   :)



#500 xm41907

xm41907

    Neophyte

  • Members
  • Pip
  • 2 posts

  • Flag: ---------

  • Favorite Pinball: addams family

Posted 31 December 2017 - 01:01 AM

I'm sure I'm missing something somewhere, but I don't see a wiring diagram for using the KL25Z with arcade buttons anywhere.  can someone point me to one?  







Also tagged with one or more of these keywords: pinscape