Showing posts with label BWD. Show all posts
Showing posts with label BWD. Show all posts

Wednesday, January 13, 2010

3ph Duo Wrap-Up Part 2: Control

This is the conclusion to:
3ph Duo Wrap-Up Part 1: Field-Oriented

And falling squarely in the category of "ZOMG," the unabridged (but barely edited) 78-page Rev0 write-up that does not include specific software implementation at all yet because I am so sick of looking at it:
3ph Duo: 2 x 1kW Brushless Motor Controller
w/ Field Oriented Control
Design Notes [DRAFT]

It does have a lot of other cool stuff, though, including MOSFET selection and analysis, a more detailed F.O.C. explanation, BLDC vs. BLAC analysis, mechanical design, etc. etc. etc. I promise I will update it with some software details when I can stomach it again. Comments greatly appreciated...

When we left off, the controller was just barely able to generate six sine wave PWM outputs (three each for two motors) and estimate the position and speed of the rotor based on Hall effect sensors. Using this position estimate and current sensors, it could also measure the vector current, expressed in the two-dimensional d-q coordinate system we set up to make life easy. The purpose of Part 2 (of 2, thankfully) is to explain what we do with this information that makes field-oriented control so useful.

Part 1 hinted at the purpose of field-oriented control. (No, it's not just for making the motor quieter.) The goal is to place all of the current on the q-axis, right in between magnets, where it can pull hardest on the magnets and produce the most torque. Any current lagging behind onto the d-axis because of motor inductance is not doing useful work. This is now a controls problem.

I've taken just about every controls class at MIT (although I did drop a couple half-way through), so sometimes I take for granted that everyone understands the basics of a feedback control system. But for the sake of fulfilling my New Year's Resolution, I won't. The idea is really simple: You measure a value, in this case current, and compare it to the value you desire. If the desired value is higher than the measured value, you do something that will increase the current. If the desired value is lower than the measured value, you do something that will decrease the current. The result is a corrective action that always tries to bring the measured and desired values together. Textbook feedback loop:

Not that kind of plant. Plant is whatever thing you are controlling.

It's borderline common sense. If the water's too hot, you turn the heat down. If it's too cold, you turn the heat up. If you're good, you can predict the overshoot and preemptively turn the heat down so as not to burn yourself. Eventually, you get to the right temperature. Only by adding math do we manage to make control systems more complicated than that.

Anyway, this is what we can do with both the d-axis and the q-axis current that we figured out how to measure in Part 1. Enter the "synchronous current regulator," a special application of the textbook feedback loop to these types of motor control problems. It's synchronous because it works in the rotating d-q coordinate system we set up before. A block diagram is worth 1,000 words in this case:

Synchronous Current Regulator. Click to enlarge.

Calm down, calm down, it's not that bad. The circle with the M? That's the motor. The triangle? That's the three-phase inverter, i.e. all of the power electronics hardware. Everything else is software. The Park transform? That's the trigonometry part that projects the A, B, and C coil current measurements onto the d-axis and q-axis, just like in Part 1. It needs the rotor position to do so. Then there are two feedback controllers: one for the d-axis and one for the q-axis. The d-axis controller's desired value is always zero. The q-axis controller's desired value is the torque command, and can be positive (accelerate) or negative (brake). The outputs, called PWMs, are switching signals that set the average voltage command on each of the three phases.

Now, that's not exactly what I did, but it's pretty damn close. Here's mine:

Modified Synchronous Current Regulator. Click to enlarge.

The differences are small. Instead of an inverse Park transform to project back from d-axis and q-axis voltage commands to A, B, and C voltage commands, I use the fast-loop sine wave generator that caused so much trouble in Part 1. And instead of a magical rotor position measurement, likely derived from an encoder or resolver, I use Hall effect sensors and interpolation. I chose to do this because cheap motors have Hall effect sensors, not encoders or resolvers.

The feedback loops are the same. Well...not quite. The difference is what comes out of the d-axis and q-axis controllers. Can you spot it? In the standard version, a d-axis and q-axis voltage (PWM) come out, then get tranformed back into values for A, B, and C voltage. This requires more trig in the fast loop...not good for my poor little processor. In the modified version, a phase (angle) and magnitude come out of the d-axis and q-axis controllers, respectively. Phase is a simple shift in the sine table...no big deal. Magnitude is a scaling operation, which, as we saw in Part 1 is still a pain in the ass on a microcontroller with no hardware multiplier, but it's not as bad as more trig. At least it scales all three values equally.

Where the heck did that modification come from? It's actually one of the first things I wrote down, and I never considered doing it anyway else. It's the least processor-intensive and most physically intuitive, IMO, even if it's non-standard. But does it actually work? Well, after about a month of screwing around with software, I finally got to the point where I could run this controller in earnest, under load, with the modified synchronous current regulator. First, here's what happens when the d-axis controller is turned off, meaning no phase angle correction can be implemented...the same as fixed-timing:


This looks very similar to the measurement done in Part 1 on the front motor. As the motor increases in speed, the effect of current lag is more and more pronounced, putting more current on the d-axis. The rear motor shows the effect even more, since it has a higher inductance. The controller tries to keep the q-axis, torque-producing current constant. The result is that the total current, the vector sum of d-axis and q-axis components (or of A, B, and C components), must increase in order to maintain constant torque.

Now the same motor and load with the d-axis phase control on,


Plain as day, the phase advance takes out the d-axis current. Just 13º lead or so is all it takes on this motor at 600RPM. Meanwhile, the q-axis controller makes sure torque is held constant. If you want proof, look at the acceleration times in both cases...they are very similar. But in the case of full d- and q-axis control, the total current is reduced thanks to the zero d-axis component. This is clearly a more efficient operating point.

And just so you don't think I'm pulling your leg, it does work with two motors at the same time:

(Believe me, I did consider leaving this test out and hoping nobody would notice...)


Well there you have it, theorized and confirmed in experiment. The modified synchronous current regulator works. (I honestly was never sure it would, but I would have bet on it.) I can't compare it to the standard synchronous current regulator because the standard version simply would not run on my hardware. But, I did simulate the difference and I can assure you I was pleased with the result. If you don't believe me, read the unabridged version.

And that's the end of the 3ph Duo field-oriented control upgrade. What? Were you expecting some dramatic ending? That's not how things work when 90% of the upgrade is done in software. You do a lot of work for...something that looks the same as it did before. That's why there are no pictures of videos of real things in this post. The only good thing about code is that once you do it, you can copy-paste it for years. (Have you ever wondered where all my data comes from? I never talk about data acquisition software...)

Anyway, now that that's done, I feel the incredible urge to go build something. Something fast.....

Friday, January 8, 2010

3ph Duo Wrap-Up Part 1: Field-Oriented

After the single most difficult embedded programming challenge I've ever faced, I am finally ready to wrap-up the 3ph Duo field-oriented control upgrade. This is a slight hardware tweak and major software overhaul that, together, allow my dual-channel, 1-kW per channel brushless motor controller to operate as a true AC (sine wave) motor controller with field-oriented control. This post, Part 1 of 2, explains the "field-orienting" part. "Control" is left for Part 2. A massive (and I mean massive) write-up is also coming, if you really can't get enough of this stuff.

But my New Year's Resolution is to make my blog posts a little more understandable, so this might be a good time to review the big picture: What the heck is field-oriented control? And don't use any big words or cite any 355-page Master's theses. Okay, here's a motor with two magnets and three coils of wire:

To be more specific, it's a two-pole, three-phase outrunner motor. The stator has three coils, A, B, and C, spaced by 120º. The rotor has two magnets, N and S, spaced by 180º. It's about the simplest BLDC motor you could imagine, and thankfully the electrical coordinate system lines up with the physical coordinate system. Speaking of coordinate systems, let's define one:

The problem is 2-dimensional, so a simple set of perpendicular axes is useful. In motor control, the axes are called d (direct) and q (quadrature) instead of x and y, and they are defined with respect to the rotor. So, as the rotor rotates, so do the axes. The d-axis is always lined up with the magnets, and the q-axis is always 1/4-cycle ahead of the d-axis. (So, in the picture above, the motor is rotating counterclockwise.) If the motor had more poles, the axes would not be physically at right angles, but the d-axis would always be on magnets and the q-axis would always be in between magnets.

To get the motor to spin, the current is sent through the coils, turning them and the steel around them into electromagnets. These electromagnets attract or repel the permanent magnets. By alternating the direction of current in the coils, a rotational motion is created. Another way to look at it is that the coils are used to create a rotating magnetic field and the magnets are pulled along by this field.

The coils A, B, and C are aligned at 120º intervals, so any quantity (current, voltage, magnetic flux) that can be attributed to a coil has a particular direction to it. In other words, these quantities are vectors. As such, they can be projected onto any set of axes we want using simple trigonometry. In field-oriented control, these quantities are projected on the d-axis and q-axis as we have defined above. A simple example:


In this case, current is sent into coils B and C, and comes out of coil A. The magnitudes, represented by the lengths of the red arrows, are such that currents A+B+C = 0, since the coils are all connected at a single point. These three vectors, if added together, would give only d-axis current. (Current A has no q-axis component; B and C have equal and opposite components on the q-axis.)

But what does this mean for the motor? Well, the current passing through the coils turns them into electromagnets. The d-axis, which has the permanent magnets on it, would like to align itself with the electromagnet being created by the coils. In this case, it already is aligned. The motor is perfectly happy where it is and will resist being moved in either direction. To see how torque is produced, imagine this case:


Here, the resultant current is entirely on the q-axis. The magnets still want to align themselves with the current, though, so the rotor will try to rotate counterclockwise, producing torque as it does. By keeping the resultant current (the sum of the three current vectors, A, B, and C) on the q-axis as the motor rotates, the rotor is always trying to catch up and producing the maximum amount of torque.

The ultimate goal of field-oriented control is to be able to directly control both the magnitude and the angle of the total current vector by using the individual coils. Since the angle is defined with respect to the rotor, this requires knowledge of the rotor position. In order to make the vector math easier, everything is assumed to be a sine wave and the power electronics used to drive the coils produce a sine wave ouput.

This is very different than traditional BLDC control where the output is a square wave, and there is no knowledge or control of the current angle. In BLDC controllers, the timing of coil firing is fixed by Hall-effect sensors. Why not just fix the timing so that the coil fires on the q-axis, you say? Well, you can, and for most motors this works pretty well. However, the coils are also inductors, and inductors resist rapid changes in current. Thus, it takes time for current to build up in the coil after it has been fired. This delay means that although you may be firing on the q-axis, some current will lag behind and wind up on the d-axis:


Because the current is no longer on the q-axis exclusively, torque and/or efficiency are reduced. The actual angle by which the current lags is a function of motor inductance, resistance, and speed, so it is very difficult to predict the lag ahead of time and dead-reckon the correct coil firing time. (Some controllers do this! You will get back some of the torque, of course.) Field-oriented control can directly measure and control this effect. This post will focus on the measurement aspect, arguably the hardest part. Part 2 will focus on control.

In this ECN article, Daniel Torres says:
The most common technique utilized for controlling BLDC motors is trapezoidal control. However, both PMSM and BLDC motors can be controlled using sinusoidal control and Field Oriented Control (FOC).

FOC has become more popular in recent years, due to the fact that the cost required to implement this technique is no longer a constraint. The available technology and manufacturing processes now make it possible to implement this control technique in a 16-bit, fixed-point machine, such as Microchip’s dsPIC Digital Signal Controllers (DSCs).
And here are some application notes specific to the dsPIC that illustrate sinusoidal control and field-oriented control of BLDC motors:

AN1017: Sinusoidal Control of PMSM Motors with dsPIC30F DSC
AN1078: Sensorless Field Oriented Control of PMSM Motors
These very informative application notes both use the dsPIC30F, which, I will grant, is a fixed-point 16-bit processor. (It doesn't have hardware floating-point capability like an ARM or Pentium processor might have). But what it does have that my poor little MSP430F2274 does not is a 30Mhz instruction clock and single-cycle multiplier. Without the hardware mutiplier, the processor can only multiply by a power of 2 or add things together, meaning it takes several shift/add steps to multiply two arbitrary numbers by each other. In other words, while the dsPIC can multiply two numbers together in 33 nanoseconds (!!) it takes me somewhere in the neighborhood of 4,000 nanoseconds. :(

With that in mind, what exactly needs to happen for my controller to be able to execute sinusoidal, field-oriented control? First, let's focus on the sine wave part. As it turns out, this was the most difficult part of my particular endeavor. The hardware for producing a sine wave output is virtually the same as it is for square-wave BLDC control: six transistors (MOSFET or IGBT) switching at high speed to produce three voltages on the motor terminals. I'll spare you the details, but they'll be in the final write-up.

Although it didn't start out as such, my control program wound up converging on a pretty typical fast loop/slow loop configuration. The fast loop, which caused all the problems, handles sine wave generation and runs at the switching frequency of the transistors, which in this case is about 14.4kHz. This loop is responsible for looking up the base voltages from a table of sine values (doing actual trigonometry is out of the question) and then scaling them by some magnitude. It is also responsible for estimating rotor speed and position, which unfortunately involves a division. The problem here is that, while Daniel Torres insists it can be done, I don't have a hardware multiplier for scaling. Oh, and I need to do it for two motors. So how screwed was I? This little test reveals how screwed:


What you see there is a signal that turns on at the start of every 14.4kHz fast loop and turns off when the fast loop code is finished. In the 69 microseconds between each cycle, I needed to do six look-ups, six scaling operations, and occasionally two divisions! (Remember that each multiply takes about 4 microseconds.) The brighter line is the time it takes when not doing the divisions. The dimmer line is the extra time it takes to do the two divisions. You can see the code did finish in time, but only just barely, with about 2 microseconds to spare for all the other processes, including the slow control loop! You know how your computer gets when one program starts using 99% of the processor? Yeah, that's what happens. And occasionally the fast loop code would not finish on time...then very bad things happen. I needed to get back at least a tiny bit of processor time for the slow loop. (Or, you know, get a faster controller or just settle for one motor. NO!)

Here are just a few of the many tricks I needed to pull for this to work:
  1. You don't need to calculate all three values for each motor. Since they are balanced sine waves, A+B+C = 0 applies. It is sufficient to look up and scale two, then do a simple subtraction to find the third. This was hugely important.
  2. It's faster to use a variable zero-sequence voltage. I made a horrible attempt to explain this in a previous post. It basically means not adding in an extra offset to center the sine waves at half the DC (battery) voltage.
  3. 99.999% of the time, the motor speeds aren't calculated in the same fast loop. This is because a Hall-effect sensor triggers the calculation, and the chance of two coming in at the same time is very slim. But when it happens, the two divisions can cause the fast loop to fail. The simple solution: don't even try processing two. If they both come in, make one wait until the next cycle. An extra 69 microseconds is not going to make much of a difference to the speed calculation.
The result is a fast loop with a lot more cushion:


Now even with a division, the loop finishes in 53 microseconds. This leaves plenty of time for the slow loop to sneak in some processing time each cycle. The slow loop, which only runs once every 8.2 milliseconds, has plenty of time, about 120 fast loop cycles, to finish. This is time-division multi-threading...on an embedded processor. Wheeeeee!

The slow loop, running in these gaps of left-over processing time, does all the real work. It measures currents, voltages, throttle signals, initiates wireless data communication, and, oh yeah, it runs the control loop. But that's a topic for Part 2 of this wrap-up. The important thing to mention now is that, despite being slow, the loop knows the position of the rotor at the moment when current is measured in all three coils. (Okay, again, only two are measured. The third is calculated from A+B+C = 0.) So, it can project the three currents onto the d-axis and q-axis just like in the example above. Thus, the field is oriented! We know exactly where it is, even when it is lagging behind our coil timing.

Here is an example of this measurement, done on the front scooter motor under load:


What you see there is exactly what you would expect with no control of the coil timing, if they are fired at the same angle no matter what. The q-axis current is held steady at 20A. (The controller does do this.) But as the motor increases in speed, some current starts to lag into the d-axis. You could, in fact, use this data to estimate the motor inductance. (Actually, you need to know its resistance as well.) Sparing you the details, which will be in the huge write-up, you get about 0.1mH, which is about right...at least the right order of magnitude.

So the current lag really does exist, even on motors with relatively low inductance. The rear scooter motor is even more susceptible, since it has more turns per winding and thus a higher inductance. But if you have an accurate measurement of the current as a vector, with the d-axis and q-axis components known, it is a simple matter to advance the coil timing in real time to make up for the lag. This is the topic for next week, though, since this post is already too long! Also because my plant threw a tire so I can't take any more data until I get more urethane glue...

I have awesome plants.

Sunday, December 13, 2009

3ph Duo: Codefest, Part II

If nothing in my last post made any sense, this is what I was trying to say:



I used my good camera w/ directional microphone, and set up the scooter frame so that it would resonate. The difference is pretty clear here. Everything you hear translates to what you would feel while riding it, so the ride will be much smoother as well.

I finally worked out all the sign (+/-) kinks. The remaining task is to make it fault-tolerant and load test. The Hall effect sensors are not perfect, and they can occasionally throw in a false signal or miss a real signal. This becomes even more important when they are being relied upon for a speed estimate that drives the sine waves. The motor and MOSFETs should be able to tolerate a glitch like this, but at high speeds it can cause a draw-down on the main capacitor, which can sometimes cause the microcontroller to spontaneously jump out of the program loop. So it would be better if this didn't happen...

More to come.

Thursday, December 10, 2009

3ph Duo: Codefest

These days, most people are surprised when I tell them that my background is in mechanical engineering, not electrical, since more often then not I am troubleshooting some circuit or winding a giant inductor or something. But probably the thing that nobody knows is that my real background is in software. Okay, not in the educational sense, but I've been programming things since I was like...ten. I won't make any claims about my actual skill, but I will say that on more than one occasion I have been saved by a bit of software fidgeting that I probably couldn't have done if I hadn't been writing all those games (e.g. Pokemon Hunter and Pokemon Hunter II) when I was too little to use power tools.

In one of the saddest tragedies of my life, the original source code for Pokemon Hunter (written in QBASIC!) has been lost forever, but I assure you the graphics looked roughly like this.

Oh yeah, this is a post about my brushless motor controller. Or, the latest of them, anyway. If you've lost track, here is a side-by-side comparison of the three real iterations it has gone through:

Left-to-Right: Newest, Middle, Oldest


First was the double-stack IRFB3077-based controller (right), my very first shot at three-phase brushless motor control. While it has the distinction of MOSFETs so powerful they caused the aluminum bus bars to desolder themselves (Yes, you can solder aluminum.), it was impractically large for the scooter because each one only controlled one motor. Next was the greatly compacted 3ph Duo, so named because it controlled two motors from a single board using two IXYS GWM 100-01X1 six-pack MOSFET bridges as the inverter stages. And it works. But as I described in the last post, that won't stop me from making yet another one.

The most obvious visible change is the lack of LEM current sensors. These were large and expensive and have been replaced by the ACS714 surface-mount sensors, two each per motor. Two each so that I can effectively measure three-phase currents, instead of assuming that only two phases conduct current at a given time. If you want to know more about why I am concerned with this, this post sort-of sums it up. The goal is to implement full sine wave commutation with the possibility of phase adjustment, something that would separate this controller from other similarly sized and priced small vehicle brushless motor controllers on the market. Turns out from a hardware standpoint, this is very easy. The microcontroller I use, the TI MSP430F2274 already has six independent PWM output channels (three per motor). So the circuit board is essentially the same, with a few signals re-routed to make room for the six PWM pins.

The real challenge is the software. This is not a 32-bit processor with native floating-point. It is a regular old 16-bit mixed-signal processor that runs at a relatively poky 16Mhz and doesn't even have hardware multiply. Your cell phone probably has 10x more processing power. To roughly lay out the challenge: the PWMs are refreshed at a rate of 15kHz, setting the upper limit on the resolution of the sine waves generated. (You get 15,000 points per second with which to draw the sine function.) But to use all 15,000 points per second, six PWM values must be generated and scaled appropriately at every refresh. The clock speed is 16MHz, so all this has to happen in less than 1,000 clock cycles. To give you an idea of how hard this is, just multiplying two integer numbers together takes about 70 clock cycles on this chip. Forget about fractions and definitely forget about trigonometric functions. The only way to generate a sine wave is to use a look-up table, in this case 256 bytes in memory that store the value of the sine function for various angles. To set a baseline, this is how I originally implemented a sine-wave look-up on six channels:
aidx_int += aspeed;
aidx = aidx_int >> 8;
atemp = SIN8LUT[aidx];
btemp = SIN8LUT[(unsigned char)(aidx - TWOTHIRDSPI)];
ctemp = SIN8LUT[(unsigned char)(aidx + TWOTHIRDSPI)];
atemp = 65023 - ((atemp * amag) >> 6) + ((127 * amag) >> 6);
btemp = 65023 - ((btemp * amag) >> 6) + ((127 * amag) >> 6);
ctemp = 65023 - ((ctemp * amag) >> 6) + ((127 * amag) >> 6);

uidx_int += uspeed;
uidx = uidx_int >> 8;
utemp = SIN8LUT[uidx];
vtemp = SIN8LUT[(unsigned char)(uidx - TWOTHIRDSPI)];
wtemp = SIN8LUT[(unsigned char)(uidx + TWOTHIRDSPI)];
utemp = 65023 - ((utemp * umag) >> 6) + ((127 * umag) >> 6);
vtemp = 65023 - ((vtemp * umag) >> 6) + ((127 * umag) >> 6);
wtemp = 65023 - ((wtemp * umag) >> 6) + ((127 * umag) >> 6);
One motor is ABC, the other is UVW. This steps through the sine table at some speed, looking up values with an independent index for each motor. Then, it scales those values by some magnitude and shifts them such that their PWM-average outputs are sine wave voltages centered at half the DC voltage:


The PWM outputs, normalized to the DC (battery) voltage, for full-command (top) and half-command (bottom). In both cases, they are centered at half the battery voltage.


Well, this almost worked. It worked with 1, 2, 3, and 4 channels. But with 5 or 6 channels, the interrupts starting running into each other because it took longer than 1,000 clock cycles to get through that block of code. Luckily, it's not a very efficient way of doing things, so the next few paragraphs will describe how it was trimmed down. First, the zero-sequence hack. I don't know of anyone who refers to it as such, but this is my favorite motor code hack of all time. A lot of the code above is being used simply to offset the PWM values so that they are always centered at 50% duty cycle. This is...stupid. (Maybe not, but I declare it to be so.) So I ditched that drive method in favor of one that always puts the peak of the sine waves at +Vbat, like this:


The modified drive signals at full-command (top) and half-command (bottom).


The difference is that, except at full command, the three sine waves are shifted up to higher voltages with respect to the battery. But what really matters, as far as the motor is concerned, is the relative voltage across the three phases, which is the same in either case. The same amount of current will come out of or go into each wire, and the bulk shift does not change the motor operation. It does, however, greatly simplify the code:

aidx_int += aspeed;
aidx = aidx_int >> 8;
atemp = SIN8LUT[aidx];
btemp = SIN8LUT[(unsigned char)(aidx - TWOTHIRDSPI)];
ctemp = SIN8LUT[(unsigned char)(aidx + TWOTHIRDSPI)];
atemp = -((atemp * amag) >> 6);
btemp = -((btemp * amag) >> 6);
ctemp = -((ctemp * amag) >> 6);

uidx_int += uspeed;
uidx = uidx_int >> 8;
utemp = SIN8LUT[uidx];
vtemp = SIN8LUT[(unsigned char)(uidx - TWOTHIRDSPI)];
wtemp = SIN8LUT[(unsigned char)(uidx + TWOTHIRDSPI)];
utemp = -((utemp * umag) >> 6);
vtemp = -((vtemp * umag) >> 6);
wtemp = -((wtemp * umag) >> 6);
The extra multiplication of the magnitude to get the sine waves in the right place is gone. So is the bulk offset. All that's left is a negative of the magnitude times the sine value. (Don't ask why it's negative...you don't want to know.) This manipulation gets the interrupt routine down to a size where it can actually run at 15kHz...barely. The processor utilization is up near 60%:


This signal is high when the processor is in a PWM interrupt executing the above block of code.

Of that, roughly half of the time is spent just doing the six multiplications. There are tricks for fast software multiplication, but only if one of the operands is known a priori (not the case here). The sine table look-ups, as fast as they are, also take up some time. The adds and shifts are relatively small contributions. Amazingly, though, this actually works. Try getting your computer to do anything when its processor is being utilized by background processes 60% of the time. (Okay, dual core...I know...) But this can still execute a slow loop with control and data acquisition functions and read in more interrupts from the hall-effect sensors. It's still a little quirky, but it didn't collapse in a mess of horrible interrupt stack Jenga blocks like I thought it might.

But...it can actually be even more efficient. The key observation is in the nature of the outputs, a balanced three-phase set of voltages. This type of output only really has two degrees of freedome...magnitude and phase. So you should really only have to look up two numbers, right? (Can you see it coming?) If you add the sine of any three angles separated by 120º each, you get zero. Try it. Or have Wolfram Alpha try it. Here's my proposal: Look up and scale two sine values per motor. The third is the sum of the first two, negated. C = -(A+B). W = -(U+V). It's a bit more complicated because of magnitude offsets, but if this offset is calculated based on the magnitude in the slow loop, it can be simply added to the third value:
uidx_int += uspeed;
uidx = uidx_int >> 8;
utemp = SIN8LUT[uidx];
vtemp = SIN8LUT[(unsigned char)(uidx - TWOTHIRDSPI)];
utemp = -((utemp * umag) >> 6);
vtemp = -((vtemp * umag) >> 6);
wtemp = utemp + vtemp - woffset;

aidx_int += aspeed;
aidx = aidx_int >> 8;
atemp = SIN8LUT[aidx];
btemp = SIN8LUT[(unsigned char)(aidx - TWOTHIRDSPI)];
atemp = -((atemp * amag) >> 6);
btemp = -((btemp * amag) >> 6);
ctemp = atemp + btemp - coffset;
That's two fewer table look-ups and two fewer multiplies. The resulting interrupt should run 30% faster, giving back valuable clock time. Again, don't ask why everything is negated...

That's a far stretch in the name of efficient computation, but I assure you it makes a difference. Although everything seemed to be more-or-less working even with the bulkier interrupt. It's always good to write simple code, for many reasons. Which reminds me of another good one:



Yep, finally ran out of program memory. And I sure as hell am not going to buy the $N,000 full version of IAR Embedded Workbench. For the record, no compiler is worth that much money. It's not like Solidworks or some specialized simulation program that costs a lot of money to develop. It's a f*cking compiler. It takes C code and makes assembly code based on a set of well-understood standards. Even if I were using it for a commercially, it would be more worth my time to get a free GCC compiler and learn how to use Eclipse. Screw you, IAR. But I love your free version. :) So I will just have to keep my code size down.

