A Rubik’s Cube solver robot that solves a person’s initials on the face of a 3×3 Rubik’s Cube. Type in you code name to a webpage and click “Solve”. The pieces move around for a few minutes and eventually come to rest with three letters on the front face — A person’s initials!
You can take a look at all the source code here:
The robot is based on a design by KAS https://forum.arduino.cc/t/rubiks-cube-robot-solver/262557 . It uses only two grippers the hold the cube in place as it moves the pieces around. The design was ideal for my application. I felt it was important to put the focus on the cube, not so much on the solver. This robot exposes the cube to onlookers better than other robots that are available. The cube is accessible and out in the open. Whereas many of the other robot designs available seem to engulf the cube thus a little less accessible to the audience. I also decided to 3d-print the robot all in black for the same reason: to put the focus on the cube not the robot.
The down side of this robot configuration is that, with only two grippers, it is very slow. It is limited to moves only on the “down” and “back” sides of the cube. So these are the legal moves: Y, Yi, Y2, Z, Zi, Z2, D, Di, D2, B, Bi, B2. (This site has nice explanations of cube notation: https://ruwix.com/the-rubiks-cube/notation/). This limitation significantly increases the number of motions on the robot to solve the cube. For instance, to rotate the “front” layer (“F”) you would need to rotate the entire cube to the 180 degrees first then move the “back” (“B”), then rotate 180 again to the front. So this: Y2, B, Y2.
The result is it takes around 60 moves to solve on average. Whereas, if we had used a different robot with a total of 6 grippers it would take roughly 20 moves on average to solve. On my robot it takes about 4-5 minutes to solve the cube.
The computer inside the base of the robot is a Raspberry Pi 4b computer. There is also a pca9685 PWM circuit board to control the servo motors that grab and rotate the cube.
The 3d print files are downloaded from here:
- (Which is a remix from the original: https://www.thingiverse.com/thing:2800244)
The project uses a raspberry pi camera to scan an unsolved scrambled cube should that be needed. The camera works well if the lighting is fully controlled using good photography equipment that is bright and produces no glare on the shiny stickers. But even with good lighting the camera is not perfect. The computer is surprisingly bad at recognizing colors.
Luckily, at Christmas no one needed to use the camera scanning mode because I had previously scanned the cube and saved it’s state. Also, at the end of every solve, the state is preserved as a starting point for the next solve.
In scan mode, the robot rotates the cube to show all sides of the cube to the camera where the image of each side is divided into 9 squares — one for each sticker on the face. Additionally, there is one additional white sticker attached to one of the grippers used to calculate uniform white balance to be consistent for all 6 sides.
I used a totally awesome piece of software to help accurately assign a color to every sticker: https://github.com/dwalton76/rubiks-color-resolver . The color resolver app picks colors based on legal colors for every piece on the cube.
Even though rubiks-color-resolver gave a much more set of reliable color assignments, it is not perfect. So I created a webpage to allow users to edit cube colors manually.
Early experiments with opencv character recognition proved unreliable. Again, variations in lighting on the low quality Raspberry Pi camera caused considerable variations in calculating the outline of letters on the cube. With well-established color recognition software available, I went with the color approach instead. TODO: maybe try to get optical character recognition to work properly. Maybe a better camera will give better results.
I used a standard off-the-shelf Rubik’s cube. Many of the faces are strategically decorated with 1/4 inch black vinyl stickers — each is one of the initials of someone in the family. Many of the faces are not decorated at all since there are a lot of empty spaces on the front of a solved cube (six unadorned stickers if a person has three initials).
The letters “TMW” appear on the white (front) face of the cube when it is solved “normally” for a solid color on every side. If the cube is solved for a person’s initials (e.g “MNH” or “KLH”) the colors appear to be somewhat random.
Note that speed cubes don’t work well with this robot. If you use a speed cube with nicely oiled ball bearings, you will need to slow down the spin of the grippers for whole-cube movements (Y and Z) otherwise the top of the cube will separate from the bottom as that moves slower than the bottom. The cube will be out of sync and jam the grippers as it begins the next move.
Everything is written in python. The software for generating a “letter” cube is based on this solver: https://github.com/pglass/cube I used the matrix math and other functionality from that body of code but I significantly refactored it to support the concept of labels instead of colors.
Generate a cube
This program is used to generate the definition of a solved cube where a person’s initials appear on the front of the cube.
Solve the generated cube
For an optimized solution I used the awesome cube solving software from kociemba installed like ths:
- pip install RubikTwoPhase
The kocimba optimization that solves the entire cube efficiently and work out to be about half the number of moves using the “novice” method to solve only the front side of the cube. Ideally it would be best to modify the kociemba functionality to solve only the front of the cube since we really don’t care about the solved positions of the middle and back layers of the cube. TODO: maybe modify the code here to solver only one layer: https://github.com/hkociemba/RubiksCube-TwophaseSolver
One more issue with this generic approach to solving the cube is that the orientation of the center front piece is not predictable. The letter might be right side up. Or it could be upside down or sideways. Randomly in any of the four possible positions. TODO: force a specific orientation of the center front piece when solving.
I created a small webpage to give users control of the robot and enter information. I used Bottle framework (https://bottlepy.org) which generates html from python commands. This creates an HTTP server on the Raspberry Pi 4b. The intention is to run the webpage from a browser that is also running on the Raspberry Pi but could also be access from another computer such as a laptop in the room.
The webpage provides the following functionality:
- open robot grippers
- cradle grippers (to allow a person to place a cube ready to be solved or remove it)
- stop all operation. Abort whatever is going on right now.
- input a message to solve.
- solve it
- You can import a cube state
- You can edit any sticker in case software calculated it wrong.
- You can save the cube state