Chibi-Mikuvan: Getting “Tired” of All This; Making the HCL Actually Function; Plus Other Work

As the Detroit Maker Faire and its attendant PPPRS race draw closer, Chibi-Mikuvan testing and modifications have been intensifying still! With each silly night testing video (when the parking lot is empty) comes more rework and rethought of the original design elements. I’m actually glad it’s all being done now, and things are being broken during testing now, because there are a handful of things on the design which are turning out to be bad ideas suboptimal for reasons like ease of maintenance, parts swapping, etc.

The story continues where it last left off: with my indoor testing of the Hysterical Current Limiter. I was gradually pushing the maximum current higher and higher and driving around while staring at the scope screen to get a handle on what kind of surge currents it was seeing with the error of the controller being quite large at low speeds. With the limiting code itself working, I began to implement the ‘time decay’ where the controller would keep track of how long it’s been running over a designated continuous maximum current, and then slowly lower the maximum allowed current over a few seconds to the continuous level. The idea of this would be to get more acceleration ‘punch’ but not risk blowing the fuse.

The way this code worked was that it counted how many loops (fixed delta-T, hence how many seconds) the current stayed above the continuous limit, and obtained a maximum current based on a lookup table with the delta-t count as the index. It would reset if the current fell back under the continuous limit. Seems simple, right?

//Obtain a current limit value for this loop
    if(delta_ts_overcurrent > 512) local_max_amps = MAX_AMPS_CONT;
    else {
      //an 500+ entry table would be overkill, so here we change the max current ceiling every 8 loops (16 milliseconds)
      //This requires only 64 entries [0-63].
      local_max_amps = MAX_AMPS[(delta_ts_overcurrent / 8)];
    }

    //Hysterical current limit algorithm
    //Unlike in Ragebridge, we only care about driving current, so the case of decrementing throttle quickly is not handled.
    if((amps_to_use > (float)local_max_amps) && limited_current) { 
      //local_max_amps = Either a fixed constant or obtained from a LUT
      throut -= OC_MULTIPLIER * RAMP_US_PER_LOOP;
      if(throut <= 1500) throut = 1500; //Don't go past neutral
      delta_ts_overcurrent++;
    } else {
      delta_ts_overcurrent = 0;
    }

That’s where the logic was flawed. Recall that the current waveform is messy. It’s a noisy sawtooth, not a smooth monotonic function. As I found out during testing, the chances that the current waveform goes under the MAX_AMPS_CONT value and therefore resets the lookup table index was almost 100% – when it worked, it was a bug.

I finally pushed it a little too far when doing a 120 amp launch (which could have seen errors as high as 200 amps, knowing the low speed performance). The current trace never sank, and I managed to mentally process that this was probably bad a few milliseconds before the fuse went out.

On dumb DC systems, a fuse-out will just cause everything to stop working. But this controller has regeneration ability – and for whatever reason, the failure mode of loss of battery input is “snap to 100% regen”. If the battery were present, a large burst of negative current will flow (into the battery) and I will faceplant through the scope screen. But without the battery there, regenerating into space just causes extremely high voltage spikes. I could smell the magic smoke coming from the ammo box right after stopping.

Fortunately, only the controller itself was toast. After resetting the power, everything else turned back on and still worked. Unfortunately, digging the controller out of the box is a 15+ minute service job. In the field, this was going to be intolerable. Furthermore, I now had a serious problem. A fuse-out is guaranteed controller death, so I have to keep the overload bursts conservative with the consequence of reduced acceleration.

I first turned my attention to the code. It took me a while of thinking to recognize the problem I described with it, and then a bit more thinking about how to fix it.

//Hysterical current limit algorithm
    //Unlike in Ragebridge, we only care about driving current, so the case of decrementing throttle quickly is not handled.
    if(limited_current) {
      if((amps_to_use > (float)local_max_amps)) { 
        //local_max_amps is either a fixed constant or obtained from a LUT
        throut -= OC_MULTIPLIER * RAMP_US_PER_LOOP;

        //This causes the time-current curve to only reset if the current flow goes UNDER the continuous limit.
        if(amps_to_use > MAX_AMPS_CONT) delta_ts_overcurrent++; 
        //Don't go past neutral
        if(throut <= 1500) throut = 1500; 

      } else {
        //Even if we don't limit the throttle this go-around, only reset the time-current decay counter IF
        //the current has fallen under the prescribed limit, indicating you've let off the throttle
        //or have used the regen brake 
        if(amps_to_use < NOLOAD_AMPS) delta_ts_overcurrent = 0;
        else delta_ts_overcurrent++; 
      }
    }

