如何让 tello 无人机在发生某些事情时无限期飞行?

How to make a tello drone fly indefinitely while something is happening?

我正在写一个tello无人机控制程序。我需要在按下键盘上的键时让无人机飞行,否则它会停止。这是我的代码:

class Keybord_Recognition(QtCore.QObject):

    def __init__(self, drone):
        super(Keybord_Recognition, self).__init__()
        self.drone = drone

    def key_recog(self, k):
        if k.event_type == 'down':
            if k.name == 'w':
                self.drone.move_forward(30)

            elif k.name == 's':
                self.drone.move_back(30)

            elif k.name == 'a':
                self.drone.move_left(30)

            elif k.name == 'd':
                self.drone.move_right(30)

            elif k.name == 'z':
                self.drone.move_up(30)

            elif k.name == 'x':
                self.drone.move_down(30)

    def run(self):
        keyboard.hook(self.key_recog)

    def stop(self):
        keyboard.unhook(self.key_recog)

我怎样才能做我需要的事情?

如果我没理解错的话,你想在按下键盘上的键时将此事件发送到无人机,并在没有收到任何键时超时后退出。

这使用 termios 所以它适用于 Linux 和 macOS。

#! /usr/bin/env python3

from functools import partial
from contextlib import contextmanager
import os
from threading import Timer

class Drone:
    def f(self, name, *args):
        print('drone', name, args[0], '\r')

    def __getattr__(self, name):
        return partial(self.f, name)


@contextmanager
def term(kbd):
    import termios, tty
    try:
        fd = kbd.fileno()
        saved = termios.tcgetattr(fd)
        tty.setraw(fd)
        os.set_blocking(fd, False)
        yield
    finally:
        termios.tcsetattr(fd, termios.TCSADRAIN, saved)


drone = Drone()
should_stop = False
timer = None
TIMEOUT = 2.0


def stop():
    global should_stop
    should_stop = True


with open('/dev/tty') as kbd:
    with term(kbd):
        while not should_stop:
            if timer is None:
                timer = Timer(TIMEOUT, stop)
                timer.start()
            ch = kbd.read(1)
            if ch == 'w':
                drone.move_forward(30)
            elif ch == 's':
                drone.move_back(30)
            elif ch == 'a':
                drone.move_left(30)
            elif ch == 'd':
                drone.move_right(30)
            elif ch == 'z':
                drone.move_up(30)
            elif ch == 'x':
                drone.move_down(30)
            else:
                continue
            timer.cancel()
            timer = None

当您 运行 它并按下一些键时:

drone move_forward 30
drone move_forward 30
drone move_forward 30
drone move_forward 30
drone move_forward 30
drone move_forward 30
drone move_right 30
drone move_right 30
drone move_right 30
drone move_right 30
drone move_right 30
drone move_back 30
drone move_back 30
drone move_back 30
drone move_forward 30
drone move_forward 30
drone move_forward 30
drone move_forward 30
drone move_forward 30
drone move_left 30
drone move_left 30
drone move_left 30
drone move_left 30
drone move_left 30
drone move_left 30
<<< wait 2 secs >>

你需要一个while循环来不断检查不同的方向,而且不需要添加另一个位置static-fly(不移动)。但是,如果您出于任何原因想要打破 while 循环,只需在末尾添加一个 except KeyboardInterrupt: 即可。

更具体地将您的代码更改为:

try:
     while True:
           if k.name == 'w':
              self.drone.move_forward(30)
    
            elif k.name == 's':
                self.drone.move_back(30)
    
            elif k.name == 'a':
                self.drone.move_left(30)
    
            elif k.name == 'd':
                self.drone.move_right(30)
    
            elif k.name == 'z':
                self.drone.move_up(30)
    
            elif k.name == 'x':
                self.drone.move_down(30)

except KeyboardInterrupt:
    print("Press Ctrl-C to exit")
    pass