Sub-Class CANTalon to represent 3 motors

Hi everybody,

This year our team is going with a 6-motor drive train, and our programming team came across the problem of RobotDrive only having two motor and four motor constructors. We only have a tank drive, but I personally like using RobotDrive because of the ease of switching between Tank drive and arcade drive. I saw an old post from 2010 mentioning adding a whole new constructor to the RobotDrive file itself, but I wanted to take a different approach.

Would there be anything wrong with writing our own sub-class of CANTalon (or any class that implemented SpeedController, we are just using CANTalons), whose constructor creates three instances of CANTalons, and overrides .set() by calling .set() on each of the Talons, then constructing RobotDrive with two objects of this class, one for each side of the drive train?

Code outline (not guaranteed to compile :wink: )

public class ThreeMotorGearbox extends CANTalon {
    public CANTalon talon1, talon2, talon3;

    public ThreeMotorGearbox(int talon1id, int talon2id, int talon3id) {
        super(talon1id); //We will be overriding all the important methods, anyway)
        talon1 = new CANTalon(talon1id);
        talon2 = new CANTalon(talon2id);
        talon3 = new CANTalon(talon3id);
    }

    @Override
    public void set(double speed) {
        talon1.set(speed);
        talon2.set(speed);
        talon3.set(speed);
    }
}

//Somewhere in the code
public ThreeMotorGearbox leftSide, rightSide;
public RobotDrive driveTrain;

leftSide = new ThreeMotorGearbox(1,2,3);
rightSide = new ThreeMotorGearbox(4,5,6);
driveTrain = new RobotDrive(leftSide, rightSide);


You’d probably be better just implementing the SpeedController class.

Edit: SpeedController

Why?

The SpeedController is the base interface for all of the motor controllers. This way you know you are implementing all of the stuff that needs implemented. Really it should just be calling the same method that you’re implementing for each of the CANTalons.

I thought the same at first (when I started writing this), and figured I could use super for most of the functions I needed. But I realized as I was writing this that each function that will get called and actually DOES anything needs to be @Overrid and pointed to all three Talons. Unless there is a function in CANTalon that simply IDENTIFIES the CANTalons, that doesn’t DO anything that needs to be overridden (eg public String getType() {return “CANTalon”}, it would be simpler. He has a point, there is no reason TO implement CANTalons unless there is said identifying function

CANTalon does implement SpeedController, by extending it my class inherits all the functions, plus the way CANTalons identify themselves

Ultimately, it comes to not having to call the super constructor, and I will go with notmattlythgoe that directly implementing SpeedController is better

If anyone is looking to group together multiple motors under a single Motor object (i.e. three drivetrain motors under one object like OP’s code), I’d like to point to a library of 1902’s that has a class called MotorGroup. It works like so:


MotorGroup leftDrive = new MotorGroup(CANTalon.class, 0, 1, 2);
leftDrive.setPower(1);

MotorGroup rightDrive = new MotorGroup(new CANTalon(3), new CANTalon(4));
rightDrive.setPower(-0.5);

MotorGroup is very flexible because it takes any type of Motor and can contain as many motors as you want, so it should help eliminate having to make awkward wrapper classes or mass-call SpeedController.set().

The link to the source file (and the rest of the repo) can be found here.

To get completely back on-topic and to answer the original question, that wrapper class should work fine. My only suggestion would be to not extend CANTalon.

Disclaimer: MotorGroup relies on other parts of the library to exist, so it does not work as-is without changing it not use BCNLib classes.

CanTalons have a Follower mode, where set() takes the CAN ID of a talon to constantly copy speed from. That way, you only need to pass 2 “master” talons to RobotDrive and have the rest copy those.

+1. Check out section 16.33 in talon srx software reference manual.

The only problem with that is RobotDrive does not know to call .setPower, it only every calls .set() assuming any class that implements SpeedController uses that method

Yup, that’s because MotorGroup is part of an overall wrapper/utility library that effectively creates it’s own, better versions of WPILib’s classes. To get MotorGroup to work with WPI’s RobotDrive, you just make it implement SpeedController instead of extending Motor and rename a few functions.

Would that be more “reliable” then setting them all in code?

The slave/follower features of the Talon SRX are reliable. Many teams were successful using this feature last season. You can read more about it in the Talon SRX Software Reference manual.

Check out section 16.33 for a specific example of a solution to your OP.
http://www.ctr-electronics.com/talon-srx.html#product_tabs_technical_resources

Thanks all!