pi-robot is a Python control library for a Raspberry Pi based robot demo. It groups the robot's hardware features into light, motion, sound, and vision modules, and includes example programs that trigger robot actions from ArUco tag detection and voice commands.
- Light control: eye LED blinking and head RGB status lights.
- Motion control: arm capture, put-down, reset, head nod/shake, and waist twist actions.
- Voice interaction: reads command codes from an I2C voice recognition module and supports voice announcements.
- Audio playback: plays MP3 files through
pygame, macOSafplay, or Raspberry Pi/Linuxmpg123. - Vision detection: detects OpenCV ArUco tags and maps tag IDs to robot actions.
- Example scripts:
main.pyruns the full integrated demo, whilemain_sound.pyhelps test the voice module.
.
├── main.py # Full demo: vision, voice, lights, and motion
├── main_sound.py # Voice recognition and audio playback demo
├── pi_robot/
│ ├── light/ # Eye LED and head RGB light controllers
│ ├── motion/ # Arm, head, and waist serial controllers
│ ├── sound/ # I2C voice module and MP3 playback
│ └── vision/ # ArUco tag detection
├── docs/source/ # Sphinx documentation sources
├── pyproject.toml # Project metadata and tool configuration
├── requirements.lock # Locked runtime dependencies
└── requirements-dev.lock # Locked development dependencies
- Python 3.8 or newer.
- Raspberry Pi, or another Linux device with equivalent hardware interfaces.
- USB/CSI camera for ArUco tag detection.
- Serial controller board. The default serial port is
/dev/ttyUSB0at115200baud. - I2C voice recognition/announcement module. The default address is
0x34on bus1. - GPIO wiring:
- Eye LED: BCM
23 - Head RGB: red BCM
27, green BCM22, blue BCM17
- Eye LED: BCM
Note:
RPi.GPIOandsmbusare intended for Raspberry Pi environments. On macOS or a regular PC, you can still inspect and develop parts of the code, but hardware-related examples will usually fail without the required interfaces.
Create and activate a virtual environment:
python -m venv .venv
source .venv/bin/activate
pip install -e .If your environment does not already include the hardware or vision packages, install them as needed:
pip install opencv-python pyserial pygameOn Raspberry Pi, enable I2C and install the system packages:
sudo raspi-config
sudo apt update
sudo apt install -y python3-smbus i2c-tools mpg123For documentation and development tools:
pip install sphinx sphinx-autobuild sphinxcontrib-napoleon ruffBefore running the demo, check that the required interfaces are available:
ls /dev/ttyUSB*
i2cdetect -y 1Common setup notes:
- If the current user cannot access the serial port, add the user to the
dialoutgroup and log in again:
sudo usermod -aG dialout "$USER"- If the arm, head, or waist controller is not connected to
/dev/ttyUSB0, pass the correct port when creating the controller. - If the camera is not at index
0, updateTagDetector(camera_index=...). main.pyusesmpg123for MP3 playback by default, so make sure it is installed.
Run the full integrated demo:
python main.pyRun the voice module demo:
python main_sound.pyRun individual module demos:
python -m pi_robot.motion.arm
python -m pi_robot.motion.head
python -m pi_robot.motion.waist
python -m pi_robot.light.eye
python -m pi_robot.light.head
python -m pi_robot.sound.sound
python -m pi_robot.sound.player
python -m pi_robot.vision.tagmain.py initializes these components:
EyeLightController: turns on the eye LED and starts a background blink loop.HeadLightController: uses RGB lights as action/status indicators.ArmCommandSender: sends arm action commands through serial.RobotHeadController: controls nod and shake actions.RobotWaistController: controls waist twist actions.SoundController: reads voice command codes and triggers announcements.SoundPlayer: plays local MP3 files.TagDetector: detects ArUco tags and checks whether they are aligned with the camera.
The main loop continuously detects ArUco tags. When a target tag is detected and its angle satisfies the alignment threshold, the program triggers the action mapped to that tag ID. A background voice-recognition thread runs at the same time and triggers actions from command codes returned by the voice module.
| Tag ID | Action |
|---|---|
1 |
Left arm capture |
2 |
Right arm capture |
3 |
Left arm put down |
4 |
Right arm put down |
5 |
Nod |
6 |
Shake head |
7 |
Reset head/waist action state |
8 |
Reset left arm |
9 |
Reset right arm |
10 |
End the main loop |
11 |
Twist waist |
Tag detection uses the DICT_4X4_50 dictionary. In main.py, target IDs are 1 through 11, the minimum area ratio is 0.02, and the alignment threshold is 2.0 degrees.
| Command Code | Action |
|---|---|
1 |
Left arm detection/capture |
2 |
Right arm detection/capture |
3 |
Put down left arm |
4 |
Put down right arm |
5 |
Reset left arm |
6 |
Reset right arm |
7 |
Nod |
8 |
Shake head |
9 |
Reset joint action state |
10 |
Clear state |
11 |
Play test_sound.mp3 |
12 |
Twist waist |
EyeLightController(pin=23): controls the eye LED withon(),off(),blink(), andcleanup().HeadLightController(red_pin=27, green_pin=22, blue_pin=17): controls the head RGB light withset_color(r, g, b, duration),off(), andcleanup().
ArmCommandSender(port="/dev/ttyUSB0", baudrate=115200, blocking=True): sends byte commands to the arm controller. The main method issend_command(command: bytes).RobotHeadController(port="/dev/ttyUSB0"): providesnod()andshake().RobotWaistController(port="/dev/ttyUSB0"): providestwist().
Default arm commands:
LCAP = b"#left_color_block_capture_begin!"
LPUT = b"#left_put!"
LReset = b"#robot_left_arm_reset!"
RCAP = b"#right_color_block_capture_begin!"
RPUT = b"#right_put!"
RReset = b"#robot_right_arm_reset!"SoundController(i2c_addr=0x34, bus=1): reads voice recognition results withrec_recognition()and triggers announcements withspeak(cmd, id).SoundPlayer(sound_dir=None): plays MP3 files withplay(filename, device).
Supported SoundPlayer.play() devices:
pygame: cross-platform Python playback.afplay: macOS system player.mpg123: common command-line player on Raspberry Pi/Linux.
TagDetector(target_ids=None, min_area_ratio=0.1, camera_index=0, imshow=False, scale=1.0, aligned_thres=0.5): detects ArUco tags.detect(): returns aTagobject orNone.Tag.id: detected tag ID.Tag.aligned(): whether the tag satisfies the alignment condition.release(): releases camera resources.
The repository includes Sphinx documentation sources. Build the HTML docs with:
sphinx-build -b html docs/source docs/build/htmlFor live preview during development:
sphinx-autobuild docs/source docs/build/htmlThe project uses Ruff for linting and formatting:
ruff check .
ruff format .ModuleNotFoundError: No module named 'RPi': installRPi.GPIOon Raspberry Pi, or run only code that does not depend on GPIO in non-hardware environments.ModuleNotFoundError: No module named 'smbus': installpython3-smbusand confirm that I2C is enabled.Cannot open camera: check camera connection, permissions, andcamera_index.- Serial initialization fails: check that
/dev/ttyUSB0exists, the current user has serial permissions, and no other program is using the port. - Audio playback fails: confirm that
test_sound.mp3exists and that the selected player, such asmpg123, is installed.