🌐 Level 6 – Wi-Fi Robotics

Project 6.1: "Omnidirectional Robot"

 

What you’ll learn

  • ✅ Omnidirectional basics: Understand how 4 omni/mecanum wheels enable forward, backward, lateral, and rotational movement.
  • ✅ Direction maps: Set clear HIGH/LOW patterns for each motor to achieve the desired motion.
  • ✅ Any‑direction control: Combine lateral, forward/backward, and rotation.
  • ✅ Pattern design: Create reusable movement sequences (L‑shapes, spirals, squares).
  • ✅ Reliability: Use prints and safeguards so the robot moves predictably and stops cleanly.

Blocks glossary (used in this project)

  • Digital output (motor pins): Control L298N inputs for each wheel’s direction.
  • Helper functions: Group motor actions (forward, back, left, right, rotate, stop).
  • Serial println: Print “MOVE:
” and “DEBUG:
” messages so actions are visible.
  • Variables: Store timing (ms) and patterns.
  • Loops: Run sequences step by step with pauses.

What you need

Part How many? Pin connection (suggested)
D1 R32 1 USB cable (30 cm)
Omni/mecanum wheels 4 Mounted on 4 TT gear motors
TT gear motors 4 1 per wheel
L298N motor driver modules 2 Driver A: IN1→18, IN2→19, IN3→5, IN4→23; Driver B: IN1→16, IN2→17, IN3→4, IN4→15
Power for motors (external) 1 Motor supply per L298N; logic 5V to R32 shared ground

Notes

  • Use two L298N drivers to control 4 motors (front‑left/front‑right on Driver A, rear‑left/rear‑right on Driver B).
  • Share ground between motor power and the D1 R32. Keep wiring tidy and labels on each wheel.

Before you start

  • USB cable connected and stable
  • Shared ground verified between R32 and L298N motor power
  • Serial monitor open and showing:
print("Ready!")  # Confirm serial is working so you can see messages

Microprojects 1–5

Microproject 6.1.1 – Forward/backward movement

Goal: Drive all wheels forward together, then backward, using clear pin patterns.
Blocks used:

  • Digital output: Set IN pins for each wheel’s direction.
  • Serial println: Print “MOVE:FWD/BACK” and “MOTORS:STOP”.

MicroPython code:

import machine  # Import machine to control pins
import time  # Import time for delays
# Driver A (front motors)
FL_IN1 = machine.Pin(18, machine.Pin.OUT)  # Front-Left IN1
FL_IN2 = machine.Pin(19, machine.Pin.OUT)  # Front-Left IN2
FR_IN1 = machine.Pin(5, machine.Pin.OUT)   # Front-Right IN1
FR_IN2 = machine.Pin(23, machine.Pin.OUT)  # Front-Right IN2
# Driver B (rear motors)
RL_IN1 = machine.Pin(16, machine.Pin.OUT)  # Rear-Left IN1
RL_IN2 = machine.Pin(17, machine.Pin.OUT)  # Rear-Left IN2
RR_IN1 = machine.Pin(4, machine.Pin.OUT)   # Rear-Right IN1
RR_IN2 = machine.Pin(15, machine.Pin.OUT)  # Rear-Right IN2
def all_stop():  # Define a helper to stop all motors
    FL_IN1.value(0)  # Set Front-Left IN1 LOW
    FL_IN2.value(0)  # Set Front-Left IN2 LOW
    FR_IN1.value(0)  # Set Front-Right IN1 LOW
    FR_IN2.value(0)  # Set Front-Right IN2 LOW
    RL_IN1.value(0)  # Set Rear-Left IN1 LOW
    RL_IN2.value(0)  # Set Rear-Left IN2 LOW
    RR_IN1.value(0)  # Set Rear-Right IN1 LOW
    RR_IN2.value(0)  # Set Rear-Right IN2 LOW
    print("MOTORS:STOP")  # Print stop status
def forward():  # Define forward movement
    print("MOVE:FWD")  # Print action
    FL_IN1.value(1)  # Front-Left forward HIGH
    FL_IN2.value(0)  # Front-Left forward LOW
    FR_IN1.value(1)  # Front-Right forward HIGH
    FR_IN2.value(0)  # Front-Right forward LOW
    RL_IN1.value(1)  # Rear-Left forward HIGH
    RL_IN2.value(0)  # Rear-Left forward LOW
    RR_IN1.value(1)  # Rear-Right forward HIGH
    RR_IN2.value(0)  # Rear-Right forward LOW
