October 12, 2013

A Really Really Fast Robot Arm

Since I started working in the cheetah robot lab, I've wanted to build a high-speed robot arm using a similar low-inertia, composite construction as used on the cheetah legs.

The arm will be roughly SCARA configuration.  Rather than having a motor directly at each joint, both the motors will be located at the shoulder of the arm, and the arms second link will be driven with a linkage.  This will make the arm light and low inertia, so it can be moved back and forth quickly.

I got some excellent motors for the arm from Charles at Swapfest.  They're a pair of ServoDisc Platinum UD9-E.  They have built in optical encoders, and because they're a real part rather than hobby grade equipment, they have an incredibly detailed spec sheet.  The ServoDiscs are coreless axial flux DC motors.  So basically a mini brushed etek.  Since the rotor is just copper windings, without any steel laminations, so there's zero cogging and very low rotor inertia, which make for extremely fast response.

To make the arm as fast as possible, I wrote some code to optimize the tip speed of the second segment of the arm over the gear ratio - arm length space.  Since I'm taking How To Matlab 2.086 this term, I took this opportunity to apply what I was learning in the class just write it in Python using ScyPi.

The main thing I 'd like to change about the code at this point is to implement one of the actual built-in ODE integrating functions.  Rather than figuring out how to use the stock ones I just used my own extremely simple fixed-timestep integrator.  It works fine, but it is pretty slow if you want good output resolution.

Since I know the basic construction method I would use for the arm as well as the motor specs, I was able to model the arm pretty easily.  The model arm is a 1.5" diameter carbon fiber tube I found the mass per length number for online, with a 70 gram mass at the end of it.  The arm is attached to an aluminum HTD timing belt pulley, which is described as an aluminum disc.  For a given arm length and pulley size, you can easily find the moment of inertia of the arm about its rotation point.  From there, you can use the torque-speed curve of the motor to get an expression for angular acceleration of the arm.

