gpt4 book ai didi

python - 消除操纵杆按钮输入的抖动

转载 作者:行者123 更新时间:2023-12-01 06:09:37 26 4
gpt4 key购买 nike

我有一个用 python 和 gobject 编写的操纵杆类,除了一个小问题之外,它工作得很好。当我运行下面的代码时,按钮弹跳,它会多次按下所有按钮。如何以合理的准确度将其减少到每次按下按钮一条消息?

''' 
Copyright 2009 Jezra Lickter

This software is distributed AS IS. Use at your own risk.
If it borks your system, you have been forewarned.

This software is licensed under the LGPL Version 3
http://www.gnu.org/licenses/lgpl-3.0.txt


for documentation on Linux Joystick programming please see
http://www.mjmwired.net/kernel/Documentation/input/joystick-api.txt
'''

import gobject #needed for sending signals
import struct #needed for holding chunks of data

class Joystick(gobject.GObject):
'''The Joystick class is a GObject that sends signals that represent
Joystick events'''
EVENT_BUTTON = 0x01 #button pressed/released
EVENT_AXIS = 0x02 #axis moved
EVENT_INIT = 0x80 #button/axis initialized
#see http://docs.python.org/library/struct.html for the format determination
EVENT_FORMAT = "IhBB"
EVENT_SIZE = struct.calcsize(EVENT_FORMAT)

# we need a few signals to send data to the main
'''signals will return 4 variables as follows:
1. a string representing if the signal is from an axis or a button
2. an integer representation of a particular button/axis
3. an integer representing axis direction or button press/release
4. an integer representing the "init" of the button/axis
'''
__gsignals__ = {
'axis' :
(gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
(gobject.TYPE_INT,gobject.TYPE_INT,gobject.TYPE_INT)),
'button' :
(gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
(gobject.TYPE_INT,gobject.TYPE_INT,gobject.TYPE_INT))
}


def __init__(self,dev_num):
gobject.GObject.__init__(self)
#define the device
device = '/dev/input/js%s' % dev_num
#error check that this can be read
try:
#open the joystick device
self.device = open(device)
#keep an eye on the device, when there is data to read, execute the read function
gobject.io_add_watch(self.device,gobject.IO_IN,self.read_buttons)
except Exception,ex:
#raise an exception
raise Exception( ex )

def read_buttons(self, arg0='', arg1=''):
''' read the button and axis press event from the joystick device
and emit a signal containing the event data
'''
#read self.EVENT_SIZE bytes from the joystick
read_event = self.device.read(self.EVENT_SIZE)
#get the event structure values from the read event
time, value, type, number = struct.unpack(self.EVENT_FORMAT, read_event)
#get just the button/axis press event from the event type
event = type & ~self.EVENT_INIT
#get just the INIT event from the event type
init = type & ~event
if event == self.EVENT_AXIS:
signal = "axis"
elif event == self.EVENT_BUTTON:
signal = "button"
if signal:
print("%s %s %s %s" % (signal,number,value,init) )
self.emit(signal,number,value,init)

return True

if __name__ == "__main__":
try:
j = Joystick(0)
loop = gobject.MainLoop()
loop.run()
except Exception,e:
print(e)

最佳答案

有很多方法可以消除按钮的抖动。一种简单的、非阻塞的方法是:

  1. 随着时间的推移反复检查按钮的状态......
  2. ...如果按钮“瞬时”状态不是被视为“事件”的状态,那么...
  3. ...增加计数器并...
  4. ...如果计数器达到给定阈值,则切换按钮的“事件”状态。
  5. 每次“瞬时”和“事件”状态相同时,应重置计数器

当然,此方法要求检查程序以合理的定期间隔运行,因为 react 时间由频率*阈值给出。

编辑:我没有实际运行它的硬件,但去抖方法应该类似于:

if button_now() != button_state:
debounce_counter += 1
if debounce_counter == DEBOUNCE_THRESHOLD:
button_state = not button_state
else:
debounce_counter = 0

在上面的代码中:

  • button_now() 轮询硬件(并根据按钮电路是否闭合或打开返回 True/False),
  • button_state 是程序的其余部分如何“看到”按钮(同样:True/False 根据按钮向下或向上),`
  • DEBOUNCE_THRESHOLD 是您根据公式 reaction-time-of-the-button =Frequency-of-debouncing-routine * Threshold 定义的常量。

呵呵!

关于python - 消除操纵杆按钮输入的抖动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6578431/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com