I’m new to Java programming and happen to be the only programmer on the team (with the internet to teach me everything I need to know). I’ve started to get the hang of things but every time I run a command on the bot it stops driving. I just recently added end(); to the interrupt code and do not know if that will fix it (I am not near the bot at the moment). The robot drive (mecanum) is in the main Robot.java under teleOp so I do not know if maybe I have to put it inside of a command with the requires(chassis);. Any help would be appreciated, I will upload my code upon request. I don’t know if this is important but I did start with RobotBuilder as a template.
If you can link some of your code that will help us debug it.
Tip: make sure to use code tags when posting code in forums.
Here’s the command (LiftBox):
package org.usfirst.frc4328.Judy.commands;
import edu.wpi.first.wpilibj.command.Command;
import org.usfirst.frc4328.Judy.Robot;
import org.usfirst.frc4328.Judy.RobotMap;
//import edu.wpi.first.wpilibj.command.Scheduler;
/**
*
*/
public class LiftBox extends Command {
public LiftBox() {
// Use requires() here to declare subsystem dependencies
// eg. requires(chassis);
requires(Robot.judyelevator);
}
// Called just before this Command runs the first time
protected void initialize() {
}
// Called repeatedly when this Command is scheduled to run
protected void execute() {
RobotMap.judyelevatorSpeedControllerElevtaor.set(1.0);
//RobotMap.judydrivetrainjudyrobotdrive.mecanumDrive_Cartesian(Robot.oi.joystick1.getX(), Robot.oi.joystick1.getY(), Robot.oi.joystick1.getTwist(), RobotMap.judygyroscopeGyro1.getAngle());
}
// 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() {
end();
}
}
And here is the Robot.java:
// RobotBuilder Version: 1.5
//
// This file was generated by RobotBuilder. It contains sections of
// code that are automatically generated and assigned by robotbuilder.
// These sections will be updated in the future when you export to
// Java from RobotBuilder. Do not put any code or make any change in
// the blocks indicating autogenerated code or it will be lost on an
// update. Deleting the comments indicating the section will prevent
// it from being updated in the future.
package org.usfirst.frc4328.Judy;
import edu.wpi.first.wpilibj.IterativeRobot;
//import edu.wpi.first.wpilibj.SpeedController;
import edu.wpi.first.wpilibj.command.Command;
import edu.wpi.first.wpilibj.command.Scheduler;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
import org.usfirst.frc4328.Judy.commands.*;
import org.usfirst.frc4328.Judy.subsystems.*;
/**
* The VM is configured to automatically run this class, and to call the
* functions corresponding to each mode, as described in the IterativeRobot
* documentation. If you change the name of this class or the package after
* creating this project, you must also update the manifest file in the resource
* directory.
*/
public class Robot extends IterativeRobot {
Command autonomousCommand;
public static OI oi;
// BEGIN AUTOGENERATED CODE, SOURCE=ROBOTBUILDER ID=DECLARATIONS
public static judydrivetrain judydrivetrain;
public static judyelevator judyelevator;
public static judygyroscope judygyroscope;
// END AUTOGENERATED CODE, SOURCE=ROBOTBUILDER ID=DECLARATIONS
/**
* This function is run when the robot is first started up and should be
* used for any initialization code.
*/
public void robotInit() {
RobotMap.init();
// BEGIN AUTOGENERATED CODE, SOURCE=ROBOTBUILDER ID=CONSTRUCTORS
judydrivetrain = new judydrivetrain();
judyelevator = new judyelevator();
judygyroscope = new judygyroscope();
// END AUTOGENERATED CODE, SOURCE=ROBOTBUILDER ID=CONSTRUCTORS
// OI must be constructed after subsystems. If the OI creates Commands
//(which it very likely will), subsystems are not guaranteed to be
// constructed yet. Thus, their requires() statements may grab null
// pointers. Bad news. Don't move it.
oi = new OI();
// instantiate the command used for the autonomous period
// BEGIN AUTOGENERATED CODE, SOURCE=ROBOTBUILDER ID=AUTONOMOUS
autonomousCommand = new AutonomousCommand();
// END AUTOGENERATED CODE, SOURCE=ROBOTBUILDER ID=AUTONOMOUS
}
/**
* This function is called when the disabled button is hit.
* You can use it to reset subsystems before shutting down.
*/
public void disabledInit(){
}
public void disabledPeriodic() {
Scheduler.getInstance().run();
}
public void autonomousInit() {
// schedule the autonomous command (example)
if (autonomousCommand != null) autonomousCommand.start();
}
/**
* This function is called periodically during autonomous
*/
public void autonomousPeriodic() {
Scheduler.getInstance().run();
}
public void teleopInit() {
// This makes sure that the autonomous stops running when
// teleop starts running. If you want the autonomous to
// continue until interrupted by another command, remove
// this line or comment it out.
if (autonomousCommand != null) autonomousCommand.cancel();
}
/**
* This function is called periodically during operator control
*/
public void teleopPeriodic() {
Scheduler.getInstance().run();
RobotMap.judydrivetrainjudyrobotdrive.mecanumDrive_Cartesian(oi.joystick1.getX(), oi.joystick1.getY(), oi.joystick1.getTwist(), RobotMap.judygyroscopeGyro1.getAngle());
RobotMap.judyelevatorSpeedControllerElevtaor.set(oi.joystick2.getY());
}
/**
* This function is called periodically during test mode
*/
public void testPeriodic() {
LiveWindow.run();
}
}
And yes, our robot is named Judy (she has a large tail so you know… big booty Judy seemed to fit.) Also, I apologize for not putting it on GitHub, our school blocks it and I really don’t feel like pulling another VPN from Japan or something.
Can you also post your judyelevator Subsystem?
Right now you are going to have a conflict when you try to run the command because both the command and your teleopPeriodic() method are trying to use the same motor.
RobotMap.judyelevatorSpeedControllerElevtaor.set(1.0);
RobotMap.judyelevatorSpeedControllerElevtaor.set(oi.joystick2.getY());
// RobotBuilder Version: 1.5
//
// This file was generated by RobotBuilder. It contains sections of
// code that are automatically generated and assigned by robotbuilder.
// These sections will be updated in the future when you export to
// Java from RobotBuilder. Do not put any code or make any change in
// the blocks indicating autogenerated code or it will be lost on an
// update. Deleting the comments indicating the section will prevent
// it from being updated in the future.
package org.usfirst.frc4328.Judy.subsystems;
import org.usfirst.frc4328.Judy.RobotMap;
//import org.usfirst.frc4328.Judy.commands.*;
import edu.wpi.first.wpilibj.*;
import edu.wpi.first.wpilibj.command.Subsystem;
/**
*
*/
public class judyelevator extends Subsystem {
// BEGIN AUTOGENERATED CODE, SOURCE=ROBOTBUILDER ID=DECLARATIONS
SpeedController speedControllerElevtaor = RobotMap.judyelevatorSpeedControllerElevtaor;
// END AUTOGENERATED CODE, SOURCE=ROBOTBUILDER ID=DECLARATIONS
// Put methods for controlling this subsystem
// here. Call these from Commands.
public void initDefaultCommand() {
// BEGIN AUTOGENERATED CODE, SOURCE=ROBOTBUILDER ID=DEFAULT_COMMAND
// END AUTOGENERATED CODE, SOURCE=ROBOTBUILDER ID=DEFAULT_COMMAND
// Set the default command for a subsystem here.
//setDefaultCommand(new MySpecialCommand());
}
}
Also something weird, anytime I try to set RobotMap.judyelevatorSpeedControllerElevtaor to a SpeedController (to shorten the name) it compiles but when ran on the RIO it immediately crashes. Same with RobotMap.judydrivetrainjudyrobotdrive. And I am aware elevator is mispelled. I am not terribly worried about it because this is off season and only test code.
For example:
SpeedController RobotMap.judyelevatorSpeedControllerElevtaor = elevator;
Even when i use new on a separate line or combine them, whatever. Can compile, will show code, but when i hit enable it crashes.
Can you post your OI class? I’m assuming that is where you are firing your command from correct?
Will have to post tomorrow. Laptop is inaccessible at the moment. And as for the speed controller shortening, that was in robot.java (although I believe Iwill be taking that and putting it somewhere else as a solution). I tried referencing the OI and in some places it worked and others it gave an error. Although today I found out that custom commands (non robotbuilder) can reference the OI with Robot.OI. instead of oi. Will be trying these tomorrow.
Here’s the OI
// RobotBuilder Version: 1.5
//
// This file was generated by RobotBuilder. It contains sections of
// code that are automatically generated and assigned by robotbuilder.
// These sections will be updated in the future when you export to
// Java from RobotBuilder. Do not put any code or make any change in
// the blocks indicating autogenerated code or it will be lost on an
// update. Deleting the comments indicating the section will prevent
// it from being updated in the future.
package org.usfirst.frc4328.Judy;
import org.usfirst.frc4328.Judy.commands.*;
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
import edu.wpi.first.wpilibj.*;
import edu.wpi.first.wpilibj.buttons.*;
/**
* 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 {
//// 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);
// 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());
//Initialize inputs
public JoystickButton trigger;
public JoystickButton joystickButton2;
public JoystickButton joystickButton11;
public JoystickButton joystickButton12;
public Joystick joystick1;
public Joystick joystick2;
public OI() {
//Make joystick objects
joystick1 = new Joystick(0);
joystick2 = new Joystick(1);
//Make button and trigger objects
joystickButton2 = new JoystickButton(joystick1, 7);
joystickButton12 = new JoystickButton(joystick1, 12);
joystickButton11 = new JoystickButton(joystick1, 11);
trigger = new JoystickButton(joystick1, 1);
//Assign command to the buttons
trigger.whileHeld(new Strafe());
joystickButton2.whileHeld(new recalibrategyro());
joystickButton11.whileHeld(new LiftBox());
joystickButton12.whileHeld(new LowerBox());
// SmartDashboard Buttons
SmartDashboard.putData("Autonomous Command", new AutonomousCommand());
SmartDashboard.putData("Recalibrate Gyroscope", new recalibrategyro());
}
public Joystick getJoystick1() {
return joystick1;
}
public Joystick getJoystick2() {
return joystick2;
}
}
Ok so I separated the elevator code into its own command instead of having it in robot.java. The catch is I now have to call that command with a trigger or button to use the elevator. This solves my problem but I would like to use it without pulling my trigger. To do this would I just take the code and put it in the elevator subsystems default command? Same with drive train I assume, if I’m going to be using commands with it as well.
Correct, you’ll use whatever command you want as the defaults for both subsystems and set them as the default commands using setDefaultCommand().
If you are looking for some examples you can look at out past code.
2014
2015
Awesome, thanks for the help. Our robot is now exactly how we want it.