Here is the new logic structure. A new variable has been added – NOLOAD_AMPS. This isn’t a “no load” current in the motor equation sense but rather a lower limit to the current limiter – at what point does it turn off and reset? Now, the delta_ts_overcurrent counter will continue incrementing as long as the current does not fall under this lower bound. I set NOLOAD_AMPS at reasonably low number to start – 20 amps. This is the correct implementation of the behavior I described firstly – that the limit will reset essentially only if I let the throttle off in the process of being about to brake, or after the vehicle’s reached cruising speed anyway.

(Notice the flag limited_current up to… You know what this means).

With the code fixed, now I actually had to fix the thing. I decided to implement a change that I had thought about since the Trackstar failed the first time due to its signal board falling off: moving it ouside, right next to the motor. This has the effect of creating a single swappable module that consisted of the gearbox, motor, and controller, so if something goes sideways in the race, it can be swapped with a spare entire unit in a minute and then someone else can take their sweet time fixing the failed unit later.

I designed a new motor mounting plate that has an added ‘tab’ where the controller sits.

…and cut it out on my mechanical waterjet. Wait, what? Yeah, I went back to using the Shopbot gantry router as a makeshift waterjet with an 1/8″ wide nozzle. There’s nothing really stopping this machine from cutting metal, but its limitations are twofold – one, it isn’t nearly as rigid as a CNC mill, and two, it doesn’t have any provisions for chip removal or coolant.

The solution to the former is to take light passes at aggressive feedrates – keep the tool cutting, but make the cutting forces tiny. I whipped out my old experimental setting from the last time I did this, and refined it a bit more. The final settings I used were 18,000 RPM, 125 inches per minute, and 0.025″ deep passes.

The solution to the latter is more complicated. Coated carbide endmills are great about not having build-up problems, but chip recutting (chips being sucked into the next pass) will easily kill the little 1/8″ endmills from past experience. I used a dual approach of slathering the area with Tap Magic Aluminum cutting fluid as well as keeping a compressor air gun handy to clear chips on every pass. I’m not as confident machining aluminum dry, because even a little bit of build-up can break the cutter – at the least, I think it needs a mist coolant system where a tiny bit of coolant is dropped into an air blast stream.

On the whole, it worked great. Here’s the tab bent into place after the holes were cleaned up. Mechanical waterjet!

And here is one of the spare Trackstars installed onto the tab. This is now the unit that I’ll make a spare(s) of and replace whole in the event of chaos. The Trackstar is also in a much better cooling position here, being in the airstream.

As I was extending the power cable coming from the contactor inside the ammo box, I had the idea of Adding More Buscap. Galactic amounts of bulk capacitance helps smooth the DC input rails by isolating peak current spikes from the battery (and hence current sensor) – this should help clean up the readings some as well as supply the controller with more stable power. I basically tripled the mount of capacitance for the controller here, with four 820uF capacitors. The 8 gauge short wire leads shouldn’t cause trouble since the ESR of the capacitors should still dominate the amount of current ripple through them, but ideally you’d want them as close to the controller as possible. This shit’s important – the inside of high powered motor controllers are basically made of capacitors.

The caps were bundled, soldered together, then the soldered legs bent over to attach to the wire. It was wrapped up in a heat shrink burrito.

With this setup, I verified that the ‘time decay’ element of the current limiter was indeed working, and we went out once more. The idea of these testing rounds was to get everyone on the team who might be driving (and we seem to have JUST enough people to have drivers, a pit money, and an event staff helper) to get some driving time in WHILE possibly breaking it so we can fix it ASAP.

The results of this test were fantastic – the current limit was still set rather conservatively, there were no fuse problems, and I think people are realizing what they got themselves into. The noise coming out of the gearbox at the end was indicative of future troubles. That test actually ended with the tapered input shaft of the gearbox pinion slipping once again – I came into the near turnaround with full regenerative braking, then suddenly the gearbox no longer output torque.

This was to be the last time the tapered shaft will bother me, because I’m done with this 1,1,1, Trichloroethane shit.

The spare angle grinders I bought (these) have input shafts with Woodruff keys instead of…. well, nothing.

