Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trigger and Move Button have a lot of dropouts #380

Open
Jaywalker64 opened this issue Feb 12, 2019 · 14 comments
Open

Trigger and Move Button have a lot of dropouts #380

Jaywalker64 opened this issue Feb 12, 2019 · 14 comments

Comments

@Jaywalker64
Copy link

All Buttons except Trigger and Move have a high fidelity. Pressing them gives the expected response of pressed and released. The Trigger and Move are less responsive. The faster you click one of those, the less click events are published. This behaviour is seen in the example and example_new_api, Windows 7 and 10 with inbuilt Bluetooth.

@nitsch
Copy link
Collaborator

nitsch commented Feb 12, 2019 via email

@Jaywalker64
Copy link
Author

ZCM2

@nitsch
Copy link
Collaborator

nitsch commented Feb 12, 2019 via email

@Jaywalker64
Copy link
Author

I had different tests:
1.Console Output
2. Lighting the bulb
2.a with limiter
2.b w/o limiter
3. psmove.exe responsiveness : move button should switch light to white, this did not happen on every button click
4. Switched to desktop with external bluetooth adapter, problem still there.

What helped was re-pairing the psmove. After that the buttons did response correctly, but after some time the error reappears and Move/Trigger Button are coming through approximately 3 out of 10 times.
Re-pairing every time this happens is unfortunately not an option and it is not fully tested, whether this workaround helps 100%.

@nitsch
Copy link
Collaborator

nitsch commented Feb 13, 2019

Does the behaviour change if, prior to calling psmove_poll() in your update loop, you consume input reports that might have stacked up? Like so:

while (keep_running) {
    // consume old input reports
    while (psmove_poll(move)) {
        ;
    }

    // get latest input report
    if (psmove_poll(move)) {
        unsigned int buttons = psmove_get_buttons(move);

        // handle button presses etc.
    }
}

@Jaywalker64
Copy link
Author

When i do it like your example i only get infrequent updates from the move controller for all buttons.
For a simple test of the move button i did it like that:

 
           while (psmove_poll(it->second)) {
                ;
            }

            // get latest input report
            if (!psmove_poll(it->second)) {
                unsigned int buttons = psmove_get_buttons(it->second); 
           
                if (buttons & Btn_MOVE) 
                {
                    if (lastbuttons[Btn_MOVE] != ((buttons & Btn_MOVE) == 524288))
                    {                       
                        mStopWatch->stop();
                        int64_t elapsedTime = mStopWatch->elapsedMicroseconds();
                        printf("Move is pressed: %d\n", elapsedTime);
                        mStopWatch->start();
                    }                    
                }
                else
                {
                    if (lastbuttons[Btn_MOVE] != ((buttons & Btn_MOVE) == 524288))
                    {                    
                        mStopWatch->stop();
                        int64_t elapsedTime = mStopWatch->elapsedMicroseconds();
                        printf("Move is released: %d\n", elapsedTime);
                        mStopWatch->start();
                    }
                }
             }

My current implementation has this form:

int delay = psmove_poll(it->second);
while (delay != 0)
{
    delay = psmove_poll(it->second);
}
unsigned int pressed, released;
psmove_get_button_events(it->second, &pressed, &released);
for (unsigned int j = 0; j < mButtonMaskVector.size(); ++j)
{
    //handle buttons
}

Results for the time it took to get the release event after having the button pressed and releasing it(in microseconds):
Move: 648426
Triangle: 63100

Pressed and released the Buttons as fast as i could(not highly sophisticated, but gives a overview). Move Button takes 10 times longer.

@nitsch
Copy link
Collaborator

