Adding acceleration to my motors [Help]

The launcher on our robot currently has 4 motors on it for the 4 flywheels and I’m worried that suddenly ramping the motors for it up to 127 might damage them or the robot. I’m worried about the drive motors too especially because we have a 4 wheel drive omni robot only controlled by two motors (and our bots getting pretty heavy). I’m attempting to add acceleration to all these motors but I just can’t get it to work. Here is what I have now

#pragma config(Motor,  port2,           rightdrive,    tmotorServoContinuousRotation, openLoop)
#pragma config(Motor,  port3,           launcher,      tmotorServoContinuousRotation, openLoop)
#pragma config(Motor,  port9,           leftdrive,     tmotorServoContinuousRotation, openLoop, reversed)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//
int launchspeed = 1;
int increment = 10;
task main()
{
	while(true)
	{
		motor(port9) = vexRT[Ch3];
		motor(port2) = vexRT[Ch2];
		motor(port3) = launchspeed;
		if(vexRT[Btn5D] == 1)
			
					while(true)
					{
						launchspeed = increment + launchspeed;
						wait(.2);
					}				
			}
}

The idea is the motor equals launchspeed and each time the while loop completes which should be every two tenths of a second the launchspeed has the increment added to it. Right now, however, It dosen’t do anything at all. The drive motors work fine.

This isn’t the final code for our actual competition bot but for the test bot I have at home. Any help would be greatly appreciated.

#pragma config(Motor,  port2,           rightdrive,    tmotorServoContinuousRotation, openLoop)
#pragma config(Motor,  port3,           launcher,      tmotorServoContinuousRotation, openLoop)
#pragma config(Motor,  port9,           leftdrive,     tmotorServoContinuousRotation, openLoop, reversed)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//
int increment = 10;
int speed = motor(port3);
int launchspeed;

task main()
{

	while(true)
	{
		motor[port9] = vexRT[Ch3];
		motor[port2] = vexRT[Ch2];
		motor[port3] = launchspeed;
		if(vexRT[Btn5D] == 1)
		{
			while(true)
			{
				launchspeed = increment + speed;
				wait1Msec(20);
			}
                wait1Msec(20);
		}
	}
}

I think I fixed your problem. I have never tried anything like this before, and I am still a beginner so maybe someone such as @jpearman can help by providing some clarification.

The program you currently have doesn’t have a way to break out of the forever loop to accelerate.
Something like


while(launchspeed<SpeedDesired)

will fix that.
Also, the motor speed needs to be constantly updated, so add


motor[port3] = launchspeed;

inside the while loop. I don’t know if the compiler allows it or not, but motor] is standard, not motor().

If you want to keep driving while accelerating the flywheel, you need to create a separate flywheel task to multitask.

