SpeedControllerGroup vs .follow on CAN motor controllers

Hi Everyone,

I have a question that have not been able to find a good answer to by going through the docs.

Given a standard differential drivetrain that is using multiple CAN bus motor controllers (4x SparkMax in this example)

public DriveTrain() {

      mot_leftFrontDrive = new CANSparkMax(kDriveTrain.CANLeftDriveFront, MotorType.kBrushless);    
      mot_leftRearDrive = new CANSparkMax(kDriveTrain.CANLeftDriveRear, MotorType.kBrushless);
      mot_rightFrontDrive = new CANSparkMax(kDriveTrain.CANRightDriveFront, MotorType.kBrushless);
      mot_rightRearDrive = new CANSparkMax(kDriveTrain.CANRightDriveRear, MotorType.kBrushless);

There are two ways that you could link together the motors.

//#1 Follow using motor controller API
      m_drive = new DifferentialDrive(mot_leftFrontDrive, mot_rightFrontDrive);


 //#2 Using a Motor Controller Group
      m_leftGroup = new SpeedControllerGroup(mot_leftFrontDrive, mot_leftRearDrive);
      m_rightGroup = new SpeedControllerGroup(mot_rightFrontDrive, mot_rightRearDrive);
      m_drive = new DifferentialDrive(m_leftGroup, m_rightGroup);

Is there any reason to select one of these methods over the other? We’ve been using the follower method for a couple years - mostly because I was guessing that it would lower the number of CAN packets sent over the network. Anyone with a deeper understanding of the APIs at play able to provide a definitive answer?

I’m pretty sure (although I haven’t tested it myself) that if you’re doing open-loop driving (or implementing a PID loop on the RIO) that the two methods are basically equivalent.

The SpeedControllerGroup construct just pushes throttle commands to all of the members when you write to it.

The follow is important when you’re running a control loop on the motor controller. In that case, the RIO isn’t commanding the master motor controller directly, and so can’t push throttle updates to the follower. Instead, the follower will get throttle directly from the master, over CAN, effectively becoming part of the “plant” of the control loop running on the master motor controller.


SpeedControllerGroup limits you to percentOutput control. Where as motors you can do many styles of control and follow will pick up those changes. A good example would be if you wanted to use Talon Motion Magic. SpeedControllerGroup would not work well for that.

1 Like

Thank you both @CarlosGJ and @Bmongar. I wasn’t thinking of the on controller PID or other advanced functionality =)

As a team we have always used the follow mode in cases like this. That being said, this thread has made me consider the alternative.

One counterpoint, I think, is around resiliency. The risk with follow mode is that if the master motor controller fails, you completely lose both motors.

If you used the “motor controller group” in code concept, the Roborio would separately signal each motor controller and you have a chance of still driving (albeit with less power) around a motor controller failure. With CANBus, the bus wiring is still a single point of failure.

You could perhaps use PWM to both motor controllers and avoid even that single point of failure – at penalty of potentially losing even more features of the controllers (e.g. current limiting). You also would lose access to any internal encoders in the motors (e.g. Neos w/ SparkMax in your example). You would obviously need to do any closed loop control in the Roborio, with external encoders in place of brushless motor internal encoders.

Again, we have always just used follow mode. Simply a thought experiment to consider possible “pros” of the alternative.


Even if you’re controlling a CAN motor controller over PWM, you can still use some of the “smart” features like current limiting and limit switches by configuring the features beforehand with the hardware client GUI.

1 Like

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.