The first thing to build in a technically challenging project is a functional prototype that helps to test and iterate on the core technical problems without being constrained by environmental, reliability, or aesthetic requirements. For the first functional prototype of this project my goals are to demonstrate automatic detection and re-rolling of dice while ignoring the dice selection aspect of the technical challenge. This allows quick iteration on the vision algorithms used while also serving as an extremely barebones end-to-end test platform.
Physical Prototype
The architecture I wanted to base this prototype off of is the “self-loading dice tower”, where a linkage is used to raise the dice in their tray and dump them into the top of the dice tower. By adding a motor to this linkage I can automatically continuously re-roll all of the dice in the tower. By adding a camera to the top of the tower looking down at the tray I can read the roll result (or at least capture images for training some future algorithm).
Design
While I think 3D printing will play a bigger role in the final design due to its ability to generate intricate internal cavities and external visual features, I prefer to use laser cut plywood for quick prototyping where possible because you can iterate parts in minutes instead of hours. This also makes it easy to think in 2D and layout a basic kinematic system.
The die tumblers inside of a boxy tower are a fairly obvious shape to make from laser cut wooden panels, but designing the moving tray and camera mount around it was less obvious. I wanted the camera as far away from the tray as possible in order to minimize distortion in the image. I also wanted to avoid adding a second (probably passive) degree of freedom to the tray.
To prevent the dice from sliding “down” towards the tower while the tray pivots up due to the components of gravity pushing in that direction, the centripetal force from the rotation of the arm needs to provide an equal and opposite force (within the margin of error where friction helps prevent motion). This is fairly easy to calculate, and resulting speed and torque requirements are in the right ballpark for using hobby servos.
I chose the ST3215 bus servo from waveshare because it was cheap, had good margin on torque (not as much on speed), and would be extremely easy to connect to python for prototyping with their adapter board. The “bus” type servos are great because they give you live position feedback (as well as current feedback in most cases) so you can time other actions with the motion perfectly.
One other notable difference between this design and other self loading dice towers is that the dice enter from the side of the top of the tower instead of the very top of the tower. This is necessary to give adequate space to mount the camera directly above the tray when it is in the down position.
Build
This ended up taking 7 sheets of 18″ x 24″ x 1/8″ plywood to cut on the 55W CO2 laser, but it was all over in about an hour. Gluing the pieces together took considerably longer because I had to progress in stages based on what was easy to clamp.
I started with the dice tower portion so i could get to the point of rolling the dice and capturing the images as soon as possible. My immediate realization is that I made the tower way too big! It is about 5.5 inches square with 1.5 – 2.0 inch gaps between baffles. This is much bigger than any dice tower I have ever used and it feels absolutely cavernous.
The camera I planned around is the Arducam 5MP M12 USB webcam because of the easy desktop python/openCV integration (although I may switch to the OpenMV Cam H2 in the future for an embedded option). I switched to a more narrow 8mm x 1/2.5″ lens (I am targeting a ~20 degree field of view) and was able to focus the camera on the dice very easily. It was exciting to see the system working with manual rolls!
Afterwards, I glued up the arm and installed the servo. The provided python library for the servo worked very well, although it took me some time to realize that I should not use target positions around “0”, because the control loop did not handle rollovers from 0 to 360 very well. I got some good results after re-homing with just a little bit of speed tweaking.
Unfortunately the system was not perfect. If the arm does not spend a decent amount of time at the top of its stroke waiting for all of the dice to roll off some dice don’t make it all the way into the tower. However, if the arm waits too long at the top of its stroke some dice make it all the way through the tower before the arm can lower itself to the ground.
I thought that the dice would spend much more time tumbling, but it became clear that a secondary feature would be necessary to “hold” the dice at the top of the tower until the arm has fully retracted. Simply speeding up the arm does not seem to solve the problem. To simplify things I just used another ST3215 servo, directly attached to a 3d printed flap that collects the dice at the top of the tower. This gives the arm plenty of time to move back down to the bottom.
Imaging System Tweaks
The first issue I tackled was getting consistent lighting. Ambient lighting seemed to work OK in places with a lot of overhead fluorescent lights, like my garage (where the original test images were captured) but performed poorly in dimmer spaces like my office. I tried a few local lighting options (including a ring light and multiple off-angle lamps) but the best option I found was using an ultra bright “photography” compact fluorescent bulb just off axis of the camera.
This washed out most of the shadow on the white background while maintaining a consistent lighting on all of the exposed die faces (even the ones not facing directly up). The light was so bright that the captured image did not appear to change even when the device was placed near an open window with plenty of sunshine or a room with a single bright light in the center. Unfortunately, there was a significant glare on the “top” edge of any die because of the point light source, and some shadowing still existed.
A suggestion I got from a friend in the video industry was to use a black felt background to soak up all of the shadows (and possibly protect the dice from damage!). I jumped at the idea because the dice tower was extremely noisy and I was hoping that the felt would muffle all of the clacks from bouncing dies. The felt definitely eliminated the shadow problem (although now I will probably struggle to use black dice) however the glare remained. Additionally, the lower overall brightness of the image might have thrown off the gain or white balance of the camera, causing significant artifacts around the white numbers.
A suggestion I got from a friend in the robotics industry was to use polarized filters on the light and camera to reject direct-reflection glare from my image. I picked up a cheap microscope ring light and polarizing filter-cover set to try out the concept. The on-axis ring light made an extremely disruptive glare, but by adding the polarizing filters it was nearly eliminated.
Unfortunately there was still some kind of issue with a weird fuzzing artifact around the numbers. My friend in the video industry mentioned that this kind of artifact is exactly the thing people see when they buy cheap lenses, and of course I was using the cheapest plastic M12 x 8mm lens I could find on Amazon. He recommended upgrading the lens quality (and potentially also the polarizing filter) before spending too much time screwing around with gain and white balance settings.
Although I have experience buying high quality (and high priced) optics for industrial projects, the $100 lens option from Edmund Optics seemed like overkill. In the end I went with Commonland Optics for a $50 option. I elected to use a high “f number” (smaller diameter aperture) compared to my plastic lens to get more consistent brightness across the frame and a potentially crisper image.
I was extremely satisfied with the result! The fuzzing was basically eliminated and I was left with a very crisp, clear, contrasting image. Each color die stood out from the background with contrasting borders and numbers, and without any glare.
I may need to change out the purple D10 to something closer to a pink color to make it more distinguishable from the blue D8. I also might need to swap the green tetrahedron D4 for a barrel-style shape to make the top number more distinguishable. However, the mechanical and imaging systems are ready for a ton of software work and data capture!