Now might be a good time to step back and ask what the heck I am doing. Optimizing this one timy bit of code is a long way from making a new sine-commutated motor controller, and I have a long way to go before I can say I've finished the latter. But with the sine wave generator running at 15kHz in the background, all that's really left is to integrate the Hall effect sensors and some sort of master control loop.

The Hall effect sensors are really easy...dare I say easier than they are with the normal six-step commutation scheme where they drive a state machine. When a sensor hit comes in, you abandon whatever position you were at before and jump to the "correct" place in the sine table. "Correct" is tricky, and this is where a phase offset can be added in. But for now, I will rely on the scooter's moveable Hall sensors to make this work. The other piece of the puzzle is to set the speed of advance through the sine table, aspeed and uspeed in the code above. This is done by (carefully) estimating the time of one electrical cycle, which is six Hall effect transitions or in this case 1/7th of a revolution. I say carefully because this breaks down at low speed and also can be "glitchy". So there is more software work to be done here.

Lastly, the master control loop. This is where the high-level implementation happens. Eventually, this will hopefully measure and control both the quadrature- and the direct-axis current. The quadrature-axis current is the current that actually pulls on the magnets, creating torque. The direct-axis current can be used to change the torque-speed curve by countering the magnets, but I doubt this will make much difference for the scooter motors. Anyway, there is still some work to be done before this method of control is fully functional. For now, it is easy enough to create something that works by just controlling some semi-arbitrary current measurement, or even just running it open loop. This is where I am now...testing the subsystems to make sure they are working reliably before I integrate everything in the master loop.

But that didn't stop me from trying to ride it. The most noticeable difference (besides the fear that it might jump out of the program loop and short the motor at any moment) is the reduced torque ripple. You can actually hear the difference between DC (six-step) operation and AC (sine wave) operaiton. Okay, maybe you can't really hear the difference...but that's mostly because my microphone is terrible and the sensors were still not quite in the right place in either case. But there is definitely less high-frequency noise. If you don't believe me, believe MATLAB:

I promise I will do a better job capturing the results in a future update. That is, assuming I don't go crazy from debugging software. It's usually not my favorite thing to do. There's some fun in squeezing every last drop of computational power out of this thing, but I would still rather be making something tangible. Although in the end that's what this is for, so that's one plus. And if things go downhill, the old controller worked perfectly fine. Which...hrm...why am I doing this again?

I also promise a massive technical write-up for anyone who is interested in how this thing actually works. Ha...funny...nobody cares about controller. But there will be a write-up nonetheless.


Friday, November 6, 2009

SMMA Fall Technical Conference - Wrap-Up

Well, I don't really have any new pictures, so here's some dessert.

Yesterday wrapped up my trip to the SMMA Fall Technical Conference and I failed to update the "live blog" (which I have decided never to do again) mostly because I spent many hours in the airport and on a plane. But anyway, I am back in Cambridge now. The trip was definitely a good one for me. I expected to learn a lot, and I did. Here's a few things that I came away with:
  • The electric motor industry is very big, reaching out into many markets. The biggest ones seems to be industrial (big constant duty induction motors) and automotive (little accessory PM motors, not traction). But both of those markets took a big hit. The "new markets" are renewable generation (wind) and automotive traction. Almost everyone identified these markets, but few have stepped into them yet, it seems.
  • There was a very interesting idea proposed by EMERF for a pre-competitive research consortium that could maybe focus on some of these new markets, or on PM issues. The thing that comes to mind for me is the FEMMulator. Here's what I mean: The "industry" is slow, and built on a large pool of experience and expertise and data from existing designs. And then there's the FEMMulator...a free program that one person wrote to run an iterative FEA design simulation on a brushless motor. Here's the "disruptive technology," except instead of a technology it's really more of a disruptive methodology. The idea that anyone can get access to enough information and computing power to design a motor these days means that the process is different...and a collaborative research intiative seems to make sense, IMO.
  • On the technical side, there are a lot of things I know now that I will have to look at more closely. For one, segmented drive PWM. I thought I knew all there was to know about PWM in an h-bridge or inverter, but apparently not. So I will look into the more interesting methods and see if they could be applied to my controller at all. Also, there is a commercial sensorless zero-speed-start BLDC controller available call the DPFlex, from Agile Systems. It uses variations in inductance to measure starting position of the rotor. I knew this was possible and had been researched, but it's interesting to see one in production. I wonder if I could get my hands on one for cheap...or else it's good at least to know that it exists.
  • There were also some ideas that were met with a bit of skepticism. There was QM Power, which, well I understand where the skepticism comes from. I actually thought their presentation was pretty good, but after going back and reading their website...their idea is either ridiculous or they do have a clever breakthrough and need to fire their entire marketing/promotional team for making it sound ridiculous. There's also a clever idea for a harmonic drive motor, which is like a harmonic drive gearbox but without the strain wave generator...you use electromagnetic forces to move the spline. That one is really clever, and it would certainly work. The question is how efficient it would be. But it would be great for robot actuators, etc.
  • I got some good feedback on the axial motor concept. It's fairly unique even among axial motors, and most people think it could get very good power/torque density. Interesting to see how it works out.
