Analyze, implement, and tune the control system for a provided reaction-wheel motorcycle platform capable of autonomous lateral balance and forward motion across a 2-meter course. All mechanical hardware was pre-supplied by the course; the work centered on stability analysis, PID controller tuning, and embedded software implementation.
Platform: pre-built two-wheeled motorcycle chassis
Balancing mechanism: internal reaction flywheel
Sensor: BNO055 IMU for roll angle feedback
Microcontroller: Arduino with Motor Carrier shield
Drive motor: rear wheel DC motor
Race course: 2 meters, fully autonomous
Analyzed the motorcycle-flywheel system using a state-space dynamic model, extracting physical parameters from the provided hardware
Performed pole-zero and root locus analysis in MATLAB to characterize open-loop instability and identify the negative-gain control requirement
Interpreted stability analysis results to inform PID controller design
Iteratively tuned PID balance controller gains through hardware testing across multiple configurations
Implemented integral anti-windup and 14° safety cutoff in the embedded controller
The motorcycle and flywheel form a coupled dynamic system whose behavior was characterized using a state-space model, parameterized with the physical measurements of the hardware — including motorcycle mass (0.2948 kg), flywheel mass (0.0695 kg), flywheel radius (0.05 m), and motor constants (Ke = Kt = 0.019). Converting the state-space representation to a transfer function using MATLAB yielded:
G(s) = −1.024s / (s³ + 0.6607s² − 96.56s − 61.92)
The pole-zero map shows the poles of the open-loop transfer function, the values that describe how the system behaves without any active control. Poles in the left half of the plane are stable, meaning a disturbance decays over time, while poles in the right half are unstable, meaning a disturbance grows. The system had three poles: two on the left, and one at approximately +9.8 in the right half plane. That single unstable pole confirms mathematically what is physically obvious, the bike falls over if left uncontrolled, and it establishes that active control was required before any controller design began.
The root locus builds on this by showing how those poles move as controller gain is varied from zero upward. Sweeping positive gain drove the unstable pole further into the right half plane, making the system more unstable. Only with negative gain did all three poles migrate into the left half plane, into stable territory. This result is the mathematical basis for using negative gains throughout the controller, and it follows directly from the flywheel's reaction torque, since a positive command reinforces a lean rather than correcting it. The root locus also showed the two originally stable poles breaking off the real axis and forming a complex pair as gain increased, predicting the oscillatory behavior that was later observed on hardware at higher proportional gain.
With the stability analysis establishing the sign and approximate magnitude of the required gains, a PID balance controller was implemented in Arduino C++ using roll angle feedback from the BNO055 IMU. MATLAB's pidtune function provided a starting point of Kp = −4280, Ki = −100, Kd = −200.
Testing these gains on the physical bike showed a response that was too soft, correcting slowly and drifting under quick disturbances. Proportional gain was raised to Kp = −6000 for a faster, stiffer correction. That stronger response reintroduced overshoot under rapid tilt changes, so the derivative gain was doubled to Kd = −400 to add damping and settle the motion. With proportional now carrying more of the corrective load, the integral gain was reduced to Ki = −25, since less residual error remained for it to correct and the original value was causing the bike to overshoot past vertical.
The final gains, Kp = −6000, Ki = −25, Kd = −400, produced reliable balance with approximately 3 seconds settling time and minimal overshoot. The controller included integral anti-windup to prevent integrator saturation during large disturbances, and a hard 14° cutoff that zeros motor output beyond a recoverable tilt angle.
This step response was generated in MATLAB using the initial pidtune gains (Kp = −4280, Ki = −100, Kd = −200), simulating the linearized model's predicted response to a disturbance. The model settles in roughly a tenth of a second, since the simulation contains none of the real-world effects present on the physical bike, including motor deadband, bearing friction, and asymmetric weight distribution. On hardware, these unmodeled effects meant the actual settling time was closer to 3 seconds even after further tuning. This gap between the idealized simulation and the physical result is a large part of why hardware refinement, rather than the model alone, was necessary to achieve reliable balance.
Forward motion was implemented as an open-loop timed sequence, fully decoupled from the balance loop. Empirical testing over four runs established that the bike covers 2 meters in an average of 1.71 seconds at full duty. A 20% time buffer was added, producing the final sequence: 5-second balance settling delay → 2 seconds at 100% duty → 0.5-second linear ramp-down to 0%. The drive motor also cuts off if tilt exceeds 14°, linking the two control loops through a shared safety condition.
Completed the 2-meter drive phase in under 2 seconds, following a 5-second balance stabilization period
Zero falls, zero penalties
Root locus analysis confirmed negative-gain requirement — one positive pole at s = +9.82 confirmed open-loop instability
Negative-gain PID (Kp = −6000, Ki = −25, Kd = −400) achieved ~3 second settling time through iterative hardware tuning