[RobotC] Programming order

Ok, I’m back with yet another programming issue!

Our team has a cap manipulator that we plan to rotate 180° on a toggled button, that is, click button, rotate 180° one way, click once more and it rotates back to the spot it started at. We have a potentiometer connected to the shaft to guage what degree of rotation the shaft is at, but we are having troubled ordering the program in such a way to allow this toggled button system to work. I believe the program follows this order:
If the specified button is pressed,
Sense what the shaft’s degree of rotation is,
If the degree is between 0 and 90,
While the degree is less than 175,
Motor turns one direction,
Else,
If the degree is between 91 and 250,
While the degree is greater than 5,
Motor turns opposite direction,
(And it would not let me add an selse here unless I was doing it wrong which is entirely possible)
Now my question is, how else can we make our program so that it actually works.

It’s a bit hard to tell why you can’t add the


else

without seeing the actual code (you’re most likely missing a curly brace or something like that). Here is your algorithm formatted like a program (correct me if I got the algorithm wrong):


if (vexRT[Btn8D]) {
    if (0 < degree && degree < 90) {
        while (degree < 175) {
            motor[m] = 127;
        }
    }
    else if (91 < degree && degree < 250) {
        while (degree > 5) {
            motor[m] = -127;
        }
    }
}

In the above code,


degree

is your potentiometer’s angle (in degrees) and


m

is the flipper motor. This assumes you want to use button 8D to flip, change that as you see fit.

This should work fine as long as you run it in a separate task- otherwise the


while

loops will freeze your code until the cap flips, not allowing you to drive. Here is a good description of how tasks work in RobotC. Basically you’ll want to format your code like this:


task flipperTask() {
    while (true) {
        // put your flipper code here
    }
}

Then you just need to run


startTask(flipperTask);

at the beginning of


usercontrol

(before your infinite loop).

One potential issue of your algorithm is momentum. You should definitely run the code and see how well it works, but depending on how your robot is built there is a very real possibility that the momentum of the motor will spin the flipper too far after the motor turns off. If something like this happens you should implement a proportional control. There are many good tutorial online, but your algorithm would need some special modifications as to not break your toggling functionality, so if you are interested feel free to PM me and I’ll be glad to help.

I will post the actual code once I get access to it, but one thing I know for sure is that the way you are sensing degrees is different than the way I am. I have an If(sensorvalue= 0-90){rest of code} not the way you did it, so ill redo the code to look more like yours. I wasn’t confident that 0-90 would work as sensing a range, but it didn’t give me any errors, so I didn’t question it.

And as far as the mementum thing, I only rotate the motor at 40/127 speed to try to counteract the possible momentum problem.

To solve this problem, you would have to develop a toggle in ROBOTC which would output an integer value that can be used to change positions.
Try something similar to this (I don’t have ROBOTC installed on this computer so I cannot copy things over, rather more just make the program on this vexforum):


task main() {

int buttonPressed = false;
int wristPosition = 1;

while(1 == 1) {

/* Toggle which would switch between two integer values when button pressed */

//Activate this block when button is pressed and hasn't been pressed in the past.
if(vexRT[Btn6U] == 1 && buttonPressed == false){ 
buttonPressed = true; //Sets buttonPressed to true to prevent this block from running a second time

//This switches the value of wristPosition to be able to output a consistent value
//NOTE: Make sure the second block is an "else if" or "else" statement, not an if statement.
if(wristPosition == 1) {
wristPosition = 2;
}
else if(wristPosition == 2) {
wristPosition = 1;
}

}
//Resets the buttonPressed value to false to make the block above be able to be ran again
else if(vexRT[Btn6U] == 0) { 
buttonPressed = false;
}

/*Apply the output integer "wristPosition" to the wrist*/
if(wristPosition == 1) {
//Apply a control loop for the wristhere for position one
}
else {
//Apply a control loop for the wrist here for position two
}

}
}

If I were you I would also add some code that slows down the motor the closer it gets to it’s end position, this will make the flip more accurate. Either this or add a mechanical stop aswell as the current code

This is the code

   if(vexRT[Btn7D] == 1){
    if(SensorValue[MPot] < 1150){
     while(SensorValue[MPot] > 1){
    	motor[Manipulator] = 40;
   }}
   else
    if(SensorValue[MPot] > 1150){
     while(SensorValue[MPot] < 2750){
     	motor[Manipulator] = -40;

Because you’re asking for such values, are you certain that it’s not an encoder?
For a simple controller with something like a wrist that doesn’t require much accuracy to place the caps I usually stick with a P loop. With a P loop with a potentiometer/encoder you would do something like this (Note, you would have to tune with the kP a bit to change slope/sensitivity of the approach):


/*Apply the output integer "wristPosition" to the wrist*/
if(wristPosition == 1) {
motor[wrist] = -((SensorValue[Pot] - 175) * 0.9);//"175" is the value to approach, "0.9" is kP or slope of power.
}
else {
motor[wrist] = -((SensorValue[Pot] + 5) * 0.9);//"175" is the value to approach, "0.9" is kP or slope of power.
}

When applying this all together you would get something like this:


task main() {

int buttonPressed = false;
int wristPosition = 1;

while(1 == 1) {

/* Toggle which would switch between two integer values when button pressed */

//Activate this block when button is pressed and hasn't been pressed in the past.
if(vexRT[Btn6U] == 1 && buttonPressed == false){ 
buttonPressed = true; //Sets buttonPressed to true to prevent this block from running a second time

//This switches the value of wristPosition to be able to output a consistent value
//NOTE: Make sure the second block is an "else if" or "else" statement, not an if statement.
if(wristPosition == 1) {
wristPosition = 2;
}
else if(wristPosition == 2) {
wristPosition = 1;
}

}
//Resets the buttonPressed value to false to make the block above be able to be ran again
else if(vexRT[Btn6U] == 0) { 
buttonPressed = false;
}

/*Apply the output integer "wristPosition" to the wrist*/
if(wristPosition == 1) {
motor[wrist] = -((SensorValue[Pot] - 175) * 0.9);//"175" is the value to approach, "0.9" is kP or slope of power.
}
else {
motor[wrist] = -((SensorValue[Pot] + 5) * 0.9);//"175" is the value to approach, "0.9" is kP or slope of power.
}

}
}