at rest event triggering too often
ArminBmrt opened this issue · 4 comments
Hi,
I am trying to get some simple analog values from the controller. The values are x (up/down) and y (left/right) and these values should also be zero when released.
Output from my test move is below: I move the left joystick to its maximum right position and a bit up. When I slowly move the joystick lower the at rest event
is triggered when the x is zero. The problem is only one axis is at rest, the other one still has some input.
In my code I set both x and y to zero when at rest. This does not work because only x is zero and y still has a value. When I remove the at rest event
the output is never zero
Is this the intended behaviour and how is it possible to get the correct output?
Output from a test run:
Waiting for interface: /dev/input/js0 to become available . . .
x: 0.00 y: 0.00
Successfully bound to: /dev/input/js0.
x: 0.00 y: 0.00
x: 0.00 y: 0.00
x: 0.00 y: 0.00
x: 0.00 y: 0.00
x: 0.54 y: 1.00
x: 0.18 y: 1.00
x: 0.10 y: 1.00
At rest
x: 0.00 y: 0.00
x: 0.00 y: 0.00
At rest
At rest
x: 0.00 y: 0.00
x: 0.00 y: 0.00
x: 0.00 y: 0.00
x: 0.00 y: 0.00
x: 0.00 y: 0.00
^CTraceback (most recent call last):
File "./test.py", line 62, in <module>
time.sleep(0.5)
KeyboardInterrupt
My test code:
#!/usr/bin/python3
import threading
import time
from pyPS4Controller.controller import Controller
from pyPS4Controller.controller import Event
class MyController(Controller):
def __init__(self, **kwargs):
Controller.__init__(self, **kwargs)
self.scale = 32767
self.x = 0.0
self.y = 0.0
def start(self):
self.start_thread = threading.Thread(target=self.run, args=())
self.start_thread.daemon = True # Daemonize thread
self.start_thread.start()
# Auto setup connection and start thread and stuff
def run(self):
while True:
self.listen()
self.stop_motion()
print('listen exit, should not happen')
time.sleep(1)
def stop_motion(self):
self.x = 0.0
self.y = 0.0
def on_connect_callback(self):
super()
print('Hoi on_connect_callback event')
def on_disconnect_callback(self):
print('Hoi on disconnect event')
def on_L3_up(self, value):
self.x = value / self.scale
def on_L3_down(self, value):
self.x = value / self.scale
def on_L3_left(self, value):
self.y = value / self.scale
def on_L3_right(self, value):
self.y = value / self.scale
def on_L3_at_rest(self):
self.x = 0.0
self.y = 0.0
print('At rest')
controller = MyController(interface="/dev/input/js0", connecting_using_ds4drv=False, event_format="3Bh2b")
controller.start()
while True:
print(f'x: {controller.x:.2f} y: {controller.y:.2f}')
time.sleep(0.5)
Hey Artur, could you please make a quick edit so that the button_id of the joystick is returned with the R3_at_rest() and L3_at_rest() in your event handler. That way we can distinguish between the horizontal and vertical joystick rest positions.
I hacked it quickly just to test. I copied controller.py to my own project. I forgot to commit until all changes were done so I do not have a diff.
I basically replaced the L3 events with two of my own in the listen method of the Controller class
elif event.L3_event():
if event.button_id == 1:
self.on_L3_up_down(value)
elif event.button_id == 0:
self.on_L3_left_right(value)
# if event.L3_at_rest():
# self.on_L3_at_rest()
# elif event.L3_up():
# self.on_L3_up(value)
# elif event.L3_down():
# self.on_L3_down(value)
# elif event.L3_left():
# self.on_L3_left(value)
# elif event.L3_right():
# self.on_L3_right(value)
And when inheriting the class I override these fuctions with:
def on_L3_up_down(self, value):
self.x = -value / self.scale
def on_L3_left_right(self, value):
self.y = value / self.scale
This gives me a value between -1 and 1 for each axis. For my application this makes more sense than a up,down,left,right event.
@ArminBmrt I see the issue. Looks like both axis will trigger the at rest events.
...
def L3_at_rest(self):
return self.button_id in [1, 0] and self.value == 0
...
I'll look into splitting that event into two separate events for each axis.
@ArminBmrt Pushed a fix to dev branch, unfortunately I do not have anywhere to test the fix on right now, if you can confirm its working - I can push it to master and deploy new version to Pypi.