I’m looking for techniques to use for compensating the drive system for speed and control.
Conceptually, I’m looking for techniques for smooth acceleration and for fine speed control.
I’d like to prevent the robot from accelerating too quickly. The usual process is to just transfer the joystick value to the drive motors and just use the motor acceleration curve. I’d like to have more control over that curve. I’m looking for ideas for what the transfer function looks like for controlling that curve.
For fine speed control, I’d like to do something like a computer mouse control. Some mice have a transfer function that allows for micro control at small movements but accelerated control at larger movements. This allows you to move the most quickly across a large screen without actually having the same real estate.
Any articles or suggestions for similar ideas would be a great help.
I’m sure you have thought of this already, but something we have done in the past:
To get fine and precise control, while using Tank Drive, we had a button on the joystick, that when held, would divide the joystick inputs by half. Essentially this allows the full range of motion of the joysticks, but limits the speed to half. This allowed us to do very precise turns and small movements. (Used it in 2010 to have our vacuum latch onto the soccer balls).
Another option is to have a button, that when held, changes your inputs from a linear correlation to a different type. The joysticks value is a floating value, from -1 to 1. Like you said, most code will just assign the motor.Set () function to the joystick.GetY () (or x, whatever axis you use). Try having a button that squares the value instead (or cubes, try different values!) of just a linear correlation. This should also give you more precise control.
We programmed a rate limiter this Saturday, which just looks at the motor output the last time, and you set a threshold, (max allowed change per loop time) and if greater, just adds the max, to the output.
This worked well at keeping the totes on the stack, but makes the drivers controls “laggy”.
I just posted a question to the programming team, if they thought the rate limit could/should be varied depending on the speed of the bot, or motor output of the controller… Seeing it is a kinematic energy problem, and mathematically, the formula always seems to have a velocity squared term, maybe the rate limit variance should be based on a square of the velocity.
based on our “Kitbot on Steroids” programming mule, this equated to a rate limit of 1.1 or stop to full speed in 0.9 seconds, this was enough acceleration/deceleration to keep a stack of 4 totes on the bot, suspended by the handles only… (trying to determine the pro/cons of supportting tote in two, three, or 4 points. )
We typically do
x = joyx * abs(joyx); y = joyy * abs(joyy)
this squares the input giving a parabolic response while maintaining sign.
It does not protect from the driver slamming full forward to full reverse. For that, you also need to add a ramp function. The old jaguars had that built in to minimize over current issues so you may want to look up the data sheet for time constants.
I don’t know how much this applies, (when you say more control over acceleration this just jumped to my mind) but we created an acceleration rate limiter (“ramping” function) to ramp acceleration when the driver jams full speed on the joysticks (this helps with current spikes and wheel slip among other things). You can adjust your max desired slope which is the variable Slope_a and move the joystick slider to simulate joystick movement. There is an indicator of the motor output labeled “motor” as well. The graph will show you the joystick value (white line) in comparison with the motor output (red line). The smaller Slope_a is the longer it takes the motor to reach the full desired speed. When controlling finer movements, these curves overlap exactly. Here is the LabVIEW VI if you want to take a look. (Sorry if it is a little messy!) If you aren’t too versed in LV, I’d be happy to explain more, if you have problems with the link let me know.
I’ll try to find a machine that still has LabView on it. (We’ve completely switched to C++.)
The Talon SRX also has a ramp builtin. We’ll do some experiments with the ramping functions there as well. Might as well use all the processors we have on board.
I’ve implemented ramping speed filters in RobotC using this example from one of our old programming leads. Essentially, the filter adds to the current speed the different between the current speed and the desired speed divided by some “alpha”. This “smooths out” any motor speed changes.
So basically:
speed = speed + (joystick - speed)/alpha
Note that in his example, he multiplies then divides by an arbitrarily large value. I’m told he did this because the controller either didn’t support floats or did floating point calculations much more slowly.
The wpilib actually has this built in. If you call the arcadeDrive (or tankDrive) method, one of the parameters is a boolean “squaredInputs”, which does pretty much what your doing.