I decided to prepare these for use in the vehicle and only keep the tapered-shaft gearbox around for emergency spares if all else has failed. The stock Woodruff key seemed to be a 3/8″ or 10mm one, which is a bit small for my tastes, so I bought some 1/2″ circle ones to upgrade the size.

I took a chunk of 12mm shaft and turned one end down to 10mm to mate with the bore of the gear…

I borrowed a little woodruff cutter to make the slot in the side.

The completed new input shaft assembly. This time, it even installs from the outside of the gearbox, so I no longer have to open it up to remove the input shaft. On the previous Harbor Freight gearbox, the plate holding the bearing in came with pre-stripped screws, so I couldn’t remove it. On this one, they were removable, but low quality, so I replaced them with M4 socket cap screws.

I did repair the previous tapered shaft gearbox. This time, I took care to clean up the taper where it had slipped in both gear and shaft. Then I drilled out the screws I couldn’t remove from the bearing retainer plate, freeing it up and allowing this gearbox to also be serviced from the outside. Then I put the gear and shaft on a 5 ton press and shoved until it could move no more. This gearbox will now be on reserve as the last-ditch backup.

I also finally made a lower battery bracket to prevent the half-sized battery from pivoting on the frame because it only has two coaxial fastening locations. This makes battery changes way, way easier.

With these modifications done, we had the most insane testing session so far:

The goal of this testing round was to stress the new gearbox as much as possible. I also wanted to see how adding the shell affected the handling, so at the risk of putting another dent into it, we brought it along. The good news is that it doesn’t much – since it weighs so little, driver weight differences still dominate (Time to diet!).

However, this was when the weakness of the Harbor Freight pink wheels finally showed. I’ve had this set since the thing was built, and the rears were definitely showing wear, but little did I know how thin the tread area actually was. Ben, the test driver of the last lap, pulled probably the best save I have seen yet when the rear right tire blew out on a turn.

I may have died on the spot if it planted into the curbside.

I cut open the failed tire and noted how thin the tread was. Even if the tread were new, there would only be about 3mm or so of it surrounding the tube, which seemed very low and could result in the tire being fragile. Its also inconsistently molded, as you can see from some spots being hair-thin (around the failed location) and some spots still having thick tread.

So I swapped on another set of pink wheels with the goal of driving the tires off. We would purposefully push hard, drift, and slide, just to see a worst case tire wear scenario:

Here’s that video.

One thing we began favoring was using the powerful regenerative braking on the rear axle along with weight transfer to help kick the rear end around. I figure this wouldn’t be very useful except in certain cases of executing a pass on someone’s inside, but it was one way to get some artificial wear and tear on the tires and also beat them up. Once again, Ben is the destructor of Harbor Freight tires.

This was an eye-opening test. Even though that happened at the very end, after 14 of those S-curve laps and 15 loops around the outside, it began turning me off to the Harbor Freight 8″ wheels. They seemed okay for low speeds, but the tread was too thin to be durable otherwise.

I also don’t think they’re vulcanized, or if they are, they’re not done well. This was the wear pattern on the tread of the outside front wheel after that test – the rest weren’t much better, and all showed this “feathering” wear. After this test, I was now totally dissatisfied with the Harbor Freight pink wheels – they’re nice and grippy, but the tread life on them is extremely limited due to how thin the tread is.

Other options for tires in this “handtruck” size were limited. It’s smaller than the most common small industrial tire (4.10/3.50-4) that more manufacturers make. I ordered some of Northern Tool 189399, and since it comes from an actual known tire/wheel company, they’ll hopefully be more durable.

In the mean time, I swapped to a set of Cheng Shin 2.50-4 tires that I bought from Surplus Center (but whose page is no longer up). The difference between these and even a new Harbor Freight pink tire was striking – the tread area was far more rigid to a finger push than the HF wheels which just deformed inwards. The sidewalls were also much stiffer. I only have 6 of these tires, however, so I’m countting on the Northern Tool ones being legitimate.

Finally, we went to fool around on these, but only recorded the shenanigans:

Overall, I’m much more satisfied with these – a couple laps of hard driving and they hardly looked different.

While awaiting the order from Northern Tool, I’m going to take care of one very irritating problem that made itself painfully noticeable during all this testing: Changing the tires. Right now, you have to thread a bolt through two rim halves AND have it line up with the hub’s threaded holes! I’m not sure why I didn’t go with a stud method like every single automotive hub in existence (Probably because I was like “Ooh, these wheels come with free bolts!”).

