Romi

Romi picture
Time constant graph
Romi animation

Project information

Romi Autonomous Navigation Bot

This project was centered around building a mobile robot that could autonomously navigate an obstacle course with a decent level of consistency and speed. We used the Pololu Romi chassis as the mechanical base with two motors and two encoders. Additionally, we added a 7-sensor IR reflectance array, a BNO055 IMU, and bump switches. The brains of the system was an STM32 Nucleo-L476RG running MicroPython through a custom board called the “Shoe of Brian.” That board basically let us skip the C setup entirely and get straight to programming with Python.

The task was to complete a fixed track with several required checkpoints, meaning we couldn’t just hardcode the whole thing. So, we ended up using a mixed approach: algorithmis for the straightaways and curves, and some hardcoding of the track for error correction and certain obstacles. The IR array took care of the line-following, while the encoders and IMU took care of odometry and orientation. The bump sensors were used for the final wall section and error detection (if we hit an obstacle).

Wiring everything to the Nucleo was difficult. Some components required analog reads, others timers, and some had to use I2C. A lot of the work was just making sure each pin was assigned correctly by reading datasheets. We also banned some pins entirely due to overlaps or unstable behavior. Power for all the devices came from the Romi's PDB, which also provided motor power through a dual H-Bridge.

On the code side, we broke the logic into tasks using cooperative multitasking. Each subsystem (line follow, motor drive, encoder read, etc.) ran in its own task with shared variables for coordination. We also designed the overall behavior of the robot using a finite state machine (FSM), allowing it to respond to events like line loss, checkpoint detection, and bumper presses in a structured and predictable way. PID controllers were used to manage motor effort based on encoder feedback and for tracking the line centroid from the IR array. A lot of these features were implemented using object oriented programming.

We also modeled Romi’s motion using nonlinear kinematics and tested our assumptions with an RK4 numerical model in Jupyter. This gave us a sense of how Romi should behave and helped us tune gains for better performance on the real track. We used code to run step tests to get motor time constants and steady-state gains, which were then used as parameters in the simulation.

All of that said, we ran into issues. Our biggest one was the IR line sensor. We picked a narrow array and it just didn’t work with the thin course lines. It worked fine on wide lines in early testing, but once we hit the final track layout, the IR sensors above the line would still receive reflected light from the sensors beside them. So, the line detection stopped working. We tried blinders to limit ambient bounce-back and they worked. But since they were a last minute fix with cardboard and hot glue, they did not work very well. If we could go back, we’d swap the sensor out entirely for a wider array or make a more functional set of blinders.

We also had a lot of instability with the Nucleo itself. It would randomly lock up and need multiple firmware reflashes to come back to life. We never figured out why that happened, but it burned a lot of debugging time. The Bluetooth module was meant to provide easy debugging and testing, but we were never able to get the bluetooth paired to a computer. So, we eventually pulled it from the design.

At the end of the quarter, we made it consistently through checkpoint 2. Beyond that, our line tracking couldn’t hold long enough to get to the final obstacle. The rest of the control structure (motor PID, obstacle response, heading correction, etc.) was working and ready to go, so we’re confident the system could have completed the track with a better IR sensor setup or more time to hardcode a backup routine.

Overall, this project gave me solid experience building up a full mechatronic system from scratch. We learned about everything from power distribution and GPIO management to system modeling, firmware/drivers, and debugging. The Romi platform was extremely modular, the code structure was lightweight and readable since we used MicroPython. This was definitely a fun mix of electrical, mechanical, and software challenges all mixed into one project.