def backward():  # Define backward movement
    print("MOVE:BACK")  # Print action
    FL_IN1.value(0)  # Front-Left backward LOW
    FL_IN2.value(1)  # Front-Left backward HIGH
    FR_IN1.value(0)  # Front-Right backward LOW
    FR_IN2.value(1)  # Front-Right backward HIGH
    RL_IN1.value(0)  # Rear-Left backward LOW
    RL_IN2.value(1)  # Rear-Left backward HIGH
    RR_IN1.value(0)  # Rear-Right backward LOW
    RR_IN2.value(1)  # Rear-Right backward HIGH
forward()  # Run forward
time.sleep(1.0)  # Move for 1 second
all_stop()  # Stop all motors
time.sleep(0.5)  # Pause briefly
backward()  # Run backward
time.sleep(1.0)  # Move for 1 second
all_stop()  # Stop all motors

Reflection: Forward/backward uses the same pattern on all four wheels—great for straight motion tests.
Challenge:

  • Easy: Change each move to 2 seconds.
  • Harder: Add a safety “STOP” between moves for 1 full second.

Microproject 6.1.2 – Lateral movement (strafe left/right)

Goal: Move sideways using opposite wheel directions (mecanum/omni principle).
Blocks used:

  • Digital output: Set pin patterns for strafe.
  • Serial println: Print “MOVE:LEFT/RIGHT”.

Tip: Depending on wheel orientation, you might need to swap left/right patterns.

MicroPython code:

import time  # Import time for delays
def strafe_left():  # Define lateral left movement
    print("MOVE:LEFT")  # Print action
    # Front-Left backward, Rear-Left forward
    FL_IN1.value(0)  # Front-Left backward LOW
    FL_IN2.value(1)  # Front-Left backward HIGH
    RL_IN1.value(1)  # Rear-Left forward HIGH
    RL_IN2.value(0)  # Rear-Left forward LOW
    # Front-Right forward, Rear-Right backward
    FR_IN1.value(1)  # Front-Right forward HIGH
    FR_IN2.value(0)  # Front-Right forward LOW
    RR_IN1.value(0)  # Rear-Right backward LOW
    RR_IN2.value(1)  # Rear-Right backward HIGH
def strafe_right():  # Define lateral right movement
    print("MOVE:RIGHT")  # Print action
    # Front-Left forward, Rear-Left backward
    FL_IN1.value(1)  # Front-Left forward HIGH
    FL_IN2.value(0)  # Front-Left forward LOW
    RL_IN1.value(0)  # Rear-Left backward LOW
    RL_IN2.value(1)  # Rear-Left backward HIGH
    # Front-Right backward, Rear-Right forward
    FR_IN1.value(0)  # Front-Right backward LOW
    FR_IN2.value(1)  # Front-Right backward HIGH
    RR_IN1.value(1)  # Rear-Right forward HIGH
    RR_IN2.value(0)  # Rear-Right forward LOW
strafe_left()  # Run strafe left
time.sleep(1.0)  # Move for 1 second
all_stop()  # Stop all motors
time.sleep(0.5)  # Pause briefly
strafe_right()  # Run strafe right
time.sleep(1.0)  # Move for 1 second
all_stop()  # Stop all motors

Reflection: True omni movement feels like “sliding”—pin patterns must mirror left vs. right.
Challenge:

  • Easy: Try 1.5 seconds per strafe.
  • Harder: If drifting, add a short forward pulse to straighten after each strafe.

Microproject 6.1.3 – Rotation on its own axis

Goal: Spin in place by driving left and right sides in opposite directions.
Blocks used:

  • Digital output: Opposite directions on left vs. right sides.
  • Serial println: Print “MOVE:ROTATE_LEFT/ROTATE_RIGHT”.

MicroPython code:

import time  # Import time for delays
def rotate_left():  # Define rotation to the left
    print("MOVE:ROTATE_LEFT")  # Print action
    # Left side backward
    FL_IN1.value(0)  # Front-Left backward LOW
    FL_IN2.value(1)  # Front-Left backward HIGH
    RL_IN1.value(0)  # Rear-Left backward LOW
    RL_IN2.value(1)  # Rear-Left backward HIGH
    # Right side forward
    FR_IN1.value(1)  # Front-Right forward HIGH
    FR_IN2.value(0)  # Front-Right forward LOW
    RR_IN1.value(1)  # Rear-Right forward HIGH
    RR_IN2.value(0)  # Rear-Right forward LOW
