Last active
December 22, 2023 03:33
-
-
Save artpoz/d66f72a6092b580b9903d088dd6d1262 to your computer and use it in GitHub Desktop.
Lego vehicle controlled by ps4 gamepad (DualShock 4)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
__author__ = 'Artur Poznanski' | |
import evdev | |
import ev3dev.auto as ev3 | |
import threading | |
import time | |
## Some helpers ## | |
def clamp(n, minn, maxn): | |
return max(min(maxn, n), minn) | |
def scale(val, src, dst): | |
return (float(val - src[0]) / (src[1] - src[0])) * (dst[1] - dst[0]) + dst[0] | |
def scale_stick(value): | |
return scale(value,(0,255),(-1000,1000)) | |
def dc_clamp(value): | |
return clamp(value,-1000,1000) | |
## Initializing ## | |
print("Finding ps4 controller...") | |
devices = [evdev.InputDevice(fn) for fn in evdev.list_devices()] | |
ps4dev = devices[0].fn | |
gamepad = evdev.InputDevice(ps4dev) | |
forward_speed = 0 | |
side_speed = 0 | |
running = True | |
class MotorThread(threading.Thread): | |
def __init__(self): | |
self.right_motor = ev3.LargeMotor(ev3.OUTPUT_C) | |
self.left_motor = ev3.LargeMotor(ev3.OUTPUT_B) | |
threading.Thread.__init__(self) | |
def run(self): | |
print("Engine running!") | |
while running: | |
self.right_motor.run_forever(speed_sp=dc_clamp(forward_speed+side_speed)) | |
self.left_motor.run_forever(speed_sp=dc_clamp(-forward_speed+side_speed)) | |
self.right_motor.stop() | |
self.left_motor.stop() | |
motor_thread = MotorThread() | |
motor_thread.setDaemon(True) | |
motor_thread.start() | |
for event in gamepad.read_loop(): #this loops infinitely | |
if event.type == 3: #A stick is moved | |
if event.code == 0: #X axis on left stick | |
forward_speed = -scale_stick(event.value) | |
if event.code == 1: #Y axis on left stick | |
side_speed = -scale_stick(event.value) | |
if side_speed < 100 and side_speed > -100: | |
side_speed = 0 | |
if forward_speed < 100 and forward_speed > -100: | |
forward_speed = 0 | |
if event.type == 1 and event.code == 305 and event.value == 1: | |
print("X button is pressed. Stopping.") | |
running = False | |
time.sleep(0.5) # Wait for the motor thread to finish | |
break |
roachdaniel
commented
Jan 28, 2021
via email
Thanks for your help. I'll let you know how it turns out. Have a great day!
Dan
…On Wed, Jan 27, 2021 at 6:49 PM Quantum357 ***@***.***> wrote:
***@***.**** commented on this gist.
------------------------------
It's been a while since I've worked with this, but I'll see if I can help.
I'm pretty sure that it doesn't like having assigned ports disconnected,
and in the Error log I see this: 'Exception: LargeMotor(outC) is not
connected' which leads me to think that this is (A) incorrectly assigned,
(B) accidentally unplugged, or (C) the wrong motor type. Check if any of
these are the case.
On Wed, Jan 27, 2021 at 5:37 PM roachdaniel ***@***.***>
wrote:
> ***@***.**** commented on this gist.
> ------------------------------
>
> Sorry for a dumb question but, I am using your code with the ev3dev os
> with a Pistorms-V2 module. I have everything set up correctly and can run
> the OS and I have paired the ps4 controller successfully but I am not
> getting any response when I run your program. Any suggestions? The error
> log is below if that is helpful.
>
> _**Exception in thread Thread-1:
> Traceback (most recent call last):
> File "/usr/lib/python3.5/threading.py", line 914, in _bootstrap_inner
> self.run()
> File "/home/robot/ps4explor3r.py", line 42, in run
> self.right_motor.run_forever(speed_sp=dc_clamp(forward_speed+side_speed))
> File "/usr/lib/python3/dist-packages/ev3dev/core.py", line 799, in
> run_forever
> setattr(self, key, kwargs[key])
> File "/usr/lib/python3/dist-packages/ev3dev/core.py", line 589, in
speed_sp
> self._speed_sp = self.set_attr_int(self._speed_sp, 'speed_sp', value)
> File "/usr/lib/python3/dist-packages/ev3dev/core.py", line 223, in
> set_attr_int
> return self._set_attribute(attribute, name, str(int(value)))
> File "/usr/lib/python3/dist-packages/ev3dev/core.py", line 216, in
> _set_attribute
> raise Exception("%s is not connected" % self)
> Exception: LargeMotor(outC) is not connected
>
> Traceback (most recent call last):
> File "/home/robot/ps4explor3r.py", line 51, in
> for event in gamepad.read_loop(): #this loops infinitely
> File "/usr/lib/python3/dist-packages/evdev/device.py", line 254, in
> read_loop
> r, w, x = select([self.fd], [], [])
> KeyboardInterrupt**_
>
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub
> <
https://gist.github.com/d66f72a6092b580b9903d088dd6d1262#gistcomment-3610351
>,
> or unsubscribe
> <
https://github.com/notifications/unsubscribe-auth/AODJGCDRBY7PAYRDNHDWZG3S4CPTHANCNFSM4HHRPTOQ
>
> .
>
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<https://gist.github.com/d66f72a6092b580b9903d088dd6d1262#gistcomment-3610473>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AORWB3CX6PUSHLB35TLDPTTS4DGETANCNFSM4HHRPTOQ>
.
There's a little problem in the stopping code. 305 is the O button, not the X button.
Is there a micropython version of this code? I wanted to the ps4 controller for a robot competition and waiting 20 whole seconds is not great. Can anyone help? (it will be great if i can control the motor separately with each joystick on my ps4)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment