Introduction: Control Moment Gyroscope | Active Boat Roll Elimination
Hello, and welcome to my instructable. This project is to make a scaled prototype for an active control system to eliminate boat-roll caused by waves.
This project was originally designed by myself, Kaden Werner, and my project partner, Alex Morin, for a college course in Electrical Engineering Technology. The goal of the course was to design, construct and program some form of control system related to process control and automation. Together, we decided to use the angular momentum of a spinning flywheel to apply torque to a model ship's body in response to offset in the roll axis to control the oscillations of the model as it returned to center.
This project is inspired by the commercially available product, the Seakeeper, and a project video posted by James Bruton on Youtube.
Our goal was to design this project to use commonly available components as well as 3D printed components, designed with Fusion 360, included in this instructable.
Please note that this instructable is being submitted to the Electronics contest here on Instructables, so please consider voting for this project here if you find this project interesting, and thank you for your support.
This project will explore using and integrating the Arduino Uno micro-controller, servo motors, brushless DC motors, inertial measurement units, and PID control.
Disclaimer: I am not affiliated with any of the purchasing links provided in this project. These are here so you can find the exact parts that we used for this project, and I gain no compensation from your purchases.
A note on safety: This project uses (relatively) high currents (up to 25A) and heavy objects spinning at very high speeds. Use the appropriate PPE, such as safety glasses, while operating at your discretion. Do not work on the electrical components while energized. I am not responsible from any injury or harm as a result of this projects replication. Please take the time to asses risks and act accordingly. From personal experience, accidents are not planned and happen faster than you can react. PLEASE be safe.
Supplies
Project Components and materials:
- Arduino Uno R3
- Arduino Uno proto-shield
- MPU-6050 Inertial Measurement unit
- Brushless DC motor
- Electronic Speed Controller (ESC)
- Servo motor
- 12 V battery (We used a small 12V Lead-Acid battery as it was on-hand and capable of supplying sufficient current to the motor)
- 5mm bearing
- <1kg PLA filament
- 25A circuit breaker (optional protection / means of switching power)
- steal ball bearings
- 3/4" NPT plumbing flange (used as the flywheel)
- 8mm M5 nylon locking nut
- assorted electrical connectors
- assorted wire
- assorted nuts / bolts
Tools used in this project:
- Labists ET4 3D printer
- 3D pen
- Soldering iron / solder
- wire cutters / strippers
- assorted hand tools
Step 1: How This All Works
The purpose of this project is to produce and demonstrate a scaled prototype for an active control system which stabilizes boat oscillations caused by waves about the roll axis. Since boats float on water and must be able to travel, solid external structures cannot be used to push/ pull against to apply the necessary torque for stabilization. To overcome this, the angular momentum of a spinning gyroscope will be utilized to create a self-contained method of exerting torque on the ship hull to reduce and dampen the oscillations caused by waves.
The active control system created in this project uses the Arduino Uno R3 to control the overall process. This controller will interface with a solid-state inertial measurement unit (IMU), a servo motor, and an electronic speed controller / brushless DC motor.
The IMU measures the hull model's acceleration in 3 axes and can be used to calculate the roll angle of the hull from -90→90 degrees. This is used as feedback to the controller to identify its offset from the center point of balance.
By outputting a pulse width modulation (PWM) signal to the electronic speed controller (ESC), the speed of the brushless DC motor can be controlled. This motor drives the flywheel used as the control moment gyroscope. The ESC also provides power to the microcontroller via the 5V and ground lines attached to the data line.
The Servo motor is used to rotate the cradle which houses the flywheel and its motor. By outputting a PWM signal to the servo, the angular position it rotates to and holds can be set by the controller. The rotation of the flywheel axis via the servo motor will be used to exert torque on the body of the hull about the roll axis.
The Arduino microcontroller will be operating a PID loop, using the feedback from the IMU as the process variable and the command position of the servo motor as the control variable. The PID loop will be trying to keep the boat hull in an upright position (0o offset) by changing the servo position to exert torque in the opposite direction of the offset angle detected by the IMU.
Step 2: 3D Printing
See the print list to find the quantities for each file to be printed. All of these parts are self designed using Fusion 360. Additionally, the slicer settings for Ultimaker Cura that I used for printing. Note the grey cells in the print settings table. These settings were specifically chosen for these parts to reduce print time, increase resolution or prevent supports from causing issues on the surface of the print.
Step 3: Mechanical Construction
- Preparing printed parts for mechanical assembly
- Each bolt hole created in the 3D printed parts has a recessed area for the hex-nut to be set in. The nuts should fit tightly in their spot to make assembly easy, and may require using a soldering iron to briefly heat the nut before pressing into the plastic
- Note that using the soldering iron to heat the hex nuts may cause burns to the user. Do not directly handle the heated metal parts while inserting and allow to cool completely before handling again.
- Also note that excessive heat may melt and deform the printed parts beyond what is necessary to press fit the hex nuts. Only apply heat for 2-3 seconds.
- The following nuts need to be inserted in the following locations:
- Bottom of servo cradle – 4x6-32
- Hull bottom – 4x10-32
- Hull top – 2x6-32
- Cradle bracket – 1x10-32
- Attach servo motor to servo bracket
- The servo motor needs to be inserted into the servo bracket. Note that the leads coming from the motor will prevent it from being inserted as is. To overcome this, remove the four screws holding the backplate of the motor in place. This will allow you to remove the backplate and pass the wire leads through the bracket while installing.
- Also note the fitment of the motor in the bracket. A common issue in 3D printing is retaining dimensional accuracy as the plastic filament tends to expand / contract as it warms and cools. This part may need to be filed before the servo motor can fit into it.
- After inserting the servo, re-attach the backplate and use two ½”x10-32 screws to secure it in place.
- The bracket can now be attached to the hull with two ¾”x10-32 screws, and the motor leads can be passed through the hole next to the mounting spot.
- Attach servo arm to motor
- The servo motor comes with an ‘arm’ which will be used to connect the motor to the servo cradle. The arm should be pointing straight downwards when at its middle position. A simple program was uploaded to the Arduino to command the servo to position itself at 90o, and the servo arm was attached such that it pointed as close to straight downwards as possible.
- Note that the arm is attached to the shaft by gripping the teeth of the shaft. This results in limiting the arms placement accuracy. After finding the closest desired spot, the servo was turned to values near 90o until the arm was pointing straight down. It was found that 85o was the closest value that could be used, and this will be noted for the programming phase.
- The arm should have its screws tightened so that it is securely attached to the motor shaft.
- Attach the servo cradle
- The servo cradle is held between the servo and the cradle bracket. The 5mm bearing should be inserted at this time, and then the cradle should be attached to the servo arm in its bracket.
- The cradle bracket can now be attached to the cradle using a ¾”x10-32 screw through the 5mm bearing.
- The cradle bracket can now be attached to the hull with two ¾”x10-32 screws.
- Attach the Brushless motor
- The DC motor can now be attached to the servo cradle using 4 ½”x6-32 screws.
- Note that the mounting hole on the brushless motor may be slightly too small for the 6-32 screws. These need to either be bored to a slightly larger size, or have threads tapped so the screws can be inserted.
- Attach the flywheel
- First, screw the flywheel bushing into the ¾ inch plumbing flange. This may require channel-locks or an adjustable crescent wrench to ensure a tight fit.
- Attach the flywheel to the motor using the M5 nylon lock nut (uses 8mm socket wrench). It is recommended that blue thread-locker is also used to ensure the flywheel is securely attached.
- Attach side panels / load ballast / add center-of-gravity (COG) adjustment
- Note that it is not recommended that you complete this step until the electrical assembly is completed.
- This process is done to lower the center of gravity of the entire object so that it doesn’t topple over, as well as adjust the COG from left to right so that the hull can balance on its center point. It is our goal to add as little ballast weight to accomplish this in order to demonstrate the active control stability of the system being created.
- Adding the electrical components will affect the center of gravity of the body, so it is recommended that adjusting the weights and positioning is completed last
- Additionally, adding the ball bearing as ballast will interfere with installing the IMU in the electrical assembly section.
- Attach the two COG adjustment brackets to the end of the hull opposite of the servo motor using melted PLA plastic. It is recommended that a handheld 3D pen is used for this. Insert the 13mm captive hex nuts as well as the two M8x45mm screws to act as counterweights. The two screws can be adjusted in / out to move the COG left and right
- Attach one of the side panels to the hull using the 3D pen. Fill the cavity beneath the IMU mounting section with enough ball bearings to prevent the weight of the motors / flywheel from toppling the model over when tipped. Lay the model flat and press the second side panel into the cavity so that the ball bearings are packed tightly.
- Note that the side panels are made thin enough to bend, aiding in pushing the second one in the cavity. This is an important step as it will prevent the ball bearings from shifting left / right, changing the body’s COG.
Step 4: Electrical Installation
- Prepare power source, circuit breaker and electronic speed controller (ESC)
- Prepare two 15cm long 12-gauge wires each with one end stripped about 1cm and the other about 2cm. These will be the positive leads and should have red insulation.
- Crimp on a female quick-disconnect connector to the 1cm end of each wire
- Attach the 2cm long ends to the circuit breakers line and load terminals
- Prepare one 30cm long 12-gauge wire (black insulation) and strip each end by about 1cm
- Crimp one male and one female quick-disconnect connector to the ends of the negative lead.
- Cut off the stock battery connector from the ESC and strip 1cm from the leads. Crimp a male connector to the positive lead and a female connector to the negative lead.
- Remove the connector from the 3-wire lead and strip / tin each lead.
- Prepare servo motor
- Remove the connector from the 3-wire lead and strip / tin each lead.
- Prepare IMU board
- Prepare four 22-gauge wires, approximately 10 cm long, by stripping 1cm from each end. The following wires should be soldered to the following through-hole mounts
- Red – VCC
- Black – Ground
- Yellow – SCL
- Green – SDA
- Prepare Bluetooth module
- Prepare four 22-gauge wires, approximately 10 cm long, by stripping 1cm from each end. The following wires should be soldered to the following pins
- Red – VCC
- Black – Ground
- Yellow – RX
- Green – TX
- Install Arduino board
- On the under section of the hull is a raised platform marked “UNO.” Place the Arduino Uno board into the space so the end with the USB port is underneath the retaining bracket.
- Use two ½”x6-32 screws to secure the board to the hull though the mounting holes.
- Prepare prototype shield
- The connections should be made on the prototype board before installing the rest of the electrical hardware, as per the two proto-shield images included with this step.
- Install shield on Arduino board by pressing the header pins in place
- Mount ESC
- On the raised area of the hull’s underside marked “ESC,” secure the ESC in place with a zip tie so that the end with the 3 output leads faces the same direction that the brushless motor’s leads point out.
- The three motor leads can now be connected to the ESC. Note that the lead connection will affect the direction of rotation, however it is unknown what direction the motor will spin until further testing is done. For now, connect the leads in any orientation.
- Mount the IMU
- Use a zip tie to secure the IMU to the bottom portion of the hull labeled “IMU.”
- As previously mentioned, this should be done before filling the bottom with the ballast weights as that would interfere with this process.
- Mount Bluetooth module
- Use hot glue to mount the Bluetooth module (in its plastic case) to the hull next to the Arduino board.
- Connect to power
- Connect the black lead made in step 1 to the negative battery terminal / lead on the ESC.
- Connect the circuit breaker leads to the positive battery terminal / lead on the ESC
- Wrap the ESC leads with electrical tape to prevent the leads from shorting
Step 5: Programming
The included INO file contains the Arduino sketch that we created for this project. You may need to install some of the libraries included with the control program.
This program will automatically turn on the flywheel drive motor upon start up, so be careful. It uses PID control to take the measured angle from the IMU and compare it to zero degrees of offset to calculate the needed movement of the servo arm to apply torque to the body as needed.
Note that upon start up, it is essential to have the boat hull sitting in an upright position so that the control program can calculate its zero position to use as a reference.
The programming process used example code from the following sources:
https://github.com/rfetick/MPU6050_light/blob/master/examples/GetAngle/GetAngle.ino
https://github.com/PaulStoffregen/PWMServo
https://github.com/br3ttb/Arduino-PID-Library
Please consider supporting these brilliant creators who made this project possible!
Arduino Sketch:
// Created by Kaden Werner and Alex Morin, April 2022. // See documentation on Instructables.com for code references #include <PID_v1.h> #include "Wire.h" // for communication with IMU #include <MPU6050_light.h> // for scaling raw IMU data to degrees #include <PWMServo.h> // for servo control //General setup______________________________________________________________________ int motor=11;// ESC data line, pin D11 int motor_speed = 114; // minimum PMW value to turn on motor (lowest speed) PWMServo servo_cradle; // declare servo object to be used by PWMServo //PID _______________________________________________________________________________ double SetP, PV, CV; // declare setpoint, process variable and control variable objects double Pk1 = 0.6667; //gain double Ik1 = 0.03; //integral double Dk1 = 0.0; // derivative ( off ) PID PID1(&PV, &CV, &SetP, Pk1, Ik1 , Dk1, DIRECT); // attach variables to PID1 func. //IMU data___________________________________________________________________________ MPU6050 mpu(Wire); // for communication with IMU unsigned long timer = 0; //used for timing updates void setup() //executes once upon energizing { pinMode(motor, OUTPUT); analogWrite(motor, 113); //idle value for motors ESC delay(5000); // gives ESC enough time to recognize idle command as it starts up servo_cradle.attach(10); servo_cradle.write(85); //closest center value achievable with barbs on servo arm //PID________________________________________________________________________________ PID1.SetMode(AUTOMATIC); // ALEX probably change this to MANUAL and have the HMI change to AUTOMATIC PID1.SetOutputLimits(-25, 25); PID1.SetSampleTime(10); // milliseconds //IMU________________________________________________________________________________ Wire.begin(); byte status = mpu.begin(); while(status!=0){ } // puts controller into infinite nothing loop until it can connect to IMU mpu.calcOffsets(); // physical position at this time will generate zero } void loop() //continuous control loop { //IMU______________________________________________________________________________ mpu.update(); if((millis()-timer)>10)// get data every 10ms { PV=(mpu.getAngleY()); // update PV timer = millis(); } //PID control______________________________________________________________________ SetP = 0.0; //declare setpoint to be 0 degrees (centered) if(PV>2 or PV<-2) // creates +/- 2 degree deadband about center { PID1.Compute(); // PID updates inputs and output values } //Servo____________________________________________________________________________ int servo_pos = map(CV,-25,25,60,110); //scale PID output to +/- 25 degrees about centerpoint servo_cradle.write(servo_pos); // update servo position //Motor control____________________________________________________________________ analogWrite(motor, motor_speed); //motor just turns on at lowest RPM setting }
Attachments
Step 6: Setup & Testing
Upload the control code to the Arduino, and disconnect from the PC. Connect the power source terminals to the power input of the ESC. Ensure the model is sitting upright, and adjust the center-of-gravity bolts so that the model balances on its own. Apply power, and the system will begin running on it's own. When tipped side to side, the control system will try to return the model back to center as quickly as possible with little to no oscillations. Try turning off the system and tipping the model to see how much it oscillates without the active flywheel.
Finally, with a functioning system, the acceptance testing process began. To test the effectiveness of the active control system, the main control file was uploaded to the controller. Without energizing the module, the hull was placed on a flat surface and tipped to 20, 45, and 70 degree offset angles and let go of. The number of oscillations and time it took for the model to return to its center of balance was recorded. This procedure was repeated with the active control enabled, and the boat roll elimination percentages for each angle of offset was calculated with the following formula:
The results of the acceptance tests showed the active control system to achieve between 83-100% elimination of boat roll, in time it takes the model hull to return to its center position and the number of oscillations prior to settling. This proved the effectiveness of the control moment gyroscope in dampening the effects of disturbances in the hulls position on the roll axis while settling.
Step 7: Conclusions
After lots (and lots) of hard work over the course of a semester, we had successfully created a functioning control system to achieve boat roll elimination. It was an incredible and rewarding process to see the project through to the end and demonstrate its functionality for our professor and fellow classmates.
What do you think? Is this a potential product you can see as being useful? What would you have done differently with your experience and skills? Please feel free to comment your thoughts on our work!
Again, please note that this is being entered in the Electronics contest here on Instructables and please consider voting for this submission if you enjoyed reading through this post, if this inspired you to make a similar control system, or if you think our efforts deserve recognition.
Thank you for making it to the end of my instructable. I have a passion for making and electrical design, and appreciate your time for reading this post.