My highschool required the seniors to use the last month before graduation to work on some sort of personal project. At the end, there would be a day where the seniors would present the projects to their teachers and underclassmen in small groups. The seniors put varying levels of effort in various directions from art or science projects, campus or community improvement projects, or things like "Holistic Self-Improvement." Around that time, a highschooler in Florida came up with an ingenious design for a robot to solve 3x3x3 Rubik's Cubes. His design eventually dominated the Rubik's cube robot scene, with the current record of 0.38 seconds held by a robot of the same general design. Having seen the original video around the time, I decide that I was going to build a similarly inspired robot for my senior project. Before I go over the design and build process, here is a quick video of the robot solving a cube:
At the time, I was not familiar enough with CAD software to produce a design I could build from. For our senior project, we had a rather restrictive budget limit of about 400USD, so my parts list was a cheap speed-cube, 6 of the cheapest stepper motors and drives I could find, a couple of power supplies, an Arduino Mega, and a couple 1 inch steel square tubes. Since I don't have any of the quick design sketches I made before I built it, I took a few pictures of the showing the design:
The construction was a bit rushed since I only had a month to do it, but I had a lot of fun building this machine. The frame is roughly shaped like an octohedron and is made from the 1 in square tube, although I omitted some of the edges to save material. I taught myself to MIG weld with some videos on YouTube and the theater shop teacher let me use the shop "MIG" welder (in quotes because it was a gasless, flux core machine) to assemble the frame. I had first tried to use JB Weld but I couldn't get the joints to stay put. Welding produced a rigid and durable frame, and I think it turned out reasonably well given that it was my first time welding and no one else around knew how to operate the welder.
The stepper motors are just bolted onto homemade (with a hacksaw and a lot of effort) flanges with some Tetrix bolts and washers for spacing and alignment. Probably the hardest parts to make were the arms between the motors and the Rubik's cube. I ended up making them out of PVC pipe squared at the end to fit in the centers of the Rubik's cube and press-fit a piece of acrylic rod into the ends that then press-fit onto the stepper motor shafts. I could probably make a lot of improvements to these arms, since the would sometimes bind against the frame or slip on the shafts. The speed cube I bought conveniently had center faces that could be removed and exposed a square hole, which allowed me to drive them with the PVC tubes.
Finally, I made a mount for the electronics out of some plastic cardboard and zipties, which was pretty convenient and fairly robust, but it was mostly a quick hack to make the project presentable.
The electronics for this project were probably the easiest part. I connected the stepper motors to the terminals on the drivers and wired the step and direction pins for each controller to the Arduino. The power supplies were connected to a plug with a switch in the live cable turn the power on or off, and each driver was connected to one of the power supplies. I used two 24V power supplies, but I probably could have gotten away with just using one. The Arduino was just powered by my laptop, since it needed to be connected anyway. That's all there really was to the electronics.
The algorithm to solve Rubik's cubes quickly and in a small number of moves is interesting, but I didn't have enough time to program and optimize my own version for this project. I used a Java library that implemented the solving algorithm instead, but I had written my UI for controlling the robot in Rust. Calling the library from my Rust code wasn't trivial. In the end, I hacked together a pretty ugly solution where the Rust code called a small C module that would start a JVM, load the library, and pass data back and forth. The solver program ran on my laptop, which then sent a string of commands to the Arduino. The Arduino was loaded with a simple sketch that would read this string of turn commands and turn it into step and direction pulses for the steppers with the Arduino stepper library. I made one online optimization to the command sequence on the Arduino: it would detect if two opposite sides were turned consecutively and sequence those moves to happen at the same time. The improvement in solving time would be minimal, but the
One key feature that my robot lacked was computer vision to detect the initial state. While I was building and programming the robot, I implemented a GUI that let me enter the facelet colors for each of the sides. It was slow, but it worked, and I ended up not having enough time to figure out how to do the computer vision in a robust way. For demos, I would scramble the cube and enter the facelets in the GUI before the presentation. Thankfully, during the final presentation to a small panel of teachers to make sure I hadn't squandered the month, the device thankfully worked perfectly and produced a neatly solved cube. During the presentations to my peers, unfortunately, the machine jammed and I had to rely on the YouTube video as backup. Overall, the project was a success, and I learned a lot and gained a lot of experience from the project. If you want to take a look at the source, the GitHub repository is here.