Problem
Build a robotic system that can perceive a chessboard, decide on a move with a chess engine, and execute it as a smooth, collision-free dual-arm motion. Constraints: hobby-grade actuators with non-zero backlash, a single overhead camera, a budget that ruled out industrial-grade encoders, and a deadline driven by a class demo.
Approach
Three layers. A vision layer (OpenCV) rectifies the board from the overhead camera, segments occupied squares, and emits a (from, to) move. A planning layer (Python + MATLAB Robotics System Toolbox) solves inverse kinematics for both arms and produces a time-parameterised joint trajectory with parabolic blends to soften acceleration discontinuities. A control layer (Arduino Mega) consumes joint angles over serial at 100 Hz and dispatches them to a NEMA 17 stepper for J1 and MG996R servos for J2–J6.
| Qty | Part |
|---|---|
| 2 | NEMA 17 stepper |
| 6 | MG996R servo |
| 1 | Arduino Mega 2560 |
| 1 | Raspberry Pi 4 (4GB) |
| 1 | Logitech C920 webcam |
| 1 | Custom 3D printed arm set |
Implementation
I designed the structural arm in SolidWorks with a 300 mm reach and 100 g payload. Parts were 3D printed in PETG at 50 % infill and iterated three times to eliminate flex at J3. I tuned the trajectory generator in MATLAB by validating each candidate move against a soft virtual fence around the chessboard, rejecting any plan that violated the 5 mm clearance margin.
End-effector position error vs joint travel
Results
End-effector positional error stayed under 2.5 mm across the full 300 mm travel envelope. The system completed a full self-played match without collisions over a 40-move game.
Lessons
The single biggest win was treating the camera as a state estimator, not just a sensor — recalibrating board pose every 10 moves let me dead-reckon between captures and stay robust to small bumps. Hobby servos are limiting; the next iteration would replace J2/J3 with closed-loop steppers.
Gallery