def rotate_right():  # Define rotation to the right
    print("MOVE:ROTATE_RIGHT")  # Print action
    # Left side forward
    FL_IN1.value(1)  # Front-Left forward HIGH
    FL_IN2.value(0)  # Front-Left forward LOW
    RL_IN1.value(1)  # Rear-Left forward HIGH
    RL_IN2.value(0)  # Rear-Left forward LOW
    # Right side backward
    FR_IN1.value(0)  # Front-Right backward LOW
    FR_IN2.value(1)  # Front-Right backward HIGH
    RR_IN1.value(0)  # Rear-Right backward LOW
    RR_IN2.value(1)  # Rear-Right backward HIGH
rotate_left()  # Run rotation left
time.sleep(1.0)  # Spin for 1 second
all_stop()  # Stop all motors
time.sleep(0.5)  # Pause briefly
rotate_right()  # Run rotation right
time.sleep(1.0)  # Spin for 1 second
all_stop()  # Stop all motors

Reflection: In‑place rotation is a hallmark of omni robots—mirror left and right sides.
Challenge:

  • Easy: Reduce each spin to 0.6 s for tighter angle control.
  • Harder: Build a “rotate 90°” helper using timing you calibrate.

Microproject 6.1.4 – Movement in any direction (combine strafe + forward/back)

Goal: Diagonal or angled motion by mixing forward/back with lateral patterns.
Blocks used:

  • Digital output: Set combined patterns.
  • Serial println: Print “MOVE:DIAG_*”.

Example shown: diagonal forward‑left and forward‑right.

MicroPython code:

import time  # Import time for delays
def diag_forward_left():  # Define diagonal forward-left motion
    print("MOVE:DIAG_FWD_LEFT")  # Print action
    # Mix forward + left strafe: bias wheels so net vector is forward-left
    FL_IN1.value(0)  # Front-Left slightly backward to bias left
    FL_IN2.value(1)  # Front-Left backward HIGH
    FR_IN1.value(1)  # Front-Right forward
    FR_IN2.value(0)  # Front-Right forward
    RL_IN1.value(1)  # Rear-Left forward
    RL_IN2.value(0)  # Rear-Left forward
    RR_IN1.value(0)  # Rear-Right slightly backward to bias left
    RR_IN2.value(1)  # Rear-Right backward HIGH
def diag_forward_right():  # Define diagonal forward-right motion
    print("MOVE:DIAG_FWD_RIGHT")  # Print action
    # Mix forward + right strafe: bias wheels so net vector is forward-right
    FL_IN1.value(1)  # Front-Left forward
    FL_IN2.value(0)  # Front-Left forward
    FR_IN1.value(0)  # Front-Right slightly backward to bias right
    FR_IN2.value(1)  # Front-Right backward HIGH
    RL_IN1.value(0)  # Rear-Left slightly backward to bias right
    RL_IN2.value(1)  # Rear-Left backward HIGH
    RR_IN1.value(1)  # Rear-Right forward
    RR_IN2.value(0)  # Rear-Right forward
diag_forward_left()  # Run diagonal forward-left
time.sleep(1.0)  # Move for 1 second
all_stop()  # Stop all motors
time.sleep(0.5)  # Pause briefly
diag_forward_right()  # Run diagonal forward-right
time.sleep(1.0)  # Move for 1 second
all_stop()  # Stop all motors

Reflection: Any‑direction motion comes from combining straight and sideways patterns—balance the bias.
Challenge:

  • Easy: Create diag_back_left and diag_back_right using the same idea.
  • Harder: Make a “vector table” comment block that lists pin patterns for 8 compass directions.

Microproject 6.1.5 – Complex movement patterns

Goal: Execute repeatable sequences (square, L‑shape, spiral feel) with pauses and prints.
Blocks used:

  • Functions: Reuse forward/strafe/rotate helpers.
  • Loops: Step through patterns in order.
  • Serial println: Print “PATTERN:*”.

MicroPython code:

