How to Program Joystick Channels to Ramp Up in Driver Control

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

Adriana you can use a for loop and have the value be the motor power

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?

Do you mind sending a picture of your drive code? I can check that first.

Right now we have the basic joystick programming.

motor[leftDrive] = vexRT[Ch3];
motor[rightDrive] = vexRT[Ch2];

So it is a two motor drive as in one motor on each side correct?

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.

No. We have 2 high-speed motors on each rear side. (It is a four-motor drive.) Then we have one dummy wheel on each side in the front. (4 wheels.)

@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?

We are using y-cables.

That explains that bit.

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.

If the gears are slipping, there may be a problem with the gears, or they may not mesh properly together.

Absolutely!

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.

Link to original post
Link to library and documentation

I think we’re going to try to make the mechanical change of adding bearing flats all around the wheels and the gears first.

But, @callen I’m still interested in how the programming would work. I have a couple of specific questions:

  1. What actual RobotC line of code would you use to control your while loop during the driver control period? We’ve been having some trouble with that.
  2. In the pseudocode, what do the “…” represent?

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;
  }
}