task FlywheelControl()
{
  while(1)  //forever loop
  {
    if(btn)
    {
      while loop for acceleration
    }
    sleep(25);  //This is the same as wait(.025).
  }
}
task main()
{
  startTask(FlywheelControl);  //only needs to be called once
  while loop for driving (add a wait so you don't hog the CPU)
}
#pragma config(Motor,  port2,           rightdrive,    tmotorServoContinuousRotation, openLoop)
#pragma config(Motor,  port3,           launcher,      tmotorServoContinuousRotation, openLoop)
#pragma config(Motor,  port9,           leftdrive,     tmotorServoContinuousRotation, openLoop, reversed)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//

int launchspeed = 0;

task main()
{

	while(true)
	{
		motor(port9) = vexRT[Ch3];
		motor(port2) = vexRT[Ch2];
		motor(port3) = launchspeed;
		if(vexRT[Btn5D] == 1)
		{
				launchspeed += 10;
				wait1Msec(20);
		}
	}
}

You can have a ‘+=’ operator which would cause the value of launchspeed to increase by a value of 10.

I would also recommend an if statement that limits the value at 127 when it eventually becomes greater than 127.

Thanks so much for you help but I still can’t seem to get it to work. Here’s what I have now.

#pragma config(Motor,  port2,           rightdrive,    tmotorServoContinuousRotation, openLoop)
#pragma config(Motor,  port3,           launcher,      tmotorServoContinuousRotation, openLoop)
#pragma config(Motor,  port9,           leftdrive,     tmotorServoContinuousRotation, openLoop, reversed)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//
int launchspeed;
task FlywheelControl
{
    if(vexRT[Btn5D] == 1)
    {
    	while(launchspeed < 127)
			{	
				motor[port3] = launchspeed;
				launchspeed = launchspeed + 1;
				wait(.2);
			}
    }
    else
    {
    	motor[port3] = 0;
    }
}
task TankDrive
{
		motor[port2] = vexRT[Ch2];
		motor[port9] = vexRT[Ch3];
}
task main
{
	while(true)
	{
		startTask(TankDrive);
		startTask(FlywheelControl);
	}
}

I think I implemented all your suggestions but still all I have is a normal tank drive and I’ve checked my motors but all that happens is the tank drive works all the time but when I press 5D the motor spins full speed then stops and won’t come on after that.

You seem to know what your doing would you look at what I have now I posted It on this thread. Thanks.

task main
{
	while(true)
	{
		startTask(TankDrive);
		startTask(FlywheelControl);
	}
}

Calling a task once will be suffice, so

task main
{
	startTask(TankDrive);
	startTask(FlywheelControl);
	while(true)
	{
		sleep(25);
	}
}

should be good, but someone might need to check this.

Also, you need () after all of your task names, like


task main()

You need a forever while loop to keep updating motor speeds.

task FlywheelControl()
{
	//What you have already
	sleep(25);	//To prevent it from hogging the cpu.
}
task TankDrive()
{
	//What you have already
	sleep(25);	//To prevent it from hogging the cpu.
}

You also need to set the launchspeed to 0 after you set the flywheel to 0 because it will not accelerate with it kept at 127.


    	motor[port3] = 0;
        launchspeed = 0;


    	while(launchspeed < 127)
			{	
				motor[port3] = launchspeed;
				launchspeed = launchspeed + 1;
				wait(.2);
			}

This will take 127*.2 seconds, or about a minute to accelerate to full speed since it’s increasing only by 1 each round.
launchspeed+=10, as mentioned by N0m4D_3560, can replace launchspeed = launchspeed +1.
launchspeed will stop at 130, which will automatically give motors full power, so it is okay.

Oh, and +1 to 3921’s post

Well it seems I’ll have to go with the system we have now which includes not being so hard on the drive motors as best we can and the code I have now. Here It Is…

task autonomous()
{
	SensorValue[dgtl9] = 0;//Reset the encoder
	while(true)
	{
		if(SensorValue[dgtl9] > -1000)//If the encoder hasn't reached a certain value yet
		{
			if(SensorValue[dgtl11] > 10)//And the sonar dosen't detect anything too close
			{
				motor(port1) = 127;
				motor(port10) = 127;//The Robot drives forward
				motor(port2) = 0;
			}
			else if(SensorValue[dgtl11] < 5)//If something gets way too close
			{
				motor(port1) = -127;
				motor(port10) = -127;//It goes backwards
				motor(port2) = 127;
			}
			else//Otherwise
			{
				motor(port1) = 0;
				motor(port10) = 0;//It stops
				motor(port2) = 0;
			}
		}
		else//If the encoder hasn't reached a value yet
		{
			motor(port2) = 0;
			motor(port1) = 0;
			motor(port10) = 0;//Stop the robot
			motor(port3) = 63;
			motor(port4) = 63;
			motor(port8) = 63;
			motor(port9) = 63;//Sets the motors to half speed
			wait(1);//Allows 1 second spin up
			motor(port3) = 127;
			motor(port4) = 127;
			motor(port8) = 127;
			motor(port9) = 127;//Ramps the motors up to full speed
			wait(1);//Allows 1 second spin up
			motor(port2) = 127;//Intake spins so balls don't roll and are picked up easily
			motor(port5) = 63;//Feeder feeds the fywheels
			wait(100000);//Keeps the while loop  from repeating
		}

	}//Closed while loop

}//Closed autonomous

You can see the motors ramp up to half speed for half a second then to full speed this prevents any damage during autonomous, except to drive motors which I’m not too concerned about for the 1 time they really experience any stress during each match.

		if(vexRT[Btn5DXmtr2] == 1)//If you press button 5D on the partner joysick the launcher motors spin at half speed
		{
			motor[port3] = 60;
			motor[port4] = 60;
			motor[port8] = 60;
			motor[port9] = 60;
		}
		else if(vexRT[Btn5UXmtr2] == 1) //Button 5U on the partner joystick makes them go full speed
		{
			motor[port3] = 127;
			motor[port4] = 127;
			motor[port8] = 127;
			motor[port9] = 127;
		}
		else //Otherwise they do not spin
		{
			motor[port3] = 0;
			motor[port4] = 0;
			motor[port8] = 0;
			motor[port9] = 0;
		}

During driver control the motors spin at half speed when a button is pressed which allows for shooting goals close up. Then once they have spun up you can press another button and ramp it up to full speed for shooting farther away without damaging it. Also the motors are spread across the breakers in the cortex so they are least likely to trip.

Anyways thanks for helping me even though we couldn’t get it. If any of you get it working post it on this thread so we know later. Until then this is the first time I’ve been the main programmer for our team and I hadn’t really done any programming before this year so let me know what you think of my code above and if you have any suggestions I’d love to hear them. And also I’m attaching a picture of our robot don’t make me regret it. If we show up at a competition and you copied our design were gonna beat you nerds up (It’s not done yet).

Thanks,
Adam
pasted_image.png

I’m not sure if this code actually works (I don’t have a robot to test with right now), but it doesn’t throw any errors, which is good. It may be worth trying, if you are willing to try it today. On another note, I also added thresholds to the drive, because Vex motors under load behave weirdly at very low power, and because joysticks don’t usually reset perfectly to 0. The motors shouldn’t be able to move anything at less than 5 power anyway, so it shouldn’t make much of a difference. If you want to use an arcade drive rather than tank, I can post some code for it.


#pragma config(Motor,  port2,           rightDrive,    tmotorVex393_MC29, openLoop)
#pragma config(Motor,  port3,           launcher,      tmotorVex393_MC29, openLoop)
#pragma config(Motor,  port9,           leftDrive,     tmotorVex393_MC29, openLoop, reversed)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//

int launchSpeed = 0;
const int accelInc = 10; //Amount added to launchSpeed per cycle
int leftY = 0; //Makes thresholds more readable, also helps with arcade control
int rightY = 0;

task main()
{
	//Reset variables to ensure that variables start from zero,
		//rather than random values (it can happen)
	launchSpeed = 0;
	leftY = 0;
	rightY = 0;

	while(true)	{
		
	//Drive Control
		
		//Thresholds
	
		//Left Drive
		if(abs(vexRT[Ch3]) >= 5) {
			leftY = vexRT[Ch3];
		}
		else {
			leftY = 0;
		}
		
		//Right Drive
		if(abs(vexRT[Ch2]) >= 5) {
			rightY = vexRT[Ch2];
		}
		else {
			rightY = 0;
		}
		
		//Motor Control
		motor[leftDrive] = leftY;
		motor[rightDrive] = rightY;
		
	//Acceleration
		
		//Execute if Button Pressed
		if(vexRT[Btn5D]) { //Allows exiting to use rest of program
			if(launchSpeed <=127) { //If launchSpeed is within range of acceptable values
			//Increment
				launchSpeed += accelInc;
			}
			else { //If launchSpeed > 127 (not a value a motor can take)
				launchSpeed = 127;
			}
		}
		//If Button not Pressed
		else {
		//Stop motor[launcher]
			launchSpeed = 0;
		}
		
		//Set motor[launcher]
		motor[launcher] = launchSpeed;
		
		wait1Msec(20);
	}
}

Currently reverse engineering your robot’s design. Cya at Worlds :stuck_out_tongue:

Actually most PID Loops for Flywheel Velocity Control will ramp the motors to 127 before lowering the power to get the correct speed.

Like you, I had the concern of damaging my system if I ramped it up to 127, but this is inevitable if you want to implement forms of Flywheel Velocity Control (PID).

Now, I have a PID Loop for Flywheel Velocity Control (which ramps the motors to full power at the very start), and till now my flywheel system isn’t getting damaged.

That’s neat! I’m hoping I can get away with just ramping the motors up to a certain speed and basically spraying and praying but we’re not certain we want to put the engineering of firing full field in yet but If we do decide to do that I’ll probably have to use some form of PID.

@lpieroni
Everything looks good to me except:

I think you need

if(vexRT[Btn5D] == 1)

And I’ll definitely be implementing the thresholds for my drive motors.

Currently engineering a robot to destroy your robot that’s a copy of ours. Cya at Worlds :wink:

I CAN CONFIRM! This code works for the acceleration of port 3 and the thresholds on 2 and 9. I only changed is slightly making the const int accelInc 2 which worked better than 10 for my purpose and there was a hiccup where in the if statement for the button where the condition was incomplete but other than that @lpieroni wrote all this code and it works very well.

Thanks for letting me know that this code works. I will hang on to it as a backup, since currently my team is using a TBH algorithm, which has worked well for us. Just out of curiosity, did RobotC throw a warning or error for the conditional statement involving a button press, or did you just notice it? I have never had an issue with


if(vexRT[Btn5D] { }

but if you prefer doing


if(vexRT[Btn5D] == 1) { }

that works the same way. It’s a matter of personal preference, and every programmer has his/her own style, consisting of little things like this. Also, if you want to try it the (7 keystrokes) shorter way, the opposite (if the button is not pressed) is


if(!vexRT[Btn5D])

compared to


if(vexRT[Btn5D] != 1) { }

or


if(vexRT[Btn5D] == 0) { }

I agree with style here. I personally use == or != 1 when programming because my main purpose is to write code for my team, which they have to at least somewhat understand. I find that doing


if(vexRT[Btn5U])

can at times be a little confusing, so I keep it as understandable as It can be :stuck_out_tongue: (At least IMO and IMTO (In my teams opinion).

Now I just do it automatically. :smiley: