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
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.
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)
}
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.
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.
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.
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).
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);
}
}
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.
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
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 (At least IMO and IMTO (In my teams opinion).