That's pretty much the wrap-up. Lots of new contacts and lots to think about. It was an good trip for me and I think the presentation part went pretty well. (Nobody asked about the segway...so that's good...) As promised, a link to the presentation I did (minus videos) and also to the paper. (Overview of the Summer Engineering Workshop with emphasis on the BWD Scooter project, with cool pictures of course.)

Tuesday, November 3, 2009

SMMA Fall Technical Conference - Day 1

Today was the pre-conference workshops day, and that meant a four-hour course on "Fundamentals of Brushless Motor Control" for me.

Oh boy.


Despite the 8AM-ness of it, I got a lot out of it. It was just the right level for me...stuff I had seen before but don't full understand yet. Hence the reading material. That's the kind of thing that will keep me entertained for quite a while.

For one, I learned that there are more ways than I knew of to drive a PWM signal in an h-bridge or 3-phase bridge. I don't really understand some of the more clever ways yet, or the differences in performance, but it's something to look into in the controllers I build.

Other than that, today was Essex Active plant tour day. I learned what a slot wedge is:

A slot wedge.


It's a wedge that goes in slots. (Motor slots, of course.) It can be made of many things, including Nomex. The windings presumably go inside the wedge. And presumably the wedge is a tad longer than the slot. So the windings never touch steel. Genius. I wish I had some when we were winding the scooter motors. Oh well.