The plan to remedy this is just to thread the bolts in from the other side, tighten them, and then tack weld them to the hub, then use proper nuts on the new “studs”.

I think there will be more hard testing to come once I perform this bolt to stud conversion, and at least one “full dress rehearsal” involving a live battery and tire change. I’ve ordered a little aluminum hydraulic jack to assist in the process once I discovered how impossible it was to change the tires quickly.

Chibi-Mikuvan: Experimenting with the Trackstar 200A and the Hysterical Current Limiter

As usual with something I’m working on, let me open this update by yelling at Sparkfun Electronics. Remember when I said:

I couldn’t get it to change baud rates, however, despite trying that command a few times…

This was regarding the serial LCD kit I got for the Chib-Mikuvan digital dashboard. I meant that in the sense of no matter what I tried, I couldn’t get the baud rate change command (0x81) to take effect. So what the hell? It seems like it acknowledged the command, but it wouldn’t carry through a power cycle no matter what. There was nothing on the tutorial page about why this might be the case, but there were definitely a bunch of confused commentors, a few of which were having the same issue (but no answers) The firmware link didn’t go to the firmware, but to the command page. I found, along the way, a few custom user-designed firmwares for the LCD that claimed to fix all of the ills, but I was in no mood to deal with those.

As usual with the “open source” product world, it seems like forum comments and Git repositories are an acceptable form of documentation.

Finally, after some fumbling, in a product page comment post that was three years old, I found:

Tip: ensure that you are not sending any data to the backpack for the first second after powerup. If this happens, the backpack will revert to 9600 baud as a safety measure in case you don’t know what baud rate you set it to. Note that connecting this to an Arduino’s serial port WILL send data to it when the system is powered on, as the bootloader will try to connect to a host computer if present. If you connect the backpack to another set of pins using NewSoftSerial, this won’t be an issue.

Wait, could that have been the issue? Is that why everyone, no matter what, tells me to use a software serial port, without explanation as to why? Or if there is one, it’s “Well because it might interfere with the USB communication when you’re programming the Arduino”. Why the hell is this information not front and center on the front page of the product, or at least mentioned in the “datasheet” page? How is this a remotely acceptable form of product support, making your customers rile through forum posts and internet comment threads to find relevant thread that a comprehensive datasheet or product page should have in plain view? This isn’t the first time I’ve had to deal with this kind of “let the community be your tech support” from open source hardware producers either. Anyways, stay tuned for more details as to why I had to change the baud rate on this thing. It’s been working fine after I wasted about an hour trying to make up for undocumented behaviors.

In the last post, I had mentioned that the digital dash was a critical ingredient in seeing how much current this thing actually pulled during acceleration. I wanted to understand if I could run a race entirely using “tuned finger control” or not: the vast majority of R/C type motor controllers, like the Trackstar 200A unit I decided to use, don’t have current control or even current limiting, so a little twitch of the throttle at higher throttle levels can result in huge battery current spikes, which would cause trouble with the PPPRS regulation fuse. I’m glad to say that it served its purpose well:

This video featuring test pilots Dane and Mike. Unfortunately, it showed that my predictions were true: That the motor could pull spikes of 150-200 battery amps at most speeds just by blipping the throttle. This would cause some pretty instantaneous embarrassment, even though the MIDI type fuses specified are slow-blow types.

Now, the system also happily drew 200+ (pegging my current meter) amps at low speeds too, so the motor-side current must have been incredible. I tried, near the end of the video, to “current limit” by carefully ramping in and out of throttle. This only worked to a degree – any mess-ups resulted in spikes of high current. That’s what you get when your motor is more or less a dead short.

It was clear from that night of testing that, if Chibi-Mikuvan wasn’t going to consume 50A fuses every lap, I had to do something in software or hardware to limit the battery current draw. But what?

My ideal system would let the motor current be whatever it felt like – to exact maximum acceleration at low speeds – so long as the battery side current didn’t exceed 50 amps for more than a brief period. The MIDI type fuses are actually very tolerant of overloads, as their datasheet shows – the minimum opening time for a 200% overload is 3 seconds. That, for me, means hopefully enough time to push several hundred amps out to the motor as it spooled up, before falling back to a more reasonable current limit (which it seems like is 60A or so).

Since I don’t have direct PWM percentage access, and the DHAB-S/34 current sensor pulled out of the Fusion battery only has a 250Hz (???!!!) bandwidth, and I can only update an R/C controller so fast, I can only do “average” current control – there will always be spikes and transients. This wasn’t going to be some kind of kilohertz-bandwidth torque controller, but that isn’t the idea anyway.

