Data Collection Robot

Just repeating what I said in my other posts: this is not a live post, I was busy when I made this project, so I’m coming back now and writing it all down…

Anyways, onto the project itself:

This summer (2016), I’m working on a project that I’m going to apply for a science fair with. Without going into too much detail, a big part of my project revolves around having data, specifically pictures. In fact, the amount of images that I need is on an order of magnitude of a million… Not some small feet feat.

The best/worst part of this is that these photos need to be collected by your’s truely, as there is some other information that works alongside photos to make the data usable.

At the beginning of the project, I just picked up some pieces of metal, and scrapped together this:

  

 

If you can see past the table clutter (sorry about that) you can see that this robot is a very simple robot with a tank thread drive train, and a web cam for collecting photos.

This robot worked, but the Raspberry Pi controlling the robot could only take 1 photo every 7 seconds or so, making this a VERY inefficient little system. Not only that, but this robot was back heavy, so I had to strap a can of coke onto the front to even the weight out:

 

I couldn’t take it anymore, and I ended up designing my own robot from scratch…

 

First thing I did was to decide on what I was going to keep from the old robot. I wanted the wheels (I figured 3D printing new ones would take way too long) and all the electronics, except for the camera hardware (more on that later). After that, I hopped into AutoCad and started to design the bot:

One of the main focuses of this bot was to make sure that center of gravity was close to the bottom, to reduce the amount of wobble in camera and top part of the robot. For this reason, I wanted the bottom of the robot to be a shallow box where I could put the motors, battery, and arduino: which should be enough to move the center of gravity closer to the bottom:

Robot Base

As you can see, it is a very simple box design (that took painstakingly long) with holes cut out for the motor mounts, the neck of the robot, as well as some holes for running wires out of the base.

Next thing was the neck, or what elevated the camera from the base. I, again, wanted to have a very slim build, which would play its role in lowering the center of gravity. Looking back on it, I wished that I had left some more material in the neck, but it works:

Robot Neck

Finally, the cherry on top was the top mounted plate. I was not a big fan of having a photo every ~7 seconds, as that is just inefficient. Luckily, my adviser (shout out to Mr. Medvitz!) hooked me up with a pair of these Mobius Actioncams. These are similar to the ever popular Go-Pro, and they are capable of recording at 60 fps. And because I have a pair of them strapped onto my robot, they would have an effective 120 fps. That means that this robot can take the same number of photos the previous robot did in 14 minutes, but do it in one freaking second.

You gotta love technology.

Anyways, here is the design for the top plate:

TopPlate

 

Then it was off to school to laser cut these Bad Larry’s out.

It should be noted that I used and designed these pieces to work with 2.032mm (or 0.080″ if you don’t have a burning love for SI units) acrylic.

 

Finally assembled:

 

 

Note: I had to jerry-rig some tank threads out of duct tape because it turns out that the robotics kit I stole the wheels from has more friction in the system than my feet on the ground when my parents drag me out shopping. This resulted in the robot just pushing the front wheels around, and an inability to handle bumps of any nature. By connecting the pair of wheels by some duct tape, I am losing energy and potentially battery life, but all the wheels are powered and the robot can now handle almost every surface type.

I know that this robot is not very pretty or even that “impressive.” Given more time and materials, I would have preferred to have made a much more elegant robot with a 4 wheel drive, maybe even geared for speed. However, given that this robot was thought of, precisely measured, designed, cut, and assembled within a matter of days, I’m happy with the results.

Flywheel Controller

Normally, I don’t post much about robotics, as the things developed are usually simple things as mapping a button on a controller to motor power; however, I just pulled off an all-nighter for this program, so I think it deserves a writeup.

Before that, some background:

This year’s competition in VEX is called “nothing but net,” where robots have to get small stress ball into a net that is roughly 2 – 3 feet high. There is one big limitation, however: the robot cannot extend past 18 inches, until the last 30 seconds.

What our team decided to do was to have a flywheel, and a ramp under it, so we could launch the balls into an arc and right into the high goal:

Now, this worked great, but we had to find out a way to accurately control the flywheel in order to make it be useful.

First we tried a simply PWM-type system.

We had build these custom ratcheting clutches that only spun one way, and free spun the other. What the code basically did was to run the flywheel at full power until it reached a desired angular velocity (omega), and then simply turned off the power so the wheel just kept on spinning, with no power behind it. This worked fairly well, however we noticed that it was extremely inconsistent, as when the ball hit the wheel, it would it the wheel at different times in the PWM cycle (one time it would hit when the wheel was free-spinning, other times it would hit when it was powered), so we had to scrap that idea and do something else.

We then came up with another solution: have to microcontroller adjust the motor power until the actual omega was the same as desired omega. So we did just that:

Nothing but Net Oscillator Code

This worked, but it took forever to stabilize. This was due mostly in part to the mass of the flywheel, and the fact that the inertia was messing up the microcontroller. This meant that the motor power would oscillate until it finally got a value that was stable, which is what we wanted, but it did it in 10 seconds, which is something that we did not want (Keep in mind that the whole match is 1.5 minutes long). So we had to work up on another solution.

We had the code to determine the motor power for any desired omega, so we decided to just take a bunch of data points and make a function out of it, which we did:

Power VS RPM data Points Power Vs. RPM Curve Fit

Power Vs. RPM Code

Now, this worked great, but the problem was that our correlation coefficient wasn’t 1, so we didn’t have an accurate function, at least the precision to what we needed. Then we realized if we combined this function with the oscillation, we would be able to have a accuracy of the oscillator program, with the speed that the function offers. This can be modeled with the following graph:

f(x) and oscillator only

In this case, error = (actual omega – desired omega). Basically when the user changes the desired rpm, the program gets a baseline number (determined by the function above) and uses that until the error gets within a certain threshold (indicated by the dashed lines). Once the error is within that threshold, the oscillation program takes over, and the amount of time that the oscillator takes is reduced because the motor speed is already close enough to the stable value that the oscillator only has to do a minimal amount of work:

Oscillator and Function Code

This reduced our rev up / recovery time to 2.5s, and got us to worlds! However, I still wasn’t satisfied. Which leads me to *sigh* last night.

What I was thinking was that the function gave a fairly accurate value (which isn’t actually the case, but I’ll elaborate on that later), so I thought, why not use more power the higher the error is to make the recovery time even smaller? That was pretty poorly phrased, so the model below will probably do a better job than I can to explain it:

As you can see, the greater the error, the greater or less the motor power, resulting in a derivative with a larger magnitude. It is also important to note that the second point (P2)’s y value is the calculated motor power from the function. What we have there, then is two points, and a linear line that is connecting them. A simple bit of algebra later, and you have the following equations:

Now, this is what you call fast. However, I noticed that there was still a great amount of inaccuracies. After realizing that I was torturing the robot batteries, I realized that the whole function we had was completely reliant on battery voltage.
Linear Controller Code

I connected up a few wires and was able to get a reading of the battery voltages from the microcontroller. I then setup a simple test, where I had a bunch of different voltages and determine the actual motor power required compared to the calculated value:

Battery Voltage Function

It turns out that the equation for the lines of best fit for the rpms of 1850 and 2155 are nearly the same, and that 2450 starts to plateau off at the end. Instead of making some killer rational function or something like that, I just took the average values from the lines of best fit from the 1850 and the 2155 graphs, and cut it off after the error was over 28 (which was to account for the plateau in the 2450 graph):

Battery Voltage Function

Note: I divided the sensor value by 275 to convert the raw value into volts. After this, I simply offset this value from the other graph:

Voltage and Linear Code

Now, before the whole internet jumps on me, I now realize that I made a math error that is pretty stupid. Instead of adding an offset to the equation, I should have modified the y value of the point P2 (a couple of images ago) to properly account for the battery error. This was indeed an amateur mistake made at 4 in the morning, however, I came up with a solution that might be able to compensate for that mistake.

So this worked a lot better, however inertia was still a problem. Basically the rate of change of the line was too steep, so the microcontroller couldn’t keep up with the wheel.

To account for this, I decided instead of using a linear relation between the two points, use a parabolic relationship instead:

After a little algebra: I came up with the following:

After committing it to code (and using the voltage offset on P2, NOT a vertical translation), this is the final result:

Flywheel Controller Final

And the best part:

Robotics Nothing but Dank