Skip to content

Drivetrain Motors

Drivetrain

The kitbot uses a 4 motor tank drive meaning the left and right sides are driven independently by 2 motors each. This allows the robot to move similar to a tank by driving the left and right sides at different speeds. For this stage, the four drivetrain motors will be referred to as leftLeader, leftFollower, rightLeader, rightFollower.

Motors can not be controlled directly. Instead SystemCore talks to a motor controller and the motor controller then drives the motors. Motor controllers can also provide sensor data from the motor such as its velocity or temperature. Vendors, such as REV or CTRE, provide classes that can be used to both control and get sensor data from their motor controllers. While each individual type of motor controller has its own class, motor controllers from the same vendor are mostly interacted with in the same way so this stage will only use the SparkMax for REV code and the TalonFX for CTRE code.

When creating a motor controller object, the physical motor controller’s CAN ID and the CAN Bus ID are given. CAN Bus refers to which of the 5 SystemCore CAN ports, or which CANivore, the device is plugged into. CAN ID is an integer that each CAN device is configured to have. All devices on a given CAN Bus must have a unique ID. Using the combination of CAN Bus and CAN ID SystemCore can give commands to the correct motor controller.

For this exercise the motor controllers will have the IDs:

  • leftLeader: CAN Bus 0, CAN ID 0
  • leftFollower: CAN Bus 0, CAN ID 1
  • rightLeader: CAN Bus 0, CAN ID 2
  • rightFollower: CAN Bus 0, CAN ID 3

The motor controller objects should be created inside the Robot.java at the top of the class. This is how the motor controller objects for the left motors will look.

private final int leftLeaderID = 0;
public TalonFX leftLeader = new TalonFX(leftLeaderID, CANBus.systemcore(0));
private TalonFX leftFollower = new TalonFX(1, CANBus.systemcore(0));

For the CTRE code, the CAN ID of the leader motors are stored as a variable since they will be used later on to tell the follower what motor controller to follow. This helps prevent errors from occurring by ensuring that there is a single source of truth for the correct CAN ID. Additionally, CTRE uses a CANBus object to store the CANBus instead of just an integer.

Now try creating the right motor controllers on your own.

Solution
private final int rightLeaderID = 2;
public TalonFX rightLeader = new TalonFX(rightLeaderID, CANBus.systemcore(0));
private TalonFX rightFollower = new TalonFX(3, CANBus.systemcore(0));

Motor Controllers have many settings that can be changed such as IDs, motor types, and limits. Vendors provide software, such as REV’s REV Hardware Client 2 and CTRE’s Phoenix Tuner X, to run and configure their devices from a computer. Motor Controllers have many settings that can be changed. Vendors provide software, such as REV’s REV Hardware Client 2 and CTRE’s Phoenix Tuner X, to run and configure their devices from a computer. However, it is recommended to configure devices through code to ensure that all motor controllers are properly configured. This is especially useful because it can be easy to forget all of the configurations that need to be added and their proper values.

Note

Motor controllers should usually only configured once and should never be configured periodically during the main robot loop. This is because configuring motor controllers is usually a blocking command. This means that the robot code will pause and wait for the motor controller to confirm that it has been properly configured before continuing. This can cause the robot to respond in unexpected and dangerous ways if done repeatedly while the robot is enabled since motor controllers will not be getting new commands.

For this section only the motor controller’s invert setting will be configured. This setting controls what direction Since there are 2 motors on each side of the drivetrain, its important to ensure that the each of the motors on a side move in sync with eachother. This can be accomplished by telling one of the motor controllers to follow the other. This is why one motor is named Leader and the other is Follower. The code tells the Follower to listen to the commands given to the Leader.

The motor controller configuration will be done inside of the constructor for the robot class Motor Controllers are configured by first creating a motor controller configuration object. This object stores the configuration so it can be changed and shared across different Motor Controllers.

var leftConfig = new TalonFXConfiguration();

Next, settings can be changed from their default by calling various functions on the configuration object with their new values. For the left motors, the invert setting will be true for REV code and Clockwise_Positive for CTRE code. This will cause the motors to spin in a direction that would drive the robot forward when a positive input is given. Since the motors on the right side of the drivetrain are facing the opposite direction they would cause the wheels try and drive the robot backwards when given a positive input if they were configured the same way. Instead they should be configured with an invert setting of false or Counter_Clockwise_Positive so they also drive the robot forward when given a positive input.

leftConfig.MotorOutput.withInverted(InvertedValue.Clockwise_Positive);

Finally, the configuration object gets given to the motor controller object. It’s important to remember that settings only get changed when the configuration gets given to the motor controller.

For CTRE Motor Controllers, becoming a follower is a ControlRequest instead of a configuration.

leftLeader.getConfigurator().apply(leftConfig);
leftFollower.getConfigurator().apply(leftConfig);
leftFollower.setControl(new Follower(leftLeaderID, MotorAlignmentValue.Aligned));

Now try configuring the right motor controllers on your own. Remember that some of the configurations may be different.

Solution
var rightConfig = new TalonFXConfiguration();
rightConfig.MotorOutput.withInverted(InvertedValue.CounterClockwise_Positive);
rightLeader.getConfigurator().apply(rightConfig);
rightFollower.getConfigurator().apply(leftConfig);
rightFollower.setControl(new Follower(rightLeaderID, MotorAlignmentValue.Aligned));