# 13 - Encoders

## Ok, this example looks a little more complicated than the last few...
That's because it is, we're getting further along now that you've seen more of the simple stuff, now we need to address more complicated topics. 

## What is an Encoder?
This is covered in slightly more detail in [8 - Basic Robot Electronics](../8%20-%20Basic%20Robot%20Electronics/), but to reiterate, an Encoder is something that can be used to determine:
- The direction a motor/wheel is moving
- The speed at which a motor/wheel is moving
- The distance a motor/wheel has moved
These are all important tidbits of information if you want to go from saying "drive forward 2 seconds" to "drive forward 60 inches". 

## How does the encoder know how fast or far it's gone?
Well, we sort of have to tell it. All encoders are, in some way, counting specific events. Hardware internal to the encoder usually "announces" (or pulses) when there is something to count, and then some software (either on the encoder itself or on the RoboRIO) is taking that count of pulses and determining speed over time and distance travelled. 

All encoders will "announce" there's something to count a certain number of times within a single rotation of the encoder. We can use that information to determine how far, for instance a wheel attached to the same shaft as the encoder turns for one announcement or pulse of the encoder. 

The way we do this is with a specific formula. `math.pi * Wheel Diameter / Pulses Per Revolution`. By doing this, we're basically dividing up the circumference of the wheel into slices that match the pulses (or announcements) the encoder will make in one complete rotation. This will make the information provided by methods (behaviors) like getDistance() and getRate() take on the units of whatever the wheel diameter is. If the wheel diameter provided is in inches, for example, then getDistance() will return inches and getRate will return inches/second

## This seems like a better solution than timers, what's the catch?
While it is a better solution than timers, the way we have this set up doesn't allow for turning, and isn't controlling the drivetrain in a way that will end up being super accurate. 

Averaging both sides of the drivetrain together makes for some easy code. But our target is to drive straight 60 inches, what happens if something slows one side of the drivetrain or the other? Let's say that one side of the drivetrain goes 90 inches, and the other goes 30, that's a right turn, not driving straight, this code has no way to correct for that. 

The other issue here, is lets say the drive base goes forward perfectly straight. What happens if we drive 65 inches because momentum carried us that far? 65 inches may not work for what we're trying to do. With this code, the robot can't correct for overshoot. 

In future examples, we'll see how to solve the above problems. 