import time  # Import time for delays
def pattern_square():  # Define a square path pattern
    print("PATTERN:SQUARE_START")  # Announce pattern start
    forward()  # Move forward edge
    time.sleep(1.0)  # Travel duration
    all_stop()  # Stop before turning
    rotate_right()  # Rotate right at corner
    time.sleep(0.6)  # Corner rotation (approx 90° with calibration)
    all_stop()  # Stop after rotation
    forward()  # Next edge forward
    time.sleep(1.0)  # Travel duration
    all_stop()  # Stop before turning
    rotate_right()  # Rotate right at corner
    time.sleep(0.6)  # Corner rotation
    all_stop()  # Stop after rotation
    forward()  # Third edge
    time.sleep(1.0)  # Travel duration
    all_stop()  # Stop before turning
    rotate_right()  # Rotate right at corner
    time.sleep(0.6)  # Corner rotation
    all_stop()  # Stop after rotation
    forward()  # Final edge
    time.sleep(1.0)  # Travel duration
    all_stop()  # Stop at end
    print("PATTERN:SQUARE_DONE")  # Announce pattern completion
def pattern_l_shape():  # Define an L-shape pattern
    print("PATTERN:L_START")  # Announce pattern start
    forward()  # Long forward segment
    time.sleep(1.5)  # Travel duration
    all_stop()  # Stop before turn
    rotate_right()  # Rotate to face sideways
    time.sleep(0.6)  # Corner rotation
    all_stop()  # Stop after rotation
    strafe_right()  # Short right segment
    time.sleep(0.8)  # Travel duration
    all_stop()  # Stop at end
    print("PATTERN:L_DONE")  # Announce pattern completion
pattern_square()  # Run square pattern
time.sleep(1.0)  # Pause between patterns
pattern_l_shape()  # Run L-shape pattern

Reflection: Patterns make the robot feel choreographed—clean stops keep shapes sharp.
Challenge:

  • Easy: Add “PATTERN:LINE_SLIDE” (forward then strafe).
  • Harder: Create “PATTERN:SPIRAL_FEEL” by mixing shorter forward + brief strafes and turns.

Main project – Omnidirectional robot control

Blocks steps (with glossary)

  • Pin setup: Define 8 motor inputs for 4 wheels across 2 L298N drivers.
  • Motion helpers: forward, backward, strafe left/right, rotate left/right, stop.
  • Any‑direction: Diagonals by mixing forward/back and strafe.
  • Patterns: Square and L‑shape sequences with rotation timing.
  • Serial prints: Clear “MOVE:” and “PATTERN:” messages for visibility.

MicroPython code (mirroring blocks)

# Project 6.1 – Omnidirectional Robot
import machine  # Import machine to control GPIO pins
import time  # Import time for delays and sequence timing
# Driver A pins (front motors)
FL_IN1 = machine.Pin(18, machine.Pin.OUT)  # Front-Left IN1
FL_IN2 = machine.Pin(19, machine.Pin.OUT)  # Front-Left IN2
FR_IN1 = machine.Pin(5, machine.Pin.OUT)   # Front-Right IN1
FR_IN2 = machine.Pin(23, machine.Pin.OUT)  # Front-Right IN2
# Driver B pins (rear motors)
RL_IN1 = machine.Pin(16, machine.Pin.OUT)  # Rear-Left IN1
RL_IN2 = machine.Pin(17, machine.Pin.OUT)  # Rear-Left IN2
RR_IN1 = machine.Pin(4, machine.Pin.OUT)   # Rear-Right IN1
RR_IN2 = machine.Pin(15, machine.Pin.OUT)  # Rear-Right IN2
print("PINS: FL(18,19) FR(5,23) RL(16,17) RR(4,15)")  # Print pin map
def all_stop():  # Stop all 4 motors
    FL_IN1.value(0)  # Front-Left IN1 LOW
    FL_IN2.value(0)  # Front-Left IN2 LOW
    FR_IN1.value(0)  # Front-Right IN1 LOW
    FR_IN2.value(0)  # Front-Right IN2 LOW
    RL_IN1.value(0)  # Rear-Left IN1 LOW
    RL_IN2.value(0)  # Rear-Left IN2 LOW
    RR_IN1.value(0)  # Rear-Right IN1 LOW
    RR_IN2.value(0)  # Rear-Right IN2 LOW
    print("MOTORS:STOP")  # Confirm stop
def forward():  # Drive forward (all wheels forward)
    print("MOVE:FWD")  # Print action
    FL_IN1.value(1)  # FL forward
    FL_IN2.value(0)  # FL forward
    FR_IN1.value(1)  # FR forward
    FR_IN2.value(0)  # FR forward
    RL_IN1.value(1)  # RL forward
    RL_IN2.value(0)  # RL forward
    RR_IN1.value(1)  # RR forward
    RR_IN2.value(0)  # RR forward
