Java button help

Hello, we are brand new to programming in Java this year. We are following the cookbook from firstforge. We were able to move the robot using a joystick but cannot figure out how to use a button to enable a motor. We created a subsystem called shooter then a command called ShootBall. We get an error in out code and can’t figure out why. Our code is in the attachment.

Here is shooter:


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package edu.wpi.first.wpilibj.templates.subsystems;

import edu.wpi.first.wpilibj.Jaguar;
import edu.wpi.first.wpilibj.buttons.Button;
import edu.wpi.first.wpilibj.command.Subsystem;
import edu.wpi.first.wpilibj.templates.commands.ShootBall;


/**
 *
 * @author Developer
 */
public class Shooter extends Subsystem {
    Jaguar leftMotor, rightMotor;
    // Put methods for controlling this subsystem
    // here. Call these from Commands.

    public void initDefaultCommand() {
        setDefaultCommand(new ShootBall());
        // Set the default command for a subsystem here.
        //setDefaultCommand(new MySpecialCommand());
    }
    
    public Shooter(){
        leftMotor = new Jaguar(3);
        rightMotor = new Jaguar(4);
        leftMotor.setSafetyEnabled(false);
        rightMotor.setSafetyEnabled(false);
    }

    public void ShootBall(Button a){
        a.whileHeld(new ShootBall());
    }
}

And here is ShootBall:


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package edu.wpi.first.wpilibj.templates.commands;


/**
 *
 * @author Developer
 */
public class ShootBall extends CommandBase {
    
    public ShootBall() {
        requires(shooter);
        // Use requires() here to declare subsystem dependencies
        // eg. requires(chassis);
    }

    // Called just before this Command runs the first time
    protected void initialize() {
    }

    // Called repeatedly when this Command is scheduled to run
    protected void execute() {
        shooter.ShootBall(oi.getButton());
        
    }

    // Make this return true when this Command no longer needs to run execute()
    protected boolean isFinished() {
        return false;
    }

    // Called once after isFinished returns true
    protected void end() {
    }

    // Called when another command which requires one or more of the same
    // subsystems is scheduled to run
    protected void interrupted() {
    }
}

Here is OI in case you need it:


package edu.wpi.first.wpilibj.templates;

import edu.wpi.first.wpilibj.Joystick;
import edu.wpi.first.wpilibj.buttons.Button;
import edu.wpi.first.wpilibj.buttons.JoystickButton;

/**
 * This class is the glue that binds the controls on the physical operator
 * interface to the commands and command groups that allow control of the robot.
 */
public class OI {
    public static final int JOYSTICK_PORT = 1;
    private Joystick stick;
    private Button a;
    
    public OI(){
        stick = new Joystick(JOYSTICK_PORT);
        a = new JoystickButton(stick, 1);
    }
    
    public Joystick getJoystick(){
        return stick;
        
    }
    
    public Button getButton(){
        return a;
    } 
    //// CREATING BUTTONS
    // One type of button is a joystick button which is any button on a joystick.
    // You create one by telling it which joystick it's on and which button
    // number it is.
    // Joystick stick = new Joystick(port);
    // Button button = new JoystickButton(stick, buttonNumber);
    
    // Another type of button you can create is a DigitalIOButton, which is
    // a button or switch hooked up to the cypress module. These are useful if
    // you want to build a customized operator interface.
    // Button button = new DigitalIOButton(1);
    
    // There are a few additional built in buttons you can use. Additionally,
    // by subclassing Button you can create custom triggers and bind those to
    // commands the same as any other Button.
    
    //// TRIGGERING COMMANDS WITH BUTTONS
    // Once you have a button, it's trivial to bind it to a button in one of
    // three ways:
    
    // Start the command when the button is pressed and let it run the command
    // until it is finished as determined by it's isFinished method.
    // button.whenPressed(new ExampleCommand());
    
    // Run the command while the button is being held down and interrupt it once
    // the button is released.
    // button.whileHeld(new ExampleCommand());
    
    // Start the command when the button is released  and let it run the command
    // until it is finished as determined by it's isFinished method.
    // button.whenReleased(new ExampleCommand());
}

Sorry if we posted things wrong. We didn’t know how to attach code

You never set the speed of the motors once you get the value of the button (true/false)
Not sure how its done in the subsystem programming methods, but in iterative, its:

if(joystick.getTrigger())
      leftMotor.set(1);
      rightMotor.set(1);
else
      leftMotor.set(0);
      rightMotor.set(0);

In the Subsystem objects you want to include all the methods which control the hardware of that subsystem.

So for instance in the Shooter subsystem you would want a method that would drive the shooter wheel:

i.e.



//drives the left motor and the right motor with the same value
public void spinMotor(double speed)
{
	
			leftMotor.set(speed);
			RightMotor.set(speed);

}

You don’t need the shootBall method. And can safely delete it.
Also Delete the defaultCommand, because that will cause that command to run, even without pushing a button (it runs by default).

Once you have that method in your Shooter Subsystem, you create a command that requires that subsystem and calls the “drive” method in the execute method.

In this case, since you are using a button, you will not have variable control of the motor, but on off control. So the idea is everytime the button is pressed, drive the shooter wheel with a constant value between -1 and 1.

Your execute method in the ShootBall command should look something like this:

    protected void execute() {
        shooter.spinMotor(1);

/*change value, you should really use the RobotMap class to control
 constants so this call should look more like
 shooter.spinMotor(RobotMap.motorVal), where in RobotMap.java you 
declare a public static int motorVal =1; 
   */     
    }

I also trust in the CommandBase.java definition you instantiate a Shooter object called “shooter”.

Lastly, now that you have your subsystem and command set up, in OI map all you need to do is:



public OI()
{

stick = new Joystick(JOYSTICK_PORT);
        a = new JoystickButton(stick, 1);

a.whileHeld(new shootBall());
}

You should add methods to the OI.java class which return the joystick values of your joystick

i.e one method could be


public double getRightStickVal()
{
return stick.getRaw(3);
}

You should do this for all joysticks, pots, etc.

You could then create another command call shootBallWithJoystick, have it require shooter as well and in the execute method of that command do something like this:


protected void execute() {
        shooter.spinMotor(OI.getRightStickVal());
}

You could make the command ShootBallWithJoystick your default command of your subsystem, so now when the robot starts-up you have default control of the motors with your joystick for maintaining manual control, but when you press the button it will drive the wheel with the constant speed. A very nice way to maintain automated, and manual control at all times.

We used the CommandBase Robot template for our 2012 robot in Java, and find it to be an extremely nice way to control the robot.

Hope that helps,
Kevin

Thanks you were an immense help.