Affixing anything to anything in such a way that it can be removed and repaired is a process that takes forethought.
With my early decision to implement a vector bot as the “shiftable weight”, it was imperative to find a way to attach panels to the outside of the sphere without inhibiting the wheels.
So, glue, right? Epoxy? I want these panels to be removable so I can make inevitable repairs and upgrades.
Bolting through the inner sphere was out. I can’t use magnets since the large magnet would just rip panels off with the dome.
I decided to use t-nuts. I would need to print spacers to make up the 3/16 or so difference between the panel circumference and the sphere circumference. I want to keep that gap for wires when I hook up the shell LEDs.
The spacers allow me to glue the t-nuts to the body without piercing the inner sphere.
It took me a few tries to get the spacer thickness just right. I settled on 2.6mm.
One of the panels can just be removed to access the inner vector bot. The others may need to be removed to get enough visability to assemble the bot in the sphere.
After the recent setbacks with stepper motors, I decided to focus on optimizing the two simplest forces at play: friction and torque.
The amount of friction increases when weight is added. After adding a few pounds of weights to my vector bot, the added friction on my axels was too much for my motor torque to overcome. The best way to reduce friction in my case was to add bearings.
This loss in friction allowed me to find motors that could supply enough torque in my price range.
After purchasing new motors and motor controls, I set about designing and 3D printing the new robot frame.
I also heat pressed t-nuts into the frame so I could use hex screws to secure the platform.
This is the robot upside down. After figuring out how to mount the weights and the battery, it was time to put the robot in the sphere.
A couple evenings ago it became abundantly clear to me that my use of stepper motors was not going to provide enough power. Which is a little frustrating. I learned something very important that I didn’t know before. Stepper motors are rated by holding torque.
The holding torque on these motors is great and sufficient for what I need. But because of the way stepper motors work, when they are ‘stepping’ to the next position (which can happen thousands of time per second) they have very little moving torque. Certainly not enough to move around a 14 pound robot body inside a sphere.
Mindset of a builder and maker
When I make a mistake like this it helps me to take stock of what I have, what I don’t have, where my next step is and what’s salvageable. This helps me focus on actionable tasks instead of focusing only on the negative. But I also need to know what the negatives are. so we’ll get there.
What I do have
I can control my BB-8 body with my rf remote. It can move in all directions.
Torque. I simply don’t have enough movement torque to overpower the other forces at work and make the sphere move well. It can move slowly, it’s just not quick to make trajectory changes. I can hear the motors skipping steps so I know it’s the motors.
Where I go from here?
I just need to change motor technology. I like the precision that I can get from steppers, but I simply need more torque. Some precision is important since my motors have to move in relation to each other, but what’s precision without enough torque?
I’ll move forward using DC motors with encoders (pictured above). The motor encoders will allow me to get feedback from the motors as they are turning. I’m going to try setting them up without using feedback. If the speed is pretty consistent between motors, I won’t need to use encoding.
Almost everything. I’ll need to replace the motors and motor controllers. Fortunately, I have written a lot of code that I can keep. The radio control code, Raspberry Pi code, movement math. All of this is reusable.
I’ll need to tweak my vector bot frame to accommodate the different style of motor, but even that should prove to be a relatively easy task. I’ll have to change my gearing, I was stepping down for power, but I’ll need to step up for speed (probably a 1:2 ratio vs 16:1 of the steppers).
What are the negatives?
Time mostly. Being on a pretty tight rolling budget for this build, I can only purchase 1 motor a month if I want to do other work on BB-8 as well. So it will be a bit before I’ll be able to have a ‘working’ body sphere again.
This does give me time to address solving a few other problems and complete the build of the dome.
The positive side of the negatives, is that I want to build a CNC anyway. now I have the steppers and controllers required. I only need a few more parts to build a primitive one.
Now, on to figuring out what I can sell to make all this move faster.
I have been asked a not a few times how I get the vector bot in and out of the sphere. Well that’s easy. The sphere has a small hole in it.
But that hole in only 5.25″ in diameter… and the vector bot is 19″ if it were a circle and not obviously a triangle… Solution: Design and build the vector bot to break down into parts that will fit through a 5.25″ hole. Everything is labeled and marked so it will only go together one way (easily).
I could have cut the hole larger, but I thought that leaving it small would give the sphere more integrity. It also leaves a smaller hole to patch later. Which is a nice side benefit. I did have my daughter (who was being mischievous with the duct tape at the time) put some tape around the cut edge of the hole. It’s amazing how a little tape can make you stop cutting yourself accidentally.
I also recorded it for you. And sped it up so you don’t have to sit through a 13 minute video.
I finally got all the components talking correctly. The Raspberry Pi receives data from the RF transmitter and sends movement instructions via USB serial (angle and velocity) to the Arduino. The Arduino translates those instructions for each of the 3 motors. This happens BLAZINGLY FAST (and explaining what is happening will be a different post once I work out the kinks that I’m happily ignoring for the time being).
Here are the first steps of the vector bot that drives my BB-8! Each wheel is offset by 120 degrees. This is just looping through 360 degrees of movement. I think the wobble is from my inability to cut 120 angles by hand 😉
The math is pretty straight forward to find each motor’s relative velocity. Since the SIN method assumes radians, I have to convert degrees to radians.
motor_1_rv = SIN(degrees * pi / 180)
motor_2_rv = SIN((degrees + 120) * pi / 180)
motor_3_rv = SIN((degrees + 240) * pi / 180)
These will return a value between 0 and 1. Then you take each relative velocity and multiply it by an absolute velocity.
Later, I’ll probably map these relative values so the highest in the relative set would be 1. That way you don’t end up with two motors going 0.84 * velocity instead of both moving at 100%. Things to think about.
“Every body perseveres in its state of rest, or of uniform motion in a right line, unless it is compelled to change that state by forces impressed thereon.” — Isaac Newton
Simply put, if you want something to move, you’ll need another force to act on it. If you want something to stop moving, you’ll need another force to act against it.
In something like a bicycle this is easy. Legs create a linear force by pushing downward on the pedals using the gravitational force of the rider’s body which is then transferred by chain to the wheels. The wheels grip the road (friction caused by gravity acting on the spandex road troll) and the bicycle moves forward.
A car is slightly more complex. We replace the leg with a piston and gravitational force previously attributed to the body with a controlled explosion in the engine cylinders. That linear movement is translated to rotational motion (crankshaft) and geared properly before being transferred to the wheels. The wheels grip the road (friction caused by gravity acting on the vehicle) and the car moves forward.
In both of these oversimplified examples, there are only a few forces that really matter at the scale we’re talking about (BB-8 scale that is). We can throw wind speed and aero dynamics out the window since he’s not winning any derbies. We really only need to keep track of a few forces. Namely gravity, friction and inertia. Since we’ll be discussing going from one state of INERTIA to another, we only need to add GRAVITY and FRICTION (and this lamp). As a point of order, I reserve the right to make up additional forces as we go. That’s the law according to the rules.
Onward to Spherical Stability:
Weebles demonstrate part of this discussion very practically. For simple spherical stability, you need a low center of gravity (I’m purposely ignoring gyroscopic stability since it would not be considered simple). We’ll refer to this weight as a ballast. As you adjust the center of mass to the outside of the sphere (lower the center of gravity) you increase stability. Weebles (and weight driven spheres) have very low centers of gravity. You can increase stability even further by increasing the weight ratio of ballast to total weight.
Spherical motion, in many ways is far simpler than the bike or vehicle explanations. You can apply motion to the sphere by moving the ballast to another location in the sphere. Done. By moving the ballast, you change the sphere’s center of gravity. Then the sphere rolls to orient the ballast to it’s lowest point. How you move that ballast is up to the designer. The point is, you are always applying force somewhere in order to change the position of the ballast.
Hamster in a ball
The literal hamster in a literal ball works because the hamsters weight offsets the sphere center of gravity. When the hamster walks (or runs, trips, slides, rolls) ‘up’ one of the sides, its weight changes the spheres center of gravity and the balls rolls. Replace the hamster with a small robot and you have Hamster drive.
If you connect two opposing poles of the sphere via a shaft (or axel) and hang a ballast from it, you have effectively also lowered the center of gravity. By attaching motors to the shaft supporting the ballast, you can ‘move’ the center of gravity and thus move the sphere.
Turning can be achieved by tilting the ballast left and right perpendicular to the rotation force, parallel to the axel. Then the sphere will lean. You can spin the sphere by quickly rotating the ballast. Since the ballast outweighs the sphere, the sphere inertia is overcome before the ballasts inertia.
Omni Vector Drive
My solution (for now) is to attach the ballast to the sphere via omni wheels. The weight of the ballast gives the wheels enough friction to reposition the ballast and thus drive the sphere.
I’ll leave you with two pictures and a gif. I’ll highlight more of my design in another post.
Here you can see the wheels rotating to correct the ballast position. This is me rotating the sphere and watching the wheels correct, but in reality the reverse will be happening.
I like to always start with the end in mind What did I want these arrays to look like? How did I want them to function? What are the initial hurdles? And most important to a pragmatic problem solver… Do I know enough to get started?
I wanted my arrays to appear independent. This brings up an immediate hurdle. Arduino is a single threaded processor. People have done some AMAZING things with Arduino, but at their core, they are very simple. Here’s what a simple Arduino program looks like: (this is not actual code)
Do something with that information
This repeats until you turn off the device. If I want all of my arrays to appear independent, I’m going to have to fake “threading”. There are a number of ways to do this. Since all of my arrays involve some aspect of time variance, it’s simple enough to make that the base of my loop, and fire off updates to the LEDs when the appropriate (random) amount of time has passed. (still pseudo code)
check the current time
if enough time has passed, update sweeper1
if enough time has passed, update sweeper2
if enough time has passed, update jitter
This will work, except we need to do a couple things if ‘enough time has passed’. In order to continue to make these calculations, we need to store a couple variables. We need to know when each array was last updated, and how much time should pass before the next update. Simple. Each “IF Block” would look more like this:
if enough time has passed:
The current state of the code:
This has obvious organizational issues and things that can be done better, but it works. Quick note for those following along from home: In order to chain and control multiple TLC5940 together, you need to edit your tcl_config header and change the number of chips.