Command Based robot error

Hello,

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)

Thanks for your help!

1 Like

This is typically caused because your OI getting instantiated prior to the subsystems. Make sure the OI is created after the subsystems.

1 Like

how do i go about doing this? sorry I am new to command based programming

Can you post your code

also line 17 of the command with the error is just the requires statement:

requires(Robot.drivetrain);

Are you calling new Drivetrain() and new OI() in your robotInit or when you create the variable?

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();
}

so should i put the drive train as line one of this method?

Change it to:

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();
}
1 Like

ok, i will try this.

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.

2 Likes

@notmattlythgoe
That allowed it to deploy the code and enable the bot. However, some of our commands are not working because of this error:

Warning at edu.wpi.first.wpilibj.IterativeRobotBase.printLoopOverrunMessage(IterativeRobotBase.java:273): Loop time of 0.02s overrun

i am not sure what this means either…

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();
}

Steve

1 Like

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?

1 Like

no i do not… But here is the suspicious command

/----------------------------------------------------------------------------/
/* Copyright © 2018 FIRST. All Rights Reserved. /
/
Open Source Software - may be modified and shared by FRC teams. The code /
/
must be accompanied by the FIRST BSD license file in the root directory of /
/
the project. /
/
----------------------------------------------------------------------------*/

package frc.robot.commands;

import edu.wpi.first.wpilibj.command.Command;
import frc.robot.Robot;
import edu.wpi.first.wpilibj.Timer;

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() {
}
}

i am trying to have a button make the robot turn for a specific amount of time…

I also have the button set to whenPressed for this command… I assumed if it is when pressed it would do the command once through and then stop?

Yeah, in the command based structure you can’t run loops like that. Every iteration of execute must finish very quickly.

What you can do is put a timeout on the command itself instead.

In your command’s constructor put
super(3);

This will timeout your command after 3 seconds.

Change your execute method to:

protected void execute() {
    Robot.drivetrain.drive(.5, -.5);
}
1 Like

is this even true on “whenPressed”

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.

http://team2363.org/topics/programming/

1 Like