I am running into trouble getting the RobotPy Motor Encoder to work in autonomous mode. I am trying to get the motors to spin when autonomous is enabled.
I have already tried to adjust the rev.CANEncoder.EncoderType() value, but with no avail. I have also tried increasing and decreasing the self.motor1CAN.setposition() value, but also with no avail. When I set up a print value to actively print the .setposition() value, the value was changed, but the motor was not moving. The controllers I am using are the CANSparkMax motor controllers. I am using NEO Brushless Motors as well. I have 4 seperate motor controllers set up (I am currently just trying to get one to work), and they are all updated with the latest firmware. The motor controllers are using the CAN bus. My team and I have double checked the physical connections between the motor and the CANSparkMax controller, and they are connected correctly.
I could be wrong, but I think setPosition() the way you are thinking goes to the motor. I think to test the encoder, I would start with get position() and getVelocity().
An encoder is a sensor - all the encoder class will do in code is tell you the currently measured position. It cannot move the motor; that is not what an encoder does.
To move a motor to a position, you need to employ some sort of control strategy using both your motor controller and your sensor.
The SparkMAX keeps track of its encoders and controllers. If you were trying to get the SparkMax to run a motor until a certain encoder value was reached, I think you want something like this:
motor_type = rev.MotorType.kBrushless # same as your rev.MotorType(1) but more readable
self.motor_1 = rev.CANSparkMax(1, self.motor_type) # same again, assuming on CAN address 1
self.PID_controller_1 = self.motor_1.getPIDController() # now you get the controller and can talk to it
self.encoder_1 = rev.CANSparkMax.getEncoder(self.motor_1) # ask the motor controller for its encoder
you can set conversion factors now (insert your own values, but if it’s a wheel):
What you were doing was telling the encoder it was at 20. If you meant to drive to 20, you should use (after doing setP, setI, setD, etc on the controller if you didn’t do it in the rev hardware control):
You could instead set it to voltage, velocity, or other control types.
EDIT: I just looked a bit closer at your code. You don’t need to keep setting the setpoint in AutonomousPeriodic() [which isn’t a thing, by the way. check your capitalization ]. You can set it once in the autonomousInit() and let the controller do the work.
Could you be a little more specific in your description? What doesn’t work? How doesn’t it work? What exactly is it doing? What do you expect it to do? Do you get any errors in the output (log file/riolog/etc)?
Ah, trying to do the same thing as up above, which is make the motor move when switched to autonomous. Right now its not doing that, and I took @CJ_Hill 's code and implemented it, but the motor didn’t spin when I switched it to autonomous. The errors from the driver station were very vague, as far as I know only saying there was an error on line 19, which I tried fixing with no avail.
I see several typos here, if this is cut and pasted from the code.
you are dropping underscores. self.motor1 and self.motor_1 are two different things
self.PID_controller_1 = self.motor1.getPIDController is missing parentheses, you are assigning the self.PID_controller_1 to a function. you need self.PID_controller_1 = self.motor1.getPIDController() . Same on the second controller.
I kinda gave you some clunky advice on getEncoder(). .getEncoder is supposed to be called on an instance of a CANSparkMax object, so it’s much better as self.encoder_1 = self.motor_1.getEncoder()
no need to setReference in autonomousPeriodic. You can set it once in autonomousInit.
I can’t vouch for what happens in wpilib.TimedRobot, but you are probably fine. I use from commandbased import CommandBasedRobot or from commands2 import TimedCommandRobot , depending on if you want to use the old or new version of the command-based library.
if __name__ == “__main__”:
wpilib.run(MyRobot)
Also, note that in general you will want nearly all of this in a drivetrain subsystem.
Our 2021 code is a bit sprawling because we simulated it to death, but you may get some hints on how to do this in our git here.
So, I updated my code to “somewhat” match yours @CJ_Hill , but it still doesnt want to move. No errors through the dashboard, so I honestly have no idea whats going on. Thanks for all the help so far as well!