Report - RossC3/ECE387FinalProject GitHub Wiki
Background
Objective
The goal of this project was to create a smart weightlifting belt that could improve weightlifting performance and safety for the user. Using a gyroscope/accelerometer, the belt monitors the tilt of the user in all for directions and provides haptic feedback to notify the user of dangerous movements. Documentation and the setup process for the project can be found below. A demo of the device's application in performing squats and deadlifts is included as well.
Background Information
The Problem
One of the main problems associated with heavy lifts such as deadlifts, cleans, squats, and snatches is the strain these exercises put on the lifter's back. While these exercises are part of a healthy work out routine, they are particularly stressful on the joints and soft tissue of the spine. Increased strain over long periods of time can lead to serious health conditions such as Arthritis and herniated disks. This strain can becaused by a variety of factors such as posture, stance, over lifting, and high weightloads, but a common symptom of all of these is incorrect form and twisting of the body in an unnatural motion that differs from the recommended weightlifting moment. Weightlifting belts have long been a solution to this issue, but they do not completely eliminate improper flexing of the back.
MPU6050
The main chip chosen for this project was the MPU6050 sensor. The MPU6050 can sense motion on 6-axes with its 3-axis Accelerometer and 3 Axis Gyroscope. There is also a built-in Digital Motion Processor for reading motion data and a Temperature sensor that can be used to calculate Drift in certain applications.
Important Pins
- VCC: 5V DC Power Supply Pin
- GND: Ground Pin
- SDA: Serial Data Pin
- SCL: Serial Clock Pin
- XDA: Serial Data Pin pass-through for other I2C devices
- XCL: Serial Clock Pin pass-through for other I2C devices
Design Description and User's Guide
Hardware
For this project, the Raspberry Pi was chosen because of previous experience and the ability to create a simple graphic user interface for testing and an application. For early attempts at building the belt and testing the model used was a Raspberry Pi 3 B+, with the final prototype using a Raspberry Pi Zero W. Testing was done on the more robust Pi 3 due to it's higher clock speed which helped improve developer experience while tinkering with code and finetuning the belt. While the majority of the belts abilities come from its software's use of the MPU 6050 Accelerometer and Gyroscope, 3.3 V haptic feedback motors used commonly in mobile phones were incorporated into the final product as a warning for the user that their motion is unnatural.
Software
Setup.py
This script was modified from a script found at Electronic Wings.
Setup.py allocates register space, initializes the necessary pins on the Raspberry Pi and processes all the data from the MPU 6050 module formatting it into useable outputs. The gyroscopic data is converted to degrees per second and the Accelerometer is converted to g's. This module is not meant to be directly interfaced with by the user but is implemented by other modules within the library, but does contain get Methods for all 6 axis values incase a desired implementation calls for it.
Functions include:
- MPU_Init: Writes data from MPU 6050 to registers allocated to it at run time.
- read_raw_data: Reads data from the MPU 6050 device based on the address of the component given
- getGx: returns X angular velocity in degrees per second
- getGy: returns Y angular velocity in degrees per second
- getGz: returns Z angular velocity in degrees per second
- getAx: returns X acceleration in G-Force (g)
- getAy: returns Y acceleration in G-Force (g)
- getAz: returns Z acceleration in G-Force (g)
Calculations.py
Calculations.py imports data from Setup.py and handles calibration of the gyroscope to account for errors in measurements due to the physical position of the chip. The calibration function works by collecting one thousand samples of rotations on each of the axes at rest calculated from the acceleration data and finding the average value. These calibrations are then used to correct the error in rotation by normalizing the calculated rotation by the average calculated.
Calculations.py can be used by other scripts to give the +/- rotation away from zero on both the X and Y axis and also has get methods for each axis' acceleration value converted from g's to meters per second for ease of use.
Functions include:
- dist: calculates the distance between two points or values on the xyz axes
- getYRotation: Outputs +/- Y rotation from approximately zero based on calibration
- getXRotation: Outputs +/- X rotation from approximately zero based on calibration
- getZRotation: Similar to other functions, but is not consistent 100% of the time. Needs further reworking and connection to magnometer to get correct measurements
- getXAcceleration: Returns X acceleration component in m/s
- getYAcceleration: Returns Y acceleration component in m/s
- getZAcceleration: Returns Z acceleration component in m/s
- getXG: Returns X angular velocity in degrees per second
- getYG: Returns Y angular velocity in degrees per second
- getZG: Returns Z angular velocity in degrees per second
- resultantForce: Calculates Magnitude of Resultant Force based on acceleration on all 3 axes and a given mass
- calibrate: Helper method that calls calX() and calY()
- calY: takes a sample of 100 Y rotation values at rest and calculates the average resting angular position on the Y axis
- calX: takes a sample of 100 X rotation values at rest and calculates the average resting angular position on the X axis
- atRest: Determines if the user is in motion or at a starting position.
TiltControls.py
TiltControls.py imports data from Calculations.py in order to create methods that output whether the MPU 6050 chip is tilting and on what access it is. When implemented in another script, the orientation of the chip has to be set by the user in order to determine the primary horizontal axis. The methods within the module, e.g. Right() return a boolean in order to tell the user if the chip is tilting to the right or not. The user must also set the tilt sensitivity of the controller. For example, the controls for the demo game included in this wiki are extremely sensitive with the Right() method returning true if the degree of rotation exceeds 1 degree. However in another implementation, such as one focused on monitoring balance, the threshold before Right() returned true would be greatly increased. The idea behind this script was that for many applications like balancing or controlling objects, it would be the only module necessary for the user to use.
Functions include:
- setOrientation: Defines whether the X or Y axis is the vertical axis of the Controller with input 0 for Y and 1 for X. The default setting is Y.
- setSensitivity: Defines the degrees of sensitivity before Right, Up, Down, and Left methods return True for tilt in their respective directions. Increasing the inputs decreases sensitivity to Tilt.
- Right: Detects if the controller's tilt is past the +horizontal degree sensitivity
- Left: Detects if the controller's tilt is past the -horizontal degree sensitivity
- Up: Detects if the controller's tilt is past the +vertical degree sensitivity
- Down: Detects if the controller's tilt is past the -vertical degree sensitivity
Calibrations.py
Calibrations.py is what makes it possible for the belt to accurately spot the user. It uses Calculations.py to determine if the user is at rest and then calculates the maximum rotation in all directions for each rep the user completes and stores each of these values in a separate array dedicated to rotations in their respective direction. After an amount of calibration reps are finished, the average and standard deviation of each max rotation is calculated and stored in variables for later use by the MainGUI.py script.
Functions Include:
- calibrateBelt: Counts repetitions and finds the average and standard deviation of all x, y, and z rotations.
- calculateRep: Calculates x, y, and z rotations of the body during a repetition.
MainGUI.py
The MainGUI.py script is an example of how an application that uses the smart belt could work. Using the RealVNC Viewer application the GUI can be put on someone's Phone and run on startup for the prototype. The GUI was created using Pygame and consists of different screens with options for different lifts and calibrating the belt for those lifts. This script also stores the maximum rotations in each direction for future use while lifting. A Class for creating buttons is also included in this script for added features.
Functions and Classes Include:
- button: creates a button object that can manipulate the GUI.
- redrawWindow: Redraws original window on the start screen.
- calibrationScreen: Creates a screen for calibrating the belt for an exercise.
- liftScreen: Creates a screen for calibrating the belt for an exercise.
- exerciseScreen: creates a screen for calibrating the belt for an exercise.
Implementation
The design process for this device started by utilizing software libraries and developing scripts that in theory would help the built function in the way desired. Then once these scripts and the GUI were built testing was done by manipulating the gyroscope and accelerometer and then seeing whether the desired results were achieved. After this, the system, a Raspberry Pi 3 B+, was attached to the belt with cardboard and velcro for preliminary testing. Once this proved to meet the needs of the project, a more polished prototype with a 3D printed gyroscope holder replaced the cardboard mockup and an encased Raspberry pi Zero replaced the larger 3 B+. The last step was attaching the haptic motors to the belt and then the demos were filmed and the project complete.
Software
The library for the MPU6050 Chip was the same one I used for my midterm project. Setup.py handles the reading and writing from the MPU6050 module. This information is then filtered through Calculations.py to create meaningful data such as horizontal rotation and whether or not the gyroscope is at rest. Calibrations.py, which is not apart of the library, takes the rotational readings from Calculations and upon execution of its functions calibrates and calculates the parameters for the smart belts tilt sensing. These parameters are then filtered through TiltControls.py, setting the sensitivity for the belt in all directions. MainGUI.py is the way the user interacts with the smart belt and utilizes the other scripts to calibrate the belt for an exercise and perform an exercise.
The Device
The smart belt device consists of a weightlifting belt made by Fire Team Fit, a Raspberry Pi, a haptic feedback motor, and a breadboard holding the MPU6050 gyro/accelerometer. The Raspberry Pi was mounted to the belt using velcro. To hold the breadboard and gyro in the correct position a 3D printed part was created and attached in the center of the belt above the Raspberry Pi. For testing, only one haptic motor was used at the front of the belt, with options for more to implemented on the right, left and back side.
Results
Demos
- Demo of Components: https://youtu.be/yzpMwBoEnIY
- Demo of Smart Belt: https://www.youtube.com/watch?v=8UBk4kNxSNQ&t=3s
Presentation of Results
I was able to create a smart weightlifting belt that can successfully detect unnecessary stress and improper form by measuring rotation in the x,y, and z directions using a gyroscope and accelerometer. This system has a basic GUI which can be easily added to and manipulated to provide a better user experience with premade objects such as buttons.
Bill of Materials
Challenges
Challenges Faced include:
- Determining the best way in which to calibrate the belt. Originally the thought process was to create arrays and then add to them over time to improve performance of the tilt sensing, but this proved too complex to implement individually for more than one lift at a time.
- Determining the difference between small movements by the body and the movements of a lift for calibration. This was done partially through coding and by trial and error of using the belt.
- Originally I had intended to use a PN532 RFID/NFC board to store the values of a user's lifting rotations for a user by user basis, but the board was damaged during setup and was only able to work in a configuration with an Arduino. Cost also became an issue with replacing the board.
Improvements
Improvements include:
- Attaching a battery pack to the belt for more mobile use.
- Creating a more robust GUI that simplifies user interaction
- Using arrays to store lifting tilt maximums and minimums to optimize tilt sensitivity.
- Incorporating a user by user experience with RFID/NFC or by storing user information in a local database.
- Cleaning up redundant code within the GUI and other scripts
- Modeling parts for the belt with limited CAD experience.
Learnings
- I originally went into the project with plans to build a super high tech belt with gyroscopes, RFID/NFC, and a muscular EMG sensor, but the scale of incorporating these chips, troubles with components and the cost associated with materials put a limit on what I was able to do. I think having grand ideas is important, but this project has definitely taught me how to break down big ideas into little, accomplishable tasks that make projects easier.
- Better understanding of python and object-oriented programming.
- Knowledge of 3D modeling and rapid prototyping.
Conclusion
Creation of a weightlifting belt that can monitor a user's lifting form and notify them if there is a need for correction, in my mind was successful. However, improvements can be made to improve user experience and add more usefulness and practicality to this system as a real-life product.
Helpful Resources
Buying Links
- MPU 6050: https://www.amazon.com/gp/product/B0151GI5VI/ref=ppx_yo_dt_b_asin_title_o02_s00?ie=UTF8&psc=1
- Raspberry Pi Zero: https://www.amazon.com/gp/product/B07CMVDHWB/ref=ppx_yo_dt_b_asin_title_o04_s01?ie=UTF8&psc=1
- Haptic Motors: https://www.amazon.com/BestTong-0-05A-Mobile-Vibration-10x2-7mm/dp/B076ZS77T1/ref=sr_1_fkmrnull_1_sspa?keywords=haptic+mini+motor+disk&qid=1554824756&s=gateway&sr=8-1-fkmrnull-spons&psc=1
- Weightlifting Belt: https://www.amazon.com/gp/product/B013FFGQ5E/ref=ppx_yo_dt_b_asin_title_o04_s00?ie=UTF8&psc=1
Learning Tools
- Learn more about Gyroscopes and Accelerometers here: https://www.livescience.com/40103-accelerometer-vs-gyroscope.html
- Raspberry Pi Quick Start Guide: https://projects.raspberrypi.org/en/projects/raspberry-pi-getting-started
- Python Programming Guides and Pygame Tutorial: https://techwithtim.net/
- MPU 6050 Interfacing and Start Up: http://www.electronicwings.com/raspberry-pi/mpu6050-accelerometergyroscope-interfacing-with-raspberry-pi
- MPU 6050 Data/Spec Sheet: https://www.invensense.com/wp-content/uploads/2015/02/MPU-6000-Datasheet1.pdf
References
-
Hyde, Thomas E. “Bodybuilding, Weightlifting and Back Pain.” Spine, www.spine-health.com/conditions/sports-and-spine-injuries/bodybuilding-weightlifting-and-back-pain.
-
“MPU6050 (Accelerometer+Gyroscope) Interfacing with Raspberry Pi |..” ElectronicWings - A Platform to Learn about Electronics, www.electronicwings.com/raspberry-pi/mpu6050-accelerometergyroscope-interfacing-with-raspberry-pi.