My table-top demo is ready and I will be manning the post early tomorrow morning. Then in the afternoon I present, right before AC Propulsion... Moderately frightening. More pictures tomorrow when that's all over with and I can relax a bit.

Monday, November 2, 2009

Live from Chicago: SMMA Fall 2009 Technical Conference

Here goes my first-ever attempt to use the blog in semi-real-time.

This week, I am in Chicago for the SMMA Fall 2009 Technical Conference.

The SMMA is "The Motor and Motion Assocation." (The 'S' is silent.) Actually it used to stand for the Small Motor Manufacturer's Association. I wonder if I can get it changed to the "Scooter Motor Manufacturer's Association." Probably not. But anyway, you can find more information on the SMMA, which serves as the trade association for the electric motor and motion control industries, here: http://www.smma.org.

I am participating in the conference thanks to support from the Electric Motor Education & Research Foundation (EMERF) which, as the name might suggest, is right up my alley. This foundation supports and promotes academic, pre-commercial electric motor R&D, as well as educational initiatives in the field of electric motors. More information is available here: http://www.emerf.org.

This all has to do with the BWD Scooter project. Since we had the completely original, not ripped-off at all idea of making brushless hub motors for a kick scooter, I made a contact at Proto Laminations who is also a member of the SMMA/EMERF. Having now actually made brushless hub motors for a scooter, I am going to present it, or, I guess, present the Summer Engineering Workshop and its fleet (yes, fleet now) of vehicles. Of course, the scooter is the only one that's in any way portable:

I did say "in any way."

And since it is generally not acceptable to ship/check/carry batteries that you made yourself, the A123 pack has to stay at home. But cordless drills (and their batteries) are totally fine:

All Tech men carry batteries...and cordless drills.

Ok TSA? So back off. Or don't:

Not surprising.

Actually, the trip out went smoothly. Actually, very smoothly. Actually, it was the single most coordinated thing I have ever seen at an airport. A full 50 minutes before the scheduled departure time, we were told to board the aircraft as quickly as possible because they were going to try to beat a storm. ~40 people got on and sat down, the jets spooled up, and we did a rolling takeoff 20 minutes early. Amazing. I honestly don't see what all the complaining is about air travel...

As for the scooter, it survived. Or wait, did it!? Why does the rear motor feel like it's got Jello in it? This is usually a sign of a phase-to-phase short, which, if you've ever shorted the leads on a PM motor, you know is electronic braking. Well, this was a scary few minutes of wondering if the phase windings somehow shorted during transport. But the problem was a lot simpler apparently:

?


Well, actually, I have no idea what the problem was. But I know what the solution was:

  1. Remove strain relief zip-tie.
  2. Replace strain relief zip-tie.
Problem solved. I don't really want to know what is going on. At least it's not inside the motor. I just have to not mess with it for the next three days. Did I mention that I hate live demos? This is why I obsessively video tape everything while it's working. And why I brought a soldering iron...just in case. Also, the non-functional switch broke:

