2. 键盘控制

在本项目中,我们将学习如何使用键盘远程控制 PiCrawler。你可以通过键盘操作让 PiCrawler 前进、后退、左转或右转。

运行代码

cd ~/picrawler/examples
sudo python3 2_keyboard_control.py

当程序启动时,PiCrawler 会完成初始化,并在终端中显示一个键盘控制界面。

按下键盘按键即可控制 PiCrawler!

  • w:向前移动

  • a:向左转

  • s:向后移动

  • d:向右转

  • Ctrl+C:退出程序

当前速度会显示在终端中,并且可以通过以下按键进行调整:

    • / ] :提高速度

    • / [ :降低速度

每次执行动作后,程序都会加入一个短暂的延时,以保证动作的稳定性。

按下 Ctrl+C 可以退出程序。 在程序关闭之前,机器人会执行一次安全的“坐下”动作。

代码

from picrawler import Picrawler
from time import sleep
import readchar

crawler = Picrawler()

SPEED_MIN = 20
SPEED_MAX = 70
speed = 60

STEP = 1            # Number of action steps per key press
ACTION_GAP = 0.25   # Delay after each action to reduce current spikes

manual = """
Keyboard Control - PiCrawler

Movement:
W: Forward
A: Turn left
S: Backward
D: Turn right

Speed Control:
+ / ] : Increase speed
- / [ : Decrease speed

Other:
Space  : Stop (no action)
Ctrl+C : Quit (auto sit)
"""

def clamp(value, min_value, max_value):
    """Limit value within a specified range."""
    return max(min_value, min(max_value, value))

def show_info():
    """Clear terminal and display control instructions."""
    print("\033[H\033[J", end="")  # Clear terminal screen
    print(manual)
    print(f"Current speed: {speed}  (range {SPEED_MIN}-{SPEED_MAX})")
    print(f"Action gap: {ACTION_GAP:.2f}s")

def do_move(action_name):
    """Execute movement action with safety delay."""
    crawler.do_action(action_name, STEP, speed)
    sleep(ACTION_GAP)

def safe_sit():
    """Safely sit down before program exit."""
    try:
        crawler.do_step("sit", clamp(speed, 20, 40))
        sleep(1.0)
    except Exception:
        pass

def main():
    show_info()

    try:
        while True:
            key = readchar.readkey()
            k = key.lower()

            if k == "w":
                do_move("forward")
            elif k == "s":
                do_move("backward")
            elif k == "a":
                do_move("turn left")
            elif k == "d":
                do_move("turn right")

            # Speed increase
            elif k in ("+", "]"):
                global speed
                speed = clamp(speed + 5, SPEED_MIN, SPEED_MAX)

            # Speed decrease
            elif k in ("-", "["):
                speed = clamp(speed - 5, SPEED_MIN, SPEED_MAX)

            # Stop (no movement)
            elif k == " ":
                pass

            # Quit using readchar special key
            elif key == readchar.key.CTRL_C:
                print("\nQuit.")
                break

            show_info()
            sleep(0.02)

    except KeyboardInterrupt:
        print("\nQuit (KeyboardInterrupt).")

    finally:
        safe_sit()

if __name__ == "__main__":
    main()

它是如何工作的?

  1. 创建机器人对象

    crawler = Picrawler()
    

    这一行代码创建了一个 Picrawler 对象, 使程序能够控制机器人的运动。

  2. 定义安全速度范围

    SPEED_MIN = 20
    SPEED_MAX = 70
    speed = 60
    

    这些变量定义了允许的速度范围。 speed 用于存储当前的运动速度。 机器人不会超过设定的最大速度运行。

  3. 使用 clamp() 限制速度

    def clamp(value, min_value, max_value):
        return max(min_value, min(max_value, value))
    

    该函数用于确保速度保持在安全范围内, 从而避免由于极端速度值导致的不稳定运动。

  4. 执行运动动作

    def do_move(action_name):
        crawler.do_action(action_name, STEP, speed)
        sleep(ACTION_GAP)
    

    该函数向机器人发送运动指令。 ACTION_GAP 会加入一个短暂延时,以提高动作稳定性。

  5. 读取键盘输入

    key = readchar.readkey()
    k = key.lower()
    

    程序会等待用户按下一个按键。 按键会被转换为小写,以保持输入的一致性。

  6. 运动控制逻辑

    if k == "w":
        do_move("forward")
    elif k == "s":
        do_move("backward")
    

    当按下对应按键时, 机器人会立即执行相应的运动动作, 无需按下 Enter 键。

  7. 安全退出

    finally:
        safe_sit()
    

    在程序退出之前, 机器人会执行一次安全的“坐下”动作, 以防止姿态不稳定或突然断电导致的问题。