Accelerating/ Decelerating Mechanm Drive

Hello, I’m currently programming our auton and I want to slowly accelerate our mech drive up to 50 percent and decelerate back to 0 but I have no clue how to code that.

this is our mech command:

void auton_mech(int vel, int inch, directionType dirL, directionType dirR){
float WHEEL_DIAMETER=4.125;
float WHEEL_CIRCUM=WHEEL_DIAMETER*3.14;
float inchesPerDegree=WHEEL_CIRCUM/360;
float degree=inch/inchesPerDegree;
FrontRightDrive.rotateFor(dirL, degree, deg, vel, vex::velocityUnits::pct, false);
BackRightDrive.rotateFor(dirR, degree, deg, vel, vex::velocityUnits::pct, false);
FrontLeftDrive.rotateFor(dirR, degree, deg, vel, vex::velocityUnits::pct, false);
BackLeftDrive.rotateFor(dirL, degree, deg, vel, vex::velocityUnits::pct, false);
while(FrontRightDrive.isDone() == false && FrontLeftDrive.isDone() == false && BackLeftDrive.isDone() == false && BackRightDrive.isDone() == false){
wait(1, msec);
}

in our auton i have it as:

auton_mech(50,33,reverse,fwd);

any tips on how I could program the acceleration? Going straight to 50 velocity is messing up our auton

Thank youuu

I dont know if this would work but you might be able to have a loop that when lets say var x is under the speed you want it adds 1 to it every couple milliseconds and then make x your drive speed and you can even make the amount it adds to it a variable in order to be able to control acceleration but what it would do is accelerate by a certain amount until it reached the speed you predetermined.

1 Like

IDk if this will help but I’ve been struggling for >1yr trying to figure out how to change the motor speed.

Come to find out the only motor command that does not use PID is motor.spin using voltage as the velocity units (max = 12):
motor.spin(dir, units, voltageUnits::volt);

Usually both this and the voltage-varying logic is inside a while-loop.

BTW you may want to consider using motor_group() for right & left drive wheels and maybe motor.isSpinning()

I hope this helps

One could create a derived motor_with_acceleration_control from the vex motor class and override the .spin methods to provide the desired functionality.

say what? I barely grasp OOP and wouldn’t even know where to begin - esp seeing the API offers little info:
https://api.vexcode.cloud/v5/html/classvex_1_1motor.html

Wouldn’t a function be easier?

I created a drive control loop that ramps up speed and decelerates to meet the target distance. For the deceleration I used a modified PID to calculate motor power (I’ll call this mP1), although a simple P loop can work. For the ramping up I also calculated a separate motor power value (mP2) which equals the time since starting the loop times a constant, so that this value will ramp up proportionally to time. Now that you have these 2 values, just check which value is less and use that to set motor power. Something like this:

if(mP1 < mP2) set power to mP1;
else set power to mP2;

In effect, it ramps up the speed until it meets the speed calculated by the PID or P loop.

1 Like

Just use a while loop and an array of n values (the more you use the sloppier it will be)
int velocities[n]={0,0,0,0…};

velocities[i]=drive; //assign your pid value to a value within velocities array
output=mean(velocities); //find the mean of velocities (its too early, I forget the code for it in c++)
i++; //add one to our index
i%n; //make sure the index stays within n values

idk, maybe something like that?

Using a PID loop is probably what you are looking for.

While this will help with the deceleration, it won’t help with the acceleration unless there is some sort of extra logic. So use a pid to slow down, but also include a clause for speeding up or slowing down that is a version of

if (abs(newspeed-oldspeed)>10) {newspeed=oldspeed+10;}
just to limit the difference to 10 between the last speed value and the new one. Of course 10 can be substituted for any other number, and this doesnt take into account running backwards, which may need a negative integer or boolean check for direction. You can figure that out.

What everyone is saying is use a slew rate loop, which basically increases the velocity of the motor every t milliseconds. You can use a for loop to achieve this fairly easily.

for(int speed = 0; speed > maxSpeed; speed--){
        spin the motor here using  'speed' as the velocity
        delay some time
}

this will speed up your motor to the max velocity you specify, and you can do the opposite to slow down,

for(int speed = currentSpeed; speed > minSpeed; speed--){
    spin the motor here using  'speed' as the velocity
    delay some time
}

currentSpeed is the current speed of your motor, minSpeed is what you want it to slow down to.
You can also use kinematics (physics) to figure out the final position and stuff, but I wont go into that.

1 Like