nitsch commented Feb 14, 2019

            // get latest input report
            if (!psmove_poll(it->second)) {
                unsigned int buttons = psmove_get_buttons(it->second); 

You got this check backwards. psmove_poll returns 0 on error or if no new data is available.

@Jaywalker64
Copy link
Author

I had the issue of infrequent updates using

  if (psmove_poll(it->second))    

as you wrote it. With

  if (!psmove_poll(it->second))    

i get updates. I know this is contra to the return value. That's why my second code does not have this.
For clarification the first code is a different implementation than the second.
Another question on top of that. The return of psmove_poll with no new data isn't that the status we want? We are up to date with the polling. Problematic is of course that it has the same value as error, whatever an error could occur.

Coming back to my original problem. In the device property all buttons are coming through perfectly.
psmovecontroller
The different ways of using psmove_poll did not improve my situation.

Does it make a difference that the move controller is a ZCM2E? Is there a possibility to check or get more information out of the HIDAPI about the psmove controller? Lost Data or something like that, to better test or get a more profound unterstanding?

@nitsch
Copy link
Collaborator

nitsch commented Feb 19, 2019

The return of psmove_poll with no new data isn't that the status we want? We are up to date with the polling.

Yes, I realized that my suggestion was a bit broken. We would rather remove the additional check if (psmove_poll(move)) and just keep the initial while (psmove_poll(move)) {}.

Does it make a difference that the move controller is a ZCM2E?

I don't know. I could not yet test your problem on Windows.

Is there a possibility to check or get more information out of the HIDAPI about the psmove controller? Lost Data or something like that, to better test or get a more profound unterstanding?

You could just have a look at the implementation. On Windows, hidapi is using the HidD API for setup and feature reports, and regular file I/O for input and output reports (button data is in the input report). If you spot something that might help tracking down and fixing your problem, any feedback would be appreciated.

@thp
Copy link
Owner

thp commented Feb 20, 2019

Please also check out the docs in the header file: https://github.com/thp/psmoveapi/blob/master/include/psmove.h#L635

Here's the lowdown: If you want to process all events, you MUST use:

     while (psmove_poll(move)) {
         // process events here
     }

Note that ideally the event processing is "cheap" in the sense that it doesn't take forever (e.g. don't draw the UI or something, just update the internal state). If processing is "expensive" and takes a while, the system might start dropping input events if they are not consumed. This behavior is probably different in Windows, Linux and macOS.

If you do a while (psmove_pool(move)) {} (i.e. not actually process events when they arrive), you will read events and not handle them, so it's expected to not see all events. Same goes for checking if the result is zero -- when it is, it just means that since the last read there were no new updates.

The docs say:

 * \return a positive sequence number (1..16) if new data is
 *         available
 * \return \c 0 if no (new) data is available or an error occurred

I am not sure if this is the case for ZCM2E too (don't have one here for testing), but assuming it still is, you can also use the return value to see if there were any dropped frames.

Currently we take the sequence that is returned from this:

move->input.common.buttons4 & 0x0F

It might very well be that ZCM2E does not write this field (or writes it in a different spot). But anyway, psmove_poll() should still return a non-zero value in this case.

Can you for comparison try with the ZCM1 controller?

@thp
Copy link
Owner

thp commented Feb 20, 2019

Also, this part of the documentation:

 * How to detect dropped frames:
 *
 * \code
 *     int seq_old = 0;
 *     while (1) {
 *         int seq = psmove_poll(move);
 *         if ((seq_old > 0) && ((seq_old % 16) != (seq - 1))) {
 *             // dropped frames
 *         }
 *         seq_old = seq;
 *     }
 * \endcode

@nitsch
Copy link
Collaborator

nitsch commented Feb 21, 2019 via email

@Jaywalker64
Copy link
Author

Can you for comparison try with the ZCM1 controller?

I only have ZCM2E Controllers.

I can confirm that the T button and the Move button are rather unresponsive while the other buttons seem to work just fine.

That are good news for me, that you could reproduce my issue. I had no time for further tests. But if you have a clue or could use some support, i gladly help out. Do you have an idea when you can look into the issue? I would very much appreciate fixing this.

@nitsch
Copy link
Collaborator

nitsch commented Mar 5, 2019 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants