- Required Robot: Any
This challenge builds upon basic motor rotation by introducing multi-revolution position control. Students will learn to calculate and control precise motor rotations using encoder feedback, which is essential for mechanisms like elevators, arms, and conveyor systems that need to move specific distances or complete multiple rotations.
Create a subsystem that uses a button press to rotate a motor forward exactly 5 complete revolutions, then automatically stop. The motor should rotate smoothly and stop precisely at the target position using encoder feedback for position control.
- Motor: NEO with SparkMax controller (any available motor)
- Elevator Primary Motor: SparkMax (CAN ID: 52)
- Intake Arm Motor: SparkMax (CAN ID: 60)
- Controller: Xbox Controller (Port: 0)
- Motor: Any TalonSRX with encoder
- Front Left Motor: TalonSRX (CAN ID: 20) with DIO encoder (ports 0, 1)
- Front Right Motor: TalonSRX (CAN ID: 22) with DIO encoder (ports 4, 5)
- Controller: Xbox Controller (Port: 0)
- Create a new Subsystem class for position-controlled motor
- Add motor controller and encoder instances with proper initialization
- Create a method to convert revolutions to encoder units
- Implement a command that sets the target position to current position + 5 revolutions
- Use position control (PID) to drive the motor to the target position
- Add button binding in RobotContainer to trigger the 5-revolution command
- Add telemetry to display current position, target position, and motor output
- Motor rotates exactly 5 complete revolutions when button is pressed
- Motor stops precisely at the target position without oscillation
- Command completes automatically when target is reached
- Multiple button presses work correctly (each press adds 5 more revolutions)
- Telemetry shows accurate position feedback throughout the motion
- For Step 1: Create a subsystem class like
public class PositionMotorSubsystem extends SubsystemBase. Consider naming it based on the mechanism you're controlling (e.g.,ElevatorSubsystemorArmSubsystem). - For Step 2: For Competition robot using NEO, initialize with
motor = new CANSparkMax(CAN_ID, MotorType.kBrushless);and get the built-in encoder withencoder = motor.getEncoder();. For Testbed robot, usemotor = new WPI_TalonSRX(CAN_ID);and create a separate encoder instance. - For Step 3: NEO encoders report in rotations by default, so 5 revolutions = 5.0 encoder units. For quadrature encoders on Testbed, calculate:
targetCounts = revolutions * pulsesPerRevolution * 4 * gearRatio. Use the encoder specs from the hardware documentation. - For Step 4: Create an
InstantCommandthat calculates the new target position:() -> setTargetPosition(getCurrentPosition() + 5.0). Store the target position in an instance variable. - For Step 5: For NEO motors, use the SparkMax PID controller:
pidController = motor.getPIDController(); pidController.setReference(targetPosition, ControlType.kPosition);. For TalonSRX, usemotor.set(ControlMode.Position, targetCounts);. Set appropriate PID constants in the constructor. - For Step 6: In RobotContainer, bind to a button like:
driverController.a().onTrue(subsystem.rotateForwardCommand());. Make sure the command requires the subsystem. - For Step 7: In the subsystem's
periodic()method, add:SmartDashboard.putNumber("Current Position", getCurrentPosition()); SmartDashboard.putNumber("Target Position", targetPosition); - Common Issue: If the motor doesn't stop at the target, check your PID constants. Start with P=0.1, I=0, D=0 and tune from there.
- Common Issue: If positions are incorrect, verify your encoder conversion calculations and make sure the encoder is properly connected and configured.
- Safety Tip: Add reasonable position limits to prevent the motor from rotating indefinitely if there's a sensor failure.
- Bidirectional Control: Add a second button that rotates the motor backward 5 revolutions.
- Variable Revolutions: Use different buttons for 1, 3, 5, and 10 revolution movements.
- Speed Control: Add a parameter to control how fast the motor rotates to the target position.
- Soft Limits: Implement software limits that prevent the motor from exceeding safe position ranges.
- Homing Sequence: Add a limit switch and create a command that homes the motor to a known zero position before executing rotations.
- Continuous Operation: Create a command that continuously rotates the motor 5 revolutions, waits 2 seconds, then repeats until cancelled.