Took a cool approach on the throttle control response curves.
There are three throttle-to-motor control curves: Advanced, Regular and Kiddie. I expect the Advanced curve will be the most popular among test drivers at LM. There is also a configuration that completely ignores curves altogether, but there's nothing cool about that aside from the adrenaline factor.
All three curves aim to make the center area of the joystick smooshy so that inadvertent bumps to it and people with less-than-precise hand movements can control the chair easily, especially at low speeds.
The motor controller I'm using (Dimension Engineering Sabertooth 2x60) can work in a number of modes, but I'm using it in a simple serial mode. You can command each motor individually with a single byte. Motor 1 is idle when you send a value of 64. 127 is full forward and 1 is full reverse. Motor 2 is idle at 192. 255 is full forward and 128 is full reverse. A 0 (zero) will cut power to both motors simultaneously.
In initial driving tests (Vimeo: Very first test drive of Office Chairiot Mk II in garage.), I used the controller in the plain old analog mode, where the potentiometers in the joystick were directly connected to the inputs on the controller. The controller was then configured to use its own internal smoothing and control curves for input smoothing. That worked amazingly well, but I wanted a little more control over the throttle response (safety being one concern), which is why I run the command of the motors through the Office Chairiot Mark II Run-Time Operating System (OCMkII RTOS). (I'm being silly, but it really is a custom-built, run-loop kinda RTOS-ish thing running the show.)
I designed the curves in Adobe Illustrator. The graph for the curves had all of the possible analog values of the joystick potentiometers on the X axis (0 to 1023) and the motor command values on the Y axis (1 to 127 for motor 1 and 128 to 255 for motor 2). I output the graphs for the Regular, Advanced and Kiddie curves to PNG, imported them into a kind of reverse graph plot program and extracted 32 data points along the curves. I then ran those points through a Bézier curve routine to get a smooth run of motor command values from full reverse to full forward. I found a great Bézier curve snippet written in C#, which I don't do, so I translated it into straight C. It outputs a full range of motor command values for every analog stick value from 0 to 1023. That way I can store precomputed values for any stick position, saving the little AVR microcontroller a ton of cycles that would have been required to computed those values on the fly.
If you're following along at home, you realize that each curve will occupy 1,024 bytes of memory. That's precious space on a microcontroller, especially one with only 256K AND a big-arse semi-OS running on it controlling very large number of subsystems.
I only need the curve data on-demand (once) when the throttle curve is set on the control panel. Retrieving that from an SD card would be fairly quick and painless. Not too tough to do. But, I figured out a better way: Store only enough data points for each curve so that the Bézier routine can fill in the blanks on-the-fly. This would only require a few bytes for each curve and the curve computation goes pretty quickly (about the same as pulling it from an external storage medium). Bob's your uncle.
The Advanced curve gives the driver complete range of speed commands to the motors. But the curve becomes a straight climb to the max values more slowly from the center position. At about ⅓ throttle, the curve starts on a more direct path toward the maximums (for motor 1, the command for full forward is 127; the full reverse command is 1).
The Regular control curve keeps the center of the stick mooshy, but it only allows the Office Chairiot Mk II to go a maximum of ~50% throttle forward or backward. It's a safe and reasonable way to get across a parking lot for those people who might not be retired skydivers or stunt people.
Finally, the Kiddie curve only lets the vehicle go to about 25% throttle in either direction. Why? Because you know at some point someone is going to ask if their kid can drive it. What do you suppose would (could) happen if a 10-year-old got into a motorized office chair that was capable of doing 20+ MPH? I don't have a waiver for that, yet.
All that being said up there, this thing is nearly ready to drive. I'm updating the throttle code on the Arduino tonight/tomorrow morning and hopefully it will be drivable this weekend. After everyone is back from the conference, it should be ready to pilot around the grounds at LM!