Just for clarification, I posted this in the official RobotC Help Forum, but I wanted some community advice as well, not just the mods.
Here goes:
I’ve added a little bit of test code to our main code, to see if my programming skills are up to par.
My task is as follows:
Or robot is a catapult. We use a pronged intake. When it is pushed all the way down, a slipgear causes it to fling upward with the force of a thousand bulls charging at once. We have a limit switch on the front of the robot and a limit switch on the back of the robot. It works similar to the RI3D team’s. When the catapult is fresh after firing, and the arm is pointing upward, it’s pressing the back limit switch. When the arm is brought down and the intake is parallel to the field floor, the front limit switch is being pressed. If the catapult is moved about an inch even lower, the slipgear will slip and the catapult will launch, flinging the arm up and resetting to the original position and hitting the back limit switch.
I want it so that if the back limit switch is pressed, I can press button 8D and the catapult will pull down until it hits the front limit switch. When I press (and hold) 6D, it should bring the catapult arm even lower and fire the catapult back to the original position. At the same time, if the front limit switch is pressed and instead of firing it I want to pull it back up to the back limit switch, I can press 8R.
I need advice on whether or not the following chunk of code will serve this purpose effectively, if there are any flaws, and how I can rearrange or revise the code to either be cleaner or less repetitive.
//TEST CODE FOR CATAPULT MOTORS:
//Mini pre-note to self & teammates: When referring to buttons, use Xbox controller button names for easy reference
//If the FRONT limit switch is pressed...
if (SensorValue[FrontLimit] == 1) {
// 1. If the Right Trigger is pressed, Shoot the catapult
while (vexRT[Btn6D] == 1) {
motor[BackLeftCatapult] = 127;
motor[BackRightCatapult] = 127;
motor[FrontLeftCatapult] = 127;
motor[FrontRightCatapult] = 127;
}
// 2. If Button "B" is pressed, Pull arm back to back limit switch
if (vexRT[Btn8R] == 1) {
while (SensorValue[BackLimit] == 0) {
motor[BackLeftCatapult] = -127;
motor[BackRightCatapult] = -127;
motor[FrontLeftCatapult] = -127;
motor[FrontRightCatapult] = -127;
}
}
}
//If the BACK Limit Switch is pressed...
if (SensorValue[BackLimit] == 1) {
// 1. If Button "A" is pressed, Pull down Catapult until it hits front limit switch
if (vexRT[Btn8D] == 1) {
while (SensorValue[FrontLimit] == 0) {
motor[BackLeftCatapult] = 127;
motor[BackRightCatapult] = 127;
motor[FrontLeftCatapult] = 127;
motor[FrontRightCatapult] = 127;
}
}
}
//END OF TEST CODE
I haven’t dived into your code but, after taking just a glance, I wanted to be sure that you remember to place some lines of code that turn off your motors at some point. A common mistake is to put all sorts of while and if statements that turn things on but if you don’t tell the motors to turn off, they will keep running even if the program flow has left the loop that first started the motors.
It does also seem like your motors are either going fully 127 or fully -127. Is there a point where the motors are supposed to stop?? It seems like it will keep on shooting or keep on going one direction… May I get more information of how your catapult works or where the limit switches are located, and I can be able to make a program that will fix the issue?
I think you are on the right track, and have described your plan accurately in english. It might be smart to copy that text into your code as comments and create control structures that match. You are looking to have motor control for four conditions:
1:
(note, as soon as you start lowering the arm, the switch will go back to 0.)
2:
3:
(note, as soon as you start raising the arm, the switch will go back to 0.)
4: As others have mentioned, you need to stop the motors when no buttons are pressed.
Thanks for all the help! I think I fixed it, tell me if I’m wrong:
task usercontrol()
{
// User control code here, inside the loop
while (true)
{
//Joystick-to-Drive-Motors Mapping and Updating
//Left Side Wheels
motor[FrontLeftWheel] = vexRT[Ch3];
motor[MidLeftWheel] = vexRT[Ch3];
motor[BackLeftWheel] = vexRT[Ch3];
//Right Side Wheels
motor[FrontRightWheel] = vexRT[Ch2];
motor[MidRightWheel] = vexRT[Ch2];
motor[BackRightWheel] = vexRT[Ch2];
//TEST CODE FOR CATAPULT MOTORS:
//Mini pre-note to self & teammates: When referring to buttons, use Xbox controller button names for easy reference
//If the FRONT limit switch is pressed...
if (SensorValue[FrontLimit] == 1) {
// 1. If the Right Trigger is pressed, Shoot the catapult
while (vexRT[Btn6D] == 1) {
motor[BackLeftCatapult] = 127;
motor[BackRightCatapult] = 127;
motor[FrontLeftCatapult] = 127;
motor[FrontRightCatapult] = 127;
}
// 2. If Button "B" is pressed, Lift Robot up Pole
if (vexRT[Btn8R] == 1) {
while (SensorValue[BackLimit] == 0) {
motor[BackLeftCatapult] = -127;
motor[BackRightCatapult] = -127;
motor[FrontLeftCatapult] = -127;
motor[FrontRightCatapult] = -127;
}
}
motor[BackLeftCatapult] = 0;
motor[BackRightCatapult] = 0;
motor[FrontLeftCatapult] = 0;
motor[FrontRightCatapult] = 0;
}
//If the BACK Limit Switch is pressed...
if (SensorValue[BackLimit] == 1) {
// 1. If Button "A" is pressed, Pull down Catapult
if (vexRT[Btn8D] == 1) {
while (SensorValue[FrontLimit] == 0) {
motor[BackLeftCatapult] = 127;
motor[BackRightCatapult] = 127;
motor[FrontLeftCatapult] = 127;
motor[FrontRightCatapult] = 127;
}
}
motor[BackLeftCatapult] = 0;
motor[BackRightCatapult] = 0;
motor[FrontLeftCatapult] = 0;
motor[FrontRightCatapult] = 0;
}
//END OF TEST CODE
Now there’s a problem. I added the drive code In there for a reason. Today a mentor at school told me that while we’re moving the catapult, we wouldn’t be able to drive at the same time, because the program would be focusing on that while loop, not the drive part at the top. How do we fix this so that the drive code is ALWAYS running in the background and the code can continue on and we can operate the catapult at the same time as driving?
Change your whiles to ifs. When you let go of the button, vexRT[Btn6D] will be 0 and the condition will be false, resulting in that statement not executing. However, you code for buttons 8R and 8D will not execute while the limit switch is not pressed. Understand you can test multiple conditions at once … look up operators in robotC help. You also have more options than just if or while… look up control structures.
One possible way to look at it is that you always want the motors to stop when they reach the limits, so you could test if either of them are pressed and stop the motors:
if (frontSwitch == 1 || backSwitch == 1) // || is the operator for "or"
{
// stop motors
}
else
{
// check button presses to set the motion you want (might take multiple if statements)
}
Or you could test for each of your four situations separately using if, else if, else if, else:
if (8R == 1 && backSwitch == 0) // && is the operator for "and"
{
// raise the arm until the back switch is triggered
}
else if (8D == 1 && frontSwitch == 0)
{
// lower the arm until the front switch is triggered
}
else if (frontSwitch == 1 && 6D == 1)
{
// launch the catapult
}
else // no test condition required... if all of the above are false, this is executed
{
//stop motors
}
When you are using else if and else, it executes the first one that is true and ignores the rest.
if (SensorValue[FrontLimit] == 1) {
// 1. If the Right Trigger is pressed, Shoot the catapult
while (vexRT[Btn6D] == 1) {
motor[BackLeftCatapult] = 127;
motor[BackRightCatapult] = 127;
motor[FrontLeftCatapult] = 127;
motor[FrontRightCatapult] = 127;
}
// 2. If Button "B" is pressed, Lift Robot up Pole
if (vexRT[Btn8R] == 1) {
while (SensorValue[BackLimit] == 0) {
motor[BackLeftCatapult] = -127;
motor[BackRightCatapult] = -127;
motor[FrontLeftCatapult] = -127;
motor[FrontRightCatapult] = -127;
}
}
motor[BackLeftCatapult] = 0;
motor[BackRightCatapult] = 0;
motor[FrontLeftCatapult] = 0;
motor[FrontRightCatapult] = 0;
}
Now your catapult won’t move at all because it’s told to go a certain speed, then it was interrupted afterwards by being told to go 0… How about something along the lines of:
task usercontrol()
{
// User control code here, inside the loop
while (true)
{
//Joystick-to-Drive-Motors Mapping and Updating
//Left Side Wheels
motor[FrontLeftWheel] = vexRT[Ch3];
motor[MidLeftWheel] = vexRT[Ch3];
motor[BackLeftWheel] = vexRT[Ch3];
//Right Side Wheels
motor[FrontRightWheel] = vexRT[Ch2];
motor[MidRightWheel] = vexRT[Ch2];
motor[BackRightWheel] = vexRT[Ch2];
//TEST CODE FOR CATAPULT MOTORS:
//Mini pre-note to self & teammates: When referring to buttons, use Xbox controller button names for easy reference
//If the FRONT limit switch is pressed...
if (SensorValue[FrontLimit] == 1) {
// 1. If the Right Trigger is pressed, Shoot the catapult
if (vexRT[Btn6D] == 1) {
motor[BackLeftCatapult] = 127;
motor[BackRightCatapult] = 127;
motor[FrontLeftCatapult] = 127;
motor[FrontRightCatapult] = 127;
}
// 2. If Button "B" is pressed, Lift Robot up Pole
else if (vexRT[Btn8R] == 1) {
while (SensorValue[BackLimit] == 0) {
motor[BackLeftCatapult] = -127;
motor[BackRightCatapult] = -127;
motor[FrontLeftCatapult] = -127;
motor[FrontRightCatapult] = -127;
}
else{
motor[BackLeftCatapult] = 0;
motor[BackRightCatapult] = 0;
motor[FrontLeftCatapult] = 0;
motor[FrontRightCatapult] = 0;
}
}
}
//If the BACK Limit Switch is pressed...
if (SensorValue[BackLimit] == 1) {
// 1. If Button "A" is pressed, Pull down Catapult
if (vexRT[Btn8D] == 1) {
if (SensorValue[FrontLimit] == 0) {
motor[BackLeftCatapult] = 127;
motor[BackRightCatapult] = 127;
motor[FrontLeftCatapult] = 127;
motor[FrontRightCatapult] = 127;
}
else{
motor[BackLeftCatapult] = 0;
motor[BackRightCatapult] = 0;
motor[FrontLeftCatapult] = 0;
motor[FrontRightCatapult] = 0;
}
}
}
//END OF TEST CODE
Now there’s a problem. I added the drive code In there for a reason. Today a mentor at school told me that while we’re moving the catapult, we wouldn’t be able to drive at the same time, because the program would be focusing on that while loop, not the drive part at the top. How do we fix this so that the drive code is ALWAYS running in the background and the code can continue on and we can operate the catapult at the same time as driving?
Now there’s a problem. I added the drive code In there for a reason. Today a mentor at school told me that while we’re moving the catapult, we wouldn’t be able to drive at the same time, because the program would be focusing on that while loop, not the drive part at the top. How do we fix this so that the drive code is ALWAYS running in the background and the code can continue on and we can operate the catapult at the same time as driving?
Thanks a lot! I saw the changes you made and they really were better than the code I started off with. Thanks!
Thanks! I was just a little confused, because the link you posted by @jpearman said that tasks run in a round-robin fashion, and they take turns and go one after another, rather than simultaneously.