Non-blocking functions

#1

I want to use VCS C++ to make a non-blocking function (like a task in RobotC). I want to be able to call the function then have the rest of the code still run (I want to call a function to flip a cap, but still be able to drive during the flipping).

0 Likes

VCS V5 Encoder Autonomous
#2

Read this:
https://help.vex.com/article/120-how-to-use-blocking-vs-non-blocking-code

1 Like

#3

Not really what I’m looking for. This is my code. I want to be able to call the void from the if statement and have my driver controls still running
flipCap2.PNG
flipCap.PNG

0 Likes

#4

By default the rotateFor are blocking, you must have the parameter “true” to make it non-blocking.

Your code snippet for the cap flipper has them both blocking, if I am not mistaken.

From the API

//Set the velocity of the left and right motor to 50% power. This command will not make the motor spin.
LeftMotor.setVelocity(50, velocityUnits::pct);
RightMotor.setVelocity(50, velocityUnits::pct);

//Rotate the Left and Right Motor for degreesToRotate.
LeftMotor.rotateFor(degreesToRotate, rotationUnits::deg, false); //This command must be non blocking.
RightMotor.rotateFor(degreesToRotate, rotationUnits::deg); //This command is blocking so the program will wait here until the right motor is done.
//The motors will brake once they reach their destination.


http://help.vexcodingstudio.com/#cpp/namespacevex/classvex_1_1motor/rotateFor

1 Like

#5

What I’m trying to do is have the motor go [up then down] in the same function. If non-blocking it will just go down because it won’t have time to go up.

0 Likes

#6

The task I want it to do is in a [void] of its own. The if statement calls it.

0 Likes

#7

Well, you don’t really need to run it in its own task/thread to block the next part. You can read the encoder value and use motor.spin, then as you cycle through your while(true) of the driver control, you keep checking to see if you’ve reached your target. If you have, you swap directions.

For a task like this, I find the easiest way is to look for the event. Instead of using button.pressing, use button.pressed.

Controller1.ButtonA.pressed(flipCap);

You might put x=1 in at the beginning of flipCap. Also, make sure button.pressed isn’t being used inside the while(true) loop, because that will start up a crazy number of threads all doing the same check on the same button. You place it before the while(true) loop begins.

0 Likes

#8

You beat me to it, use the pressed method. It’s starting it’s own task/thread to do the work.

0 Likes

#9

Like this?
Capture.PNG

0 Likes

#10

That looks like it should do what you want.

0 Likes

#11

Yes, though I cannot see if you changed flipCap. If that x=1 and x=0 are critical, telling something else when certain processes are running, then just make your first line of flipCap x=1; and you should be all set.

0 Likes

#12

Already did that. I use it so that I can hit a button, it does the sequence, and I can’t do it again until it finishes. Will test tomorrow.

0 Likes

#13

Could I suggest you change “x” to “flipCapRunning” or something like that? As a general strategy while coding, its a good things to make reading your variables reveal what they mean. Otherwise, when you get to programs that are thousands of lines long with lots of different parts, it gets hard to keep track. Even commenting won’t save you entirely, because you’ll still have to go back to the comments to decipher things more than you should, which will take more time. So with my suggestion you might read “if(flipCapRunning)” instead of “if(x),” and I expect you can see how much more obvious the first one is. You’ll never regret starting this habit early.

0 Likes