VinUniversity

InMoovXtra, a humanoid you can talk to

An upper-body humanoid built from the open-source InMoov design: 3D-printed, moved by hobby servos, with a silicone face that shows expressions and a spoken conversation through a large language model. I worked on its power, wiring and servo control.

The InMoovXtra robot from the front: silicone face, neck, printed torso and waist, and a left arm and hand, mounted on a pole. The robot's back: an Arduino Mega and green servo driver boards at the top, with bundles of servo leads and thick power cables running down to the base.
The robot from the front, and its back, where the Arduino Mega and the servo driver boards sit.

Goal

InMoov is an open-source, life-sized humanoid that anyone can 3D-print and build from off-the-shelf parts, but its own software only recognises fixed commands. The goal was a low-cost robot for teaching and demonstrations that holds an open-ended spoken conversation, shows facial expressions that fit what it says, and does simple pick-and-place with its hand.

The robot

The upper body is printed in PLA+, with PETG for the parts that mesh or slide, such as worm gears and lead screws, so that mating parts expand alike. It has three degrees of freedom in the neck, two in the waist, three in the shoulder, one each in the elbow and the wrist, and five tendon-driven fingers. Filament ran short, so the right arm and the back were not built.

A face that shows expressions

Servos inside the skull move the eyes on two axes, the eyelids, the eyebrows, the jaw and three points on the lips, all through rigid linkages. Over them sits a platinum-silicone skin, cast in a 3D-printed mould and held on with magnets; the final mask took five casts. Each expression is a stored set of servo positions, calibrated from a neutral resting face.

Two views inside the head without its skin, labelled: the jaw, eye and eyelid servos from the side, and from the front the eyeballs with linkages to the eyebrows, upper lip and side lips.
Inside the head: the jaw, eye and eyelid servos, and the linkages to the eyebrows and lips.
The silicone face at rest.
Neutral
The face smiling, lip corners raised.
Happy
The face with lowered eyelids and a downturned mouth.
Sad
The face with eyes wide open and the mouth slightly open.
Surprise
The face with narrowed eyes and the teeth showing.
Anger
The face with half-closed eyes and a tight mouth.
Disgust
Six of the expressions, each a set of servo positions under the silicone skin.

Strong joints from hobby servos

The heavy joints run through worm gears, which also hold the arm in place with the power off. A worm gear needs several turns of its servo for one sweep of the joint, more than a hobby servo allows, so in the shoulder, elbow and waist the servos' internal stops were removed and their potentiometers moved out to the joint, where they read the joint's real angle. Where two servos must turn in opposite directions, as in the neck roll and the waist, one keeps its electronics and the other is wired to it as a bare motor with reversed polarity, so the pair always moves together. The printed gear teeth came out too tight and had to be filed, sanded and greased before they turned freely.

A printed shoulder gearbox, open: a worm on the left meshing with a large toothed wheel, both coated in grease.
A shoulder worm gear, greased after its teeth were filed to fit.
The waist module on a cutting mat: two red 60 kg servos at the front drive worm gears either side of a large black central gear.
The waist: two 60 kg·cm servos turn one central gear, one mirroring the other.

A tendon-driven hand

Five servos in the forearm pull braided lines that run through PTFE tubes to the fingers, and springs at the knuckles open each finger again. A sixth servo turns the wrist, and the wrist does nothing else, to spare the tendons that pass through it.

The open forearm and hand on a cutting mat: a row of servos with pulley wheels inside the forearm, and leads running out to a test board.
The forearm, with the finger servos and their tendon pulleys.

Conversation

Speech is transcribed with Whisper, answered by GPT-4o and spoken with gpt-4o-mini-tts, streamed so that the robot starts talking before the whole reply has been synthesised. A voice-activity detector ends the speaker's turn after 0.5 to 1 second of silence. MyRobotLab, on a PC, runs the robot's services and sends the servo commands to the hardware.

What I built

Power and wiring

The control chain runs from MyRobotLab over USB serial to an Arduino Mega 2560, which drives PCA9685 16-channel PWM boards over I²C. The servos draw from a 6 V switching supply, apart from the logic supply but on a common ground. In early tests the servos moved erratically because the supply could not deliver enough current; a larger supply and checked ground connections fixed it. Inside the head, where space is tightest, I planned the routing and tied every lead down so that nothing pulled loose while the face moved.

Servo configuration

Each servo got its channel, direction and limits in MyRobotLab's InMoov2 service. I set each limit by stepping the joint to its mechanical end, so that no servo can drive into a stop: the jaw, for example, works between 50° and 120°. Servos mounted mirror-image are inverted in software, and a fault where several servos moved on one command turned out to be servos sharing a channel. The services also have to start in order: the Arduino, then the servo drivers, then InMoov2.

From voice to motion

Commands such as “say hello”, “smile” or “pick up the cup” are matched by keyword to pre-scripted servo routines: gestures, facial expressions and pick-and-place moves. The expressions are timed against the speech, so that the face changes while the robot talks.

Testing

Testing went from the bottom up: each servo on its own, then each joint with its mechanism, then the hardware with MyRobotLab and the speech pipeline, and finally live conversations, with observers judging the timing and the expressions.

Result

The robot answered spoken questions in about 2 seconds on average, changed expression in under a second, and grasped and held light plastic cups and small blocks. Through long test sessions it ran without resets, overheating or communication faults. Joints landed within about ±10° of their targets: enough for gestures and expressions, too coarse for precise reaching, which would need servos with better feedback and inverse kinematics.

What I learned

  • Powering many servos that can all draw current at once, with the servo and logic supplies kept apart on one ground.
  • Bringing up a large set of hobby servos one at a time, with limits taken from the mechanism rather than the datasheet.
  • How worm gears, relocated potentiometers and mirrored pairs turn cheap servos into strong, wide-range joints.
  • Tying a cloud speech loop to physical motion, where the timing has to feel natural to the person talking.
  • Testing a large system from the bottom up, so that a fault shows in the smallest piece that has it.