Skip to content

Trigger and Move Button have a lot of dropouts #380

Open

Description

@Jaywalker64

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.

Activity

  1. nitsch commented on Feb 12, 2019

    @nitsch
    Collaborator
  2. Jaywalker64 commented on Feb 12, 2019

    @Jaywalker64
    Author

    ZCM2

  3. nitsch commented on Feb 12, 2019

    @nitsch
    Collaborator
  4. Jaywalker64 commented on Feb 13, 2019

    @Jaywalker64
    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%.

  5. nitsch commented on Feb 13, 2019

    @nitsch
    Collaborator

    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.
        }
    }
  6. Jaywalker64 commented on Feb 14, 2019

    @Jaywalker64
    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.

  7. nitsch commented on Feb 14, 2019

    @nitsch
    Collaborator
                // 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.

  8. Jaywalker64 commented on Feb 18, 2019

    @Jaywalker64
    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?

  9. nitsch commented on Feb 19, 2019

    @nitsch
    Collaborator

    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.

  10. thp commented on Feb 20, 2019

    @thp
    Owner

    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?

  11. thp commented on Feb 20, 2019

    @thp
    Owner

    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
    
  12. nitsch commented on Feb 21, 2019

    @nitsch
    Collaborator
  13. Jaywalker64 commented on Mar 1, 2019

    @Jaywalker64
    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.

  14. nitsch commented on Mar 5, 2019

    @nitsch
    Collaborator
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions