Motor Control Discussion
Setting up a motor
There are 2 basic ways to control a motor - a direct command, or a direct voltage command. Throughout a match, a robot's battery will begin to be depleted, so it is almost always better to control a motor based on the battery voltage, which allows the speed controller to give enough power to the motor to keep it running at the same speed.
CTRE, since the 2024 Season, has used Control Requests (you can find more about them in the API). Control Requests allow you to do many modes of output, such as VoltageOut, which requests that the motor runs at 12 volts (or whatever you choose).
- Falcon 500 / Kraken X60 Motor - controlled through a Talon FX inbuilt speed controller
// Create a new TalonFX motor controller using the CAN ID.
// This ID should be checked with the actual CAN ID on the robot, and then stored in Constants.java
WPI_TalonFX motor = new WPI_TalonFX(0);
// Set the motor to 50% speed
motor.set(0.5);
// Here we create a VoltageOut Control Request with a requested voltage of 9.5 volts
VoltageOut voltageOut = new VoltageOut(9.5);
//Here we tell the motor to apply the Control Request
motor.setControl(voltageOut);
// You can also apply other voltages, here we are setting 12 volts:
motor.setControl(voltageOut.withOutput(12))
REVLib doesn't have the same features that CTRE uses, though.
- Spark Max Motor - controlled through a Spark Max inbuilt speed controller
// Create a new Spark Max motor controller
CANSparkMax motor = new CANSparkMax(0, MotorType.kBrushless);
// Set the motor to 50% speed
motor.set(0.5);
// Set the motor to 50% voltage in mind
motor.setVoltage(12 * 0.5);
The format of creating and using motors is fairly similar between motors, so to see how other motors are initialized, check their manufacture's documentation.
Motor Inversion
If a motor is spinning in the wrong direction, we can invert it by using the setInverted() method.
// Create a new TalonFX motor controller
WPI_TalonFX motor = new WPI_TalonFX(0);
// Invert the motor
motor.setInverted(true);
Speed Controller Groups
Say we want 2 motors to be controlled at the same time. We could set each motor individually, but that would be a lot of code. Instead, we can use a motor controller group to control multiple motors at once.
// Create a new TalonFX motor controller
WPI_TalonFX motor1 = new WPI_TalonFX(0);
WPI_TalonFX motor2 = new WPI_TalonFX(1);
// Create a new speed controller group
MotorControllerGroup motors = new MotorControllerGroup(motor1, motor2);
// Set the motors to 50% speed
motors.set(0.5);
// Set the motors to 50% voltage in mind
motors.setVoltage(12 * 0.5);
// You can also invert Speed Controller Groups
motors.setInverted(true);
Encoders
If a motor has an encoder, we can use it to get the position of the motor.
// Create a new TalonFX motor controller
WPI_TalonFX motor = new WPI_TalonFX(0);
// Create a new encoder
// this encoder would be separate from the speed controller.
Encoder encoder = new Encoder(0, 1);
//Talon FX motor controllers have an encoder built in, so we can use that instead
// Note that this value is in encoder ticks. For a Falcon 500 motor, there are 2048 encoder ticks per rotation of the motor shaft.
motor.getSelectedSensorPosition();
Joysticks
Joysticks are used to control the motors. They are usually connected to the driver station, and are used to control the robot.
// Create a new joystick
Joystick joystick = new Joystick(0);
// Get the joystick's x value
joystick.getX();
// Get the joystick's y value
joystick.getY();
// Get the joystick's z value
joystick.getZ();
// Get the joystick's throttle value
joystick.getThrottle();
// Get the joystick's twist value
joystick.getTwist();
// Get the joystick's button value
// There are ~16 buttons on a joystick, which can be checked in Driver Station
joystick.getRawButton(0);
A Final Note
There are much more complicated methods to control a motor to be able to move it to an exact position, however for this training, we will keep it simple. Just keep in mind that these methods are the base interface to control motors on robots.