The project represents my personal attempt to bring a differential drive mobile robot to life, focusing on a Raspberry Pi Pico microcontroller as its brain. The low-level logic (differential drive controller) is written in C++ (with C headers), while additional features are implemented in Python.
- 🥧 Built on Pico SDK C++ for hardware control
- 🔧 CMake build system for Pico cross-compilation and flashing
- ⚡ PIO-based motor encoder reading for position feedback
- 🎛️ MotorManager class for dual motor coordination (adapted after jondurrant/DDD-Exp)
- 🎯 Custom PID controller for smooth speed regulation
- 🤖 Differential drive kinematics for motion control
- 🌐 TCP server hosted on Pico for wireless commands
- 📡 Python client for velocity command transmission
- 🎮 PS4 controller integration for teleoperation (made use of the library piborg/Gamepad)
- 👁️ AprilTag detection for autonomous navigation (made use of the library pupil-labs/apriltags)
Fingertip-driven goal selection for a diff-drive robot: place your index fingertip in one of two on-screen boxes (left = POS1 for top-left, right = POS2 for bottom_right) to send the robot (with the AprilTag on top) to the corresponding workspace coordinates. The robot rotates to face the target and drives forward, re-aligning if it drifts off course.
- Chassis & Drive
- 2× 65mm Wheels
- 2x 100RPM DC Gear Motors
- 1x Motor driver board (TB6612FNG)
- Board
- Raspberry Pi Pico W
- Custom PCB board
-------└── # CMakeLists.txt & pico_sdk_import.cmake — CMake build files for the Raspberry Pi Pico firmware;
-------└── # C++ source files (.cpp/.h) for robot classes and CMakeLists.txt for build configuration
-------└── apriltag_detection/ ------- # AprilTag detection and pose estimation for autonomous navigation
-------└── utils/ ------- # Joystick input handling and TCP velocity command transmission
-------└── # collection of small, single-purpose Python scripts for different control tasks (navigation, perception, utilities)
-------└── # External libraries and submodules for project dependencies
-------└── # Gif file for the demo showcase
- Clone the repo, build the project with CMake, and flash the Pico by copying the generated .uf2 file to the Pico in BOOTSEL mode.
git clone --recurse-submodules https://github.com/cristianooo1/pico_robot.git
cd ~/pico_robot
mkdir build
cd build
cmake ..
makeFor the TCP server to work on your local network, you need to manually create a secrets.cmake file containing your WiFi credentials.
cd ~/pico_robot/src
touch secrets.cmake
echo 'set(WIFI_SSID "XXXXX")' > secrets.cmake
echo 'set(WIFI_PASSWORD "XXXXX")' >> secrets.cmake- The Python side of the project is managed by uv. Many scripts in python_scripts/ accept command-line arguments. Any script that communicates with the mobile robot requires --ip and --port (the IP address and port of the TCP server hosted on the Pico - see the Pico's serial output for these values). Other scripts may accept additional flags; use uv run <script>.py --help to list the available options.
Example to run the demo application.
cd ~/pico_robot/python_scripts
uv run nav_main_task.py --ip "X.X.X.X" --port XXXX --targetLeft -0.54 -0.10 \
--targetRight 0.68 0.44 --cam4apt /dev/video0 --cam4finger /dev/video1 --tag_id 13- A lot
👻 This is my second major project and represents my personal learning journey in robotics. There's always room for improvement, and I welcome feedback and contributions from the community!

