Problems with Encoders

I’ve been reading through the documentation for encoders, and I’m really confused. My team has a motor controller/motor/gearbox/encoder combination (AM 2971), and I really need to be able to make it turn X number of degrees then stop. Does anybody know how to do this? Thanks in advance.

IDK if you’re using iterative robot or command base but essentially:



private int start;

public void initialize() {
	start = encoder.get();
	motor.set(speed);
}

public void loop() { //this would be execute in a command not sure in iterative
	if(encoder.get()-start > 500) {
		motor.set(0);
	}
}

Not tested not even written in an IDE so take it with a grain of salt

If you would like to just start at a certain angle, you’re going to have a few issues.

Your first issue is that if you just stop your motors at a certain angle, you will get a ridiculous amount of overshoot. In order to fix this, I would use a PID system. You have the option of using the PIDSubsystem that WPILib has built in (a quick tutorial for which can be found here), or you can write your own. I wrote my own due to a little issue I found with the built in PID subsystem, but by all means you can use the built in sub system. If you would like a better explanation of what a PID Controller is/how it works, here’s a fantastic video explaining it.

Another issue you’ll find is that if you don’t implement a PID system, encoders don’t usually report back in angles anyways. We have two encoders on my team, one where a full rotation is 1500 from encoder.getRaw(), another type where a full rotation is 1000. To convert from degrees to encoder ticks, you would multiply by (ticks per full rotation / 360). To convert to degrees, you would multiply by (360 / ticks per full rotation). You would have to figure out what your encoders rotation is empirically.

If you have any questions, feel free to message me. Sorry if anything is fuzzy, very tired right now.

What was the little issue you found?

Using motors, I found little consistency (and a ton of undershooting) due to the fact that motors don’t overcome inertia until a certain point. So I solved this by writing a linear equation to map the entire range of -1.0 to 1.0 into the effective range. The equation looks like this, where z is the minimum percent that overcomes inertia and x is the desired speed:

(1.0 - z)x + z

Hope this helped someone out there, I was very happy about how well my controller worked after I made this adjustment.

I also want to mention I would totally recommend writing your own PID controller anyways. The math behind a basic one isn’t complicated and I have a much better understanding of why a PID controller works now that I’ve written one.

Edit: Should also mention that while I could probably have adjusted Kp to a perfect point, my mentor had been messing around with WPILib’s PIDController for over a week trying to perfectly tune and still couldn’t get it even close to consistent, which made me want to make my own implementation.

*I could use a bit of help understanding what you wrote. Could you clarify what you mean by the following phrases please?

“motors don’t overcome inertia until a certain point”

“map the entire range into the effective range

“minimum percent that overcomes the inertia

By the way, I agree with you that writing your own PID can be an effective learning experience, for those so inclined.

By “overcoming inertia” I just mean go from not moving to moving. Overcoming inertia was probably not the best terminology, but I couldn’t think of a better term.

So I’ll explain what I mean by effective range by example. With the CIM I was testing this with originally, I found the motor started moving at around .14. This means that everything from -.13 to .13 wouldn’t move the motor at all. So what my function did is just make every value -1.0 to 1.0 move the motor. For that motor, the equation is:

.86x + .14

So if we take a speed the PID Controller would output that originally wouldn’t move the motor like maybe .05, we’d fine that now .05 would set the motor to .183, therefore moving the motor.

Sorry for having to clarify. Like I said before I’m incredibly tired right now so my writing is bound to be a little cloudy.

Edit: Forgot to mention: with this solution, you do have to specially test for zero, and you do have to negate the equation if x is negative.

That would be static friction and motor controller deadband, not inertia. You can “overcome” friction and deadband, but you never “overcome” inertia: it is always there even when the motor is turning.

Overcoming inertia was probably not the best terminology, but I couldn’t think of a better term.

If you take a physics class, you’ll learn all about inertia and Newton’s Second Law :slight_smile:

So I’ll explain what I mean by effective range by example. With the CIM I was testing this with originally, I found the motor started moving at around .14. This means that everything from -.13 to .13 wouldn’t move the motor at all.

Yes. That’s static friction and motor controller deadband.

So what my function did is just make every value -1.0 to 1.0 move the motor.

Very good. You’re re-mapping the joystick output. There are occasions (as you have discovered) when this can be quite useful. You’re encountering the fun of learning useful new stuff.

Just for the record, you don’t have to write your own PID to use joystick re-mapping. Just send the re-mapped joystick values to the PID, instead of the raw joystick values.

And I’m looking forward to it :slight_smile: Unfortunately it’s never been offered as a class for me until next year, so I don’t have near the understanding I want to have.

For the record, the static friction and deadband was referred to as inertia in previous code I was reading, that’s why I had the term in my head. Thank you very much for the information.

Very good. You’re re-mapping the joystick output. There are occasions (as you have discovered) when this can be quite useful. You’re encountering the fun of learning useful new stuff.

Just for the record, you don’t have to write your own PID to use joystick re-mapping. Just send the re-mapped joystick values to the PID, instead of the raw joystick values.

Not using a joystick for the PID Controller. Main reason my mentor wanted it is for automated tasks and movements towards a setpoint e.g. Autonomous mode movement, arm presets, etc.

Once again, thanks for the info!