We carried out polling mechanisms to obtain IMU values by implementing a Kalman filter and an exponential moving average filter. After tracking how perceptive each filter was to changes in position based on the IMU's data, it was determined that the Kalman filter was more successful in filtering noise. One issue with using the Arduino Uno is that the frequency at which it can poll from software is lower than the frequency at which the motor encoder counts update. So, in our code, we attached interrupts to the motor encoder pins so that any physical update to the encoder would be handled by the Arduino at an acceptable rate.
The planning portion of the project occurs in real time when the stick attempts to stabilize itself to its equilibrium position. At every time step, it calculates the displacement of its current position and the desired equilibrium located at the center of mass, and then it determines the motor PWM for each axis required to return to equilibrium using PID control.
Our reaction wheels are the part of our mechanism that are responsible for moving to the desired location. They are orthogonally mounted so that the combined torque generated by their spinning enables our stick to move anywhere in R2 within a reasonable radius.
Essentially, this is an inverted pendulum problem, where our stick is perpetually in a state of unstable equilibrium. This means that when it is disturbed from equilibrium (and even when it attempts to balance on its own without disturbance), any amount of displacement will cause it to depart even further from its original equilibrium position. We are attempting to have the stick sustain its equilibrium position for at least several seconds, as well as be able to return to its equilibrium position upon slight disturbance.
The way that we can achieve this is due to the fact that when each reaction wheel spins, it generates a torque perpendicular to the plane of the wheel that opposes the direction that the stick is falling in and pushes it back to equilibrium. Since the tip of our stick is fixed and just serves as a pivot, we only need two orthogonal wheels whose combined forces can always allow us to travel back to the equilibrium from any surrounding point. The amount of torque generated from each wheel is determined by its speed: a faster spinning reaction wheel will also be faster at returning the stick to upright since it generates more torque than a slower spinning wheel. The direction that each wheel spins (clockwise or counterclockwise) determines the direction along its respective axis of the generated torque.
The central formula for our problem is defined below via the Conservation of Momentum, where we essentially set the moment of inertia of the wheel equal to the moment of inertia of the pendulum and factor in the torque generated by the system and environmental forces. There are several variables that we focused on throughout the design and implementation process: by manipulating the mass of the system (m), the length of the stick (l), and the radius of the wheel (theta), we could achieve the desired moments of inertia for the system.
Schematic: Side View of a Wheel
Pertinent Variables and Formula
There were a few major design decisions when creating the base model of our hardware. The first was the modularity of the design: It was important to have a flexible design which allowed for quick changes and tweaks. The entire balancing stick can be broken up to 5 main components: the stick, the wheel, the motor, the electronics, and a platform to hold it all together. Along with the quick supply of parts from 3D printing, having a linear construction allowed us to adapt to any potential problems that could have arisen. This proved to be useful as we switch out stick designs and wheel designs quite often.
Additionally, weight was a huge factor in our design choice: not only were we concerned with how much mass we had to move with reaction wheels but also where the center of mass was located. Some things that were done to solve this problem was adding holes in the design to reduce material usage and using CAD simulations to determine how that mass was distributed. Although there weren’t many drawbacks to our approach, it became clear that 3D printing didn’t give us the precision and quality we were looking for. In addition, the parts we bought like motors offered limitations to how the assembly actually came together.
Reaction wheel with added weights
Nidec 24H BLDC motor
Choosing the motors was the most important and difficult task, so we took our time evaluating different types of brushless servo motors. We decided to trade off the weight of the motor for power and opted to have an encoder and driver on board which would decrease the latency caused by separate circuits. After we agreed on the Nidec 24H BLDC motors, we ordered them within the first week of the project. Although they didn't arrive until several days before our demo day due to shipping delays, we continued designing the rest of the system given the information we had about the Nidec motors and used placeholder motors with drivers and separate encoders to implement and test our hardware in the meantime. In hindsight, we traded off time for better motors, which would have allowed our system to be more efficient, but instead caused it to be less robust as we had to redo all motor tests once the correct motors arrived.
We designed housing for the motors to support orthogonal axes as well as a centered center of mass.
Motor housing design
We choose the Arduino-Uno as a microcontroller for our project: it's an unthreaded microcontroller that processes all functions sequentially rather than in parallel. In hindsight, this was a poor design choice as it increased the system's latency. This was exacerbated by the fact that the microcontroller runs with a different clock speed than the PWM driver on the motors. We made a workaround by masking the timers in code.
Timing is arguably the most important aspect of our system, and thus we have to decrease the latency as much as possible. A better option would have been to use a faster multithreaded option, namely the ESP-32. Another microcontroller design alternative would be to control the motors separately on different microcontrollers and establish a connection between the stick and ground station using UART or BLE. This solution is not ideal as connections might get interrupted.
Arduino-Uno Microcontroller