SparkMax SetInverted affecting PID position control

We have found that using position control of the neo brushless motors does not work if we had used the SetInverted function to invert the motor. It works when using percent motor output control but in position control the motor will go full speed in the wrong direction and coast down about 4 times past the desired setpoint. We manually inverted the motor in the code by just giving a negative value to the motor output and the setpoint, but is anyone else having a similar issue? We are using the built-in encoder for the NEO motor.

Yes we also have just been inverting the motor using negatives

I know for the talon srxs, it is important that you have the phase between the motor and the sensor set correctly. If you have the phases opposed, you will see the behavior you have which is called “runaway” in industry terms.

That makes sense and could be the problem but I do not know of a way to set the sensor phase with spark maxs. I don’t think it’s in the API as of yet but that could very well be the issue and it might be added soon.

Hi, Everyone:
This is a year late, but we started using SparkMax’s this year, and ran into this same problem. Its possible to solve this (as above) by reversing the motors, but this leads to unfortunate consequences using path following-- the Wpilib path weaver assumes forward sense of the motors.

If you’re using the stock SparkMax, there’s a 6 pin JST connector going to the encoder. Pins 3 and 4 ( the middle two) are channels A and B of the built-in hall effect encoder. You can change the direction of the encoder by swapping those pins.

Can you elaborate on the issue you are having here? The invert functionality works just fine and allows you to invert the output of the motor without inverting the setpoint. If you are using the integrated sensor you do not need to worry about sensor phase. You can safety invert one side of the drivetrain in software and this is a common use case for just about every team using a differential drive in FRC.

While yes this is the true, I do not recommend doing this. If you have a motor with the sensor cable swapped this way and mistakenly try to plug the motor phases to the correct color you will stall the motor. This also creates a difficult to debug case.

Hi, Will:

Yes, actually you’re right about swapping the pins.

We’re not having a problem getting the usual DifferentialDrive to work correctly–as you mention, we simply invert one side.

The issue is that the encoders still read negative values on the inverted side. We want to have positive values, because the Wpi provided path stuff doesnt expect negative values.

Using CANTanlons, we would historically just software reverse the sense of the encoders to solve this. But the CAnEncoder class for SparkMax, though it has an invert method, throws an exception when you’re using the hall effect encoders.

Of course it’s possible to invert the right side encoder signal, but that leads to confusion down the road. The current problem is that https://first.wpi.edu/FRC/roborio/release/docs/java/edu/wpi/first/wpilibj/controller/RamseteController.html is not happy when the encoder counts are inverted on one side.

1 Like

My team was also having significant issues with a SparkMax/Neo drivetrain and Ramsete causing it to turn in odd ways. I believe encoder phase to be at least part of the issue, but haven’t found an appropriate solution yet.

This should not be the case. Whenever you invert the controller, the encoder values follow that inversion. Commanding a positive setpoint will result in an incrementing position and positive velocity, regardless of the inversion setting.

If you are using the NEO built in sensor, the phase will always match, there is no setting to make the encoder and motor out of phase.

I understand that part, which lead to significant confusion about the issue because I couldn’t explain the behavior any other way. I did post in the FRC discord the other day and got a few suggestions to try, so I expect we’ll be doing that tomorrow.

I’m not sure what we ate missing, but there is no question that our encoders are reading negative. When we invert the drives, the encoders read positive but as you might guess, we turn when we should be going forward.

We printed the encoder values to the smart dashboard. We are using the getEncoder() method

It might help to note what happened when we swapped the a and b channels on the encoder cables. When we did that, we could manually turn all four wheels by hand, and observe that the encoders we positive and incearsed when the wheels turn in the forward direction. But then when you try to drive, the motors would turn briefly the wrong way (we would see the encoders very briefly go negative, and then the drives would stop. It looks like the dribes were expecting to move forward, and then stopping due to a fault.

Inverting the motors at that point using set Inverted had no affect… The drives still twitched.

This tells me that indeed, the stock wires expect a single direction. Unfortunately that leaves us with negative encoders