Robot Autonomous Not Move Robot

Um our robot doesnt even move with this program, anyone know why?
v5code-project-IchAbzuleckenDieKiwi.zip (15.6 KB)

Could you post your code on the fourm.

Specifically the autonomous portion, as well as check that the auton is actually called at some point.

Oh and preferably as either a screenshot or paste the code into the post so that we don’t have to download anything.

1 Like

Yeah, sorry about that.

//Autonomous
void autonomous(void) {
//Reset Encoders
RightDriveEncoder.resetRotation();
LeftDriveEncoder.resetRotation();
BackDriveEncoder.resetRotation();

LeftDrive.setVelocity(15, percent);
RightDrive.setVelocity(15, percent);
LeftIntake.setVelocity(100, percent);
RightIntake.setVelocity(100, percent);
TopSnail.setVelocity(100, percent);
BottomSnail.setVelocity(100, percent);

while(true){
 RightCurrentValue = RightDriveEncoder.value();

 if(RightPreviousValue == 0){
      RightPreviousValue = RightCurrentValue;
 }
 else{
 RightChange = RightCurrentValue - RightPreviousValue;
 RightPreviousValue = RightCurrentValue;  
 }
 wait(100, msec);
}

 while(true){
 LeftCurrentValue = LeftDriveEncoder.value();

 if(LeftPreviousValue == 0){
      LeftPreviousValue = LeftCurrentValue;
 }
 else{
 LeftChange = LeftCurrentValue - LeftPreviousValue;
 LeftPreviousValue = LeftCurrentValue;  
 }
 wait(100, msec);
}

while(true){
 BackCurrentValue = BackDriveEncoder.value();

 if(BackPreviousValue == 0){
      BackPreviousValue = BackCurrentValue;
 }
 else{
 BackChange = BackCurrentValue - BackPreviousValue;
 BackPreviousValue = BackCurrentValue;  
 }
 wait(100, msec);
}

Controller1.rumble(rumbleShort);

//Run into tower
RightDrive.spin(forward);
LeftDrive.spin(forward);

waitUntil(TowerLimitSwitch.pressing());

//Score ball
TopSnail.spinFor(forward, 5, turns, false);
BottomSnail.spinFor(forward, 5, turns, false);

waitUntil(TopSnail.isDone());
vex::task::sleep (50);

//Back up
RightDrive.spinFor(forward, -5, turns, false);
LeftDrive.spinFor(forward, -5, turns, false);



waitUntil(LeftChange = -5);
vex::task::sleep (500);

//Turn
BackDrive.spinFor(forward, 1, turns, false);

waitUntil(BackChange = 1);
vex::task::sleep (50);

//Forward, to goal
RightDrive.spin(forward);
LeftDrive.spin(forward);

waitUntil(TowerLimitSwitch.pressing());

//Score ball
TopSnail.spinFor(forward, 5, turns, false);
BottomSnail.spinFor(forward, 5, turns, false);

waitUntil(TopSnail.isDone());
vex::task::sleep (50);

//Back up
RightDrive.spinFor(forward, -1, turns, false);
LeftDrive.spinFor(forward, -1, turns, false);

waitUntil(RightChange = -1);
vex::task::sleep (50);

//Stop
RightDrive.stop();
LeftDrive.stop();
BackDrive.stop();
}

It’s because you have the while true loop. The program would just run the first loop forever.

1 Like

The programs I want to run forever are in the loops. The rest aren’t in it.

Are those loops supposed to be in another place?

What I mean is that the program would just run the first forever loop forever. What you should do instead is create a task and run that in the background. I am not very familiar with tasks so I can’t help you there. I understand that you are using it for some sort of position tracking but you would have to run a separate task or it won’t work.

1 Like

What he means is right now the code will never get past the first while loop. That means the only thing it will ever do is set the right encoder. It will keep looping

while(true){
RightCurrentValue = RightDriveEncoder.value();
if(RightPreviousValue == 0){
RightPreviousValue = RightCurrentValue;
}
else{
RightChange = RightCurrentValue - RightPreviousValue;
RightPreviousValue = RightCurrentValue;
}
wait(100, msec);
}

and never get past this.

Your robot will not be able to continuously update the encoder values with the way you have it set up because you cannot multitask.

I am confused as to why you are using these loops. You are essentially just trying to check whether the move is complete before moving on, yes? If so, why not just set the last parameter on the last movement to true?

Please let me know if I misunderstood your coding intentions. Hope this helps

1 Like

These programs are defining values I need to code odometry, but I am not quite there yet, obviously. I’m not sure how to do it. If I can’t put them in the autonomous, where can I put them? Also, is using encoders like I have any different than just using normal rotations?

One way to do this is to use methods. Basically, a certain line of code can be called and given parameters. (The competition template uses this) This way you can have those loops executing while your robot drives.
this and this should help understand methods.

