Engineering Design Portfolio — Robotics & Embedded Systems

Bip Biped Robot

Two-Legged Robot · 10× MG996R Servos · ESP32-S3 Gait & Balance · MuJoCo Digital Twin · Sep 2026 – present
Work in Progress ESP32-S3 + PCA9685 Fusion 360 · 3D Printed MPU-6050 Balance
ESP32-C3 Face XIAO ESP32-S3 Camera + Mics MuJoCo Sim Twin
Status Bip stands with IMU balance, takes steps and walks short distances on my desk, talks, and shows feelings on its face. It doesn't walk reliably yet: most falls happen when it starts or stops walking. This page shows where it really is.
Bip standing on the desk

I wanted a small robot with a personality that could actually walk, not a kit. Every structural part is my own Fusion 360 design, printed and assembled at home, and the main controller is my own ESP32-S3 dev board. Getting it to stand and talk was the easy half. Walking is the hard half: what works in my simulator doesn't always work on the real table, so most of the work now is making the digital twin match the real robot.

Bip standing on the desk
Bip standing on the desk
Bip standing on the desk
Front: round eyes, OLED mouth, camera, speaker grille and the sonar
Face without its cover: two GC9A01 eye displays and the SSD1306 mouth
Inside the torso during bring-up
Testing much bigger printed feet for a steadier stance
Key Components
MG996R ×10
MG90S ×2
ESP32-S3
PCA9685
MPU-6050
ESP32-C3 face
XIAO ESP32-S3 Sense
Build Progress
✓
CAD & Print
✓
Servo Calib
✓
Face & Voice
✓
Sim Twin
✓
Standing
→
Reliable Walking
What I Learned
  • MG996R servos have no position feedback. On one early power-up the servos jumped straight to their stored angles and snapped a joint. Now outputs start limp, and every move is ramped from where the leg actually is.
  • When the "dead" eye displays turned out to be a broken jumper and a chip-select wire in the wrong pin, I learned to check wiring first (swap test, continuity per wire) before blaming a module or the code.
  • A gait that looks great in the simulator can fall on the real robot within a few steps. The twin was wrong in pitch, and the real servo lag and weight distribution are its biggest unknowns.
  • Falls cluster at the start and stop of walking, when the stride changes, not in the middle of a walk.
10
Leg Servos
50 Hz
Gait & Balance Loop
3
ESP32 Boards
5 DOF
Per Leg
Mechanical build, walking and the simulator, face and senses below ↓

Project Overview

Leg Servos
10×
MG996R, 5 per leg
Main MCU
ESP32-S3
My own dev board + PCA9685
Power
2S LiPo
5 V 7 A UBEC (6 V servo rail planned)
Build Status
In Progress
Stands, short walks

Goal. A small, friendly two-legged robot that can walk, see, listen and talk, built from my own design rather than a kit.

Approach. A Fusion 360 printed body with 10 leg servos, an ESP32-S3 running the kinematics, gait and IMU balance, separate boards for the face and the camera/microphones, and a MuJoCo digital twin that runs the same gait code so new settings are tried in simulation before they risk the hardware.

Result so far. Bip stands, walks short distances on the table, talks and reacts with its face. Reliable walking is the current focus.

At a Glance
TypePersonal project
My roleSolo: design, CAD, wiring, testing
CodeWritten with AI coding help (Claude Code)
TimelineSep 2026 – present
SkillsKinematics · control · embedded C++ · simulation · CAD
ToolsFusion 360 · Arduino C++ · Python · MuJoCo
StatusIn progress
Built On (Credits)
Servo driver libraryAdafruit PWM Servo Driver
Display librariesArduino_GFX, U8g2
Physics engineMuJoCo
SpeechWhisper (Groq + local), Silero, Piper
Vision & soundYOLOX, YuNet, SFace, MediaPipe, YAMNet
ConversationClaude Haiku (Anthropic)
Coding assistantClaude Code

Mechanical & Electronics

Every structural part is designed in Fusion 360 and 3D printed. Each leg has five joints: hip yaw, hip, knee, ankle pitch and ankle roll, all on MG996R servos driven by a PCA9685. Hip yaw is limited in firmware (10° toes-in, 30° toes-out) so the feet can't hit each other when they turn.

Legs & Motion
Servos10× MG996R (5 per leg)
Servo driverPCA9685 over I²C
Balance sensorMPU-6050
Control loop50 Hz IK + gait
HeadPan / tilt servos
Boards & Senses
MainESP32-S3 (own dev board)
FaceESP32-C3, 2× GC9A01 + SSD1306
Camera + micsXIAO ESP32-S3 Sense
SpeakerMAX98357A I²S amp
DistanceHC-SR04 sonar

Key Engineering Decisions

