Back to projects

Romi w/ Dual 4-Bar Actuated Arm

2026

RBE 2001 final project: a Romi rover with a 3D-printed dual four-bar arm that places blocks on shelves at different heights, driven by inverse kinematics on an ATmega32U4

Final demonstration of our robot
Testing grabbing behavior

About this project

This was our team's final project for RBE 2001 (Unified Robotics I) at WPI, built with Alfredo J. and Nate R. on a Pololu Romi chassis. The robot had to:

  • Move two blocks to two different positions on a shelf without touching the shelf itself
  • Tuck its arm away afterwards
  • Drive to an exact final position, using a mix of forward and inverse kinematics for both the arm and the drivetrain

I designed the arm mechanism and programmed its motion. I also helped with the drivetrain odometry, the inverse kinematics, and the servo firmware.

Designing the arm

The arm uses two independent four-bar linkages, and the claw uses a smaller four-bar for each finger. I chose this from the start. The claw has to go into the shelves straight every time, so it needs to stay horizontal. A four-bar keeps it level on its own. We didn't need an extra degree of freedom at the claw, and a wrist joint would have added complexity we didn't need. The dual four-bar also makes the arm stiffer and simplifies the whole mechanism.

Every custom part is 3D printed in PLA. I used SolidWorks to check that the design would hold up:

  • FEA on the worst-case static pose gave a minimum factor of safety of about 13
  • Torque math for each servo: an MG996R at the base of the arm and MG90S servos for the other joints and the claw
  • A power budget. One LM2596 buck converter steps the Romi's 9 V supply down to 6 V for the servos. In testing, the arm never drew more than 2.5 A, which is within the converter's 3 A limit

Programming the arm

The firmware is C++ on the Romi's ATmega32U4:

  • Inverse kinematics. A geometric law-of-cosines solution for the 90 mm lower arm and 140 mm forearm, with angle offsets that account for the linkage geometry
  • Task-space waypoints. To avoid touching the shelf, the arm doesn't move straight to a block. It follows a series of waypoints that I planned out and hard-coded into the final version: into the shelf, release the block, back out, up to the next level, and so on
  • Drivetrain. Wheel-encoder odometry tracks the robot's position, and a proportional drive-to-point controller steers it to its destination
  • Tuning tools. Two potentiometers could drive the arm directly in task space, and live plots in Teleplot showed the joint angles while we tuned

The timer problem. The course's servo library produces its PWM signals from the ATmega32U4's hardware timers (Timer 3 and Timer 4), and that only works on a few pins. Timer 4 is also shared with the drive motors' speed controller. The arm needed four servos: a mirrored pair on one joint, a third arm joint, and the claw. That was more than the library could run. So we switched to the standard Arduino Servo library, which generates the pulses from Timer 1 interrupts and can drive servos on almost any pin. After that, all four servos ran without interfering with the drivetrain.


Final presentation

Title slide: Final Project, RBE 2001 Lab 1 Group 3, Alfredo J., Bryce Martis, Nate R.

Slide on how the robotic arm reaches different heights

FEA stress plot of the arm in its worst-case static configuration

Slide on the choice of PLA and its yield strength

Torque calculation for the MG996R servo

Power system slide on the LM2596 buck converter

Arm code overview: updateServos, ArmMoveToPoint, helper methods, and the Arduino Servo library

Closing slide: Thank you, any questions?

Download the presentation (PDF)