My team and I are having a programming problem. In driver control, we need our drive base to not go directly from 0 speed to 127 speed; instead, we need it to ramp up to that speed, maybe incrementing from 0 speed to 100 speed to 127 speed. On the competition joysticks, we are using Ch3 and Ch2 for the left and right sides of our drive base, respectively.
Are there any ideas on how this can be accomplished? Thanks in advance!
Team 2998A
For your robot did you gear your wheels above a 1:1 ratio or use turbo motors with a 4 motor drive? If the problem is the robot stalling, there is a possibility that there is not enough torque causing your drive to stall
Randor4478-- The problem isn’t that the motors are stalling; the problem is that the 12-tooth gears that the motors are driving are slipping until the robot catches up. We have three 12-tooth gears (1 : 1 ratio) and two high-speed motors on the rear left and rear right sides of our drive base. Would this problem be fixed by changing the motors from high-speed motors back to regular motors?
DanDanrevolution-- we know there’s probably a way to do this with programming. As a newer team, we were hoping to fix this mechanically if possible. If not, then we will start looking for ideas on the code.
@Randor4478 's question is because you only showed code to run two motors, not four. We would expect to see four motor] commands, two set to Ch2 and two set to Ch3.
Do you have a picture of your chassis? Because I’m assuming the above code is actually something like
motor [leftDrive1] = vexRT[Ch3];
motor [leftDrive2] = vexRT[Ch3];
motor [rightDrive1] = vexRT[Ch2];
motor[rightDrive2] = vexRT[Ch2];
which should work fine.
Or are you using y-cables on the chassis?
You can look up different solutions for controlling the “slew rate,” which is what you want. A really trivial way would be something like this pseudocode:
int lastLeft = 0
int newLeft = 0
while true
{
newLeft = vexRT[Ch3]
if newLeft > lastLeft + 10
{
newLeft = lastLeft + 10
}
motorLeftDrive = newLeft
lastLeft = newLeft
…
}
It’s not beautiful, but it works (in a limited way). The idea is that if you try to speed up more than a certain amount, you can only get that certain amount on each increment as a maximum increase. You would want to adjust the 10 to find something that specifically works well. Also, this isn’t written for slowing down or going negative quickly, which you’d want.
Did you support the gears’ axle on both sides of the gears? They’ll tend to slip a lot if you only support their axle on one side, even if you support it at two locations.
well if its like building up speed its because the robot does not have enough torque to power to the wheels. I would say set up a high torque ratio of gears to the wheels.
This might be more functionality than you want, but I’ve heard good things about the Smart Motor Library made by @jpearman . I haven’t actually used it yet, as my teams have used EasyC in the past, but we hope to implement it this year.
This is basically what you want. The full control loop for slew is a little less trivial that one might think on the surface because there are a few edge case considerations that need to be added to the implementation, namely handling really small errors in the set point vs output to avoid unnecessary oscillations in the output value, as well as using a consistent timing system so that the slew rate isn’t affected by processor load.
Note that I have not tested to see if this even uploads with RobotC, therefore the code is offered as is with no guarantee that it will work without minor modification.
/**
* Slew controller sample code
* @author Jason McKinney
**/
//struct for containing slew rate information for any motors that need to use it
typedef struct {
int motorValue;
float slewRate;
float slewThreshold;
} slewController;
//program time counter for calculating delta T
int timeCounter = nPgmTime;
int deltaT;
/**
* Create a slew controller for a motor
*
* @param port the motor port to use as a number (0 - 10)
*
* returns a new and configured slew controller strucutre
**/
struct slewController
slewFactory (float slewRate, float slewThreshold) {
slewController s;
s.slewRate = slewRate;
s.slewThreshold = slewThreshold;
return s;
}
/**
* Update the output value of a slew rate controller
*
* @param driveSet the desired speed state
* @param s the slew controller structure to adjust
*
* returns the updated slew controller structure
**/
struct slewController
setSlew (int driveSet, struct slewController s) {
if (driveSet == s.motorValue) {
return s;
}
if (fabs (driveSet - s.motorValue) < slewThreshold || fabs (driveSet - s.motorValue) <= 1) {
s.motorValue = driveSet;
} else {
float motorAdd = (float) slewRate * (float) deltaT / 1000.0;
if (fabs (motorAdd) < 1) {
//always ramp by 1 so that the output doesn't get stuck
motorAdd = 1;
}
int sign = sgn (driveSet - s.motorValue);
s.motorValue += sign * motorAdd;
}
return s;
}
task usercontrol () {
/* Configure slew controllers to have a rate of
12.7 units per second with a threshold of 30 units.
*/
slewController leftSlew = slewFactory (12.70, 30);
slewController rightSlew = slewFactory (12.70, 30);
while (true) {
//keep at start of while loop, this keeps track of time each loop takes
deltaT = nPgmTime - timeCounter;
timeCounter = nPgmTime;
int driveLeftSet = vexRT (Ch3);
int driveRightSet = vexRT(Ch2);
leftSlew = setSlew (driveLeftSet, leftSlew);
rightSlew = setSlew (driveRightSet, rightSlew);
motor[port3] = leftSlew.motorValue;
motor[port2] = rightSlew.motorValue;
}
}