When deploying command based robot code to our practice bot, we are getting this error. We are unsure as to what is its cause:
ERROR 1 Unhandled exception: java.lang.IllegalArgumentException: Subsystem must not be null. frc.robot.commands.DriveForwardsSlowly.(DriveForwardsSlowly.java:17)
public void robotInit() {
m_oi = new OI();
m_chooser.setDefaultOption(“Default Auto”, new ExampleCommand());
// chooser.addOption(“My Auto”, new MyAutoCommand());
SmartDashboard.putData(“Auto mode”, m_chooser);
drivetrain = new DriveTrain();
}
public void robotInit() {
m_chooser.setDefaultOption(“Default Auto”, new ExampleCommand());
// chooser.addOption(“My Auto”, new MyAutoCommand());
SmartDashboard.putData(“Auto mode”, m_chooser);
drivetrain = new DriveTrain();
m_oi = new OI();
}
What’s happening is when you instantiate OI (call new OI) it’s going through and setting up all of your buttons and commands, which requires access to your subsystems. But because you didn’t call new DriveTrain() yet it had a null value and caused issues when requires(drivetrain) is called.
Or perhaps the following if ExampleCommand requires drive train…
public void robotInit() {
drivetrain = new DriveTrain();
m_chooser.setDefaultOption(“Default Auto”, new ExampleCommand());
// chooser.addOption(“My Auto”, new MyAutoCommand());
SmartDashboard.putData(“Auto mode”, m_chooser);
m_oi = new OI();
}
This means that one more more of your commands are taking too long to execute. Do you have a code repository I can look at your code to see what’s wrong?
public class TurnLeft5 extends Command {
public TurnLeft5() {
// Use requires() here to declare subsystem dependencies
// eg. requires(chassis);
requires(Robot.drivetrain);
}
// Called just before this Command runs the first time @Override
protected void initialize() {
}
// Called repeatedly when this Command is scheduled to run @Override
protected void execute() {
Timer timer = new Timer();
timer.start();
while(timer.get() < 3){
Robot.drivetrain.drive(.5, -.5);
}
Robot.drivetrain.drive(0, 0);
}
// Make this return true when this Command no longer needs to run execute() @Override
protected boolean isFinished() {
return false;
}
// Called once after isFinished returns true @Override
protected void end() {
}
// Called when another command which requires one or more of the same
// subsystems is scheduled to run @Override
protected void interrupted() {
}
}
It sounds like you don’t fully understand how the command based structure works. Please read through these presentations, it will help you understand what is happening.