我正在尝试使用通过蓝牙连接到树莓派的 ps4 控制器来控制机器人,但 while 循环有问题,我需要让它移动。机器人以使其行走的模式循环腿部位置。我制作了一个成功的程序,使用键盘按住 w、a、s 或 d 将使机器人沿通常的方向移动,并在释放后停止机器人。然而,ps4 控制器使用函数进行输入的方式让我感到困惑。
这是键盘代码:
from move import move, steady, steady_X
import sys, tty, termios, time
import Adafruit_PCA9685
def getch():
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setraw(sys.stdin.fileno())
ch = sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return ch
pwm = Adafruit_PCA9685.PCA9685()
if __name__ == '__main__':
step = 1
move_stu = 1
try:
while 1:
char = getch()
if char == 'x':
pwm.set_all_pwm(0,300)
time.sleep(1)
break
if char == 'w':
move(step, 35, 'forward')
step += 1
if step > 4:
step = 1
time.sleep(0.08)
if char == 's':
move(step, 35, 'backward')
step += 1
if step > 4:
step = 1
time.sleep(0.08)
if char == 'a':
move(step, 35, 'left')
step += 1
if step > 4:
step = 1
time.sleep(0.08)
if char == 'd':
move(step, 35, 'right')
step += 1
if step > 4:
step = 1
time.sleep(0.08)
if char == 'e':
pwm.set_all_pwm(0,300)
time.sleep(0.1)
steady_X()
if char == ' ':
steady()
except KeyboardInterrupt:
pwm.set_all_pwm(0,300)
time.sleep(1)
其中 35 是机器人的速度。
控制器代码为:
from pyPS4Controller.controller import Controller
from move import move, steady, steady_X
import sys, tty, termios, time
import Adafruit_PCA9685
class MyController(Controller):
def __init__(self, **kwargs):
Controller.__init__(self, **kwargs)
self.step = 1
self.pwm = Adafruit_PCA9685.PCA9685()
self.command = False
def on_x_press(self):
self.command = True
while self.command == True:
move(self.step, 35, 'forward')
self.step +=1
if self.step > 4:
self.step = 1
time.sleep(0.08)
def on_x_release(self):
self.command = False
controller = MyController(interface="/dev/input/js0", connecting_using_ds4drv = False, event_definition = None)
controller.listen()
一旦调用了controller.listen(),它就会开始从控制器获取输入。 现在,一旦按下x,机器人就会向前移动,松开时不会停止。所以我的问题是当 x 被释放并且 on_x_release(self) 函数被调用时,如何让它停止移动?
我可能无法直接解决您的问题,因为我没有硬件来测试它,但您可以考虑编写一个
stop()
函数,在其中明确将所有电机设置为 0 位置 (如果您使用 H -桥控制器,这意味着将两个通道设置为关闭)。然后,在调用函数 on_x_release(self)
时,您将像平常一样将 self.command 标志设置为 False,而且还可以调用 stop()
函数来显式停止电机移动。
from pyPS4Controller.controller import Controller
from move import move, steady, steady_X
import sys, tty, termios, time
import Adafruit_PCA9685
class MyController(Controller):
def __init__(self, **kwargs):
Controller.__init__(self, **kwargs)
self.step = 1
self.pwm = Adafruit_PCA9685.PCA9685()
self.command = False
def on_x_press(self):
self.command = True
while self.command == True:
move(self.step, 35, 'forward')
self.step +=1
if self.step > 4:
self.step = 1
time.sleep(0.08)
def on_x_release(self):
self.command = False
stop() # (or modify the move function to accept a 'stop' string)
controller = MyController(interface="/dev/input/js0", connecting_using_ds4drv = False,
event_definition = None)
controller.listen()
另外,我认为这个问题可能是因为你没有机器人不执行任何操作的“默认”条件。通常我处理此类问题的方法是将机器人的一般行为定义为不执行任何操作,并将 x 键定义为中断。因此,每当按下按键时,就会发生一个事件,并且调用等效的 eventHandler (如果您熟悉微控制器,请考虑 ISR) 。以这种方式设计可能会给你更多的控制权。