Note

Hello, welcome to the SunFounder Raspberry Pi & Arduino & ESP32 Enthusiasts Community on Facebook! Dive deeper into Raspberry Pi, Arduino, and ESP32 with fellow enthusiasts.

Why Join?

  • Expert Support: Solve post-sale issues and technical challenges with help from our community and team.

  • Learn & Share: Exchange tips and tutorials to enhance your skills.

  • Exclusive Previews: Get early access to new product announcements and sneak peeks.

  • Special Discounts: Enjoy exclusive discounts on our newest products.

  • Festive Promotions and Giveaways: Take part in giveaways and holiday promotions.

👉 Ready to explore and create with us? Click [here] and join today!

2. Keyboard Control

In this project, we will learn how to use the keyboard to remotely control the PiCrawler. You can control the PiCrawler to move forward, backward, left, and right.

Run the Code

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

When the program starts, PiCrawler initializes and a keyboard control interface is displayed in the terminal.

Press keys on keyboard to control PiCrawler!

  • w: Forward

  • a: Turn left

  • s: Backward

  • d: Turn right

  • Ctrl+C: Quit

The current speed is shown and can be adjusted using:

    • / ] to increase speed

    • / [ to decrease speed

After each action, a short delay is applied for stability.

Press Ctrl+C to exit. Before shutting down, the crawler performs a safe “sit” action.

Code

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()

How it works?

  1. Creating the Robot Object

    crawler = Picrawler()
    

    This line creates a Picrawler object. It allows the program to control the robot’s movements.

  2. Defining Safe Speed Range

    SPEED_MIN = 20
    SPEED_MAX = 70
    speed = 60
    

    These variables define the allowed speed range. speed stores the current movement speed. The robot will not move faster than the maximum value.

  3. Limiting Speed with clamp()

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

    This function ensures that speed stays within the safe range. It prevents unstable movement caused by extreme values.

  4. Executing a Movement

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

    This function sends a movement command to the robot. ACTION_GAP adds a short delay to improve stability.

  5. Reading Keyboard Input

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

    The program waits for a key press. The key is converted to lowercase for consistency.

  6. Movement Control Logic

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

    When a key is pressed, the corresponding movement is executed immediately. Pressing Enter is not required.

  7. Safe Exit

    finally:
        safe_sit()
    

    Before the program exits, the robot performs a safe “sit” action. This prevents unstable posture or sudden shutdown.