raspberry-piplaystation

Analog control Raspberry pi using pyPS4Controller


I have a Raspberry Pi with a robotic kit and I would like to control it using a PS4 controller but using analog input. I have successfully connected the controller and I can read events and program the motors to answer binary input. The documentation (pyPS4Controller), however, is not explicit about using analog values (Ex: 50% press on R2 outputs 0.5 forward).

Could someone please help me figure out how to make this?
Thanks in advance!

# This is the example for binary buttons

from pyPS4Controller.controller import Controller

class MyController(Controller):

    def __init__(self, **kwargs):
        Controller.__init__(self, **kwargs)

    def on_x_press(self):
       print("Forward")

    def on_x_release(self):
       print("Stop")

# --> The objective is having some way to capture the "intensity" of the button press to use the motors accordingly

controller = MyController(interface="/dev/input/js0", connecting_using_ds4drv=False)
controller.listen()

Solution

  • After some tweaking and trial and error I ended up finding a solution. The analog functions receive an input called value containing the analog value of the input given to the controller.

    from pyPS4Controller.controller import Controller
    from gpiozero import CamJamKitRobot as camjam
    
    # Translate controller input into motor output values
    def transf(raw):
        temp = (raw+32767)/65534
        # Filter values that are too weak for the motors to move
        if abs(temp) < 0.25:
            return 0
        # Return a value between 0.3 and 1.0
        else:
            return round(temp, 1)
    
    class MyController(Controller):
    
        def __init__(self, **kwargs):
            Controller.__init__(self, **kwargs)
            self.robot = camjam()
        
        def on_R2_press(self, value):
            # 'value' becomes 0 or a float between 0.3 and 1.0
            value = transf(value)
            self.robot.value = (value, value)
            print(f"R2 {value}")
        
        def on_R2_release(self):
            self.robot.value = (0,0)
            print(f"R2 FREE")
        
        def on_L2_press(self, value):
            # 'value' becomes 0 or a float between -1.0 and -0.3
            value = -transf(value)
            self.robot.value = (value, value)
            print(f"L2 {value}")
        
        def on_L2_release(self):
            self.robot.value = (0,0)
            print(f"L2 FREE")
        
        # Press OPTIONS (=START) to stop and exit
        def on_options_press(self):
            print("\nExiting (START)")
            self.robot.value = (0,0)
            exit(1)
    
    
    controller = MyController(interface="/dev/input/js0", connecting_using_ds4drv=False)
    controller.listen()