:(

But since it was non-functional, I guess it's okay.

Anyway, tomorrow I am taking an early-morning brushless motor control course where I might learn just how wrongly I've been doing it. So sleep may be in order. My presentation is on Wednesday, and I will post the slides right after. (But by now, you probably know what to expect.) And, of course, I will get to see all the other demos and presentations. Pictures and updates to come.

Thursday, September 10, 2009

What's Next: 3ph Duo Controller

Fall '09 is under way with an interesting set of old and new projects on the horizon. The most immediate is yet another motor controller - version 2.0 of the 3-phase brushless series and version 7.2? or something of the modular half-bridge design. A brief history:

Version 5, oddly enough not pictured, is the only one that has never blown up on the go-kart.


Version 1.0 of the 3ph brushless controller, after a bit of troubleshooting, works just fine. It's actually overkill for the application, namely driving a 500W in-wheel motor for the B.W.D. Scooter. The motors can handle a peak current of about 20A. The v1.0 controllers, fans enabled, were tested to handle 75A for 45 seconds on a single phase before the MOSFETs started to desolder themselves. Divide that up between three phases and you get something that would probably handle 75A continuously. Combine that with 48V-compatible MOSFETs (75V rated) and you get a 3.6kW controller...for 500W motors. However, overkill alone would never make me design a new controller. The biggest problem is this:

No Step.

Despite my best efforts to make this more compact than any controller I've designed before, there just isn't enough room for two of them on the scooter. The only solution was to have them stick out through the deck. This is bad for a few reasons: One, it takes up foot space and is going to get has gotten stepped on. Two, it just looks bad. The whole point of putting the motors in the wheels and the batteries under the deck is to make it look as compact and normal as possible. Also, stacking two controllers on top of each other makes one of the fans completely useless. (The fans, along with almost every other component that wasn't soldered down, get beaten up pretty badly due to vibration, too.)

So, the challenge for v2.0:
  1. Run both motors in current/torque control mode with a single controller.
  2. Maintain at least 40A continuous current capability on each motor, at up to 48V. Two 1.9kW controllers on one board will make it actually more powerful than a single v1.0 controller.
  3. Maintain the same x-y footprint as v1.0, if not smaller. This was easy: Eagle doesn't allow you to make boards larger than 80mm x 100mm.
  4. Shrink the maximum height so that everything fits within the scooter deck. This means the entire controller must occupy less than about 1.3" (35mm).
  5. Maintain the existing modular half-bridge driver design. It's optically isolated and I know it works. There are smaller, cheaper ICs that will do half-bridge drive, but now is not the time for radical design change.
  6. Maintain the ability to record and transmit data.
Notice that cost is not an objective? That could be bad... But here are the commercially available alternatives:

The Turnigy Sentilon 100A HV. Ok, I will admit this is impressive. It is one of the most beastly high-voltage hobby RC controllers out there: 100A @ 50V. That's a 5kW controller in a 60mm x 60mm x 11mm package. And it actually wouldn't be that hard or space-consuming to add a current-controlled feedback loop around this. (As-is, it only does voltage/speed control.) But it's not sensor-commutated. Meaning, startup torque will suffer. How much, I don't know. And keep in mind that despite the massive power, it still only runs one motor. Cost for two: $232.

The Kelly KBS48051. This is the cheapest serious-business EV brushless controller you can find for 48V. It can handle 20A continuous, 50A peak for one minute, so about 1-2kW. It is fully current/torque controlled with hallf-effect sensors and regen. You can program it, although getting real-time data off is a different story. The down sides: It's the same size as my v1.0 controller. And still, only one motor. Cost for two: $200.

Okay, down to business. The first step was to find a new MOSFET solution. As much as I love the IRFB3077, there is just no way 12 of them will fit. The key discovery was an inexpensive, integrated three-phase bridge module: The IXYS GWM series, specifically the GWM100-01X1-SL, which is the only one in stock anywhere (Arrow Electronics).

IXYS GWM100-01X1-SL


At $21 each, these replace six IRFB3077s at $2.79ea. I consider that a fair trade. Specifications-wise, they have about twice the resistance per FET (7.5mOhm), but also a higher voltage rating (100V). They are rated at 1.3K/W with a proper heat sink, which is about the same as the IRFB3077, except that these share a heat sink tab. I doubt they will match the performance of the 3077s, but 40A continuous per chip should be achievable.

The other key discovery was that I only need one MSP430F2274 microcontroller to generate all six channels. It has four output-compatible timers, but each timer is mulitplexed to two pins, so really there are eight available output pins that can do high-speed PWM. And there are only really two independent PWMs required (one for each motor). It should have no trouble handling the extra hall-effect encoder interrupts, too. The only real worry I have is the 4kB code limit imposed by my free version of IAR Embedded Workbench. Here's why:

Not a lot of space left.

If the code to control one motor costs 3,255 bytes...and I need to control two motors... Well, I tend to just assume that all software problems can be solved. Realistically, most of the code is overhead that doesn't need to be repeated. But let's just hope that they know that 4kB is 4,096 bytes, not 4,000 bytes. I will probably need those extra 96.

Ugh, why am I such an EE? New MOSFETs...software constaints.... WHAT ABOUT FITTING THE WHOLE THING INTO THE DECK? Which, I believe, was the original point of all this. Here:

It..

..fits..

..in..

..the..

..deck.

The IXYS FET modules get thermal pasted to the aluminum deck, which should make an excellent heat sink. Wires get soldered in directly like in the Turnigy - no more bus bars. The single MSP430F2274 controller board gets a new home dead-center. All the gate-drive circuits have been made surface mount and take up both sides of the board now. The 15V switching regulator and associated inductor are surface mount. The only thing that can't really be made smaller are the current sensors...but they are in the right place now, at least. The result: the board occupies only 1.2" of vertical space.

And the final cost of components? Let's see... $42 for the FETs + $23 for the MSP430 board + $32 for the radio + $73.50!!! for six isolated high-side supplies + $31.62 for twelve optically-isolated gate drivers + $32.74 for two current sensors + $8 for the 15V supply + $25 for misc passive components and connectors. $270. No, I didn't count the cost of circuit boards. But I'm only building one. Extrapolate to high quantities and the total cost here isn't that bad.

I'm sort-of hoping it just works. The only major hardware changes are the MOSFETs and the placement of the current sensors. The most likely failures are actually on the software side, since I changed so many of the pins. I tried my best to think through the pin assignments, but there's always the chance that I missed something that will result in a disappointing, smokeless failure. If so, there will have to be a version 2.1...

I'll post the new schematic after testing.

Sunday, August 23, 2009

It Coexists.


I guess I'm not very good at this whole "documentation of incremental progress" thing, but anyway the B.W.D. Scooter is done and it's probably time to write up my build report. (The official documentation is now on the web, in our usual single-obnoxiously-long-page format.) This is merely my personal take on the project.

If you remember, this is round three of the Edgerton Center Summer Engineering Workshop, a unique educational program in which I get told what we are to build by a group of insane high school students. (To be fair, most of them aren't really in high school anymore, they're all off to college now to actually learn.) So maybe it's not an educational program; maybe it's more of an ad-hoc group with similar interests in things that move. Either way, good luck finding a better project team anywhere.

Oh, right, the scooter. Well, I wanted to build The Magscooter, a scooter that uses the Magmotor S28-150, a three horsepower motor famous for its utter combat-robot-propelling power in a light-weight package. Imagine that belt-driving a Razor scooter wheel. It would be the definition of overkill, and we could have built it in a matter of weeks. Except I was told that not only is that a lame idea, but also that I am unimaginative, boring, and risk-averse. So the idea for the B.W.D. scooter was born. The Summer Engineering Workshop crew decided to rip off Charles Guan and create a scooter with not one but two integrated wheel-hub-motor-things.

Wheel-hub-motor-thing. (Charles Guan's Project RazEr)

It turns out that it isn't all that hard to build a motor. To get it inside the wheel, the name of the game is brushless. The stator, with coils of copper magnet wire, sits stationary inside the wheel. The rotor, with permanent magnets, spins around it, held in place by side plates with bearings. This "outrunner" configuration is common in computer fans, hard drives, and model airplane propeller drives. There is also a lot of online documentation on how to re-wind or otherwise build custom BLDC motors.

Except...what do fans, hard-drives, and airplane props have in common? They see their highest load at high speed. Direct-drive BLDC motors that spin up to N,000 RPM make total sense for these applications. A scooter (or other electric vehicle), on the other hand, needs low-end torque, and a lot of it. And with hub motors, there is no gear reduction.

Turns out there are two keys to getting low-end torque from a motor. One is good control, which I already spent some time ranting about. The other is squeezing as much Lorentz force (F=ILB) as possible out of the motor geometry. (Ok, it's not really Lorentz force when you have steel carrying flux...but whatever.) It boils down to a good deal of current (I), a relatively wide motor (L), and many large, strong magnets (B). We started with the magnets, opting for the 12-slot/14-pole "LRK" style that Charles used. That gives plenty of surface area for mangetic interaction, and has the added benefit of reduced cogging torque because of the fractional slot:pole ratio, something we might have learned if we had paid more attention in Monaco. (Seriously...there was actually a keynote presentation about it.) Armed with the basic idea, we generated a design:

Don't you wish your CAD software could do that? (Render credit: Max H.)

Wow that looks really hard to make...even with six abrasive waterjets. But what we lack in Charles' extreme fabrication skillz, we make up for in the ability to get other people to give us nice things for free. Like, for example, laser-cut M19 steel laminations:

Stators not to be used as ninja stars.

These parts were generously donated by Proto Laminations, a company that specializes in producting low-quantity prototype motor laminations from electrical steel. The purpose for lamination is to reduce the circular eddy current that can flow in the steel as a result of the changing magnetic field. For us, the added benefit was the ability to design the motor exactly as we wanted. The biggest design feature this allowed were the small indents on the rotor for placing rectangular magnets. This saved us countless hours of aligning and gluing them in place.

That's not to say we didn't get to use the waterjet at all. Turns out winding magnet wire around sharp steel corners is not the ideal way to make a motor. Covering said corners with electrical tape also doesn't help much when you have to keep a lot of tension on the wire just to keep it wound tightly. Red fiberglass and abrasive waterjet to the rescue:

Who says you can't cut fiberglass on the waterjet?

These slightly oversized stator replicas prevent the wire from digging into the steel corners. They also look sick, and match our color scheme. But wait, they're inside the motor, right? So nobody will see them. Unless of course we already had planned to make the motor sides transparent. Seems stupid, right? Why waste all that flux out the sides and risk the entire structural integrity of the wheel for the ability to see inside? You'll see...

But first, the windings. How did we know how many windings to put? Too few and your torque will suffer...too many and the back EMF generated will limit your top speed. Too thin and the motor won't be able to carry enough current. Too thick and winding them will be very difficult. There are four ways to deal with this question, and we did all four:

  1. Copy someone else. Charles put 25 turns per tooth. We decided to wind every other tooth...so we should have a bit more.
  2. Try to do math. Well, we tried.
  3. Simulate. FEMM to the rescue. Pretty...
  4. Just freaking build one. The only real unknown is the "geometry factor" that is defined by the shape of the motor and the placement of the magnets. Motors are forgiving. The chance of making one that just completely doesn't work at all is very slim. So we built one with a low number of turns, 30, and then measured its performance. Turns out it was not far from where we predicted, but we wanted a bit more torque and less speed. So, with the geometry factor solved for, all we had to do was adjust the number of turns accordingly and we would know exactly the specs of the second motor. Single iteration; the high torque motor got 45 turns.
So now we have these two motors that are identical except for the number of turns per phase. Lots of interesting possibilities now. Do you run both at the same time? One for acceleration and one for top speed? How do you manage the transition? What's more efficient? Well...questions for later. For now, we put the high torque one in the back and the high speed one in the front and just send the same throttle signal to both. The torque adds and the speed averages out.

We made these?


Here's where anyone familiar with motors will criticize: Wow, even the high torque motor (left) isn't even half-full of windings. That could get so much more power with every tooth wound or with thicker wire. You try hand-winding a motor. But otherwise, I agree, it just looks weird. Most motors are packed full of copper wire. These could probably be two-horsepower motors if the winding density was better. But the math, simulation, and actual real-life test drives all confirm that these have plenty of torque for a scooter and they operate fairly efficiently, so the battery will last a good ways. Remember, more windings = more power, but the power still has to come from the batteries.

As for the efficiency hit, well I though this would be a problem too but it turns out that at low current (and by low I mean 20A), copper losses are small and interesting things start to happen to the efficiency curves. The benefits of brushless, low-speed, low-friction operation start to make even these hand-built motors seem like good alternatives to things like the Magmotor.

Well now that doesn't seem bad at all.

Okay, so the sparse windings don't really hurt much. What about the flux that leaks out those plastic sides? That must not be good. Well...since the stator is only 1" wide, centered in the rotor, I'd guess that the flux that counts is in that 1" band, where it is still quite straight. The flux leaking out the sides wouldn't be doing much other than short-circuiting to the other side of the magnet, even if the sides were steel. Not convinced? Still think something is being wasted? Okay, let's capture it and use it as a signal for the motor controller.

External hall-effect sensors!?!???


Yes, I wish we could say we planned this the whole way. Actually, we were originally going to use an optical encoder track. (Because the motor is brushless, the controller needs some way of knowing where the rotor is to control which coils are active.) But after noticing that the wheels had a tendency to pick up loose hardware off the floor, we though that perhaps there might be enough of a field coming through the sides to use hall-effect sensors. Many brushless motor have embedded sensors, but having them on the outside is actually extremely useful. You can find the right position very easily by rotating them with respect to the stator while testing the motor. You can also make minor tweaks to the torque/speed characteristic by rotating them.

So with the motors taken care of, we had to actually build the scooter itself in just about three weeks. Not a problem. Since there's no gearing or anything, it's really just a matter of making a frame with some forks to hold the two wheels. The deck is some folded 1/16" sheet aluminum. The rear fork is pretty straightforward:

Bandsaw clamp forks.


The front was a bit trickier, since we decided to work with the existing Razor scooter handlebar. Since the wheel is significantly wider and larger in diameter than the original wheel, we had to add an offset fork:


Front fork and steamroller wheel.


That's it right? Oh wait the batteries! We acquired a pack of A123 26650 cells, totaling 33V and 4.4Ah. Interestingly, when laid flat, they have only about 30% more energy by volume than a lead-acid pack. But they weigh a good deal less and most importantly they can source immense amounts of power for their size thanks to extremely low internal resistance. Cramming them in the deck was interesting...

Batteries in all the available space under the deck.


One thing we do pretty well is make things look good. That's where the carbon fiber deck and red LED trim lights come in:

And there you have it...

So that's it. It's not without its flaws. The urethane is being held on by "Plastic Steel Steel Weld Epoxy," which didn't last long. (The rear wheel tread came off once already.) The front of the deck needs reinforcement. And the whole thing is in serious need of some more nylon lock nuts. The vibrations are killer, especially in the ongoing roadwork nightmare that is Cambridge. But overall, it is functional and fun to ride. It's lightest and most compact of our fleet (yes, it's a fleet now), so it will probably see the light of day a lot more.

What have I learned? Motors are forgiving. Controllers are not, but if you overdesign them they might survive. Vibration sucks. Vehicles that carry seven times their own weight are awesome. Scooters are fun to ride. Make two of everything. Most importantly, probably, do something fun with a good team and you really can't go wrong.