I’m currently programming a swerve drive for this years game. I’ve seen teams have the encoder positions marked from -180 degrees to 180 degrees. I’m using a Talon SRX and the CTRE Quadrature Encoder to try and replicate this. I’m currently using the Pulse Width Encoded for the Primary Feedback Sensor, and have the Feedback Not Continuous set to true. Currently, it looks like my encoder goes from 0 to -4096 before resetting back to 0, no matter which direction I spin. I would like the encoder to go from 0 to 180 at the halfway point, then -180 back to 0 as it comes around. That way, a 90 degree turn is opposite a -90 degree turn. Sorry if it sounds confusing, I’m a little confused myself. Any help is appreciated!

The encoder returns values in encoder units. You would have to do math on top of that to translate to an angle. You can read more on the encoders here: https://phoenix-documentation.readthedocs.io/en/latest/ch14_MCSensor.html. Hope this brings some clarity to your situation.

I figured as much. Follow up question, my encoder doesn’t actually go to 0. When I put

talon.set(ControlMode.Position, 0), the encoder instead goes to -268. I set up the PID correctly, as I’m able to get to other positions, but the encoder is offset by -268 every time. Is this a programming problem, or could it be an electrical wiring one? And is there a way to set the absolute position to 0?

If I am understanding you right it’s attempting to reach zero but never actually getting there and since your using PIDs it sounds like you want to introduce a higher I value as it’s having trouble reaching it’s setpoint. Additionally if your motor it outputting negative when your device moves in the positive direction you might want to set the sensor phase.

You can read more about position closed loop here: https://phoenix-documentation.readthedocs.io/en/latest/ch16_ClosedLoop.html and you can read about sensor phase in the link from my previous reply.

If you can’t find the appropriate correction function, this will map the input to -180 to 180:

angle = ((((encoder_val - zero_offset) % 4096) + 4096) % 4096 - 2048) * 45 / 512

encoder_val is the raw number back from the encoder (works whether continuous is true or not.)

zero_offset is your -268.

The first modulo (%) pulls into the range -4095…4095, the add and next modulo make it 0…4095, subtracting 2048 makes it -4096…4095, and the multiplication and division scale it to 180.

Here’s how we do it with swerve modules:

Likely the same outcome as what @GeeTwo said, but in my opinion, simpler to understand.

Yes, ((x % y) + y) % y does the same as IEEEremainder(x,y) except that where IEEEremainder returns y/2, mine returns -y/2. There’s also likely different handling of y=0 which is not a problem in this case.

That helps me with the math. Thank you!

So, am I able to use this code whilst using the talonsrx PID controller? Or would I have to use the WPI PID controller?

Either will work. Of course, you’ll access it differently, in the first case by getting the encoder from the Talon, and in the second case by creating a WPI encoder object from a DIO pin. Using the one from the Talon will also allow you to do closed-loop functions entirely on the Talon.

Yes, the code I posted is designed so you are able to use the Position ControlMode of the talon so you don’t have to use the WPI PIDController.

If you were to use PIDController, you could make the logic simpler because PIDController supports continuous input. However, I don’t have experience using PIDController for swerve modules.

After tuning my talon and making sure all the Sensors are in phase, I’m finally ready to try this out. This might sound dumb, but what exactly does the % represent? Is it a function within Java, or is it representative of something like division?

The *%* character does the modulus math (effectively gives you the remainder of division).

Simple example:

10 % 10 = 0, remainder 0)

5 % 10 = 5 (0, remainder 5)

15 % 10 = 5 (1, remainder 5)

Oh goodness I never knew that thank you so much!

Lets say I want to put in the angle I want and return the ticks it equates to. What would that look like?

angle * 4096 / 360

or more simply

angle * 512 / 45

or angle * 11.377777…

The tricky bit is that the output will always have the sign of the “numerator”, so that

-13 % 10 = -3

The IEEE version always returns the number closest to zero, which is why it solved your initial question easier.

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.