Wrapper classes for motors and such

I was speaking with the alliance captain of the winning alliance at our week 2 regional event and they were talking about how they had created wrapper classes for their motors so they didn’t have to worry about the differences between rev and ctre apis when they were coding. I was intrigued by this and would like to implement something like this for our robot in 2023 but I’m not sure how it works. Does anyone have experience in this area that could point me in the right direction?

1 Like

Essentially, you just need to make a class that takes in the motor type in the constructor and runs the corresponding command. For example,

public GenericMotorController {
	
	WPI_TalonSRX talon;
	CANSparkMax spark;
	MotorType type;

	public GenericMotorController(int id, MotorType type) {
		this.type = type;
		if(type == MotorType.Talon) {
			talon = new WPI_TalonSrx(id);
		} else {
			spark = new CANSparkMax(id, MotorType.kBrushless);
		}

	}

	public void setVelocity(double speed) {
		if(type == MotorType.Talon) {
			talon.set(ControlMode.Velocity, speed);       
		} else {
			spark.getPIDController().setReference(speed, ControlType.kVelocity);
		}

	}



}

Where would I write this class? Would I just create a class in my robot project or could I write a library that I could import?

One way you can do this is through polymorphism. For example:

public interface GenericMotorController {
    void setVoltage(double voltage);
    void setPercentage(double percentage);
    void resetEncoder();
    void setSetpoint(double setpoint, SetPointType type);
    double getEncoders();
    // ...
}
public class CTREMotorController implements GenericMotorController {
    private final WPI_TalonSRX talonSRX;
    public CTREMotorController(int id) {
        this.talonSRX = new WPI_TalonSRX(id);
    }
    
    @Override
    public void setVoltage(double voltage) {
        talonSRX.setVoltage(voltage);
    }
    
    @Override
    public void setPercentage(double percentage) {
        talonSRX.set(percentage);
    }

    @Override
    public void resetEncoders() {
        talonSRX.setSelectedSensorPosition(0.0);
    }
    
    @Override
    public void setSetpoint(double setpoint, SetpointType type) {
        if (type == SetpointType.VELOCITY) {
            talonSRX.set(setpoint, ControlType.kVelocity);
        else if (type == SetpointType.POSITION) {
            talonSRX.set(setpoint, ControlType.kPosition);
        }
    }
    
    @Override
    public double getEncoderPosition() {
        return talonSRX.getSelectedSensorPosition() * DISTANCE_PER_TICK;
    }
}

You would do the same for the sparkmax

3 Likes

On our team, we just organize classes like these inside of a util package in our robot project. However, if you have many classes, especially shared between projects, some teams like to create libraries to import.

awesome thanks. could I just use a simple maven project to create this?

That should work.

1 Like

There’s already a MotorController interface included with WPILib; probably best to start with that rather than rewriting method like setVoltage.