Log in

View Full Version : Autonomous Help


curtis0gj
19-01-2015, 18:12
Hey all, newbie programmer here looking for some help with my autonomous code. At the moment I need to be able to turn 90 on the spot using a gyro stop and drive straight also using a gyro and encoder for distance.

public void autonomous() {

while(isAutonomous() && isEnabled()) {

SmartDashboard.putNumber("angle", gyro1.getAngle());

double angle = gyro1.getAngle();

robot.drive(-0.20, 1);

if(angle > 83) {

robot.drive(0,0);

break;

The issue I have is the robot won't stop turning :mad: . I need a basic tutorial on setting up an encoder for distance. Also if anyone could show me how I could start driving straight after this turn, Thanks for the help.

curtis0gj
19-01-2015, 19:31
Hey all, newbie programmer here looking for some help with my autonomous code. At the moment I need to be able to turn 90 on the spot using a gyro stop and drive straight also using a gyro and encoder for distance.

public void autonomous() {

while(isAutonomous() && isEnabled()) {

SmartDashboard.putNumber("angle", gyro1.getAngle());

double angle = gyro1.getAngle();

robot.drive(-0.20, 1);

if(angle > 83) {

robot.drive(0,0);

break;

The issue I have is the robot won't stop turning :mad: . I need a basic tutorial on setting up an encoder for distance. Also if anyone could show me how I could start driving straight after this turn, Thanks for the help.

I think I have solved this but I don't have a way of testing it until tomorrow, I think the issue is the double angle = gyro1.getAngle(); is in the while loop so it's just getting the angle over and over... But I still need help with setting up an encoder if anyone could help that would be great!

curtis0gj
19-01-2015, 19:53
I think I have solved this but I don't have a way of testing it until tomorrow, I think the issue is the double angle = gyro1.getAngle(); is in the while loop so it's just getting the angle over and over... But I still need help with setting up an encoder if anyone could help that would be great!

Quoting my self for a third time lol.... I spent a bit more time trying to setup the straight driving and what I did was created a new boolean and set it to true and made an if loop that it will enter if its == to true.public void autonomous() {

double angle = gyro1.getAngle();

while(isAutonomous() && isEnabled()) {

SmartDashboard.putNumber("angle", gyro1.getAngle());

robot.drive(-0.20, 1);

if(angle > 83) {

robot.drive(0,0);

break;


}

//do i need to reset my gryo? do i need to place my get angle here?


boolean turnCompleted = true;

if(turnCompleted == true) {

double angle2 = gyro1.getAngle(); // i think for driving i need a constant update of my angle
//so i will place this inside my if loop and i name it angle2 so it's a different variable.
robot.drive(-1.0, -angle2*Kp); // driving straight in a line.
Timer.delay(0.004);


}

}
} If anyone has any ideas for improvement for this please let me know.:yikes:

notmattlythgoe
20-01-2015, 14:16
I think I can give you a hand Curtis. Could you please list step by step what it is you want your autonomous mode to do?

curtis0gj
20-01-2015, 15:45
I think I can give you a hand Curtis. Could you please list step by step what it is you want your autonomous mode to do?

Hi, thanks for the reply so basically what I am looking to do is make a 180 degree turn stop and drive straight forward for a set distance via encoder. However our team only has one encoder currently I don't know if this will be a problem. Today I figured out the turn finally and I added in the straight away however I am stuck in a loop I believe here's my current program
public void autonomous() {

gyro1.reset();

while(isAutonomous() && isEnabled()) {

double angle = gyro1.getAngle();

SmartDashboard.putNumber("angle", gyro1.getAngle());

robot.drive(-0.15, 1);
Timer.delay(0.1);

if(angle > 160) {

robot.drive(0,0);
gyro1.reset();
Timer.delay(1.00);

turnComplete = false;
break;




}
}
turnComplete = true;
gyro1.reset();
while (turnComplete == true) {


double angle2 = gyro1.getAngle(); // i think for driving i need a constant update of my angle
//so i will place this inside my if loop and i name it angle2 so it's a different variable.
robot.drive(-0.15, -angle2 * Kp); // driving straight in a line.
Timer.delay(0.004);

if(isAutonomous() && isDisabled()) {
robot.drive(0,0);
turnComplete = false;
break;
}


}



}

notmattlythgoe
20-01-2015, 17:01
Curtis,

You have indeed made some progress, let's go through your program and talk about what is going on.

First, at the beginning of the autonomous period the autonomous() method is called. Anything in this method will run during the autonomous period.

public void autonomous() {
...
}


There are 2 routes you can take to program this:

[1] You can create different loops that do different things and as one loop finishes the next loop starts. This is the route that you have taken, so I will help you finish this.

[2] You can create one loop that has different checks in it to determine what to do each time.

What we you will want to do is have a loop that looks like the below for each stage of your autonomous period. If you do not check if autonomous mode is running and that you are enabled then you run the risk of getting stuck in autonomous for the entire match.

while(isAutonomous() && isEnabled()) {
...


Let's examine your first loop, which you are using to turn 180 degrees:

while(isAutonomous() && isEnabled()) {

[1] double angle = gyro1.getAngle();

[2] SmartDashboard.putNumber("angle", gyro1.getAngle());

[3] robot.drive(-0.15, 1);
[4] Timer.delay(0.1);

[5] if(angle > 160) {

[5a] robot.drive(0,0);
[5b] gyro1.reset();
[5c] Timer.delay(1.00);

[5d] turnComplete = false;
[5e] break;
}
}


Each time the loop executes it follows the following logic while the robot is in the autonomous period:
[1] Get the current gyro angle
[2] Put the current gyro angle on the SmartDashboard
[3] Drive backward at 15% speed and spin at full speed
[4] Delay the loop code for 0.1 seconds
[5] If the angle is > 160 do the folowing
[5a] Stop the robot
[5b] Reset the gyro
[5c] Delay the loop code for 1 second
[5d] Set turnComplete to false
[5e] Break the current loop and continue on with the code

[1] is done correctly.
[2] is also working, but since you have the angle already, it is better convention to use the variable already holding it. Let's change this line to:

SmartDashboard.putNumber("angle", angle);

[3] will work, but the number seem odd to me. I'd need more information about your robot setup to direct you to the proper numbers.
[4] works, but let's move it the end of the loop instead. Place it right below the closing } for your if statement.
[5], [5a], and [5b] are perfect
[5c] I'm assuming you are wanting to pause for a second after you finish your turn. If this is the case this is fine where it is.
[5d] I'm going to get you to remove this line, we won't need it later.
[5e] is also perfect

Now, let's look at your next loop:

[1] turnComplete = true;
[2] gyro1.reset();
[3] while (turnComplete == true) {

[4] double angle2 = gyro1.getAngle();

[5] robot.drive(-0.15, -angle2 * Kp); // driving straight in a line.
[6] Timer.delay(0.004);

[7] if(isAutonomous() && isDisabled()) {
[7a] robot.drive(0,0);
[7b] turnComplete = false;
[7c] break;
}
}


[1] We're not going to use this because it is unneeded, so let's delete this line.
[2] You actually already did this in the loop above, so you can either remove this line, or the identical line in the other loop.
[3] Let's make this loop run with the same check as the other loop. The reason why is if the autonomous mode ends and this loop hasn't finished then it will automatically finish.
[4] This line works just fine.
[5] This should work to keep you moving in a straight line, you'll just need to tune the Kp value to get it perfect.
[6] Any reason you are waiting for 0.004 seconds?
[7] We will change this line later to read the encoder distance and determine if we need to stop. For now let's make it:

if (false) {

[7a] This is good.
[7b] Let's remove this since we aren't using it.
[7c] This is also good

Let me know if you have any questions about what I've said so far.

curtis0gj
20-01-2015, 18:01
Curtis,

You have indeed made some progress, let's go through your program and talk about what is going on.

First, at the beginning of the autonomous period the autonomous() method is called. Anything in this method will run during the autonomous period.

public void autonomous() {
...
}


There are 2 routes you can take to program this:

[1] You can create different loops that do different things and as one loop finishes the next loop starts. This is the route that you have taken, so I will help you finish this.

[2] You can create one loop that has different checks in it to determine what to do each time.

What we you will want to do is have a loop that looks like the below for each stage of your autonomous period. If you do not check if autonomous mode is running and that you are enabled then you run the risk of getting stuck in autonomous for the entire match.

while(isAutonomous() && isEnabled()) {
...


Let's examine your first loop, which you are using to turn 180 degrees:

while(isAutonomous() && isEnabled()) {

[1] double angle = gyro1.getAngle();

[2] SmartDashboard.putNumber("angle", gyro1.getAngle());

[3] robot.drive(-0.15, 1);
[4] Timer.delay(0.1);

[5] if(angle > 160) {

[5a] robot.drive(0,0);
[5b] gyro1.reset();
[5c] Timer.delay(1.00);

[5d] turnComplete = false;
[5e] break;
}
}


Each time the loop executes it follows the following logic while the robot is in the autonomous period:
[1] Get the current gyro angle
[2] Put the current gyro angle on the SmartDashboard
[3] Drive backward at 15% speed and spin at full speed
[4] Delay the loop code for 0.1 seconds
[5] If the angle is > 160 do the folowing
[5a] Stop the robot
[5b] Reset the gyro
[5c] Delay the loop code for 1 second
[5d] Set turnComplete to false
[5e] Break the current loop and continue on with the code

[1] is done correctly.
[2] is also working, but since you have the angle already, it is better convention to use the variable already holding it. Let's change this line to:

SmartDashboard.putNumber("angle", angle);

[3] will work, but the number seem odd to me. I'd need more information about your robot setup to direct you to the proper numbers.
[4] works, but let's move it the end of the loop instead. Place it right below the closing } for your if statement.
[5], [5a], and [5b] are perfect
[5c] I'm assuming you are wanting to pause for a second after you finish your turn. If this is the case this is fine where it is.
[5d] I'm going to get you to remove this line, we won't need it later.
[5e] is also perfect

Now, let's look at your next loop:

[1] turnComplete = true;
[2] gyro1.reset();
[3] while (turnComplete == true) {

[4] double angle2 = gyro1.getAngle();

[5] robot.drive(-0.15, -angle2 * Kp); // driving straight in a line.
[6] Timer.delay(0.004);

[7] if(isAutonomous() && isDisabled()) {
[7a] robot.drive(0,0);
[7b] turnComplete = false;
[7c] break;
}
}


[1] We're not going to use this because it is unneeded, so let's delete this line.
[2] You actually already did this in the loop above, so you can either remove this line, or the identical line in the other loop.
[3] Let's make this loop run with the same check as the other loop. The reason why is if the autonomous mode ends and this loop hasn't finished then it will automatically finish.
[4] This line works just fine.
[5] This should work to keep you moving in a straight line, you'll just need to tune the Kp value to get it perfect.
[6] Any reason you are waiting for 0.004 seconds?
[7] We will change this line later to read the encoder distance and determine if we need to stop. For now let's make it:

if (false) {

[7a] This is good.
[7b] Let's remove this since we aren't using it.
[7c] This is also good

Let me know if you have any questions about what I've said so far.

So far so good thanks a ton for the help here's what I have right now with these fixes
public void autonomousPeriodic() {

gyro1.reset();

while(isAutonomous() && isEnabled()) {

double angle = gyro1.getAngle();

SmartDashboard.putNumber("angle", angle);

robot.drive(-0.25, 1);

if(angle > 150) {

robot.drive(0,0);
gyro1.reset();
Timer.delay(1.00);

Timer.delay(0.1);
break;

}
}


while (isAutonomous() && isEnabled()) {

double angle2 = gyro1.getAngle();

robot.drive(-0.20, -angle2 * Kp);

if(false) {
robot.drive(0,0); //It's calling all this dead code ):

break;
}

}


} Now I just need some help with that encoder and that would be perfect, thanks a ton! :)

notmattlythgoe
21-01-2015, 08:05
So far so good thanks a ton for the help here's what I have right now with these fixes
public void autonomousPeriodic() {

gyro1.reset();

while(isAutonomous() && isEnabled()) {

double angle = gyro1.getAngle();

SmartDashboard.putNumber("angle", angle);

robot.drive(-0.25, 1);

if(angle > 150) {

robot.drive(0,0);
gyro1.reset();
Timer.delay(1.00);

Timer.delay(0.1);
break;

}
}


while (isAutonomous() && isEnabled()) {

double angle2 = gyro1.getAngle();

robot.drive(-0.20, -angle2 * Kp);

if(false) {
robot.drive(0,0); //It's calling all this dead code ):

break;
}

}


} Now I just need some help with that encoder and that would be perfect, thanks a ton! :)

Move Timer.delay(0.1) down below the first if statement. Also add another one below the second if statement. It should look like this:

public void autonomousPeriodic() {
gyro1.reset();
while(isAutonomous() && isEnabled()) {
double angle = gyro1.getAngle();
SmartDashboard.putNumber("angle", angle);
robot.drive(-0.25, 1);

if(angle > 150) {
robot.drive(0,0);
gyro1.reset();
Timer.delay(1.00);
break;
}
Timer.delay(0.1);
}

while (isAutonomous() && isEnabled()) {
double angle2 = gyro1.getAngle();
robot.drive(-0.20, -angle2 * Kp);

if(false) {
robot.drive(0,0); //It's calling all this dead code ):
break;
}
Timer.delay(0.1);
}
}


You are correct in your comment, that section of code is unreachable right now. Once we add in an encoder it will get fixed.

Do create an encoder you'll do something like this:

Encoder encoder = new Encoder(1, 2, false, EncodingType.k4X);

The first 2 parameters are the digital channels the encoder is plugged into. The next parameter will allow you to reverse the direction of the encoder if you decide that you want it to count in the opposite direction. The 4th parameter is the type of encoder you are using. For this case I'm going to assume you are using a quadrature encoder.

Next lets configure the encoder. Configuring an encoder correctly will make your life that much easier when you want to use it.


encoder.setDistancePerPulse(0.001);

Setting a value in this method will allow you to get readings from the encoder that actually mean something. Figure out how far your robot moves in one rotation of the encoder, then divide that distance by the number of counts your encoder has.

Then, to get the reading all you have to do is call the below method, this method will return how far the encoder has. If you have configured the encoder with the correct distance per pulse then it will return how far your robot has moved.

encoder.getDistance();


Now that we have an encoder we can plug it into your code. Replace the false with a check to see if you have traveled the distance you want.

curtis0gj
21-01-2015, 08:12
Move Timer.delay(0.1) down below the first if statement. Also add another one below the second if statement. It should look like this:

public void autonomousPeriodic() {
gyro1.reset();
while(isAutonomous() && isEnabled()) {
double angle = gyro1.getAngle();
SmartDashboard.putNumber("angle", angle);
robot.drive(-0.25, 1);

if(angle > 150) {
robot.drive(0,0);
gyro1.reset();
Timer.delay(1.00);
break;
}
Timer.delay(0.1);
}

while (isAutonomous() && isEnabled()) {
double angle2 = gyro1.getAngle();
robot.drive(-0.20, -angle2 * Kp);

if(false) {
robot.drive(0,0); //It's calling all this dead code ):
break;
}
Timer.delay(0.1);
}
}


You are correct in your comment, that section of code is unreachable right now. Once we add in an encoder it will get fixed.

Do create an encoder you'll do something like this:

Encoder encoder = new Encoder(1, 2, false, EncodingType.k4X);

The first 2 parameters are the digital channels the encoder is plugged into. The next parameter will allow you to reverse the direction of the encoder if you decide that you want it to count in the opposite direction. The 4th parameter is the type of encoder you are using. For this case I'm going to assume you are using a quadrature encoder.

Next lets configure the encoder. Configuring an encoder correctly will make your life that much easier when you want to use it.


encoder.setDistancePerPulse(0.001);

Setting a value in this method will allow you to get readings from the encoder that actually mean something. Figure out how far your robot moves in one rotation of the encoder, then divide that distance by the number of counts your encoder has.

Then, to get the reading all you have to do is call the below method, this method will return how far the encoder has. If you have configured the encoder with the correct distance per pulse then it will return how far your robot has moved.

encoder.getDistance();


Now that we have an encoder we can plug it into your code. Replace the false with a check to see if you have traveled the distance you want.

Would the if statement be if(encoder.getDistance > 50) work at all?

notmattlythgoe
21-01-2015, 08:14
Would the if statement be if(encoder.getDistance > 50) work at all?

Add parameters to your method call and it's perfect.

curtis0gj
21-01-2015, 08:33
Add parameters to your method call and it's perfect.

I think I have this right but before we wrap this up I just wanted to check a few things. Do I need < , > or ==. Also I would like to print a distance traveled to my smart DS is that just SmartDashboard.putNumber("Distance", encoder.getDistance()); or can I make a double distance = encoder.getDistance(); and just put distance in there?? Here's my code so far. public class Robot extends IterativeRobot {

RobotDrive robot;
Joystick stick;
Encoder encoder;
Gyro gyro1;

static final double Kp = 0.05;

public void robotInit() {

robot = new RobotDrive(0, 1);
stick = new Joystick(0);
gyro1 = new Gyro(0);
gyro1.reset();
gyro1.initGyro();
Encoder encoder = new Encoder(1, 2, false, EncodingType.k4X);

encoder.setDistancePerPulse(0.001);
encoder.getDistance(); // does this belong in the init or my if loop?

}


public void autonomousPeriodic() {

gyro1.reset();

while(isAutonomous() && isEnabled()) {

double angle = gyro1.getAngle();

SmartDashboard.putNumber("angle", angle);

robot.drive(-0.25, 1);

if(angle > 150) {

robot.drive(0,0);
gyro1.reset();
Timer.delay(1.00);

break;

}

Timer.delay(0.1);
}

while (isAutonomous() && isEnabled()) {

double angle2 = gyro1.getAngle();

robot.drive(-0.20, -angle2 * Kp);
// This can't be right lol..... at least its no longer dead code (: also in my if statement do i need < or > or ==?
if(encoder.getDistance() > 50) {
robot.drive(0,0);

break;
}
Timer.delay(0.1);
}

}

notmattlythgoe
21-01-2015, 08:43
I think I have this right but before we wrap this up I just wanted to check a few things. Do I need < , > or ==. Also I would like to print a distance traveled to my smart DS is that just SmartDashboard.putNumber("Distance", encoder.getDistance()); or can I make a double distance = encoder.getDistance(); and just put distance in there?? Here's my code so far. public class Robot extends IterativeRobot {

RobotDrive robot;
Joystick stick;
Encoder encoder;
Gyro gyro1;

static final double Kp = 0.05;

public void robotInit() {

robot = new RobotDrive(0, 1);
stick = new Joystick(0);
gyro1 = new Gyro(0);
gyro1.reset();
gyro1.initGyro();
Encoder encoder = new Encoder(1, 2, false, EncodingType.k4X);

encoder.setDistancePerPulse(0.001);
encoder.getDistance(); // does this belong in the init or my if loop?

}


public void autonomousPeriodic() {

gyro1.reset();

while(isAutonomous() && isEnabled()) {

double angle = gyro1.getAngle();

SmartDashboard.putNumber("angle", angle);

robot.drive(-0.25, 1);

if(angle > 150) {

robot.drive(0,0);
gyro1.reset();
Timer.delay(1.00);

break;

}

Timer.delay(0.1);
}

while (isAutonomous() && isEnabled()) {

double angle2 = gyro1.getAngle();

robot.drive(-0.20, -angle2 * Kp);
// This can't be right lol..... at least its no longer dead code (: also in my if statement do i need < or > or ==?
if(encoder.getDistance() > 50) {
robot.drive(0,0);

break;
}
Timer.delay(0.1);
}

}


> will work perfectly fine.

AS for the distance variable, I would create a variable just like you did with the angle and print it to the SmartDashboard.

curtis0gj
21-01-2015, 08:47
This quote thing is driving me nuts, anyway this works right? double angle = gyro1.getAngle();
double distance = encoder.getDistance();

SmartDashboard.putNumber("Angle", angle);
SmartDashboard.putNumber("Distance", distance);

Also now that I have made my distance variable can I use it in my if statement like so, if(distance > 50) ?

notmattlythgoe
21-01-2015, 08:52
This quote thing is driving me nuts, anyway this works right? double angle = gyro1.getAngle();
double distance = encoder.getDistance();

SmartDashboard.putNumber("Angle", angle);
SmartDashboard.putNumber("Distance", distance);

Also now that I have made my distance variable can I use it in my if statement like so, if(distance > 50) ?

Yes you can, but you are going to want to make sure that you put the distance variable in the second loop so it gets updated when you are driving.

Another thing I forgot to have you do is reset the encoder prior to the second loop. You can do this in the same place you reset the gyro.

encoder.reset();

curtis0gj
21-01-2015, 08:56
Yes you can, but you are going to want to make sure that you put the distance variable in the second loop so it gets updated when you are driving.

Another thing I forgot to have you do is reset the encoder prior to the second loop. You can do this in the same place you reset the gyro.

encoder.reset();

I think this is perfect now I am very excited to test this. public void autonomousPeriodic() {

gyro1.reset();

while(isAutonomous() && isEnabled()) {

double angle = gyro1.getAngle();
double distance = encoder.getDistance();

SmartDashboard.putNumber("Angle", angle);
SmartDashboard.putNumber("Distance", distance);

robot.drive(-0.25, 1);

if(angle > 150) {

robot.drive(0,0);
gyro1.reset();
encoder.reset();

Timer.delay(1.00);

break;

}

Timer.delay(0.1);
}

while (isAutonomous() && isEnabled()) {

double distance2 = encoder.getDistance();

double angle2 = gyro1.getAngle();

robot.drive(-0.20, -angle2 * Kp);

if(distance2 > 50) {
robot.drive(0,0);

break;
}
Timer.delay(0.1);
}

}

notmattlythgoe
21-01-2015, 09:03
That looks good. Let me know if there is anything else.

curtis0gj
21-01-2015, 09:10
That looks good. Let me know if there is anything else.

Thanks a bunch I will test this tonight and get back to you if I need any more help. Thanks!

curtis0gj
21-01-2015, 17:42
That looks good. Let me know if there is anything else.

Just tested the program and the robot executed the turn and went on into the straight drive however it did not stop and I also noticed that I was not getting a distance value on my smart dashboard. Tomorrow we are going to check the encoder with a multimeter and see if we get any voltages.

Ether
21-01-2015, 17:44
we are going to check the encoder with a multimeter and see if we get any voltages.

What kind of voltages are you expecting to get?

curtis0gj
21-01-2015, 17:52
What kind of voltages are you expecting to get?



No Idea my mentor thought we would get some answers doing that. I'm just concerned the encoder may be broken.

curtis0gj
21-01-2015, 18:50
No Idea my mentor thought we would get some answers doing that. I'm just concerned the encoder may be broken.

I also think it could be the encoder.setDistanceperpulse(); because I don't know what it needs to be set at.

curtis0gj
22-01-2015, 06:42
Should the encoder be plugged into DIO or analog?

notmattlythgoe
22-01-2015, 09:47
Should the encoder be plugged into DIO or analog?

It needs to be plugged into DIO. What kind of encoder are you working with?

curtis0gj
22-01-2015, 09:53
[QUOTE=notmattlythgoe;1432076]It needs to be plugged into DIO. What kind of encoder are you working with?[/QUOTEh

http://www.andymark.com/product-p/am-0180.htm
US Digital Encoder E4P-250-250-N-S-D-D-B

notmattlythgoe
22-01-2015, 09:56
[QUOTE=notmattlythgoe;1432076]It needs to be plugged into DIO. What kind of encoder are you working with?[/QUOTEh

http://www.andymark.com/product-p/am-0180.htm
US Digital Encoder E4P-250-250-N-S-D-D-B

This will need placed into 2 DIO ports.

Ether
22-01-2015, 09:59
Tomorrow we are going to check the encoder with a multimeter and see if we get any voltages.

Did you try this yet?

curtis0gj
22-01-2015, 10:04
[QUOTE=curtis0gj;1432078]

This will need placed into 2 DIO ports.

Alright I have it in two of the DIO ports. However it is possible that we soldered it wrong or maybe have the cables plugged into the DIO backwards.

curtis0gj
22-01-2015, 10:11
Did you try this yet?




We are going to do that tonight and I think it's to check the solder we did.

curtis0gj
22-01-2015, 10:14
We are going to do that tonight and I think it's to check the solder we did.

This is the wiring we followed does it look correct?http://frc-labs.com/wp-content/uploads/2012/03/encoder.png

Ether
22-01-2015, 10:18
We are going to do that tonight and I think it's to check the solder we did.

The E4P-250-250-N-S-D-D-B has single-ended outputs, and according to the datasheet you should get a square wave on each of the 2 output signal channels (A & B).

As you manually rotate the encoder shaft (very very slowly), you should see the voltage going from ~5V to ~0.4V on each channel.

curtis0gj
22-01-2015, 10:23
The E4P-250-250-N-S-D-D-B has single-ended outputs, and according to the datasheet you should get a square wave on each of the 2 output signal channels (A & B).

As you manually rotate the encoder shaft (very very slowly), you should see the voltage going from ~5V to ~0.4V on each channel.




Alright I will give this a shot I'm not the best with electrical stuff but this sounds doable.

curtis0gj
22-01-2015, 16:23
Okay we testing out the encoder with our multimeter the volts seem good we got .4 to 5v however I am still not getting a number on my smartdash and I am not stopping. Here's the whole program.


package org.usfirst.frc.team5033.robot;

import edu.wpi.first.wpilibj.Encoder;
import edu.wpi.first.wpilibj.Gyro;
import edu.wpi.first.wpilibj.IterativeRobot;
import edu.wpi.first.wpilibj.Joystick;
import edu.wpi.first.wpilibj.RobotDrive;
import edu.wpi.first.wpilibj.Timer;
import edu.wpi.first.wpilibj.CounterBase.EncodingType;
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboar d;

public class Robot extends IterativeRobot {

RobotDrive robot;
Joystick stick;
Encoder encoder;
Gyro gyro1;

static final double Kp = 0.05;

public void robotInit() {

robot = new RobotDrive(0, 1);
stick = new Joystick(0);
gyro1 = new Gyro(0);
gyro1.reset();
gyro1.initGyro();
Encoder encoder = new Encoder(0, 1, false, EncodingType.k4X);


encoder.setDistancePerPulse(0.001);

encoder.getDistance();


}


public void autonomousPeriodic() {

gyro1.reset();

while(isAutonomous() && isEnabled()) {

double angle = gyro1.getAngle();
double distance = encoder.getDistance();

SmartDashboard.putNumber("Angle", angle);
SmartDashboard.putNumber("Distance", distance);

robot.drive(-0.25, 1);

if(angle > 150) {

robot.drive(0,0);
gyro1.reset();
encoder.reset();

Timer.delay(0.5);

break;

}

Timer.delay(0.1);
}

while (isAutonomous() && isEnabled()) {

double angle2 = gyro1.getAngle();
double distance2 = encoder.getDistance();

SmartDashboard.putNumber("Distance", distance2);

robot.drive(-0.20, -angle2 * Kp);

if(encoder.getDistance() < 10) {
robot.drive(0,0);

break;
}
Timer.delay(0.1);
}

}


public void teleopPeriodic() {

while (isOperatorControl() && isEnabled()) {


SmartDashboard.putNumber("angle", gyro1.getAngle());

stick.getThrottle();
robot.arcadeDrive(stick.getY(), -stick.getX(), false);

Timer.delay(0.1);
}

}


public void testPeriodic() {

}

}

notmattlythgoe
22-01-2015, 17:25
Okay we testing out the encoder with our multimeter the volts seem good we got .4 to 5v however I am still not getting a number on my smartdash and I am not stopping. Here's the whole program.


package org.usfirst.frc.team5033.robot;

import edu.wpi.first.wpilibj.Encoder;
import edu.wpi.first.wpilibj.Gyro;
import edu.wpi.first.wpilibj.IterativeRobot;
import edu.wpi.first.wpilibj.Joystick;
import edu.wpi.first.wpilibj.RobotDrive;
import edu.wpi.first.wpilibj.Timer;
import edu.wpi.first.wpilibj.CounterBase.EncodingType;
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboar d;

public class Robot extends IterativeRobot {

RobotDrive robot;
Joystick stick;
Encoder encoder;
Gyro gyro1;

static final double Kp = 0.05;

public void robotInit() {

robot = new RobotDrive(0, 1);
stick = new Joystick(0);
gyro1 = new Gyro(0);
gyro1.reset();
gyro1.initGyro();
Encoder encoder = new Encoder(0, 1, false, EncodingType.k4X);


encoder.setDistancePerPulse(0.001);

encoder.getDistance();


}


public void autonomousPeriodic() {

gyro1.reset();

while(isAutonomous() && isEnabled()) {

double angle = gyro1.getAngle();
double distance = encoder.getDistance();

SmartDashboard.putNumber("Angle", angle);
SmartDashboard.putNumber("Distance", distance);

robot.drive(-0.25, 1);

if(angle > 150) {

robot.drive(0,0);
gyro1.reset();
encoder.reset();

Timer.delay(0.5);

break;

}

Timer.delay(0.1);
}

while (isAutonomous() && isEnabled()) {

double angle2 = gyro1.getAngle();
double distance2 = encoder.getDistance();

SmartDashboard.putNumber("Distance", distance2);

robot.drive(-0.20, -angle2 * Kp);

if(encoder.getDistance() < 10) {
robot.drive(0,0);

break;
}
Timer.delay(0.1);
}

}


public void teleopPeriodic() {

while (isOperatorControl() && isEnabled()) {


SmartDashboard.putNumber("angle", gyro1.getAngle());

stick.getThrottle();
robot.arcadeDrive(stick.getY(), -stick.getX(), false);

Timer.delay(0.1);
}

}


public void testPeriodic() {

}

}


Try setting the distance per pulse to 1.

curtis0gj
22-01-2015, 17:57
Try setting the distance per pulse to 1.

I can try this tomorrow but do I need to maybe setup the dash board to display the distance or will it just appear?

notmattlythgoe
22-01-2015, 18:01
I can try this tomorrow but do I need to maybe setup the dash board to display the distance or will it just appear?

It will just appear. You are bringing up the java dashboard not the default one right?

curtis0gj
22-01-2015, 18:08
It will just appear. You are bringing up the java dashboard not the default one right?

Yeah what I do is switch my ds setting from remote to java and this opens my smart dashboard that I have setup with a camera and the angle reading.

curtis0gj
23-01-2015, 09:44
Yeah what I do is switch my ds setting from remote to java and this opens my smart dashboard that I have setup with a camera and the angle reading.

Is there a better way to open smart dashboard for java?

notmattlythgoe
23-01-2015, 09:47
Is there a better way to open smart dashboard for java?

That's the way we do it too. There a way to set the default to be the SmartDashboard, but I'd have to look into how to do that again.

curtis0gj
23-01-2015, 09:49
That's the way we do it too. There a way to set the default to be the SmartDashboard, but I'd have to look into how to do that again.

So setting the pulse to 1 does not work is there anything else I can try?

notmattlythgoe
23-01-2015, 09:54
So setting the pulse to 1 does not work is there anything else I can try?

Try doing encoder.start() in robotInit() after you declare the encoder. This method used to exist in last year's API but I don't see it in the documentation right now.

curtis0gj
23-01-2015, 09:57
Try doing encoder.start() in robotInit() after you declare the encoder. This method used to exist in last year's API but I don't see it in the documentation right now.
Yeah I have been encoder
start(); but it just gave me errors I guess there's no such thing this year.

notmattlythgoe
23-01-2015, 09:59
Yeah I have been encoder
start(); but it just gave me errors I guess there's no such thing this year.

Can you try changing your getDistance() to just get().

curtis0gj
23-01-2015, 10:01
Can you try changing your getDistance() to just get().

In the init?

notmattlythgoe
23-01-2015, 10:03
double distance2 = encoder.get();

curtis0gj
23-01-2015, 10:07
double distance2 = encoder.get();


How about double distance = encoder.get(); as well?

notmattlythgoe
23-01-2015, 10:19
How about double distance = encoder.get(); as well?

That's fine, but since you aren't using distance anywhere it won't effect anything.

curtis0gj
23-01-2015, 10:25
That's fine, but since you aren't using distance anywhere it won't effect anything.

I will try all this later today I am hoping this will be my fix because it's been at least 4 days of trying to setup this encoder. :deadhorse:

notmattlythgoe
23-01-2015, 10:26
I will try all this later today I am hoping this will be my fix because it's been at least 4 days of trying to setup this encoder. :deadhorse:

You did verify that the encoder is wired and plugged in correctly, including plugged into the correct ports?

I know its a basic question, but sometimes they need asked.

curtis0gj
23-01-2015, 10:29
You did verify that the encoder is wired and plugged in correctly, including plugged into the correct ports?

I know its a basic question, but sometimes they need asked.


+5 (orange) to the +5 pin of PWM connector #1
A (blue) to the signal pin on PWM connectore #1
Gnd (brown) to the ground pin of PWM connector #2
B (yellow) to the signal pin on PWM connector #2

Is what we are doing and we have the two PWM's into the DIO ports on the roboRIO.

curtis0gj
23-01-2015, 10:30
+5 (orange) to the +5 pin of PWM connector #1
A (blue) to the signal pin on PWM connectore #1
Gnd (brown) to the ground pin of PWM connector #2
B (yellow) to the signal pin on PWM connector #2

Is what we are doing and we have the two PWM's into the DIO ports on the roboRIO.

Using ports 0,1 aswell and have tried switching, flipping and inverting them.

notmattlythgoe
23-01-2015, 10:30
+5 (orange) to the +5 pin of PWM connector #1
A (blue) to the signal pin on PWM connectore #1
Gnd (brown) to the ground pin of PWM connector #2
B (yellow) to the signal pin on PWM connector #2

Is what we are doing and we have the two PWM's into the DIO ports on the roboRIO.

Ether, can you comment on this? This doesn't seem right to me, shouldn't the ground be shared between both channels?

cgmv123
23-01-2015, 10:33
Ether, can you comment on this? This doesn't seem right to me, shouldn't the ground be shared between both channels?

All of the ground pins should be connected internally.

curtis0gj
23-01-2015, 10:36
All of the ground pins should be connected internally.

? What does this mean. :yikes:

Ether
23-01-2015, 11:17
Ether, can you comment on this?

I think it's been that way for several years:

http://www.chiefdelphi.com/forums/showpost.php?p=929639&postcount=3

notmattlythgoe
23-01-2015, 11:19
I think it's been that way for several years:

http://www.chiefdelphi.com/forums/showpost.php?p=929639&postcount=3




Cool, this is why I don't wire things.

curtis0gj
23-01-2015, 12:08
Cool, this is why I don't wire things.
So wiring is good? Is it just a code thing or could the encoder be broken. :mad:

notmattlythgoe
23-01-2015, 12:09
So wiring is good? Is it just a code thing or could the encoder be broken. :mad:

Have you verified electrically that the encoder is outputting information?

curtis0gj
23-01-2015, 12:14
Have you verified electrically that the encoder is outputting information?

Yep we get it gives us voltage readings from .4 to 5 v and we are getting a nice voltage feed on the 5v cable and ground so we do have electrical readings.

notmattlythgoe
23-01-2015, 12:15
Yep we get it gives us voltage readings from .4 to 5 v and we are getting a nice voltage feed on the 5v cable and ground so we do have electrical readings.

Can you explain your testing process?

curtis0gj
23-01-2015, 12:17
Can you explain your testing process?

Sure! What we did was while running an autonomous movement code we were measuring dc voltage across the +5 and the common and we got a reading of +5. Then we ran it across the signal cables to the common and it was showing a square wave pretty much.

notmattlythgoe
23-01-2015, 12:38
Sure! What we did was while running an autonomous movement code we were measuring dc voltage across the +5 and the common and we got a reading of +5. Then we ran it across the signal cables to the common and it was showing a square wave pretty much.

I think I found the problem.

In robotInit(), delete the Encoder part of your encoder instantiaton. It should look like this:


encoder = new Encoder(0, 1, false, EncodingType.k4X);

curtis0gj
23-01-2015, 12:46
I think I found the problem.

In robotInit(), delete the Encoder part of your encoder instantiaton. It should look like this:


encoder = new Encoder(0, 1, false, EncodingType.k4X);




Yeah I think that could do it lol heres what I got.


package org.usfirst.frc.team5033.robot;

import edu.wpi.first.wpilibj.Encoder;
import edu.wpi.first.wpilibj.Gyro;
import edu.wpi.first.wpilibj.IterativeRobot;
import edu.wpi.first.wpilibj.Joystick;
import edu.wpi.first.wpilibj.RobotDrive;
import edu.wpi.first.wpilibj.Timer;
import edu.wpi.first.wpilibj.CounterBase.EncodingType;
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboar d;

public class Robot extends IterativeRobot {

RobotDrive robot;
Joystick stick;
Encoder encoder;
Gyro gyro1;

static final double Kp = 0.05;

public void robotInit() {

robot = new RobotDrive(0, 1);
stick = new Joystick(0);
gyro1 = new Gyro(0);
gyro1.reset();
gyro1.initGyro();
encoder = new Encoder(0, 1, false, EncodingType.k4X);


encoder.setDistancePerPulse(1);

encoder.getDistance();


}


public void autonomousPeriodic() {

gyro1.reset();

while(isAutonomous() && isEnabled()) {

double angle = gyro1.getAngle();
double distance = encoder.get();

SmartDashboard.putNumber("Angle", angle);
SmartDashboard.putNumber("Distance", distance);

robot.drive(-0.25, 1);

if(angle > 150) {

robot.drive(0,0);
gyro1.reset();
encoder.reset();

Timer.delay(0.5);

break;

}

Timer.delay(0.1);
}

while (isAutonomous() && isEnabled()) {

double angle2 = gyro1.getAngle();
double distance2 = encoder.get();

SmartDashboard.putNumber("Distance", distance2);

robot.drive(-0.20, -angle2 * Kp);

if(encoder.getDistance() < 10) {
robot.drive(0,0);

break;
}
Timer.delay(0.1);
}

}

notmattlythgoe
23-01-2015, 12:47
Yeah I think that could do it lol heres what I got.


package org.usfirst.frc.team5033.robot;

import edu.wpi.first.wpilibj.Encoder;
import edu.wpi.first.wpilibj.Gyro;
import edu.wpi.first.wpilibj.IterativeRobot;
import edu.wpi.first.wpilibj.Joystick;
import edu.wpi.first.wpilibj.RobotDrive;
import edu.wpi.first.wpilibj.Timer;
import edu.wpi.first.wpilibj.CounterBase.EncodingType;
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboar d;

public class Robot extends IterativeRobot {

RobotDrive robot;
Joystick stick;
Encoder encoder;
Gyro gyro1;

static final double Kp = 0.05;

public void robotInit() {

robot = new RobotDrive(0, 1);
stick = new Joystick(0);
gyro1 = new Gyro(0);
gyro1.reset();
gyro1.initGyro();
encoder = new Encoder(0, 1, false, EncodingType.k4X);


encoder.setDistancePerPulse(1);

encoder.getDistance();


}


public void autonomousPeriodic() {

gyro1.reset();

while(isAutonomous() && isEnabled()) {

double angle = gyro1.getAngle();
double distance = encoder.get();

SmartDashboard.putNumber("Angle", angle);
SmartDashboard.putNumber("Distance", distance);

robot.drive(-0.25, 1);

if(angle > 150) {

robot.drive(0,0);
gyro1.reset();
encoder.reset();

Timer.delay(0.5);

break;

}

Timer.delay(0.1);
}

while (isAutonomous() && isEnabled()) {

double angle2 = gyro1.getAngle();
double distance2 = encoder.get();

SmartDashboard.putNumber("Distance", distance2);

robot.drive(-0.20, -angle2 * Kp);

if(encoder.getDistance() < 10) {
robot.drive(0,0);

break;
}
Timer.delay(0.1);
}

}



Looks good. I'm still trying to figure out why you weren't getting NullPointerExceptions with the other code...

curtis0gj
23-01-2015, 12:51
Looks good. I'm still trying to figure out why you weren't getting NullPointerExceptions with the other code...

Hmm I've no idea what NullPointerExceptions but I don't think want any they sound pretty bad.::safety::

Ether
23-01-2015, 12:52
we were measuring dc voltage across the +5 and the common and we got a reading of +5. Then we ran it across the signal cables to the common and it was showing a square wave pretty much.

Would you please describe your test setup?
e.g. What were you measuring these voltages with? etc

notmattlythgoe
23-01-2015, 12:57
Hmm I've no idea what NullPointerExceptions but I don't think want any they sound pretty bad.::safety::

A NullPointerException happens when you try to access an object like an encoder, but the object has never been given an initial value.

So what seems to have been happening in your old code was because you had that Encoder part on the one line you were declaring a new local variable called encoder which was only used locally, and when robotInit ended it was removed from memory. What this means is that the field you called encoder was never given a value. Take a look at the old code, I'm going to bold the local variable and underline the field so you can see what I'm talking about.


package org.usfirst.frc.team5033.robot;

import edu.wpi.first.wpilibj.Encoder;
import edu.wpi.first.wpilibj.Gyro;
import edu.wpi.first.wpilibj.IterativeRobot;
import edu.wpi.first.wpilibj.Joystick;
import edu.wpi.first.wpilibj.RobotDrive;
import edu.wpi.first.wpilibj.Timer;
import edu.wpi.first.wpilibj.CounterBase.EncodingType;
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboar d;

public class Robot extends IterativeRobot {

RobotDrive robot;
Joystick stick;
Encoder encoder;
Gyro gyro1;

static final double Kp = 0.05;

public void robotInit() {

robot = new RobotDrive(0, 1);
stick = new Joystick(0);
gyro1 = new Gyro(0);
gyro1.reset();
gyro1.initGyro();

Encoder encoder = new Encoder(0, 1, false, EncodingType.k4X);
encoder.setDistancePerPulse(0.001);
encoder.getDistance();
}

public void autonomousPeriodic() {

gyro1.reset();

while(isAutonomous() && isEnabled()) {

double angle = gyro1.getAngle();
double distance = encoder.getDistance();

SmartDashboard.putNumber("Angle", angle);
SmartDashboard.putNumber("Distance", distance);

robot.drive(-0.25, 1);

if(angle > 150) {
robot.drive(0,0);
gyro1.reset();
encoder.reset();

Timer.delay(0.5);

break;

}

Timer.delay(0.1);
}

while (isAutonomous() && isEnabled()) {

double angle2 = gyro1.getAngle();
double distance2 = encoder.getDistance();

SmartDashboard.putNumber("Distance", distance2);

robot.drive(-0.20, -angle2 * Kp);

if(encoder.getDistance() < 10) {
robot.drive(0,0);
break;
}
Timer.delay(0.1);
}
}


public void teleopPeriodic() {

while (isOperatorControl() && isEnabled()) {

SmartDashboard.putNumber("angle", gyro1.getAngle());

stick.getThrottle();
robot.arcadeDrive(stick.getY(), -stick.getX(), false);

Timer.delay(0.1);
}

}


public void testPeriodic() {

}

}


Do you see how the underlined one never has the statement new Encoder(...) called for it? So it was never given an initial value.

curtis0gj
23-01-2015, 13:03
A NullPointerException happens when you try to access an object like an encoder, but the object has never been given an initial value.

So what seems to have been happening in your old code was because you had that Encoder part on the one line you were declaring a new local variable called encoder which was only used locally, and when robotInit ended it was removed from memory. What this means is that the field you called encoder was never given a value. Take a look at the old code, I'm going to bold the local variable and underline the field so you can see what I'm talking about.


package org.usfirst.frc.team5033.robot;

import edu.wpi.first.wpilibj.Encoder;
import edu.wpi.first.wpilibj.Gyro;
import edu.wpi.first.wpilibj.IterativeRobot;
import edu.wpi.first.wpilibj.Joystick;
import edu.wpi.first.wpilibj.RobotDrive;
import edu.wpi.first.wpilibj.Timer;
import edu.wpi.first.wpilibj.CounterBase.EncodingType;
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboar d;

public class Robot extends IterativeRobot {

RobotDrive robot;
Joystick stick;
Encoder encoder;
Gyro gyro1;

static final double Kp = 0.05;

public void robotInit() {

robot = new RobotDrive(0, 1);
stick = new Joystick(0);
gyro1 = new Gyro(0);
gyro1.reset();
gyro1.initGyro();

Encoder encoder = new Encoder(0, 1, false, EncodingType.k4X);
encoder.setDistancePerPulse(0.001);
encoder.getDistance();
}

public void autonomousPeriodic() {

gyro1.reset();

while(isAutonomous() && isEnabled()) {

double angle = gyro1.getAngle();
double distance = encoder.getDistance();

SmartDashboard.putNumber("Angle", angle);
SmartDashboard.putNumber("Distance", distance);

robot.drive(-0.25, 1);

if(angle > 150) {
robot.drive(0,0);
gyro1.reset();
encoder.reset();

Timer.delay(0.5);

break;

}

Timer.delay(0.1);
}

while (isAutonomous() && isEnabled()) {

double angle2 = gyro1.getAngle();
double distance2 = encoder.getDistance();

SmartDashboard.putNumber("Distance", distance2);

robot.drive(-0.20, -angle2 * Kp);

if(encoder.getDistance() < 10) {
robot.drive(0,0);
break;
}
Timer.delay(0.1);
}
}


public void teleopPeriodic() {

while (isOperatorControl() && isEnabled()) {

SmartDashboard.putNumber("angle", gyro1.getAngle());

stick.getThrottle();
robot.arcadeDrive(stick.getY(), -stick.getX(), false);

Timer.delay(0.1);
}

}


public void testPeriodic() {

}

}


Do you see how the underlined one never has the statement new Encoder(...) called for it? So it was never given an initial value.


Still not getting anything printed to my smartdash board do I need to make a new dashboard or something like that.

curtis0gj
23-01-2015, 13:04
Would you please describe your test setup?
e.g. What were you measuring these voltages with? etc




We put the robot on a table and held it up right. Then we got a multimeter and used the dc volts setting. Let me know if you need more info and I can ask the electronic guy.

Ether
23-01-2015, 13:09
We put the robot on a table and held it up right. Then we got a multimeter and used the dc volts setting. Let me know if you need more info and I can ask the electronic guy.

It just sounded like you were using either an oscilloscope or on-board voltage sampling. (You said it was "showing" a square wave).

I'm surprised you could actually see the hi/lo voltage transitions with just a multimeter if you were measuring while running your autonomous routine. Are you sure that's what was done? I had suggested turning the encoder very slowly by hand.

notmattlythgoe
23-01-2015, 13:10
Still not getting anything printed to my smartdash board do I need to make a new dashboard or something like that.

You shouldn't need to create a new one. The Distance boxis appearing on the dashboard correct? It just isn't showing any numbers other than 0?

curtis0gj
23-01-2015, 13:13
You shouldn't need to create a new one. The Distance boxis appearing on the dashboard correct? It just isn't showing any numbers other than 0?

No the box does not even appear so that's why I am wondering if i need to create one or something.

Fauge7
23-01-2015, 13:13
This is why you should use command based robot, with a turn x degrees command, drive subsyem with your encoders

notmattlythgoe
23-01-2015, 13:15
No the box does not even appear so that's why I am wondering if i need to create one or something.

You don't need to create one, it should do it on it's own. This is a very interesting one indeed. So the robot is obviously running the code, but the data isn't making it to the SmartDashboard. Are there any errors on your drive station console or in the riolog?

curtis0gj
23-01-2015, 13:16
It just sounded like you were using either an oscilloscope or on-board voltage sampling. (You said it was "showing" a square wave).

I'm surprised you could actually see the hi/lo voltage transitions with just a multimeter if you were measuring while running your autonomous routine. Are you sure that's what was done? I had suggested turning the encoder very slowly by hand.






Okay, my mentor told me that he was not really seeing a square wave however, he did see a spike in voltage and a drop in voltage. But we will try spinning it slowly by hand, we took the lazy way out last time because we did not really want to take the encoder off.

curtis0gj
23-01-2015, 13:22
You don't need to create one, it should do it on it's own. This is a very interesting one indeed. So the robot is obviously running the code, but the data isn't making it to the SmartDashboard. Are there any errors on your drive station console or in the riolog?

None in the ds error box but I don't know how to check the roborio error log.

notmattlythgoe
23-01-2015, 13:24
None in the ds error box but I don't know how to check the roborio error log.

The riolog is in eclipse. IF you don't see it as a tab near the bottom then go yo Window -> Show View -> Riolog.

curtis0gj
23-01-2015, 13:40
The riolog is in eclipse. IF you don't see it as a tab near the bottom then go yo Window -> Show View -> Riolog.

I don't see anything bad in the riolog or ds log so idk whats going on with that.

curtis0gj
23-01-2015, 15:47
Hey guys I finally got the encoder going, my electrical guy said it was grounding on something. Anyway I am getting a nice reading on smart db however, when I run autonomous mode the robot turns about 180 stops and turns again and this never ends. I think I am stuck in an if loop and it's not entering the straight driving portion of the program...

public class Robot extends IterativeRobot {

RobotDrive robot;
Joystick stick;
Encoder encoder;
Gyro gyro1;

static final double Kp = 0.05;

public void robotInit() {

robot = new RobotDrive(0, 1);
stick = new Joystick(0);
gyro1 = new Gyro(0);
gyro1.reset();
gyro1.initGyro();
encoder = new Encoder(0, 1, false, EncodingType.k4X);


encoder.setDistancePerPulse(1);

encoder.getDistance();


}


public void autonomousPeriodic() {

gyro1.reset();

while(isAutonomous() && isEnabled()) {

double angle = gyro1.getAngle();
double distance = encoder.get();

SmartDashboard.putNumber("angle", angle);
SmartDashboard.putNumber("distance", distance);

robot.drive(-0.15, -1);

if(angle > 150) {

robot.drive(0,0);
gyro1.reset();
encoder.reset();

Timer.delay(0.5);

break;

}

Timer.delay(0.1);
}

while (isAutonomous() && isEnabled()) {

double angle2 = gyro1.getAngle();
double distance2 = encoder.get();

SmartDashboard.putNumber("distance", distance2);
SmartDashboard.putNumber("angle", angle2);

robot.drive(-0.20, -angle2 * Kp);

if(encoder.getDistance() < 100) {
robot.drive(0,-0);

break;
}
Timer.delay(0.1);
}

}

notmattlythgoe
23-01-2015, 15:53
Hey guys I finally got the encoder going, my electrical guy said it was grounding on something. Anyway I am getting a nice reading on smart db however, when I run autonomous mode the robot turns about 180 stops and turns again and this never ends. I think I am stuck in an if loop and it's not entering the straight driving portion of the program...

public class Robot extends IterativeRobot {

RobotDrive robot;
Joystick stick;
Encoder encoder;
Gyro gyro1;

static final double Kp = 0.05;

public void robotInit() {

robot = new RobotDrive(0, 1);
stick = new Joystick(0);
gyro1 = new Gyro(0);
gyro1.reset();
gyro1.initGyro();
encoder = new Encoder(0, 1, false, EncodingType.k4X);


encoder.setDistancePerPulse(1);

encoder.getDistance();


}


public void autonomousPeriodic() {

gyro1.reset();

while(isAutonomous() && isEnabled()) {

double angle = gyro1.getAngle();
double distance = encoder.get();

SmartDashboard.putNumber("angle", angle);
SmartDashboard.putNumber("distance", distance);

robot.drive(-0.15, -1);

if(angle > 150) {

robot.drive(0,0);
gyro1.reset();
encoder.reset();

Timer.delay(0.5);

break;

}

Timer.delay(0.1);
}

while (isAutonomous() && isEnabled()) {

double angle2 = gyro1.getAngle();
double distance2 = encoder.get();

SmartDashboard.putNumber("distance", distance2);
SmartDashboard.putNumber("angle", angle2);

robot.drive(-0.20, -angle2 * Kp);

if(encoder.getDistance() < 100) {
robot.drive(0,-0);

break;
}
Timer.delay(0.1);
}

}


What is the reported angle during the second part of the autonomous routine? My guess is that it is not scaled enough and it is correcting it in the wrong direction.

curtis0gj
23-01-2015, 16:04
What is the reported angle during the second part of the autonomous routine? My guess is that it is not scaled enough and it is correcting it in the wrong direction.

Unfortunatly, I can't check what angle it's reading until monday. However I can fix the correcting in the wrong direction would that just be a different < or change my -1 to 1?

Ether
23-01-2015, 16:09
Hey guys I finally got the encoder going, my electrical guy said it was grounding on something.

That's why you should turn the encoder shaft slowly and observe the hi/lo quadrature behavior of A & B when testing with a multimeter...

notmattlythgoe
23-01-2015, 16:14
Unfortunatly, I can't check what angle it's reading until monday. However I can fix the correcting in the wrong direction would that just be a different < or change my -1 to 1?

I'm guessing you need to change it to positive, but that will all depend on the angle value.

curtis0gj
23-01-2015, 16:37
I'm guessing you need to change it to positive, but that will all depend on the angle value.

Okay will this fix the issue where it's not driving straight?

notmattlythgoe
23-01-2015, 16:40
Okay will this fix the issue where it's not driving straight?

I don't know. I need to know what the reported angle values are to answer that.

curtis0gj
23-01-2015, 16:47
I don't know. I need to know what the reported angle values are to answer that.

Okay I will figure this out on Monday thanks so much for the help with everything, it's really helped our team a tremendous amount. :D

mmaunu
23-01-2015, 17:31
Hey guys I finally got the encoder going, my electrical guy said it was grounding on something. Anyway I am getting a nice reading on smart db however, when I run autonomous mode the robot turns about 180 stops and turns again and this never ends. I think I am stuck in an if loop and it's not entering the straight driving portion of the program...

public class Robot extends IterativeRobot {

RobotDrive robot;
Joystick stick;
Encoder encoder;
Gyro gyro1;

static final double Kp = 0.05;

public void robotInit() {

robot = new RobotDrive(0, 1);
stick = new Joystick(0);
gyro1 = new Gyro(0);
gyro1.reset();
gyro1.initGyro();
encoder = new Encoder(0, 1, false, EncodingType.k4X);


encoder.setDistancePerPulse(1);

encoder.getDistance();


}


public void autonomousPeriodic() {

gyro1.reset();

while(isAutonomous() && isEnabled()) {

double angle = gyro1.getAngle();
double distance = encoder.get();

SmartDashboard.putNumber("angle", angle);
SmartDashboard.putNumber("distance", distance);

robot.drive(-0.15, -1);

if(angle > 150) {

robot.drive(0,0);
gyro1.reset();
encoder.reset();

Timer.delay(0.5);

break;

}

Timer.delay(0.1);
}

while (isAutonomous() && isEnabled()) {

double angle2 = gyro1.getAngle();
double distance2 = encoder.get();

SmartDashboard.putNumber("distance", distance2);
SmartDashboard.putNumber("angle", angle2);

robot.drive(-0.20, -angle2 * Kp);

if(encoder.getDistance() < 100) {
robot.drive(0,-0);

break;
}
Timer.delay(0.1);
}

}



I hope that it is ok to jump in here...

It looks like you started off with a Robot that extended SampleRobot and have now migrated to a class that extends IterativeRobot. The way that your autonomous code will be executed is very different in these two cases.

SampleRobot
When you extend SampleRobot, your autonomous method will get called for you once. You need to write loops in your code that keep running until you have completed your task. This is why you have the while loop:
while( isAutonomous() and isEnabled() )
{
//stuff
}
You also put your own calls to Timer.delay() in this type of robot because nothing is pausing your code (nothing is creating a timed structure for you).

IterativeRobot
When you extend IterativeRobot, your autonomousPeriodic() method will be called every 20 ms. If you put a loop in this method that runs for longer than 20 ms...well, that is bad. You also don't want to put calls to Timer.delay() in here as this will slow down the execution cycle. Since the code in autonomousPeriodic() is being executed every 20 ms, you want to avoid loops. Put the body of your loops in the method; since it is being executed every 20 ms, it is being looped for you. Also, be careful about resetting values in autonomousPeriodic() without checking a condition. Since the code gets executed repeatedly, you will be continuously resetting the value (e.g. the call to reset the gyro at the top of the method is constantly resetting the gyro).

Proposed new method:



//a new instance variable for the class...true until the initial turn is done...only false when you want to drive straight
boolean doingInitialTurn;

public void autonomousInit() {
gyro1.reset();
doingInitialTurn = true;
}

public void autonomousPeriodic() {

double angle = gyro1.getAngle();
double distance = encoder.getDistance(); //NOTE: changed to getDistance()

SmartDashboard.putNumber("angle", angle);
SmartDashboard.putNumber("distance", distance);

// if you are just starting and doing the first turn...turn code
if( angle <= 150 && doingInitialTurn )
robot.drive(-0.15, -1);

// otherwise, if the angle is now greater than 150 but you are just finishing the turn...stop turning
else if( doingInitialTurn ) {

robot.drive(0,0);
doingInitialTurn = false;
gyro1.reset();
encoder.reset();


}

// if you are completely done with the turn...drive forward instead
else
{
// you can reuse the original angle and distance values from the top of the method...
// they get updated every 20 ms
//double angle2 = gyro1.getAngle();
//double distance2 = encoder.getDistance();

// You also don't need to put them to the SmartDashboard again since the lines at the
// top of the method do that for you every 20 ms
//SmartDashboard.putNumber("distance", distance);
//SmartDashboard.putNumber("angle", angle);


robot.drive(-0.20, -angle * Kp);

if(distance > 100)
robot.drive(0,-0);


}

}


Also, the line of code that checks for when to stop driving forward had reversed logic; if the distance traveled was less than 100, you stopped driving. You want to stop driving only after the distance traveled is greater than 100. You had:

if(encoder.getDistance() < 100) {
robot.drive(0,-0);

break;
}


Lastly, you do not want to set the distance per pulse to be 1. The distance per pulse is the number of inches (or other unit) that the robot actually moves every time the encoder registers a "pulse", which is 250 times per revolution of the encoder (or 1000 times per revolution if you are using 4x encoding?). The Encoder's get() method returns the count (the same as the number of pulses?) since the last call to reset. The getDistance() method returns the count multiplied by the number specified in setDistancePerPulse(). If you set the distance per pulse to 1, then you will need to travel a great "distance" in your code.

To find the correct value for setDistancePerPulse(), we typically:

Reset the encoder in teleopInit(). This code will only run when you first enable teleop.
In teleopPeriodic(), get the count with encoder.get() and print it or put it up on the SmartDashboard. This code will run every 20 ms when teleop mode is enabled.
Manually move the robot forward 10 feet (as close to 120 inches as you can).
Divide 120 inches by the count from the encoder...that is your distance per pulse.


Good luck and let me know if this did or didn't work...unfortunately, I didn't test the code :(

curtis0gj
23-01-2015, 18:04
I hope that it is ok to jump in here...

It looks like you started off with a Robot that extended SampleRobot and have now migrated to a class that extends IterativeRobot. The way that your autonomous code will be executed is very different in these two cases.

SampleRobot
When you extend SampleRobot, your autonomous method will get called for you once. You need to write loops in your code that keep running until you have completed your task. This is why you have the while loop:
while( isAutonomous() and isEnabled() )
{
//stuff
}
You also put your own calls to Timer.delay() in this type of robot because nothing is pausing your code (nothing is creating a timed structure for you).

IterativeRobot
When you extend IterativeRobot, your autonomousPeriodic() method will be called every 20 ms. If you put a loop in this method that runs for longer than 20 ms...well, that is bad. You also don't want to put calls to Timer.delay() in here as this will slow down the execution cycle. Since the code in autonomousPeriodic() is being executed every 20 ms, you want to avoid loops. Put the body of your loops in the method; since it is being executed every 20 ms, it is being looped for you. Also, be careful about resetting values in autonomousPeriodic() without checking a condition. Since the code gets executed repeatedly, you will be continuously resetting the value (e.g. the call to reset the gyro at the top of the method is constantly resetting the gyro).

Proposed new method:



//a new instance variable for the class...true until the initial turn is done...only false when you want to drive straight
boolean doingInitialTurn;

public void autonomousInit() {
gyro1.reset();
doingInitialTurn = true;
}

public void autonomousPeriodic() {

double angle = gyro1.getAngle();
double distance = encoder.getDistance(); //NOTE: changed to getDistance()

SmartDashboard.putNumber("angle", angle);
SmartDashboard.putNumber("distance", distance);

// if you are just starting and doing the first turn...turn code
if( angle <= 150 && doingInitialTurn )
robot.drive(-0.15, -1);

// otherwise, if the angle is now greater than 150 but you are just finishing the turn...stop turning
else if( doingInitialTurn ) {

robot.drive(0,0);
doingInitialTurn = false;
gyro1.reset();
encoder.reset();


}

// if you are completely done with the turn...drive forward instead
else
{
// you can reuse the original angle and distance values from the top of the method...
// they get updated every 20 ms
//double angle2 = gyro1.getAngle();
//double distance2 = encoder.getDistance();

// You also don't need to put them to the SmartDashboard again since the lines at the
// top of the method do that for you every 20 ms
//SmartDashboard.putNumber("distance", distance);
//SmartDashboard.putNumber("angle", angle);


robot.drive(-0.20, -angle * Kp);

if(distance > 100)
robot.drive(0,-0);


}

}


Also, the line of code that checks for when to stop driving forward had reversed logic; if the distance traveled was less than 100, you stopped driving. You want to stop driving only after the distance traveled is greater than 100. You had:


Lastly, you do not want to set the distance per pulse to be 1. The distance per pulse is the number of inches (or other unit) that the robot actually moves every time the encoder registers a "pulse", which is 250 times per revolution of the encoder (or 1000 times per revolution if you are using 4x encoding?). The Encoder's get() method returns the count (the same as the number of pulses?) since the last call to reset. The getDistance() method returns the count multiplied by the number specified in setDistancePerPulse(). If you set the distance per pulse to 1, then you will need to travel a great "distance" in your code.

To find the correct value for setDistancePerPulse(), we typically:

Reset the encoder in teleopInit(). This code will only run when you first enable teleop.
In teleopPeriodic(), get the count with encoder.get() and print it or put it up on the SmartDashboard. This code will run every 20 ms when teleop mode is enabled.
Manually move the robot forward 10 feet (as close to 120 inches as you can).
Divide 120 inches by the count from the encoder...that is your distance per pulse.


Good luck and let me know if this did or didn't work...unfortunately, I didn't test the code :(

Thanks for the feed back! I have been receiving so much positive feed back it's wonderful. Any who, the reason I switch from SampleRobot to IterativeRobot is because I made a new project later on just to try different autonomous programs so I did not muck up my original project (Also because when I made a new project I did not know what the difference was between the two...). However, now that I have a good idea of what my autonomous is going to be should I switch back to SampleRobot? I would like to keep the loops so I am guessing I need to switch, let me know what you think. Also thanks for the setDistanceperPulse tuning I will do that on Monday to get it nice and tuned. :)

mmaunu
23-01-2015, 18:38
Thanks for the feed back! I have been receiving so much positive feed back it's wonderful. Any who, the reason I switch from SampleRobot to IterativeRobot is because I made a new project later on just to try different autonomous programs so I did not muck up my original project (Also because when I made a new project I did not know what the difference was between the two...). However, now that I have a good idea of what my autonomous is going to be should I switch back to SampleRobot? I would like to keep the loops so I am guessing I need to switch, let me know what you think. Also thanks for the setDistanceperPulse tuning I will do that on Monday to get it nice and tuned. :)

As for which template to use (Sample or Iterative), that is up to you. The SampleRobot template gets complicated quickly if you add any complexity to your code. If you like the loops, then you will need to use SampleRobot.

If the code above makes sense, though, I would encourage you to explore the IterativeRobot template. The teleop code works in a similar fashion: teleopInit() gets called once when teleop is enabled and teleopPeriodic() gets called every 20 ms for you (so avoid loops that don't exit quickly and do not use Timer.delay() to pause your code). Also, the 20 ms is just a great approximation...the loop timing is reallllly close to every 20 ms (certainly close enough for what we're doing).

If you do switch back to SampleRobot, then you will need the loops and the calls to Timer.delay().

Keep plugging away at it and keep asking questions. ChiefDelphi is full of people that want to help :)

curtis0gj
23-01-2015, 23:28
As for which template to use (Sample or Iterative), that is up to you. The SampleRobot template gets complicated quickly if you add any complexity to your code. If you like the loops, then you will need to use SampleRobot.

If the code above makes sense, though, I would encourage you to explore the IterativeRobot template. The teleop code works in a similar fashion: teleopInit() gets called once when teleop is enabled and teleopPeriodic() gets called every 20 ms for you (so avoid loops that don't exit quickly and do not use Timer.delay() to pause your code). Also, the 20 ms is just a great approximation...the loop timing is reallllly close to every 20 ms (certainly close enough for what we're doing).

If you do switch back to SampleRobot, then you will need the loops and the calls to Timer.delay().

Keep plugging away at it and keep asking questions. ChiefDelphi is full of people that want to help :)

Sweet maybe after the build season I will explore the Iterative robot but I would like to try and keep it basic this year seeing as I am new to this whole thing.

Fauge7
24-01-2015, 01:49
Sweet maybe after the build season I will explore the Iterative robot but I would like to try and keep it basic this year seeing as I am new to this whole thing.

Honestly your better off with the command based structure, its easier to manage, more people use it, and its logically broken out into easier to find places. Need a constant? RobotMap...Need a joystick? OI, need a command for autonomous? Autonomous command Group, need a motor? SubsystemA...if you need help with it I am willing to Skype you and mentor you through converting it from a sample Robot to a command based robot. Send me a pm! This applies to anybody having trouble with any of the templates!

curtis0gj
24-01-2015, 10:57
Honestly your better off with the command based structure, its easier to manage, more people use it, and its logically broken out into easier to find places. Need a constant? RobotMap...Need a joystick? OI, need a command for autonomous? Autonomous command Group, need a motor? SubsystemA...if you need help with it I am willing to Skype you and mentor you through converting it from a sample Robot to a command based robot. Send me a pm! This applies to anybody having trouble with any of the templates!

I'm not sure I understand the difference between the too? What are the benefits of using a command based robot is it easier or more efficient?

Fauge7
24-01-2015, 12:25
In terms of efficiency its negligible. I like it because it breaks the code down into more readable code project. Everything is not crammed into one class! Since Java is an object oriented programming use it for what its made for! Objects!

notmattlythgoe
26-01-2015, 09:05
I'm not sure I understand the difference between the too? What are the benefits of using a command based robot is it easier or more efficient?

Curtis, if you are interested in the Command Based structure, here is a thread that has 2 presentations that our team gave at a workshop this past fall.

This is the structure that our team uses and we like it very much. I would be willing to help you if you were interested in moving to a structure like this.

As for Iterative vs Sample. I had heard that they were planning on getting rid of the Sample(Simple) robot structure because that name was misleading because they thought teams actually had a harder time with the "Simple" robot structure.

There are many resources to help you in any of the structures as most of the people that can help you will know how to help in any of the structures.

curtis0gj
26-01-2015, 18:21
Curtis, if you are interested in the Command Based structure, here is a thread that has 2 presentations that our team gave at a workshop this past fall.

This is the structure that our team uses and we like it very much. I would be willing to help you if you were interested in moving to a structure like this.

As for Iterative vs Sample. I had heard that they were planning on getting rid of the Sample(Simple) robot structure because that name was misleading because they thought teams actually had a harder time with the "Simple" robot structure.

There are many resources to help you in any of the structures as most of the people that can help you will know how to help in any of the structures.


Switching to command based currently may be an issue because of how much I have already established with the Sample Robot Structure. However, I am interested in switching to command based next season because I am hearing it's far better. Also an update on the gyro/encoder issue, we have our robot turning 180 and driving forward with the encoder and stopping at the proper distance we wanted it just took a bit of math and calibrating but I think we are tuned in and ready for autonomous! :p

notmattlythgoe
26-01-2015, 18:31
Switching to command based currently may be an issue because of how much I have already established with the Sample Robot Structure. However, I am interested in switching to command based next season because I am hearing it's far better. Also an update on the gyro/encoder issue, we have our robot turning 180 and driving forward with the encoder and stopping at the proper distance we wanted it just took a bit of math and calibrating but I think we are tuned in and ready for autonomous! :p

Great to hear!