I spent a few on and off moments thinking about how this might be feasible, including producing quite a few whiteboard sketches that ostensibly seem to be full of science, but which I assure you are mostly made of gibberish (Engineering folks, back me up here…)

What that diagram-like abhorrence says is basically the following: Don’t limit the battery current unless it exceeds a certain minimum threshold; then, manipulate the input signal such that the current draw stays under a time-dependent limit that starts high (such as 100 or 150 amps) but decays quickly to a sustainable current like 50 or 60A.

Sounds simple enough? I was mostly in battles over how to accomplish the “manipulate the input signal” part. How should it be manipulated? The downside of not having access to the PWM % of the output directly is you don’t really ever “know” how fast the motor is spinning OR how much average voltage is being put out by the controller at any point in time. Now, I did consider rigging a sensing line to the output of the motor to capture the PWM % information, but I wanted first to see if it’s possible to do with ONLY the (non contact, not soldered or hard-connected) current sensor. Sensing the PWM % would be a direction to take if I truly wanted to shave the yak and build an intricate torque control loop around an R/C controller, which seems… excessive. Fuses, being thermal systems, don’t care that you’re carefully controlling your current at thousands of Hz.

After a while, I decided to be sensible and work on this in stages. First, I can’t make the current draw stay under anything without an algorithm that first can manage it. For this, I turned back to Ragebridge and its “Hysterical current limiter“.

I designed RageBridge on the same principles – the motor current can be whatever it wants, up a point, then that is all it’s ever getting. It was done this way as a rebellion against the recent trend in “self protecting” robot controllers which shut down if you go over their current limit. As someone who drives robots like a maniac, I couldn’t stand this at all. To me, “current limiting” meant behavior like a bench supply: Once you go over a current threshold, the voltage floats to whatever is needed to maintain that current, including shorting through your stalled motor. That’s basically what Ragebridge does, usually with a +/- 5 or so ampere accuracy. Good ’nuff for the application.

The gist of how it works is: The output command is only allowed to “ramp” up or down at a certain rate, related to the controller’s loop time (delta-t) and the amount of output units it’s allowed to deviate by each time the loop runs. At each timestep, current is sampled; if the current is over the limit, then the controller will forcibly reduce (or increase) the output command at a rate much steeper than the user-controlled ramp rate. Aside from some second-order effects such as propagation delay/leg present in the output, motor inductance, etc., the current will change on the next cycle. If it wasn’t enough (still over current), the controller will modify the output command again. And so on. The result is a current waveform that looks a bit like a sawtooth.

In that screenshot from RageBridge testing, the current sensor is reading negatively i.e. the downward slopes indicate more current being drawn. As you can see, the current increases to a certain level, then is knocked back down again, then takes several cycles to build back up to that level.

RageBridge handles this bidirectionally, and it handles both regeneration and driving current, so there was a whole ton of state machine code in that thing that I don’t hope to repeat again. In Chibi-Mikuvan, I really only care about driving current, since the way the controller performs braking doesn’t seem to “regenerate” much based on what we saw in testing. That made the code easier.

However, it was still more math that had to be done in the loop. Up until this point, I had no clue 1. how long my code took to run, or 2. if the Trackstar 200A controller could even handle high-frequency inputs. If it was limited to 50 or 100hz R/C command inputs, there was no point in trying this at all – by the time the controller got around to processing your new command, your motor is already halfway back to China. From keeping tabs on the low cost multirotor & drone world, I know that the majority of R/C controllers these days handle servo pulses via interrupt and so can run right up to 499Hz (500Hz being where a 2ms-long servo pulse signal goes continuous).

So step 1 was finding that information out.

I changed the REFRESH_INTERVAL in the Servo library for Arduino to run at 490Hz. Didn’t want to get too crazy right away, in case the Trackstar needed time to think between inputs.

Notice that the drive chain has been removed – if it somehow interpreted this as “LOL OK”, I didn’t want it taking off on me.

Success! The Trackstar took the 490Hz input without issue. I decided this was close enough to start developing the rest of the code.

The next issue was seeing how much time the code, as it stood, took to run. I wanted to increase the loop frequency to 500Hz to take advantage of the fast inputs.

Well isn’t that lovely! Something like 5% processor usage at the 100Hz it was running at. I diagnosed this by inserting a fast pin turnon/turnoff at the beginning and end of the loop. I could conceivably increase the loop to 500Hz with no problems, but I did want to see if I could optimize the code a bit to lessen the run time anyway.

