Thursday, July 21, 2011

tinyKart: Round 2

Round 2 is all about putting together the steering things:

These things.
But first, armed with many more t-nuts, we finished putting together the lightweight 80/20 frame:

It's more like 0.75-scale kart.
Next up, pressing 1/2" ID bearings into the steering reinforcement wings, a.k.a. the "cool parts":



Easy so far. The moving assembly includes a front wheel, brake disk, brake caliper, and a control arm (not shown in the above picture because it's between the chassis plates). To hold all of this together, there's a little bit of 1/4" plate jigsaw puzzling:


The control arm doubles as a support for the lower thrust bearing. It, and the upper thrust bearing support, slip (press) into what would normally be called the upright, if it wasn't so short not-upright. I'll just call it the shaft mount. Then, three 4-40 screws pass through the shaft mount, the upper thrust bearing support, the shaft mount again, and finally thread into the control arm.

Like so.
I guess I forgot one important step (in real life, too, the first time): First, the 1/4-20 cap screw that threads into the front wheel shaft must be in place, with its head in the relief cut in the top and bottom thrust bearing supports. So far, so good.  To properly align and stiffen the thrust bearing supports, three countersunk 1/4-20 screws with plastic spacers pass from top to bottom:


The image above also shows the brake caliper mount. The brake calipers will need some shimming, but they're at least located to within a few millimeters axially. No major machining or design mistakes there. Finally, we attached the front wheel shaft. This requires removing one of the screw/spacer combos and shoving a hex key in between the thrust bearing supports. It's kind-of a pain, and we don't want it to come loose ever, so we Loctited the shit out of it.


After the two front wheel assemblies were together, we had to ream the kingpin holes since (a) they were undersized to begin with and (b) there's nothing really aligning the top and bottom thrust bearing supports. Luckily, we bought a 0.499" reamer two years ago for reaming BWD's stators, and it hasn't disappeared.

MillKart
The kingpins were quickly fabricated from 1/2" 7075:


The result is a tight fit to the 0.499" hole, but not so tight that you can't force it back and forth with a rubber mallet. And it's a slip fit in the two "cool part" bearings. Those are the radial bearings that support the bending load on the kingpin, but there are also two needle-roller thrust bearings:


And then the top plates complete the sandwich:




The end result is a nice, stiff steering pivot with radial and thrust bearings on top and bottom.The frame passes the "stand on it" test, though it is a little more flexible than I thought it would be. We'll see how it changes with the added structure from the seat mounts. Total weight of the chassis so far is 21.5lbs. Still have the entire powertrain to add. The good news is that the controllers are a bit lighter than expected, so 50lbs still seems within reach.

Next up: steering linkage, motor mounts, and controller testing.

Monday, July 18, 2011

DirectDrive v1.0: 2.4kVA Test

After my ducted fan load tester turned out to be basically unworkable, I decided to go back to lower-RPM motors. This way I'm not simultaneously testing the controller's basic functionality and the ability of my FOC algorithm to handle greater than 1,000Hz electrical frequency (it can't).

The first candidate: a re-wound and sensored Turnigy 8085-170 motor:


Well this pretty much didn't work at all. There's some issue with the sensors that makes it sound horrible, and also it's too small to be able to sink a lot of power internally.

I decided to stop when the hot glue holding the sensors in started melting.
Anyway, that was just a little distraction before the real show:

Eeeeeteeek.
The Mars PMAC (brushless Etek) is probably my favorite load-test motor. It's so big that you can't really hurt it, at least not in the time scales of a bench test. I put the DirectDrive controller on its edge to give the heat sink a tiny bit of natural convection, but no active cooling for this test. I wanted to see the temperature rise. Nice, steady temperature rise, and no spontaneous FET destruction.

Now here is where it gets interesting. Short of coupling it to a second Etek, there's not much I can do to apply mechanical load to the motor. (At least with the ducted fan, I had a way of doing so.) So, instead, I brought the motor up to speed under ideal timing conditions, i.e. manipulating the phase of the drive voltage until the current draw is at a minimum. Then, at nearly full voltage amplitude, I threw the timing way off so that the motor begins to draw 100A (phase peak).


And I let it sit that way for one minute. The phase voltage is a sine wave with an amplitude of 16V. The phase current is a sine wave with an amplitude of 100A. But...they're not in phase. So the real power is still low, but the apparent power is 2.4kVA (1.5*100A*16V). The good thing about this load is that it can all be run off a bench power supply, no need to break out the giant batteries yet.

But is it actually a representative test of the controller? It doesn't really test anything outside of the bus capacitor, where the DC current is determined by real power only. But what I'm still not sure about is how it looks to the inverter itself. Here's what it comes down to:


The RMS current is the same regardless of the phase angle. The only thing that changes is the phase of the sine wave that the duty cycle traces out. But, the MOSFETs are still either blocking 36V or carrying their share of the current at any given instant. It makes sense, then, that both the conduction losses and the switching losses should be the same regardless of the relative phase of the current with respect to the duty cycle. Anyone care to confirm or refute this?

If that is the case, than I'm happy with the test results. A minute of running at 100A with passive cooling yielded a temperature rise of 15ºC. I would guess that the heat sink mass is about 0.25kg. If it was mostly just absorbing power (with no active cooling and very little temperature gradient, this is true), then a quick estimate of the power dissipated in the inverter is 24W, which is exactly where it should be for 100A.

More testing to come.

Friday, July 15, 2011

DirectDrive v1.0: First Three-Phase Tests

After provisionally solving the first big problem with DirectDrive v1.0, the current sensor coupling, it was time to port my three-phase brushless field-oriented control software over and do some testing on an actual motor. I decided not to bother with Pneu Scooter's hub motor, since at most it could handle 750-1,000W for a short period of time and I'm looking to hit 5-10kW peak. Though really it would be a better intermediate step than what I wound up using...

Nothing about this seems like a good idea now.
"Isn't using an electric ducted fan to load test a motor controller a great idea? It can sink tons of power and it cools itself!" Well, that was the original thought anyway. This is the giant 120mm EDF from Hobby King, which can produce upwards of 4kg of thrust (the same as KM Scooter's eight blower fans...combined). They're meant to be used in model jets, but you could probably do other things silly things with them if you wanted. I bought one specifically for load testing, since they're only $43. Mine uses a this 4030-1100 motor.

With this load tester, I thought I would try something new for sensing rotor position. I printed out an optical encoder disk with eight black and white segments, which I double-side taped to the back of the motor:


And I used a three-phase set of infrared optical reflectance sensors to pick up the signal:



These mimic the function of the Hall effect sensors I would normally use in this application. They differ in a few important and annoying ways, though. For one, they are analog sensors, producing a variable voltage in response to the relative reflectance of the surface in front of them. To get them to act as digital inputs, I have to set them up with a 10k pull-up resistor and put them at about 4mm from the encoder disk. Then, they produce a 4Vpp square-ish wave. But with a 10k resistor, the normal RC filter I would use on the Hall effect sensors won't work, so I had to swap it for one with lower capacitance. The net result is a sensor signal that is less precise and more vulnerable to noise than Hall effect sensors would be.

Back to that in a minute. First, I made the awesome copper heat sink a more permanent feature by drilling and tapping 4-40 mounting holes for it:



Notice that I still have the wires coming straight off the board in the direction that minimizes coupling of the two Hall effect-based phase current sensors. I set up the load test rig on what has become the Table of Load Test Rigs:

Notice the face-to-face dynamometer in the background.
The software on my laptop might look familiar. It's the same GUI and data logging setup I used for Cap Kart and Pneu Scooter - very handy tool. One thing that's nice about DirectDrive is that, for whatever reason, it doesn't cause my USB port to freak out when it's under load. So far I have not had to use the XBee radio to collect data.

I somehow managed to get the right sensor and phase combinations on the first try, and was happy to see that  the motor spun up nicely. The current sensors, temperature sensor, and other bits and pieces seemed to be working properly. But the motor was drawing way too much current, even no-load (with the fan rotor removed). By that I mean it was drawing almost as much current with the fan as without. Now, this is a load test, so in some sense that's good, but I would prefer the majority of the power to get dumped into the air, not the motor.

After a day of debating (grad student-ing), I decided that the most likely cause was the shady optical sensor rig. On a hunch, I took the data I had collected from the test run and did a histogram of the sensor states. There are six: 001, 011, 010, 110, 100, and 101. If everything is working properly, they should all occur with the same frequency.


If instead your sensor histogram is giving you the middle finger, well then you know you have issues. You can even figure out what the issue is with a little bit of logic:


The top set is what the sensor signals should look like if things are working properly. The bottom set has Phase A shifted left a bit. The result adds time to states 3 and 4 and removes time from states 2 and 5. And guess what:

That was exactly the problem.
I was able to tweak the position of the Phase A, and it definitely helped, but I think the motor still draws a lot more no-load current than it could if the sensor timing were more consistent. The edges of the square waves are also pretty soft, and I'm relying on the input pin Schmitt triggers to make it work. It only gets uglier at higher speeds.

Speaking of high speeds, there is another reason why this is a stupid load test. Thus far, the fastest motor I've run with my FOC code is the 40,000rpm 2-pole inrunner from my RC car. But at those speeds, the rotor position estimate starts to become imprecise and unreliable. Now this is a 20,000rpm 8-pole outrunner. The electrical frequency is over 1,000Hz. Trying to fit a sine wave at 10kHz onto 1,000Hz is almost useless. High speed FOC is an interesting problem, but not one that I want to solve simultaneously while load-testing a brand new controller design.

So, sadly, I may have to abandon my new load tester. It can get to high currents, since the motor has such a low resistance. De-tuning the timing by even a few degrees in either direction causes the current to quickly shoot up, even at low speeds. So I ran it at 50A, and nothing seemed to mind, but it's 50A at something like 6V output instead of the 50A at 40V output, which would be a much more interesting test. Unless I can get the fan rotor up above 10,000rpm, which isn't going to happen easily, there's just no way to get any power through it.

Time for a new plan.

Tuesday, July 12, 2011

tinyKart: Round 1

By popular demand, more picture of crazy vehicles, and less math:

Extrude...thin feature...mid-plane...
That's the size of tinyKart. So I don't know, maybe it's not really in the tiny class, more like miniKart. But whatever, we'll still call it tinyKart since it's going to be 1/5th the weight of Cap Kart.

Step one in the tinyKart fabrication adventure is the acquisition of a large amount of waterjet-cut aluminum plate. The front half of tinyKart is a sandwich consisting of two 1/8" plates with 1" 80/20 t-slot extrusion in the middle. In addition to this, the rear frame, motor mounts, steering system, and brake caliper mounts are made of a combination of 1/8" and 1/4" aluminum plate. None of the waterjets that I have access to can handle 30" lengths of plate, so the entirety of the plate stock was sent out to the Big Blue Saw. A week or so later,

Kit Kart!
It's always fun to see your 3D model almost instantly become a real thing.

Maybe we'll get in the 80/20 flipbook again.
The only problem is we ran out of t-nuts. But the frame is together enough to get a feel for the size. It's a good deal smaller than Cap Kart, but it doesn't look tiny. In other words, a reasonable person would probably call it a go-kart, not a tinyKart. But whatever.

The motors also arrived, so of course I took them apart:



I was a little disappointed, but not really surprised, by the overall construction quality. The magnets, which are the source of most of the negative reviews for this particular motor (Turnigy SK6374-170), actually seemed to be pretty well glued. But the windings are very loose and in fact on a couple of the motors, one or two strands of wire were sticking out into the air gap. So while the motors were open, I took the opportunity to epoxy all the windings in place. I also tested the resistance, and they were all right around 23mΩ, line-to-line, which is a lot lower than the specs say. And there were no shorts, so that's good.

The next order of business was to machine the shafts, which Max, et. al., made short work of:


These shafts are made of 6061 aluminum and the entire weight of the kart and driver are transmitted through them. They start as 3/4" stock and are turned down to 17mm to fit the special replacement bearings for the 8" scooter wheels we're using. The rims get sandwiched on and the shafts are bolted to the chassis with a single 1/4-20 cap screw.


The load carrying capacity of this configuration has been verified in simulation and also by the more scientific method of jumping up and down on it:


The rims needed only minor modifications: For the rear wheels, the brake mounting threads were machined off to make the overall width of the kart as small as possible. For the front wheels, the drive pulleys were machined off to save a bit of weight:



And the last little bit of machining for Round 1, boring out the steering reinforcement plates. These are the 1/4" plates that hold the bearings for the steering kingpins. They are probably the coolest-looking parts of the front frame. I decided to bore them out all at once, which Charles and I decided was a 2 on the scale of bad ideas from 1 to Eating at Bullet Train:

Turned out fine.
Here's the frame at the end of Round 1:


It's certainly come a long way since the tape version on the floor. But there's a lot more work to be done on just the mechanicals, including all of the steering system. To get a quick estimate of how we're doing on weight, I hung the frame and a box of many of the parts that are to go on it from my favorite shady hook scale:



17.63kg, or just under 39lbs, including the batteries and motors, and the weight of the milk crate.. What's missing is only the seat, four tires, the two motor controllers, the steering column and wheel, the brake cables and lever, and any other miscellany that we decide we need. So, 50lbs looks tough but still possible.

Tuesday, July 5, 2011

Sensorless FOC: More Analysis

I've been away from hardware for a (much needed) week off. But whenever I'm away from hardware, I inevitably start to think about software. So for the last couple of days I've been going back over all the references I've collected for sensorless field-oriented control, partly to refresh my memory, partly to categorize and compare them, and partly to choose one to actually implement.

I feel like this is where I should make fun of myself for being a grad student and spending all my time thinking about the solution instead of actually solving the problem. But I think in this one particular case, the analysis time will pay back many times over if I correctly choose an approach that will actually work as opposed to one that only works on paper, with properly-chosen gains, and ideal current sensors, and a perfect system model, and on a Wednesday with low relative humidity.

First, a baseline against which to compare any potential solution: In the post where I first looked into sensorless field-oriented control, I put up the following bit of motor math:


This shows how you can estimate the back EMF or the flux linkage using only the voltage applied to the terminals of the motor and the measured current. You can do this on any phase of the motor to find the back EMF of that phase. The flux linkage will give a somewhat cleaner estimate in real life because it doesn't need the derivative of a noisy current signal. You can also convert all the quantities into vectors and find the magnitude and phase of the resultant flux linkage. The phase of the flux linkage is the rotor electrical angle, and can be used for field-oriented control.

The drawback of this approach is that it's entirely open-loop, which means it is heavily dependent on model accuracy. If the values for resistance or inductance are off, the estimate will have a magnitude and phase error, and the phase error will hurt the performance of the FOC. It's still a valid approach, though, and almost certain to be stable. So any alternative closed-loop approach must outperform this baseline.

The general idea of a closed-loop observer.

Last post, I had become a fan of Microchip AN1078's closed-loop observer, so I'll start with my latest impressions of that one. It's a sliding-mode observer, which in this case means that the thing occupying the Observer Compensator black box is just a comparator. If the estimated current is higher than the measured current, it feeds back +K, else, it feeds back -K. So, it's not a linear observer. The switching structure appealed to me because

  1. It's computationally easy, saving precious time in the fast loop that would otherwise be spent multiplying out linear observer feedbacks.

  2. It is highly noise-immune with respect to the current sensor signal. As long as the noise is unbiased (zero mean) and of high enough frequency, it will get drowned out by the switching feedback. This is a huge benefit since my controllers so far have had pretty crappy current sensors. 

The part that confused me about AN1078 is what the Fake Motor box does with the stream of +K/-K feedback. It applies a series of low-pass filters which magically produce the back EMF estimate, but doesn't show mathematically why this is the case. More disturbingly, it requires a "phase compensation" which is simply pulled from a look-up table. The explanation for this? "It is recommended that phase compensation be fine tuned for any particular motor." It might still be better than the open-loop estimate, but a true observer should not need phase compensation as a function of motor speed.

I decided that I won't be taken seriously as a grad student unless I run MATLAB Simulations for a significant portion of my life:

Microchip AN1078 in Simulink
That is Microchip's AN1078 observer implemented in Simulink, including the phase compensation (bottom left). It's estimating the back EMF on a single phase, but the same exact observer could be used to estimate the two back EMF vector components (often called α and β components). The values used for the motor model come from Pneu Scooter's wheel motor, since it'll likely be the first test of any sensorless FOC I implement. 

At first glance, AN1078 does pretty well:

Yellow: Actual back EMF. Purple: Estimated back EMF.
This is at at about 2,000rpm and 40A peak amplitude, with all model parameters accurately tuned. The phase compensation is taken to be the combined phase of the two low-pass filters at this electrical frequency. (Or, sticking with the Microchip plan, pulled from a look-up table.) The phase of the back EMF estimate is insensitive to current sensor noise, applied voltage phase, and a wide parameter variation of resistance. But, crucially, it doesn't seem to like error in the inductance parameter of the model. With the inductance set to 1.5x the true value...

Yellow: Actual back EMF. Purple: Estimated back EMF.
...the back EMF estimate lags significantly. The inductance is the harder parameter to measure, so an error of 50% or even more must be tolerable. Increasing the feedback gain can diminish the phase error. But now my threshold for tweaking has been crossed. The phase compensation table, the sensitivity to inductance variation, and the overall lack of explanation for how two low-pass filters produce a back EMF estimate have led me to question AN1078, even though up to this point it has been my favorite. Having tweaked it more than I care to, I went searching some more.

Some old and new references that only very few people would find interesting enough to read (I read them all):
  • Of course there is James Mevey's thesis entitled Sensorless Field Oriented Control of Brushless Permanent Magnet Synchronous Motors. Chapter 6 contains all the information one would need to do this, in the most general way, with a full-order linear observer. I understand the theory, and if I went back to my controls notes I could find information on how to place the observer poles in such a way to force the back EMF error to zero. It's just...a lot of linear algebra to compute in the fast loop. But this is my back-up plan if all other options fail...Mevey to the rescue.

  • Another approach, which Mevey references (Mevey references more papers than I have ever read...) is in a paper called "High performance PMSM drives without rotational position sensors using reduced order observer." It's an IEEE paper, which means I can't quite link to it. But the general idea is to skip the hassle of making an observer for currents, which are known anyway from the sensors. With only two states to track (α and β components of back EMF) the computation is quicker. I just don't know enough about reduced-order observers to be able to have an opinion on this one. Didn't I learn this stuff at some point?

  • I also found Freescale App Note DRM099, which has a much more thorough explanation of a sliding mode observer than the Microchip AN1078. Rather than magical low-pass filters, the Freescale approach sends the switching feedback into a full-state observer. It's a bang-bang version of the full order observer that Mevey presents. It also explains why the back EMF error converges to zero even in the presence of modeling errors, though it does not talk about how to set the feedback gains. It also has discrete time versions of everything, which is nice for quick translation to software. And no "phase compensation" table. This looks very promising.
But now, I feel like I am back where I started, just looking at examples of sensorless algorithms and trying to decide which one I like best. I guess I could really be a good grad student and run more simulations of each one, with a standard set of test cases. But I have a feeling any of them can be made to work with enough tweaking, so how should I decide?

Fuck it, I was bored in the airport so I just made my own:

Click to enlarge.
I stole the sliding-mode idea from Microchip and Freescale, but in this implementation I have abandoned just about every other aspect from the observers detailed above. Specifically, I don't want to do any coordinate transformations in the fast loop...at all. The way I avoided coordinate transforms when I was crunched for computing power in my first FOC implementation was to use a sine wave generator, which steps through a table of sine values with some given speed. So I'm doing the same thing here, generating the back EMF estimates for phases A, B, and C as a set of three sine waves offset by 120º in the table. 

The inputs to the back EMF sine wave generator are the magnitude and the speed, which are each compensated by the sliding-mode feedback with some gains, G1, and G2. The magnitude feedback isn't as critical, but it corrects for variation of the torque constant in the motor model. The speed feedback adjusts how fast a certain magical index steps through the sine table array. This behaves like a phase lock loop, shifting the back EMF until it is in phase with the true back EMF. Don't ask me to explain it in any more detail than that. Here's it starting with a 180º phase offset and locking in:

Yellow: Actual back EMF. Purple: Estimated back EMF.


The nice thing about the PLL effect is that it doesn't matter if the feedback is positive or negative. As with the AN1078 method, this observer is immune to sensor noise, applied voltage phase, and variations from the model resistance value. But, it also doesn't mind very much having the model inductance off by a factor of 2:

Yellow: Actual back EMF. Purple: Estimated back EMF.
It might still need some tweaking to get just the right gains, but at least there is no "phase compensation" table. It also abandons linearity and state space in favor of ease of implementation. The comparisons for the sliding mode observer occur on each phase individually, and in fact only one phase is needed to run the observer. With all three phase currents, an averaging effect should make it work even better. Another interesting possibility is that the table through which the back EMF generator steps need not be a table of sine values. It could very well be an table of measured back EMF values, which should improve the position estimate in the case of trapezoidal EMF motors.

Once again I've created something that I can't really analyze. Time to try implementing it in hardware.