Editor’s note: This project was developed by student, Eric Boehlke, when he was in high school and originally posted in the MAKE community in Makezine. Eric is currently a EECS student at MIT class of '20.
After seeing the first trailer for Star Wars Episode VII, I knew what my next robotics project had to be. I wanted to build a working, full-size BB-8.
I started by figuring out how I thought BB-8 would work and I decided that I would make two robots. One robot would rest on the top of the ball and its job is just to stay on the top and not fall off. A second robot would be inside the ball moving around and rolling the ball.
I worked on this project from early June to late August of 2015. Everything in this project was new to me. I needed to learn about a new development platform, learn how to program with different motors, figure out how to wire up sensors, learn a new language, and many more things. I felt well prepared for this challenge because of my previous experience with Lego NXT robotics and electronics. I had so much fun! Each step provided a new challenge.
This project also taught me so many new things about robotics, such as building and designing the frame, using sensors and the Kalman filter to determine position, pros and cons of different programming languages, how to choose batteries, PID controllers, stepper motors, and much more. I have learned a great deal and I plan to continue improving my droid and learning more about robotics.
The two robots that make up my BB-8 needed three omniwheels to allow them to move in any direction. The wheels would need to be mounted at an angle to allow them to make good contact with the ball.
I needed to choose a development platform. My dad’s coworker lent me a BeagleBone® Black to check out and to see if it was something I wanted to use. The BeagleBone® Black is a low-cost single board computer with many connectivity options making it great for robotics.
After choosing the BeagleBone® Black as a platform, I needed to choose motors. I decided on stepper motors, which allow for precise movement, called steps, and hold their position when stationary. From there, things fell into place. I needed motor drivers and a set of sensors to determine the robot’s position. For the set of sensors, I choose a 10-axis inertial measurement unit.
My parts arrived and the first step was to solder the headers onto the motor driver breakout board. Then I was ready to wire up the board to my new BeagleBone® Black and the stepper motor.
I started programming in JavaScript, following the tutorials on Adafruit.com. I had a little trouble getting the motor to spin — all it did was twitch. I used my multimeter to check the connections and discovered that there was only 1 volt of energy going to the motor. I did some research and found out that the 5 volt power pin only gives 5 volts when a barrel jack is connected. I used the system power pin and I got my motor spinning.
The next step was to get all three motors to spin. I soldered the headers to the rest of the boards and realized that I needed a bigger breadboard. I wired up the motors to the BeagleBone® Black and started programming.
I found that JavaScript was too slow to run even one motor at full speed (50 RPM). I needed a new language that was compiled rather than interpreted, so I chose Python. It was fast enough to run all three motors at full speed and much more.
My program was able to run the stepper motors at full step and half step. I was happy to get the motors to half step because that meant that I would have better precision movements of my robot. The bigger breadboard was too big to fit in the robot so I chose to use four smaller breadboards that I attached together in a square. This allowed the wires from the bottom of the breadboard to be fed up through the hole in the middle of the breadboards and the wiring was very compact.
I first designed the frame using SketchUp and Omnigraffle. Then I tested it by cutting the pieces out of cardboard and using hot glue and screws to attach the pieces together.
Since one robot was going to be inside the ball and one on top, the wheel and motor assembly had to be positioned perpendicular to the surfaces of the ball. I didn’t know the correct angle ahead of time and could not measure it until I had made a frame and installed the wheels. I decided to allow the wheels to tilt into whatever position they needed to make good contact with the ball. Allowing the motors to tilt also allows the robot to drive on level surfaces for testing.
After I had settled on a design that I liked, I chose the material I would use to make the final robot. I wanted to see all of the wire and motors so I used.093″ sheets of acrylic to build the frame. I stuck the template onto the acrylic with a glue stick. Then I cut the pieces out on the bandsaw and drilled the holes.
When all of the parts were cut out, it was time to glue them together. I used Loctite 2 part plastic glue. This glue melts the plastic and fuses the two pieces together. Once the pieces were glued, I attached the separate pieces of the frame together with the screws.
Once the frame was assembled I attached the motors, then the wheels. Next it was time to measure the angle of the wheels so that they could make good contact with the inside and outside of the ball. I marked the positions of the screws and drilled the holes.
The next step in assembly was to attach the electronics. I put colored hubcaps on the wheels and used those colors throughout my robot. The blue motor had wires wrapped with blue shrink tubing, and it attached to a blue breadboard, with wires going up to the BeagleBone® Black that were kept together with more blue tubing. I did the same process for all of the motors and carefully wired up the robot. The colors allowed me to quickly find and fix any electrical problems and they helped with programming. I attached the BeagleBone® Black onto the top of the robot with foam tape.
I was almost done with the frame of the robot. I still needed batteries to power the motors and the BeagleBone® Black separately.
The BeagleBone® Black only needs 5V and 1A, so I chose to use a cellphone charger with the same dimensions of the BeagleBone® Black. The batteries for the motors were harder to find.
I first went to Batteries Plus to see if they had any 6–12 volt batteries that could supply 1A, had around 2 amp-hours of capacity, and that could fit in the tiny space in the bottom of my robot. It was then that I realized that I should have designed the robot with the batteries in mind.
I ended up trying CR123 batteries, which are used in cameras. They are 3V, so with three batteries in series, and two groups of series wired in parallel, I figured that they would give me the right amount of power and run time. But after testing different configurations, I ended up putting a battery pack containing two batteries in parallel in each of the three sides of the robot. I then wired the three battery packs in series to give 9.7V and 1A.
The batteries did not have the run time I wanted, so I needed a new plan. I bought two USB battery packs used for charging cell phones. They delivered 5V at 1A and claimed to have 2, 600 milliamp-hours. I thought that these batteries would be great. They should power the robot for around 2 hours and they were pretty inexpensive.
I found out that they do not have 2, 600 milliamp-hours as they only lasted about half an hour in the robot. I bought four of them — two for each robot — but two could not hold a charge and were totally dead. It turns out they were not very high quality batteries. I bought two more expensive batteries and am hoping they last longer. I also decided to power the robot from a wall adapter during testing. The wall adapter delivered 9V and could supply 2.5A, plenty for the motors.
Now that I had the robot part done, I needed the ball for the robots to go into and to balance on. My first idea was to cover a playground ball with papier mâché 1 inch thick on all sides. I planned to cut the ball in half and think of some way to make the two halves lock together, and then come apart when twisted in order to remove the robot. After the first layer of papier mâché, I realized that this plan would take far too long.
In a video I had seen of another BB-8 build, the Maker mentioned that he used a hollow styrofoam ball that came in two parts that locked together. This was a very good idea and much faster than the papier mâché plan so, I decided to order some styrofoam balls online.
It turns out that very few of these balls are made in the U.S., so I had to order a 50cm diameter ball from the U.K. The head is also a sphere, so I ordered a smaller 30cm diameter ball as well. I wanted to paint the designs on the ball to make my robot look as true to the trailer as possible. I decided that gesso, a paste that is typically brushed onto canvases to prepare them for paint, would help the paint stick to the styrofoam and provide a little protection to the ball.
I applied two coats of gesso and let them properly dry. I made the designs on the ball and the head using templates I found online and the video of BB-8 on stage at the Anaheim Star Wars Celebration. I traced the outlines of the shapes onto the ball and then painted the surface. I used acrylic paint and mixed the colors to match BB-8 as closely as possible. I dipped a Lego piece in paint and used it for the bolt marks around the ball. I made the eyepiece from a plastic Christmas ornament painted black.
ProgrammingFor a robot to balance well it needs at least two sensors to help it know when it is falling: an accelerometer and a gyroscope. The accelerometer measures the forces acting on the robot including the movement of the robot.
The accelerometer is very noisy, meaning it does not give very precise data, and is affected by the movement of the robot; however, the accelerometer always knows which way is up. The gyroscope measures the angular velocity of the robot. It is very precise, but it only measures the angular velocity and not pitch and roll.
At first I thought that I would only need one of these sensors to have the robot balance, however neither one is very good alone. The gyroscope cannot be used to make a reliable balancing robot because it does not know when it is level. The angular velocity could be measured over a short period of time and be converted into a distance traveled and all of the distances be added up over time, but the gyroscope would start to drift and the longer the program would run the more the tiny errors in the calculation would add up and eventually the robot would fall off. The accelerometer would work for a longer period of time but it would be very imprecise and the robot would quickly fall off the ball. To make a good balancing robot the values from the accelerometer and gyroscope have to be combined.
The best way to combine the data is by using a Kalman filter. I have tried other kinds of filters and have seen that this one gives the most accurate results. The Kalman filter takes the gyroscope and accelerometer values and calculates the amount of trust each one deserves. It can change the amount of trust while running and gives a much more accurate reading that the complementary filter. Once the pitch and roll are calculated by the Kalman filter the robot takes the arctangent of the two values to find the driving angle.
The robot also needs to know how fast to go. If it’s near the center of the ball it should move slower than when it’s about to fall off. The best way to calculate the speed is to use a PID (Proportional Integral Derivative) controller, which lets the robot act in proportion to the distance from the center while keeping it from going too far and allowing the robot to react quickly to any sudden changes.
The driving angle and the driving speed are given to the robot which can calculate how fast each of the omniwheels should turn to achieve the desired direction and speed. The motor controller program turns the speed of the wheels into electrical signals that are given to the motor controller breakout boards to turn the motor.
To move the wheels, I started with a full-step implementation. I then did half-steps to gain finer control. But even half- steps resulted in poor motion, so I used pulse-width modulation (PWM) to control the amount of power going to each coil. Using sine and cosine to determine the correct values, I was able to implement smooth motion with microsteps.
You can find a repository of all my Python code for BB-8 on GitHub.
Final ResultThe Kalman filter did a great job of correcting the limitations of the gyroscope and accelerometer by combining the values. This, together with the PID controller, does an amazing job of balancing the robot on top of the ball. The robot inside the ball provides stability, preventing sudden motions. The design seems good and I plan on refining the PID controller to improve the responsiveness. I want it to be able to respond quickly enough to stay on top as the ball rolls. I also want to have the head able to turn and nod while balancing. This will allow BB-8 to communicate with simple actions.
I entered and demonstrated this project through 4-H, winning the top awards at the Dakota County Fair and Minnesota State Fair. Below, you’ll find a condensed, step-by-step breakdown of how to replicate my BB-8 design.
Use a glue stick to attach the frame template to the acrylic sheet. TIP: Drill the holes before you cut them out to avoid possible cracking near edges.
- Head to the bandsaw to cut each piece out.
- Sand the edges to ensure good contact when glueing.
- Next, glue two Side Bracket pieces onto each Motor Faceplate.
- NOTE: When using the glue, you need to prepare the pieces with the Activator and wait a minute for it to work.
- Apply the Bonder to one of the pieces and place it carefully. It bonds quickly and you do not get the chance to reposition.
- To glue the Support Bracket onto the Bottom Shelf, first connect them to the Motor Brackets. This ensures that the holes will line up properly.
- Now, using the guidelines on the frame template, glue the Support Brackets onto the Bottom Shelf.
- TIP: A small amount of glue goes a long way, but even if you applied a little too much, it's best for the glue bond if you don't try to wipe up the extra.
- It's time to attach the motors. Slip each motor into a Motor Bracket and use screws to securely attach them. TIP: I found it best to have the wires closest to the Bottom Shelf.
- Finish by threading the motor wires through the center hole in the Bottom Shelf. TIP: I used differently colored shrink tubing to keep each set separate.
- After the motors are in, the two USB batteries can be attached to the bottom of the Bottom Shelf with the double-sided foam tape. NOTE: Make sure the USB output port is opposite the motor.
- You will need to make a custom cable to attach the batteries in series. Take the two USB cables that came with the batteries, cut off the small end and strip off about 3" of the outer insulation. This will expose two wires, one black and one red. Cut the black wire short on one cable and the red wire short on the other.
- Strip the ends of the four wires and solder the short black and red wires together and wrap the connection with electrical tape. Solder two 7" wires to the long wires and wrap electrical tape around the connections.
- Finish the cable with shrink tubing and feed the 7" wires up through the center hole of the Bottom Shelf.
- Connect four Mini Breadboards together to form a square. Each will be used to wire up one of the four Breakout Boards.
- Insert three of the Motor Driver Boards and the IMU board following the Wiring Template.
- TIP: It is helpful to group the set of wires coming to and going from each board with colored shrink tubing, a different color for each breakout board.
- Use double-sided foam tape to attach the battery to the top plate.
- Attach the BeagleBone® Black to the top of the battery using more double-sided foam tape.
- Thread the wires through the holes in the Top Shelf.
Connect the wires to the appropriate pins on the BeagleBone® Black using the wiring template.
- To power the BeagleBone® Black with the USB battery you will need a USB to 5.5mm barrel jack cable. To make one, first find a cable you don’t mind cutting apart with a barrel jack that fits in the BeagleBone® Black.
- Cut the USB cable and the barrel jack so that they are the right length to reach from the battery to the BeagleBone® Black.
- Strip the wires and connect red to red and black to black.
- Cover the wires with electrical tape and then use shrink tubing.
Both the robot that balances the head and the robot that moves the body are built the same. The only difference is which angle you mount the wheels. Repeat Steps 1 through 9 to build the second robot.
Step #11: Painting the ballPrint out the full-sized artwork templates on card stock. Cut out each shape and trace them onto the surface of the ball.
- Using the 3" Gesso paint brush, apply two coats of the Super Thick Gesso to the 50cm polystyrene ball and 30cm polystyrene ball (only one of the halves is needed). The Gesso needs 24 hours to dry between coats. The Gesso coating prepares the surface for painting.
- TIP: It's helpful to make a mini BB-8 paper cube as a reference as you trace and paint each area of the ball. The paper cube can be easily printed out and assembled.
Update each BeagleBone® Black to the latest version of Debian OS using these instructions.Update the kernel by following these instructions.Setup Wi-Fi on each by following the tutorial provided by Adafruit.NOTE: Depending on the kernel version, you may have to enable PWM on certain pins. This can be done by modifying the /boot/uEnv.txt file. Edit the line that starts with cape_enable=capemgr.enable_partno=
to be:cape_enable=capemgr.enable_partno=am33xx_pwm,bone_pwm_P8_13,bone_pwm_P8_19,bone_pwm_P9_16,bone_pwm_P9_22,bone_pwm_P9_28,bone_pwm_P9_42
Copy the Python source files I've posted on GitHub to each robot using SFTP. Place them in the cloud9 folder.
Assemble BB-8 by placing the driving robot inside of the ball. Use Velcro dots to keep the two halves of the ball together. Finally, place the balancing robot on the top of the ball and cap it with the head.
Eric Boehlke
Comments