TalonSRXs stay solid orange but motors move during auto

Hello -

We are having a strange issue with a timed drive command in autonomous. We use command-based Java programming, and our drivetrain has 2 TalonSRXs and 2 VictorSPXs using CAN. The goal is to have a timed command that makes the robot drive off the starting line.

When we run the autonomous command that is supposed to make the drivetrain motors run for a certain amount of time at 80% speed (we have tried a bunch of different speeds - we are using percent output mode), the drivetrain talons and victors all stay solid yellow during the time that the command is supposed to run, BUT the motors move and stutter. The stuttering lasts for as long as the timed command is supposed to run, and the motors do not move at the right speed. Not sure why the motors move when the Talons and Victors stay solid orange and do not display flashing green/red.

This is ONLY the case for the 4 driveTrain motor controllers - when we altered the code and replaced the drivetrain Talons/Victors with another TalonSRX that is controlling the spinning intake, the command worked perfectly and the intake motor moved at the correct speed for the correct amount of time.

It also should be noted that the drivetrain works perfectly in teleoperated mode - all 4 drivetrain motor controllers (and all the other motor controllers as well) change light color and obey commands from the joysticks.

In the code, I have a command called TimedMoveForward. This command is the default option for an Autonomous Chooser on the SmartDashboard. Attached below:

TimedMoveForward.java (3.3 KB)

These are the steps I have already taken in an attempt to debug:

  • I have verified that the Auto Chooser in the Smart Dashboard works correctly by making another motor run when the second option is selected and it does. (when the first option is selected, the stuttering driving happens).
  • I tried using the Phoenix Tuner and all of the drivetrain Talons and Victors can be controlled perfectly through the Phoenix Tuner using the slider.
  • I have tried just replacing the timer condition for the isFinished method with a simple “return false” and nothing changes - motors stutter for a bit and then nothing happens
  • I have put a SmartDashboard boolean that shows if the isFinished method is reached, which returns true. The command itself runs, there’s just an issue with what happens when it runs.
  • I also made another SmartDashbaord boolean that shows the timer condition (whether isFinished returns true or false) and we can see on the Dashboard that this boolean stays false for 3 seconds (the time that the command is supposed to run for) and then turns to true after 3 seconds. This demonstrates that it is not an issue with the timer.
  • I have also tried just writing Talon.set(value) right inside the execute method of the command, instead of calling a method in a separate subsystem that does the same thing. This replacement did not make a difference either - so it’s not a problem with calling the method from a different class.
  • Checked over the wiring and nothing seems to be wrong…

From reading other Chief Dephi posts, people have suggested that the Talons might be receiving multiple commands at the same time due to the linkage of the drive subsystem to a drive command (“requires()” and “setDefaultCommand” linkage, etc) (??) Does anyone have experience/other information about this?

For the past 3 years, I have written PID commands for autonomous, so I have never tried using a timed drive command before. (We decided not to use PID autonomous control this year for the first time). Although PID commands are typically more complicated, for some reason I can’t figure this out. Our team has no programming mentors to ask, and I have spent a considerable amount of time trying to debug this issue. Any feedback would be much appreciated since we have a Week 3 competition coming up next weekend!

Screenshots of the class if the upload above didn’t work:

This seems like the most likely cause, but without seeing all your code we can’t help.

1 Like

It looks like you have at least 3 different subsystems that access your drive motors. That isn’t good encapsulation and makes it easy for problems like this to occur. You should have only a single subsystem encapsulate your drive motors and have commands that require that subsystem.

If you have a lot of public variables inside your class, that is a bad sign that your code is going to work well.

Java (and other languages) all provide this notion of encapsulation to protect your class from being interfered with in other classes. FRC command-based programming has the same design idea, such that ONLY the scheduler should operate as the gatekeeper as to which classes can be operating on a given subsystem.

Why is that important? The Subsystem in and of itself should be made up of the sensors and actuators required to make that subsystem function. For example, in the case of your DriveBase (or Drive Train) subsystem, this would be things like motor controllers, maybe a gyro, maybe some encoders, maybe some solenoids if you have a shifting gear box.

The singular subsystem owns all of those pieces, and the ONLY way other code can control those items is by asking the subsystem politely…which in programming terms is done by the Subsystem exposing a method that has a public scope. In FRC Command-Based programming, those methods are called from Commands.

No other piece of the program should be able to set your motor controllers on or off. ALL of that happens within the DriveBase only, and ONLY through calling the public methods that the subsystem has declared as proper.

Here is a rudimentary example of a subsystem that could be used to drive:

public class DriveTrain extends SubsystemBase {
    private TalonSRX driveTalon;

    public DriveTrain(){
        driveTalon = new TalonSRX(1);
    }

    public void drive(double speed){
        driveTalon.set(ControlMode.PercentOutput, speed);
    }

    public void stopMotors(){
        driveTalon.set(ControlMode.PercentOutput, 0);
    }
}

Anywhere else in your code that wants the talons to move the motors would have to call the method drive() in the DriveTrain object.

1 Like

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