The code simulates the arm starting from standstill and applies constant voltage to the motor until a specified change in arm angle is reached (I've been using between 30 and 90 degrees).  Then the average speed of the tip of the arm over the motion can be found.  To get an idea of what ratios/lengths are optimal, you just repeat this process over a bunch of arm lengths and gear ratios.

Here's the Python code:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
from math import *
import scipy
from mpl_toolkits.mplot3d.axes3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np


def IntegrateArm(theta0, dtheta0, timestep, thetaEnd, L, Ta):
    
    time = 0
    theta = theta0
    dottheta = dtheta0    
    
    ########### Define Physical Properties ###########

    Kt = .081               #Motor torque constant in N-m/Amp
    V = 30.0                #Motor supply voltage
    R = .85                 #Motor terminal resistance in ohms
    L = L                   #Length of arm in m
    M = .07                 #Mass of end-effector in kg
    Ta = Ta                 #Arm pulley teeth
    Tm = 20.0               #Motor pulley teeth
    Rp = Ta*0.7958/1000     #Arm pulley radius in m, assuming HTD 5mm belt
    Ml = .164               #Linear density of arm in kg/m
    
    ########### Define Body Properties ###########
    Ma = L*Ml               #Mass of arm in kg
    Mp = 2700*.005*pi*Rp**2 #Approximate mass of pulley in kg (modeled as aluminum disc)
    Ia = (Ma*L**2)/3        #Moment of Inertia of Arm
    Im = M*L**2             #Moment of Inertia of end effector
    Ip = (Mp*Rp**2)/2       #Moment of inertia of pulley
    I = Ia + Im + Ip        #Total arm moment of inertia
    
    ########### Equation of Motion ###########
    tau = Kt*(V - Kt*dottheta*(Ta/Tm))/R   #Torque at motor shaft in N-m
    ddottheta = (tau*(Ta/Tm))/I


    while theta < thetaEnd:
        dottheta += ddottheta*timestep
        theta +=dottheta*timestep
        time += timestep
        tau = Kt*(V - Kt*dottheta*(Ta/Tm))/R   #Torque at motor shaft in N-m
        ddottheta = (tau*(Ta/Tm))/I
        
    V_avg = thetaEnd*L/time        
    return V_avg                                #Average arm tip velcity in m/s
        

def plotSurface(Lmin, Lmax, Tmin, Tmax, thetaInt):
    fig = plt.figure()
    ax = fig.gca(projection='3d')
    x = np.linspace(Lmin, Lmax, 100)
    y = np.arange(Tmin, Tmax, 1.0)
    X, Y = np.meshgrid(x, y)
    z = np.zeros([len(x), len(y)])
    
    for L in range(len(x)):
        for T in range(len(y)):
            V = IntegrateArm(0, 0, 1e-4, thetaInt, x[L], y[T])
            z[L][T] = V
        

    ax.contour(X, Y, z.T)
    surf = ax.plot_surface(X, Y, z.T, rstride=1, cstride=1, cmap=cm.coolwarm,linewidth=0, antialiased=False)
    plt.show()


def findBestGear(L, Tmin, Tmax, thetaInt):
    T = np.arange(Tmin, Tmax, 1.0)
    V = []
    for i in range(len(T)):
        val =IntegrateArm(0, 0, 1e-4, thetaInt, L, T[i])
        V.append(val)
    return t[V.index(max(V))]


The plotSurface function generates a nice 3D picture of the tip velocity vs number of pulley teeth on the arm and arm length:

Unfortunately there doesn't seem to be any global maximum.  If you keep increasing gear ratio and arm length, average tip-speed keeps on increasing.  However, for a given arm length and arm swing angle, there is clearly an optimal gear ratio.  Once I start actually designing parts, I can refine the model with more accurate arm inertias, but this gives me a good starting point.

Finally, I contacted NAC Harmonic, and they're sending me (for free!)  a 50:1 harmonic drive component set, which may or may not be used in the arm.

September 28, 2013

Finishing up the Giant Scooter

Getting the scooter to a nearly-finished state from its previous condition took a few nights of solid work.  Most of the work was done in the days leading up to the New York Maker Faire.

Last update, the scooter was basically a rolling frame.  To interface the old adjustable steering column with the motorcycle fork crown, I had to make a clamping shim to adapt the tube diameters.


To get the scooter moving on its own power, the only things to do were build a deck and battery compartment, and wire together all the electronics.

The top and bottom of the deck and battery compartment were bandsawed out of 1/8" aluminum plate.

Waterjets are for sissies
The sides of the compartment were bent from 3" wide strips of thick black acrylic.  Using acrylic turned out to be a mistake, as later one of the panels cracked.  Bends were made by clamping an aluminum plate on each side of the bend line, and heating the bend area with a heatgun.



The battery compartment fits beneath the deck and extends to the same depth as the gearbox.  Unloaded the scooter has over a foot of clearance.  The acrylic was edge tapped and fixed into place with stainless screws countersunk into the aluminum deck and underplate.


Wiring the battery pack was a bit of a mess for a few reasons.  First, I didn't leave all that much space in the battery compartment for wires.  Also, this battery pack is a funny creature: while the scooter is running, it's a 16S2P pack, for ~60V, 10Ah.  However, I don't have a 16S charger.  For charging, the pack is split into four 4S modules, which can be charged in parallel.  I needed some sort of external connector for switching the pack between charge configuration and drive configuration.

The HobbyKing hardcase LiPo bricks were fastened down with 3D-printed clamps:


This mess of wires occurred.  Without some 10 gauge Turnigy Noodle Wire this would have not been possible:


The series/parallel switching comes from these four XT90 connectors.  The boat power switch was pulled off a box of servo drives found at a lab cleanout.


Some wiring detail.  Note the gratuitous use of zip ties.


Wiring was finished at roughly 2 in the morning the day of Maker Faire, so I didn't have a chance to attach the brake caliper.  Fortunately, despite the lack of brakes, nobody was run over.


When I got back, I attached the brake caliper.  All it took was milling a funnily shaped bracket thing that screwed into the swingarm:


I still need to pocket the swingarm, because there's just too much solid metal there:


And here's the (mostly) finished scooter:  If you look closely at the fork, you'll notice that there's now a shock absorber on the outside of the fork.  I had two of the shock absorbers I originally used, so to make the fork a bit stiffer I just added the second in parallel to the first.  It's not the most elegant solution, but it vastly improves the rideability.


For reference, here's the original scooter.  Pretty neat how much of a difference one year can make.


Riding this thing is wonderful.  There was a big grassy field with a hill along one edge that I got to do some off-roading on.  The suspension smooths out the terrain extremely well.  Also, the torque is absurd.  I have the Kelly controller limited to 100 amps (out of 200 max) to avoid toasting the magmotors, and use a moderate amount of smoothing on the throttle.  This makes the vehicle a little tamer at low speeds, but if you open the throttle past ~30% it can easily pull a wheelie or throw you off.  The magmotors also seem much happier than the CIMs were.  They barely get warm in situations where the CIM's got too hot to touch.

So, that's a wrap.  My next project, which is mentally in the works, is not vehicle related for a change.  But don't worry, it has shiny motors.

August 31, 2013

The Building of the Climbing Wall

Many freshmen arrived at East Campus, and we immediately used their slave labor to build an assortment of ridiculous wooden structures.  Construction of the climbing wall went very quickly and fairly smoothly, and I didn't really take any pictures of the process.  Fortunately a more talented and better equipped photographer got some good photos and video of the process.  All photo and video credits to Billy Demaio.

Some of the construction footage compiled:



Assembling the uprights:



Building the rings.  Unfortunately no pictures were taken of the process where we lifted the rings onto the axle.  About 10 people lifted each ring, while I stood on the top of an upright to manipulate the axle into place.  Someone on the other side of the axle pushed it through, while another couple people held a crutch in place to support the weight of the rings and axle.  This was repeated about 6 times, because we had to remove two of the wings to widen the holes in the plywood.




Some other of the courtyard structures.  In the background is most of the four-story fort.  To the right, part of a ride called the "Frosh Wash", and in front to the left an impromptu swingset.






Before we put the plywood and climbing holds on, we found a bunch of fun activities to do with the structure:




The climbing actually worked well.  We found a brake position that worked for a fairly wide range of climber weights.  Two people on the sides of the cylinder would help turn it to make sure no one climbed too high up.

August 13, 2013

Scooter Mega-Update: Piling on the Absurdity

Lots of progress has been made since the revival of the all-terrain scooter project, although a reasonable person would probably describe it as progress in the wrong direction.  As I've stumbled across random components in the treasure trove that is N51/N52, the scooter has become progressively more ridiculous.

Over a month ago, I finished up the dual-mag-box: a gearbox, which much like the triple-cim-box on the original scooter, combines and reduces the speed of the outputs of multiple (in this case 2) motors.  This time, rather than chopping up and sketchily aluminum-zinc brazing together a gearbox, the gearbox housing was milled out of a 6.5" x 3" x 1.5" aluminum billet.

Here's the brick marked up and ready to mill:

SAD: Sharpie Aided Design
I bored out holes for the gears.  The big one in the center proved to be a real challenge to machine.  The boring head for the mill was too small, and the geometry of the cutting tooth on it prevents it from making flat-bottomed holes.  I ended up chucking the billet on the four jaw chuck and boring out the cavity on the lathe.


Rather than using my homemade mill-broach-thing I used on my tricycle differential gears, I borrowed a real broach set from Charles, and broached the keyways on a mini arbor press.  Real tools are nice.


The motor mounting plate, with more sharpied in dimensions:


I reused the output gear and shaft from the original gearbox.




To mount the gearbox, I had to make cutouts in the u-channel frame for the motors.  These turned out to be difficult to make, because we didn't have any proper tool large enough.  I ended up using a fly cutter and taking very shallow passes.  Even so, the process generated lots of unpleasant noises.


One major problem with the last scooter was the chain path.  Because of the location of the suspension pivot relative to the gearbox output shaft, I had a dreadful chain tensioner assembly to compensate for changes in chain path length.  While eventually it became reliable by replacing the spring with bike inner tubing, it still severely limited possible suspension travel (the springs were stiff enough that this wasn't ever a problem).

To eliminate this problem completely, there will be a pair of coupled idler sprockets that ride on the axle the suspension pivots about.  I bolted together two sprockets side to side, and pressed some bearings in to make the idler.  The idler also accomplishes a bit of gear-reduction, so this vehicle will have a no load top speed of a bit south of 30 mph.


The rear suspension is where things start getting really silly.  Because there happened to be a big aluminum billet lying around MITERS, the rear swingarm is milled from solid blocks rather than plates.  During one of those brief periods where the MITERS bandsaw had an un-borked blade, I chopped the billet in half diagonally.  


I face the edges to have a nice stripey pattern, because I liked how it looks.  Credit for this technique goes to Julian.


To hold the rear axle, I drilled a hole in the end of each arm and added a clamping mechanism.  To create an offset for the disk brake on the rear wheel, I made another diagonal bandsaw cut down the middle of one block.  I bolted the two bits back together like so:




The pivot for the rear swingarm was made out of...more billet.  Each side has a pair of bearings pressed into it.  The pivot block was bolted to the gearbox with four long bolts.


The entire assembly is held to the deck with 7 countersunk 1/4-20 bolts.  Normally, tapping all those blind holes would be miserable, but I recently purchased a forming tap for MITERS.  Forming taps are a wonderful thing.  Instead of cutting threads, they actually cold-form the metal, squishing it into a thread shape as you tap.  You drill a slightly larger hole (#1 drill, as opposed to #7 for a normal 1/4-20 tap), and you can just crank the tap down until it hits the bottom.  Since it does not produce chips, you never have to back out the tap.  If you have a drill with a strong chuck, you can just power tap until the tap hits the bottom, without worrying about chips clogging it.  Even without a drill, blind tapping is way easier than with a normal tap.




In the piles of parts left in the remains of a certain electric vehicle club I found this very fancy downhill mountain bike shock.  One of the washers that held the spring in place was missing, so I turned my own and attached it with a two piece shaft collar.  It features adjustable everything, including spring preload, compression damping, rebound damping, and internal pressure.


I milled a block to hold the shock absorber to the swingarm out of some more billet.



And here's the suspension fully assembled:



The shock absorber attachment on the frame was turned from some 3" round.  Then a large flat was milled on each side.  The shock pivots about a 7/16 shoulder bolt tapped all the way through the mounting block.



The milled-down part of the cone makes a nice hyperbola shape:


Because leaving the rear swingarms solid aluminum would be silly, I milled out a channel on each side.  The center of the milled-out region is now 3/8" thick, instead of 1.25" thick.  I plan on doing the same on the other swingarm as well.


And here's the frame assembled.  Once I attack a proper steering column and handlebars, it will be pushable.  I did some jump-testing of the suspension.  The back seems just right, but the front is definitely too soft.  I haven't decided whether it's acceptable, or if I need to stiffen up the shock absorber somehow.  Either way, the suspension travel is epic, with something like 5-6" in the front and at least that in the back.  Clearance is similarly ridiculous at over a foot with my weight on it.


Still left:  Making a wider deck, mounting the electronics, and riding off into the distance to the whine of straight-cut spur gears.