def backward():  # Drive backward (all wheels backward)
    print("MOVE:BACK")  # Print action
    FL_IN1.value(0)  # FL backward
    FL_IN2.value(1)  # FL backward
    FR_IN1.value(0)  # FR backward
    FR_IN2.value(1)  # FR backward
    RL_IN1.value(0)  # RL backward
    RL_IN2.value(1)  # RL backward
    RR_IN1.value(0)  # RR backward
    RR_IN2.value(1)  # RR backward
def strafe_left():  # Lateral left (combination of directions)
    print("MOVE:LEFT")  # Print action
    FL_IN1.value(0)  # FL backward
    FL_IN2.value(1)  # FL backward
    FR_IN1.value(1)  # FR forward
    FR_IN2.value(0)  # FR forward
    RL_IN1.value(1)  # RL forward
    RL_IN2.value(0)  # RL forward
    RR_IN1.value(0)  # RR backward
    RR_IN2.value(1)  # RR backward
def strafe_right():  # Lateral right (inverse of left)
    print("MOVE:RIGHT")  # Print action
    FL_IN1.value(1)  # FL forward
    FL_IN2.value(0)  # FL forward
    FR_IN1.value(0)  # FR backward
    FR_IN2.value(1)  # FR backward
    RL_IN1.value(0)  # RL backward
    RL_IN2.value(1)  # RL backward
    RR_IN1.value(1)  # RR forward
    RR_IN2.value(0)  # RR forward
def rotate_left():  # Spin left in place
    print("MOVE:ROTATE_LEFT")  # Print action
    FL_IN1.value(0)  # FL backward
    FL_IN2.value(1)  # FL backward
    RL_IN1.value(0)  # RL backward
    RL_IN2.value(1)  # RL backward
    FR_IN1.value(1)  # FR forward
    FR_IN2.value(0)  # FR forward
    RR_IN1.value(1)  # RR forward
    RR_IN2.value(0)  # RR forward
def rotate_right():  # Spin right in place
    print("MOVE:ROTATE_RIGHT")  # Print action
    FL_IN1.value(1)  # FL forward
    FL_IN2.value(0)  # FL forward
    RL_IN1.value(1)  # RL forward
    RL_IN2.value(0)  # RL forward
    FR_IN1.value(0)  # FR backward
    FR_IN2.value(1)  # FR backward
    RR_IN1.value(0)  # RR backward
    RR_IN2.value(1)  # RR backward
def diag_forward_left():  # Diagonal forward-left motion
    print("MOVE:DIAG_FWD_LEFT")  # Print action
    FL_IN1.value(0)  # FL backward
    FL_IN2.value(1)  # FL backward
    FR_IN1.value(1)  # FR forward
    FR_IN2.value(0)  # FR forward
    RL_IN1.value(1)  # RL forward
    RL_IN2.value(0)  # RL forward
    RR_IN1.value(0)  # RR backward
    RR_IN2.value(1)  # RR backward
def diag_forward_right():  # Diagonal forward-right motion
    print("MOVE:DIAG_FWD_RIGHT")  # Print action
    FL_IN1.value(1)  # FL forward
    FL_IN2.value(0)  # FL forward
    FR_IN1.value(0)  # FR backward
    FR_IN2.value(1)  # FR backward
    RL_IN1.value(0)  # RL backward
    RL_IN2.value(1)  # RL backward
    RR_IN1.value(1)  # RR forward
    RR_IN2.value(0)  # RR forward
def pattern_square():  # Square path using forward and rotate
    print("PATTERN:SQUARE_START")  # Announce start
    for i in range(4):  # Loop four edges
        forward()  # Move forward along edge
        time.sleep(1.0)  # Edge travel time
        all_stop()  # Stop before turning
        rotate_right()  # Turn right at corner
        time.sleep(0.6)  # Approx 90° turn (calibrate)
        all_stop()  # Stop after turn
    print("PATTERN:SQUARE_DONE")  # Announce completion
def pattern_l_shape():  # L-shape path using forward and strafe
    print("PATTERN:L_START")  # Announce start
    forward()  # Long forward leg
    time.sleep(1.5)  # Travel duration
    all_stop()  # Stop before next leg
    strafe_right()  # Short right leg
    time.sleep(0.8)  # Travel duration
    all_stop()  # Stop at end
    print("PATTERN:L_DONE")  # Announce completion
