I am currently building a robot that I would like to control with a pair of nice joysticks I bought. Up until now I've been using pygame.joystick with no problems at all with my PS4 controller. However the new joysticks have a problem. They output the correct values for like twenty or thirty seconds and function properly, but then they just freeze on a value. I can't think of any reasons they would work fine for a certain amount time and then all of a sudden just freeze.
My code is as simple as:
pygame.init()
leftjoy = pygame.Joystick.joystick(0)
leftjoy.init()
while True:
print(leftjoy.get_axis(0))
pygame.event.pump()
Update:
I tried this same code on Windows instead of raspberry pi and it worked perfectly. I plan on using ssh when controlling the robot so it should work well for that application. But I would still like to know how to fix this problem for testing.
A couple shots in the dark, without access to your hardware...
Since the PS4 controller works, I'm guessing the code and the RasPi are in good health, so the joysticks themselves might be somewhat buggy. The problem could be that the joysticks momentarily disconnect (power issue, faulty cable, just faulty hardware), and upon reconnect are assigned a new address such as 1. I don't recall that being a common problem in RasPi in general, but PyGame might have issues. Here's another post with some code that might help you detect and debug joystick disconnects in software. To much more quickly test that possibility in hardware, intentionally do a momentary disconnect-connect early, while your game is "working" and see if the same result happens.
Finally, maybe the RasPi is polling too quickly and causes the joystick to freeze. To debug this, you could try putting a delay in your loop.
Related
Our app (Python-based, cythonised and packaged for usage on computers without installed Python) has its GUI based on PySimpleGUI / Tkinter port.
In macOS, we sometimes experience an extremely slow start. On my Mac, from app launch until the main window is completely rendered and ready to use it only takes about 2-3 seconds. But on some of my colleagues' Macs, it sometimes takes 45s or even several minutes. We had this problems with an earlier version of the app but solved it in May by adding a splash window as discussed in PySimpleGUI / Tk: very slow startup on Mac. The new version (= with the splash window) always started quickly (2-3s) on all available computers at various places for several weeks but then (while we haven't changed anything in the app), the slow-start problem appeared again - only on some Macs and even depending on the location: on my colleague's computer, the app always starts in max. 3s at work, but 45s+ when she's at home.
There are Mac, Windows and Linux versions of our app. Only the Mac version has this problem (so far never observed under Win, Linux and also never in Win/Linux emulators on Mac), only on some computers in combination with some locations. At work, it's quick for all the computers our team uses but slow on computers of some of our guests; for my colleague, slow at (her) home; at (my) home, quick on my computer but slow on another one. This is what completely puzzles me!
I've added a lot of logging to the code to be able to see which parts of code take a lot of time. There's only one network interaction (license verification) and it doesn't seem to be slow: the whole function (setting up connection, retrieving the data, processing the data, closing the connection) does not take more than 2s even with those 45s+ starts. All the delays we can see are related to main-window refresh:
logging.info('.created background window', session_log=True)
main_window.refresh()
logging.info('.refreshed main window', session_log=True)
Just this refresh() takes anything between 3-10s or even more on those slow starts. It is a function of PySimpleGUI defined like this:
def refresh(self):
if self.TKrootDestroyed:
return self
try:
rc = self.TKroot.update()
except:
pass
return self
The same functions are used many times after the main window has been rendered completely, but then they are never slow again; it's always just in the start phase of the application.
So, it seems to be Tkinter's update() that takes so long. But why only on some Macs, and (on the same Macs) why only at some places?
Have you ever experienced such a behaviour in your GUI? Do you have any ideas how to deal with it?
I'd be very grateful for any hints.
I recommend replacing calls to .update() with .updateidletasks(). update not only causes the window to refresh, but it has to process all pending events of all types, and won't return until all events are processed. If, while processing an event this code is called again, you end up with event loops nested inside of event loops.
updateidletasks only process the events in the idle queue, which is mostly screen updates and jobs queue with after_idle, greatly reducing the chance you will end up with nested event loops.
I am using the NAO_demo_python controller of the latest version of webots on linux (ubuntu 18) to flash leds and open/close the hands.
However only the last part of the sequences are executed, and not in a single simulation run.
e.g. if i ask to just open the hand and light the leds, after 1 run the lights will be on and after 5 runs of the main while loop it will be opened -reaaallly slowly-. However if i ask lit leds, open hand then close hand unlit leds then the simulation will only close hand and unlit leds.
The code should be working, it is on another person's computer. In case you want it here it is (it's really basic, it's a slight modification of nao-demo-python.py):
def run(self):
while robot.step(self.timeStep) != -1:
self.setAllLedsColor(0xff0000) #red leds on
self.setHandsAngle(0.96) #open hand
#rospy.sleep(5) #originally i am to use webots and nao with ros
print("done") #to check how many runs are made
self.setHandsAngle(0.0) #close hand
self.setAllLedsColor(0x000000) #red leds off
Also, something that may be interesting: if i ask to open close the hand N times and each time print something, all the prints will be printed at once and the simulation time jump from 0:0:0 to 0:0:20 after each main loop run (+20 at each run), else, even if the simulation runs the time doesn't flow, it jumps.
I tried to update my drivers, to take off all shadows and stuff from the simulation, as webots advices. No can do. I couldn't find something on Softbank, i can't find an active forum concerning nao and webots anymore...
I have an i5 9th gen and a GTX1050Ti.
May the problem be that the simulation time isn't 1.0x? but at most 0.05x? (after taking off shadows, effect of lights, all objects, using 1 thread etc, as explained here: https://www.cyberbotics.com/doc/guide/speed-performance)
SUMMARY: Only the last sequence of the controller is executed, and if it's a motion it takes several main loops before being fully executed. Meanwhile the time jumps from 0 to +20s after each main loop run.
May someone help me out to make all the sequence work on simulation please :)
all the prints will be printed at once
Only the last sequence of the controller is executed
It sounds like the setHandsAngle function might be asynchronous (doesn't wait for the hand to move to that point before running the next piece of code)? This could be responsible for at least some of the problems you're experiencing. In this case the rospy.sleep(5) should be replaced with robot.step(5000), so the simulator has time to move the hand before sending the next command.
Thank to your indications, this works:
self.CloseHand = Motion('../../motions/closeHand.motion')
def startMotion(self, motion):
if self.currentlyPlaying: #interrupt current motion
self.currentlyPlaying.stop()
motion.play() #start new motion
self.currentlyPlaying = motion
self.startMotion(self.CloseHand)
while not self.CloseHand.isOver():
robot.step(self.timeStep)
And in the CloseHand.motion :
#WEBOTS_MOTION,V1.0,LPhalanx1,RphalanxN (until 9)
00:00:000,Pose1,0.00,0.00 etc
with 00:00:000 the moment of execution and 0.00 the angle of the hand (phalanx by phalanx).
THANK you very much! I couldn't have realized that without your advice.
The synchronization webots/ros is still unresolved but the issue of my initial question is. Thank you!
I wrote an automated code that basically takes some text from a PDF and then pastes it in a different program. This involves controlling my mouse and keyboard in order to work properly. The code runs fine, but sometimes my computer, or I guess the program I'm using (it's a program run through Citrix) lags a little. When this happens, my code still runs, but because the program is momentarily frozen, it can't click and type correctly.
Is there a way to detect when the program is lagging so that I can pause the code for a few seconds to allow the program to unfreeze? I couldn't find anything similar online
I have done something similar (albeit not from python) and if you know that your lag spikes normally last, say, 3 seconds, you may need to implement a waiting time of 4 seconds between actions, so there is a very good chance that your action has been accepted by the receiving software.
This of course will slow down the actions even when there is no spikes, and won't protect you against larger than usual spikes, but it's a start.
As it sounds I wanted to create my own kinda smart assistant that can actually unlock my pc (Cortana can't and I could not find any good solution for this).
for now, I have tried multiple ways including messing with winlogon.exe and MSGINA.dll. After about 3 hours of search, I haven't found anything that could actually unlock my pc, and I saw some programs that said that they have succeeded in unlocking their pc while messing around with this files but in reality, it just prevents the locking mechanism and it is not my intention.
right now I have seen some videos about using pyautogui and keyboard to control keyboard and mouse movement and I wrote a small script that can "unfold" the windows lock screen cover (where the time and date is displayed) but nothing more than that (it is not working at all)
import keyboard
import time
for i in range(10):
print 10 - i
time.sleep(1)
keyboard.send('enter')
time.sleep(2)
keyboard.write("password1")
keyboard.send("enter")
also tried keyboard.press_and_release and it doesn't do anything.
how can I send any keyboard input to the lock screen?
and if it is not possible, do you have any other suggestions?
EDIT: I am Working on windows 10 build 1803 and python 2.7
I'm trying to read from a PS3 controller in python on Ubuntu and I'm not having much luck. I started with the ps3joy driver from Willow Garage (http://www.ros.org/wiki/ps3joy) which supposedly publishes all the important bits of the PS3 controller to something I had never heard of called "uinput". Apparently it's a linux feature that allows userspace drivers to provide system events. ...Why the WG driver requires root access given that it's supposedly a userspace driver is beyond me, but that's not my question.
Anyway, the current state of me trying to get it to work is that I've got the driver working, and I've verified that it responds to button presses on the controller, but I don't know how to pull any of that data out so I can use it.
My first guess was to use pygame to (hopefully) read from /dev/uinput (which I'm pretty sure is where the driver sends the data):
from pygame import joystick
if not joystick.get_init():
joystick.init()
js = joystick.Joystick(0) # there is only one joystick... even if the driver isn't running(!)
js.init()
print js.get_numbuttons() # perhaps coincidentally correctly prints 17 which is the number of buttons on a PS3 controller
for i in range(js.get_numaxes()):
print js.get_axis(i) # always prints 0, no matter what I'm doing with the controller
but it didn't work. The most telling part of the problem is that it does the same thing if I don't have the WG driver running at all.
I'm sure this is something easy, that I'm just not reading the right information, but googling has not helped me find what the right information is and I'm getting tired and desperate.
You don't need the driver. Assuming the controller exposes itself as a HID, you can use the event subsystem to read controller events directly from the device.
I know it's too late, but if anyone will ever need the code or is struggling with it, you can use mine. I've wrote a script in python that gets ps3 data from USB and sends it to specific a MAC address via PC's bluetooth (you can use ps3controller.py only for data).
This was made for my quadcopter project.
https://github.com/urbanzrim/ps3controller
Try
pygame.event.pump()
before you read the joystick. I needed it to work with the 360 controller
I believe you need the following at the very least:
from pygame import joystick, event, display
display.init()
joystick.init()
js=joystick.Joystick(0)
js.init()
...
for foo in bar:
event.pump()
...
if foo:
event.pump()
...
while bar:
event.pump()
...
I believe that display.init() has to be there because it is needed for event handling...
Also, you can skip a lot of that with
import pygame
pygame.init()
js=pygame.joystick.Joystick(0)
js.init()
...
for foo in bar:
pygame.event.pump()
...
if foo:
pygame.event.pump()
...
while bar:
pygame.event.pump()
....
I could be wrong, but I think your issues are:
A) No event.pump in your if/while/for clauses
B) No display.init()
Sources:
http://webcache.googleusercontent.com/search?q=cache:I56GyE7I4CkJ:iamtherockstar.com/archive/making-hid-devices-easier-using-pygame-joysticks/+&cd=1&hl=en&ct=clnk&gl=us
and
http://www.pygame.org/docs/ref/event.html
"The input queue is heavily dependent on the pygame display module."
Solving similar problem right now: communicate/receive data from PS3 bluetooth remote with python in GNU/Linux.
What i found helpful:
Debugging PS3 Controller http://www.pabr.org/sixlinux/sixlinux.en.html
Looks like working project, for PS3 Remote http://kitlaan.twinaxis.com/projects/bluez-ps3remote/ (it requires to patch bluez 1st) did not tested, yet.
pybluez BT wrapper http://code.google.com/p/pybluez/ (checking it right now)