Aloha all!
I need help with this one. My programming skills are unfortunately limited. How would I accomplish this? I have a feeling that I’m just using a function incorrectly.
Thank you!
Aloha all!
I need help with this one. My programming skills are unfortunately limited. How would I accomplish this? I have a feeling that I’m just using a function incorrectly.
Thank you!
I would argue that it is not in your best interest to have multiple or nested loops in programming. What you will find is that when your program enters an inner loop it will stop performing the tasks in the outer loop and could potentially lock you out of control if the inner loop fails to ever be true.
while (1){
// Drive robot
// Do some other commands
while(motorSpeed < 80)
{
motorSpeed++; //Speed up
wait(20);
//locked in this loop until it succeeds
}
}
The better method would be to use an if statement. You will most likely need the main while loop to run your OperatorControl function but when the if function runs it evaluates the code and then moves on.
while (1){
// Drive robot
// Do some other commands
if (motorSpeed < 80)
{
motorSpeed++; //Speed up
wait(20);
}
}
By using if statements you can use variables, timers, or sensor readings to determine when to call some code or another function.
Hope this helps. Otherwise, post an example of what you are trying to accomplish.
Thanks for the reply!
Let me explain:
The robot is set up with a conveyor belt for feeding, another belt for bringing the object to a shooter, and then a shooter. We are trying to first have the shooter spool up, and then have the belts feed into the shooter. We are having issues getting all of them to work at the same time (it’ll will do one function, stop, and then do the next one. It seems like the example you provided would work out though. Let me know what you think.
My students have a similar design. We have a top belt that feeds the flywheel and a bottom belt that feeds the top belt. This way we can have a ball in queue while we are loading additional balls. Here is a screenshot of the top belt function.
[attachment:56674071f24ad][attachment:56674071f24ad][attachment:56674071f24ad]
Ok, we will try something similar and report back. Thanks again!
So what you are asking for sounds like multi-tasking, where you run multiple tasks at once (duh). This is accomplished by writing custom tasks and using the “endTimeSlice()” function. Some pseudo code would look like this:
task customTaskOne(){
while(true){
//do things
endTimeSlice();
}
}
task customTaskTwo(){
while(true){
//do other things
endTimeSlice();
}
}
task userControl(){
while(true){
startTask(customTaskOne());
startTask(customTaskTwo());
}
}
This does have its limitations, though. Timers are dangerous with multitasking because multi-tasking works by splitting time between each task (hence “endTimeSlice()”), and timers interfere with this.
Ok thanks will look into that too!
What I do is I use the RegisterRepeatingTimer and CancelTimer functions.
If I needed to run the intake for 1 second, I would write something like this:
void runIntakeFor1Second(void)
{
SetMotor(intakeMotor, 127);
RegisterRepeatingTimer(1000, killIntake);
}
void killIntake(void)
{
SetMotor(intakeMotor, 0);
CancelTimer(killIntake);
}
This allows me to call runIntakeFor1Second, and I can run whatever other code I need to, and the intake will stop in one second.
So, EasyC, at least the last time I used it (almost a year ago), does not support multitasking. In RobotC, tasks still are not performed simultaneously, because the Cortex only has one processor available for use, and it only has one thread. RobotC simply allows the different tasks to be scheduled so as to run consecutively, but the same result can be accomplished with EasyC and if statements. It would look something like this (I don’t own a copy of EasyC):
Note: Commands are RobotC, I don’t know the EasyC versions.
while(true) {
if(condition) {
what you want it to do
} end if statement
} end while loop
This allows the program to exit the if statement once it has executed that code, then re-enter it when it hits the end of the big while loop.
An example when this would make a difference would be in the following:
while(true) {
while(vexRT[Btn5U] == 1) { //If button 5 Up is pressed
motor[intake] = 127; //set intake motor to full power in
}
motor[leftFrontDrive] = motor[leftRearDrive] = vexRT[Ch3]; //set left drive to left y-axis value
motor[rightFrontDrive] = motor[rightRearDrive] = vexRT[Ch2]; //set right drive to right y-axis value
}
This code would not allow you to run the intake at the same time as the drive. However, this one would:
while(true) {
if(vexRT[Btn5U] == 1) {
motor[intake] = 127;
}
motor[leftFrontDrive] = motor[leftRearDrive] = vexRT[Ch3];
motor[rightFrontDrive] = motor[rightRearDrive] = vexRT[Ch2];
}
Anyway, if your question was how to actually put the if/while loop inside the main, infinite loop, you simply drag and drop it inside the infinite loop, like you would with any other command.
awhile ago when i still used EasyC i was making a sort of scheduler, it wasn’t a co-routine style one though like RobotC has but rather it stored a list of function pointers you could dynamically add to and called each one in a loop, allowing you to sort of have different loops running at the same time but you had to make them asynchronous
The issue with this is other than looking slightly cooler and abstracted away from the user it still requires nonblocking code which means it is effectively the same as just writing the function call directly inside of your while loop in user control.
Make a statemachine to keep track of what you are doing and do the needful thing for the current state.
non-statemachine-serial method: problem is tank drive doesnt work in parallel
while(1){ setmotor(M1,100), wait 1s, setmotor(M1,0),setmotor(B,100),wait 1s, tankdrive() }
Best case in parallel, never use a wait(); better to use a timer and check it later.
With Statemachine, Arcade instructions keeps running in parallel.
#define Joy1 1 //Controller 1 and only
#define Down 1 //tophat/shoulder button alias down=1
#define M1 1 //Motor Port 1
#define M2 2 //Motor Port 2
#define M5 5 //Motor Port 5
#define M9 9 //Motor Port9
#define M10 10 //Motor Port10
#define Stk1 1 //Right joystick LR channel
#define Stk2 2 //Right joystick UD channel
#define Stk3 3 //Left joystick UD channel
#define NoInvert 0 //Drive command 0 is no inversion
#define Invert 1 //Drive command 1 is inversion
#define NoLimitSwitch 0 //Limit Switch Disable = 0
#define S_Init 0 //Statemachine initial state
#define S_StartA 1 //starting A
#define S_DoingA 2
#define S_StartB 3
#define S_DoingB 4
#define S_Idle 99
extern int get ;
extern int STATE ;
void main ( void ) {
STATE =S_STARTA ; // set starting state
while ( 1 ) {// repeats forever
switch ( STATE ) {
case S_StartA : {
StartTimer ( 1 ) ;
SetMotor ( M1 , 127 ) ;
STATE =S_DoingA ;
break ; } //SA
case S_DoingA : {
if ( GetTimer(1) > 1000 ){ // time is up, go on to next thing
SetMotor ( M1 , 0 ) ;
STATE =S_StartB ;
} // otherwise dont change STATE
break ; }//DA
case S_StartB : {
StartTimer ( 1 ) ;
SetMotor ( M10 , 127 ) ;
STATE =S_DoingB ;
break ; }//SB
case S_DoingB : {
if ( GetTimer(1) > 1000 ){ // time is up, go on to next thing
SetMotor ( M10 , 0 ) ;
STATE =S_Idle ;
} // otherwise dont change STATE
break ; }//DB
default : {// Idle case, or any STATE not listed above
if ( GetDigitalInput(1) ){ STATE =S_StartA ;} // start over when DI1 indicates we should
}//Default STATE
} // switch STATE
Arcade2 ( Joy1 , Stk2 , Stk1 , M9 , M2 , NoInvert , NoInvert ) ;
JoystickToServo ( Joy1 , Stk3 , M5 , Invert ) ;
} // wend (1)
} // main
If you have multiple independent tasks, you can make independent state-machine Switch{} blocks and independent STATE2 variables.