PCA9685 for the 10 leg servos
Ten servos need a steady 50 Hz pulse each. A PCA9685 generates all of them in hardware over I²C (the same bus as the IMU), which leaves the ESP32-S3 free for the kinematics, gait and balance maths every 20 ms.
A separate board for the face
Animating two round displays and an OLED takes a lot of SPI and I²C traffic. Putting the face on its own ESP32-C3 means drawing never delays the 50 Hz walking loop; the main board just sends it short commands.
Heavy AI work on the laptop, not the robot
Recognising speech, faces, gestures and sounds, and holding a conversation, need far more memory and compute than an ESP32 has. The robot streams camera and microphone data to my laptop over Wi-Fi: vision runs offline on the laptop CPU (about 50 ms per frame), speech-to-text uses Whisper with a local fallback, and Claude Haiku writes the replies. The robot stays light and its battery goes to the motors.
Simulation first, with a deliberately "wrong" twin
Every gait or balance change is tried in the MuJoCo twin before the real robot. To avoid tuning for a perfect model, I test with random servo lag (40–80 ms), weak servos, ±2° zero errors, different friction and a shifted centre of mass. Example: a standing balance gain of 0.9 fell in 13 of 60 randomised runs, 0.3 in 0 of 60, so 0.3 is the next setting to try on the robot.
Joint limits from the CAD
In the CAD the feet touch when both turn in by about 12.75°, so the firmware limits hip yaw to 10° toes-in and 30° toes-out, protecting the feet even before calibration.
Safety around unpredictable hardware
Servo outputs stay off until enabled, every move is ramped and clamped to calibrated limits, x is an instant emergency stop, and the 2S LiPo voltage is monitored with low-battery warnings (filtered, because servo current briefly pulls the voltage down).

Walking & the Digital Twin

Phase 1 — Gait on the ESP32
Inverse kinematics and a walking gait in C++
The leg IK and gait run on the ESP32-S3 at 50 Hz: stand → crouch → walk → graceful stop, with stride, lift, lean and period tunable live over serial. The C++ gait matches my browser walking simulator to within 0.0005° on 24 test cases.
Phase 2 — MuJoCo Digital Twin
A physics simulation that runs the same code
I built a MuJoCo model from the real Fusion 360 CAD that runs the robot's own gait and balance code. I use it to test gait settings and balance gains before trying them on the robot, including runs with random servo errors, lag and friction to see which settings stay robust.
Phase 3 — Real Table Tests
Stands and walks short distances, falls at start and stop
In October 2026 I started recorded walk trials on the table: a hand-tuned gait against the gait learned in simulation, each filmed and logged. The results are in Testing & Results below.

Testing & Results

Firmware vs simulator
0.0005°
worst error, 24 test cases
Hand-tuned gait
3 walks
completed; 2 falls while stopping
Real speed
~15 mm
per step cycle (feet slide)
Sim-learned gait
3 / 3
trials fell on the real robot

How I measure it. I built a small gait camera: ArUco markers on the feet and torso, tracked by a webcam with Python and OpenCV, plus the robot's own IMU log. Each trial records speed, sway and heading, and each clip is saved with its result.

What the tests show. The firmware does exactly what the simulator does, so the gap is in the model, not the code. On the table the hand-tuned gait walks but drifts, the feet slide, and most falls happen when the stride changes at the start or stop. The gait learned in simulation fell every time, which showed the twin is wrong in pitch. The next step is to measure the real servo lag and weight distribution and feed them back into the model.

Face & Senses

An ESP32-C3 draws the face: two GC9A01 round displays for the eyes and an SSD1306 OLED for the mouth, all procedurally animated. A XIAO ESP32-S3 Sense provides the camera and microphones, a MAX98357A amp drives the speaker, and an HC-SR04 sonar sits under the torso. Voice and conversation are handled on the laptop (see Key Engineering Decisions).

What it does with them. Bip recognises my face, and its eyes follow the nearest face. It reacts straight away to hand gestures (wave, thumbs up, open palm for stop) and to everyday sounds such as a knock or a clap. It knows what objects are in front of it and, with the sonar, how far away they are, and it can answer "what do you see?" from a camera photo.

Where It Is Now

Working
Standing with IMU balanceyes
Steps and short walks on the tableyes
Animated faceyes
Head pan / tiltyes
Voice chat, camera, microphonesyes
Face recognition, gestures, soundsyes
Firmware updates over Wi-Fiyes
Not Yet
Walks without fallingfalls at start / stop
Gait learned in the simdoesn't transfer yet
Feet gripfeet still slide
Servo power at 6 Vplanned

Demo

A short walk on the table (stride 20). My hand stays close in case it falls.
⌂ Portfolio ESP32-S3 Dev Board →