The extra wide band seen above is the LCD writing code. Remember my beef with Sparkfun? That whole hour was spent trying to see if I could shrink this time by increasing the baud rate. Here was the random-dude’s-firmware-free hack I had to make to get it to, you know, work as advertised.

This is a hardware “enable” line I made with a dinky little 2n3904 transistor that prevents the LCD from getting power until I explicitly activate it in the code. That way, the Arduino can shit packets everywhere when it starts, and it doesn’t turn on the LCD until after setup() is done. Oh, and then it will artificially wait a second to make sure before issuing commands!

With this, I was finally able to change the baud rate.

…but I found out it was basically incapable of talking at 57.6K baud. So not only does it have undocumented behavior, but it doesn’t even meet its advertised speeds. Well then. I settled on 38400 baud, which was good enough.

Another speed-up-the-code thing I did was to knock off a significant figure from each of the readings. The minimum resolution of the current sensor with a 10 bit ADC is something like 0.05 amps anyway, so it wasn’t worth 2 digits of decimals to tell me. Likewise, with such imprecision in the V and A readings, there was no use having 2 digits on the watts reading either.

In the end, all this effort only took the write time down 500us. It’s certainly not nearly ratiometric between 9600 and 38400 baud, so I suspect the overhead of Serial.print and Serial.write might be more at play here. Nevertheless, there’s still 1000us left to do other stuff, including a few lines of subtraction for the current control code, so I left it.

After inserting Ragebridge genes into Chibi-mikuvan’s code and seeing it seemingly, allegedly working without the chain drive hooked up, it was time for SCIENCE

This. This is actually the most terrifying thing I have ever built. Worse than LOLrioKart, Segfault, or Deathcopter. This is Sciencekart.

Well, okay, I didn’t have a DSO Nano or one of those fancy cordless oscilloscopes, but I did have a 12v lithium module, an inverter, and lots of gorilla tape.

I scoped a bunch of things while driving around the empty hallways staring intently at the oscilloscope screen, with one hand on the throttle and the other perched over the RUN/STOP button. If they say texting while driving is bad, they clearly have never tried oscilloscoping while driving.

The signals I looked at were the R/C pulsewidth output in microseconds and the raw reading from the current sensor. I basically just gunned it from a stop for a bit, let go, then gunned it again, and so on. Square waving the throttle is the biggest rookie mistake for people not used to driving R/C throttles, and this basically eliminates that problem. It doesn’t account for “startup jump” since the controller’s starting routines are often dead-reckoned, but that’s where I come in.

I’m glad to say that it works! Clearly, not with decimal amps accuracy… perhaps now I don’t even need the time decay curve – the error of the controller alone is enough -_-

This is the sawtooth waveform the Hysterical Current Limiter generates. This was captured at around 25% top speed after I punched the throttle to 100%. The current sensor’s zero point is at +5 divisons (0.5V) on the vertical scale; I’ve moved the zero voltage line waaaaaay down to capture the peaks of the waveform more effectively. At 10mv/A sensitivity, the max current, as can be seen, is actually peaking at 100a. It’s interesting to see that the minimum current in this case was more or less 50A, the programmed limit!

My guess as to why? I think this is in part because the motor is so low inductance that the current changes much faster than the controller can keep up, and there is little back-EMF from the motor to help at low speeds. The controller only gets a little time below the current limit as a result: any increase in the command results in a ton more current flowing again. I will need to find a somewhat emptier hallway to capture higher speed waveforms, but based on eyeballing, the spikes decreased as speed increased.

I’ll continue experimenting to see how to reduce the error, but right now, it works great as-is (if not a little anemic now because it can no longer pound 150 amps). If the error is large, then I won’t really be able to utilize the ‘time decay’ method as well, but it could be fine just setting the current limit to “60A, pretty-pleeeease” and keeping it there.

Here’s a test of me driving straight towards a wall:

This was one of the early tests in which I set the current to only 40A to make sure the concept even had a chance of working. From still frames, I could see numbers like 40.6, 45.0, 32.5, and the random spike to 79.6 at the very beginning when the startup loop exits. During the cruise portion, the amps ranged from 29 to 48 or so. Promising start for now!  Tuning can occur from here as I drive around more with sciencekart!

Expect some more testing video this weekend possibly with the oscilloscope still attached.