print("TEST:BASE MOTIONS")  # Print section header
forward()  # Test forward
time.sleep(0.8)  # Move briefly
all_stop()  # Stop
backward()  # Test backward
time.sleep(0.8)  # Move briefly
all_stop()  # Stop
strafe_left()  # Test left strafe
time.sleep(0.8)  # Move briefly
all_stop()  # Stop
strafe_right()  # Test right strafe
time.sleep(0.8)  # Move briefly
all_stop()  # Stop
rotate_left()  # Test rotate left
time.sleep(0.6)  # Spin briefly
all_stop()  # Stop
rotate_right()  # Test rotate right
time.sleep(0.6)  # Spin briefly
all_stop()  # Stop
print("TEST:DIAGONALS")  # Print section header
diag_forward_left()  # Test diagonal forward-left
time.sleep(0.8)  # Move briefly
all_stop()  # Stop
diag_forward_right()  # Test diagonal forward-right
time.sleep(0.8)  # Move briefly
all_stop()  # Stop
print("TEST:PATTERNS")  # Print section header
pattern_square()  # Run square pattern
time.sleep(1.0)  # Pause
pattern_l_shape()  # Run L-shape pattern
all_stop()  # Final stop
print("DONE")  # End of main project

External explanation

  • What it teaches: How to map motor pin directions to omni behaviors: straight, lateral, rotation, diagonals, and full patterns.
  • Why it works: Each wheel’s direction contributes to the net motion; mirroring sides or corners creates sideways and rotational movement; clean stops reduce drift and keep shapes neat.
  • Key concept: “Pin pattern → net motion.”

Story time

You press run and the robot glides left like it’s on ice, spins in place like a dancer, then draws a perfect square. It feels alive because your patterns are clear and confident.


Debugging (2)

Debugging 6.1.1 – Non‑omnidirectional movement

Problem: Robot only goes forward/back; strafe or rotate doesn’t work.
Clues: Sideways commands feel like forward; prints show “MOVE:LEFT/RIGHT” but motion is wrong.
Broken code:

# All wheels set to forward for strafe (incorrect)
FL_IN1.value(1); FL_IN2.value(0)  # FL forward only
FR_IN1.value(1); FR_IN2.value(0)  # FR forward only

Fixed code:

# Mixed directions for strafe (correct principle)
FL_IN1.value(0); FL_IN2.value(1)  # FL backward
FR_IN1.value(1); FR_IN2.value(0)  # FR forward
RL_IN1.value(1); RL_IN2.value(0)  # RL forward
RR_IN1.value(0); RR_IN2.value(1)  # RR backward

Why it works: Omni/mecanum needs opposing directions across corners to create lateral force.
Avoid next time: Don’t reuse forward patterns for sideways motion—mirror corners instead.

Debugging 6.1.2 – Wheels get stuck

Problem: Some wheels don’t turn or stutter under load.
Clues: One corner doesn’t move; robot drifts and vibrates.
Broken code:

# Forget to stop before switching direction (causes stall)
forward()  # Forward
strafe_left()  # Immediately change to strafe

Fixed code:

all_stop()  # Stop before changing direction
time.sleep(0.2)  # Small pause to unload motors
strafe_left()  # Now switch pattern safely

Why it works: A brief stop prevents fighting forces and lets motors reset.
Avoid next time: Insert short pauses when changing patterns or directions.


Final checklist

  • Forward and backward move straight and stop cleanly
  • Strafe left/right slides sideways without rotating
  • Rotate left/right spins in place without drifting
  • Diagonals combine forward/back + strafe correctly
  • Patterns (square, L‑shape) run with clear prints and pauses

Extras

  • 🧠 Student tip: Label each wheel on the chassis (FL/FR/RL/RR) so debugging is fast.
  • đŸ§‘â€đŸ« Instructor tip: Have students draw a wheel direction table for each motion before wiring.
  • 📖 Glossary:
    • Strafe: Pure sideways motion without changing heading.
    • Pattern: A sequence of moves forming a shape or path.
    • Opposing corners: Diagonal wheels set to opposite directions to create lateral force.
  • 💡 Mini tips:
    • Calibrate rotation timing per battery level; note best values.
    • Add a global “SAFE_DELAY = 0.2 s” between moves to protect motors.
    • Keep wires short and balanced to reduce voltage drop across drivers.
On this page