The basic pseudocode our team uses is as follows

 driveFunction(int target)
{
while(robot has not reached it's target)
{
Your PID/odometry stuff here
}
}

This method will be running the entire movement, and then stop once the robot has hit it’s target, letting you call another movement. So your drive code would look like

drive(your target here)
drive(another target here)

and so on.

I don’t blame you if you are extremely confused, but there are a lot of other tutorials about this kind of thing on the forums and on youtube. The one that I used to learn this concept is here, but there are other good ones as well.

In regards to your second question, I’m guessing your asking whether it’s worth having an external encoder wheel, versus using motor.position(). In general, an external encoder is considered more accurate, but we use the internal motor encoders and it works fine with no extra building needed.

I hope this helps.

2 Likes

So I made a function, with all the looped coding inside of it. How exactly do I call it in the autonomous? Also, the “int RightChange” programs since they are not in the autonomous, are not recognized when I try to use them in the autonomous programming. Thank you, this has really been a great help.

Q1:

Assuming your method name is

name(int number)
{code}

you would call it like

name(1);

Q2:
Put your variable declarations outside the methods at the beginning of the program. This will define them as global variables and they can be used by all methods.

1 Like

I named the function the loops are in “encoding”, and wrote this.

while(encoding) {


RightDrive.spin(forward);

waitUntil(RightCurrentValue = 1);
}

It says “ecoding” will be ignored and will just use it as the “true” function

1 Like

I’m a bit confused here. Is this inside of a method called encoding()? If so, you can’t just have the name of the method be the parameter in your while loop.

Your Loop should Loop until your Target and your current value are basically the same for example

while(abs(target-error)>a small number)

Does this help???

1 Like

So this is the code for the function I mentioned. Is this right?

int RightPreviousValue;
int RightCurrentValue;
int RightChange;
int LeftCurrentValue;
int LeftPreviousValue;
int LeftChange;
int BackPreviousValue;
int BackCurrentValue;
int BackChange; 

void encoding() {


while(true){
RightCurrentValue = RightDriveEncoder.value();

if(RightPreviousValue == 0){
  RightPreviousValue = RightCurrentValue;
}
else{
RightChange = RightCurrentValue - RightPreviousValue;
RightPreviousValue = RightCurrentValue;  
}
wait(100, msec);
} 

   while(true){
   LeftCurrentValue = LeftDriveEncoder.value(); 

if(LeftPreviousValue == 0){
   LeftPreviousValue = LeftCurrentValue;
}
else{
LeftChange = LeftCurrentValue - LeftPreviousValue;
LeftPreviousValue = LeftCurrentValue;  
}
wait(100, msec);
}

while(true){
BackCurrentValue = BackDriveEncoder.value(); 

if(BackPreviousValue == 0){
  BackPreviousValue = BackCurrentValue;
}
else{
BackChange = BackCurrentValue - BackPreviousValue;
BackPreviousValue = BackCurrentValue;  
}
wait(100, msec);
}
}

Also, happy cakeday,

1 Like

All your updates need to be in one big while loop otherwise the code will only run the first one and never move past it.

Also, thanks.

2 Likes

First, I apologise for the very long winded response…

So lets break down the needs of your robot in autonomous. From what I understand, you need to (1.) read your encoders, (2.) update your position from odometry, (3.) update the motor speed according to the goal position on the field. This motion could be “blind” or just a move for time or distnace, or based on the odometry information.

Remember that a robot can only execute one command at a time. When a function is called like autonomous(), it will run commands one-by-one from top to bottom unless something else redirects the program flow. The while() statment will force the program to loop through the commands inside of its brackets as long as the the condition inside of it is true or nonzero. In your function, this is the only code that will run.

 void autonomous(void) {
   //Reset Encoders
   RightDriveEncoder.resetRotation();
   LeftDriveEncoder.resetRotation();
   BackDriveEncoder.resetRotation();

   LeftDrive.setVelocity(15, percent);
   RightDrive.setVelocity(15, percent);
   LeftIntake.setVelocity(100, percent);
   RightIntake.setVelocity(100, percent);
   TopSnail.setVelocity(100, percent);
   BottomSnail.setVelocity(100, percent);

    while(true){
     RightCurrentValue = RightDriveEncoder.value();

     if(RightPreviousValue == 0){
          RightPreviousValue = RightCurrentValue;
     }
     else{
     RightChange = RightCurrentValue - RightPreviousValue;
     RightPreviousValue = RightCurrentValue;  
     }
     wait(100, msec);
    }

Because the while statement is always true, the other loops will not be able to run. Your code is essentially copying and pasting these lines forever.

As a general rule, you only want one while loop running at a time. I will describe an exception to this rule later. Your robot must do all needed tasks(odometry, motors,etc.) within this while loop. Here is a super high-level overview of what the code might look like.

void odometryUpdate()
{
  // update the odometry/encoder info(no while loop)
}
void driveTo(/*Inputs, speed, location, etc)*/
{
  while(/* not at target*/)
  {
    // update the odometry information
    odometryUpdate();
    // do things to get you to location
  }
}

void autonomous(void)
{
   driveTo(/*where am I going*/);
...
}

Notice I only placed one while loop in the driveTo function. driveTo updated the odometry at every step as well as running the motors. In order to run multiple while loops, you need to use something called tasks, which allow for multiple functions to run at the same time. This is advanced coding which I don’t recommend you use for the moment. I have added a link to some discussion about this coding stategy below.

3 Likes

Okay, I understand what that means now. Thank you. I can’t have the while loops inside the autonomous. So I put them into the odometryUpdate() part, but how do I code that without the while loops? Also, how exactly and what do I put inside of the driveTo parenthesis?

So with the odometryUpdate() in my example, I was intending there to be no while loop there as well. This would read the encoders, and update the odometry variables once. If you look at the driveTo function, you find

void driveTo(/*Inputs, speed, location, etc)*/
{
  while(/* not at target*/)
  {
    // update the odometry information
    odometryUpdate();
    // do things to get you to location
  }
}

Notice that I have an odometryUpdate(); command. This runs the odometry function. Since this function is placed in line with the rest of the commands for the driveTo function, the driveTo command runs the odometry once before running any of the drivetrain code. Because its in a while loop, the odometryUpdate() function is run many times along with the drivetrain control commands. The driveTo() function should have inputs needed to get your robot to go somewhere. For example in an odometry system…

driveTo(float x, float y, float speed)

If I made the function inputs this way, I could control where I wanted to go and how fast I wanted to do that. This is ultimately up to you. The code example was more psuedo-code, which is just a template or “rough draft” than anything. When writing psuedo-code, I am trying to lay out how I want the code to work before I try to make the final working program.

2 Likes