After significant support from Peter Johnson and adopting code from BenBernard we were able to get our autonomous mode selection working for week 1. There is still one issue that I haven’t solved.
If there is a case where the FMS data is not sent, I still get the robot code crashing. I think it is the same issue as when you try to access the field before the information is available. I can reproduce this by clearing out the FMS field in the driver station. Has anyone solved this? I guess it would be more of a fail safe as hopefully it would never happen, but you never know.
Here is our code:
public void autonomousInit() {
RobotMap.drivetrainleftFrontMotorController.configOpenloopRamp(RobotConstants.TalonSrxAutoOpenRamp, 10); // Disable motor ramp limiting
RobotMap.drivetrainrightFrontMotorController.configOpenloopRamp(RobotConstants.TalonSrxAutoOpenRamp, 10);
RobotMap.drivetrainleftFrontMotorController.configClosedloopRamp(0, 10); // Disable motor ramp limiting in closed loop
RobotMap.drivetrainrightFrontMotorController.configClosedloopRamp(0, 10);
try {
gameData = DriverStation.getInstance().getGameSpecificMessage();
if(gameData == null) { gameData = "";}
}catch (Exception e) {
gameData = "";
}
int retries = 100;
while (gameData.length() < 2 && retries >0) {
try {
Thread.sleep(5);
gameData = DriverStation.getInstance().getGameSpecificMessage();
if (gameData == null) { gameData = "";}
} catch (Exception e) {
}
retries--;
}
SmartDashboard.putString("TestField", gameData);
// autonomousCommand = chooser.getSelected();
String ChooserCommand = chooser.getSelected();
if (ChooserCommand.equals("AutoRedScale")) {
autonomousCommand = new AutoRedScale();
}
else if (ChooserCommand.equals("AutoRedSwitch")) {
autonomousCommand = new AutoRedSwitch();
}
else if (ChooserCommand.equals("AutoBlueScale")) {
autonomousCommand = new AutoBlueScale();
}
else if (ChooserCommand.equals("AutoBlueSwitch")) {
autonomousCommand = new AutoBlueSwitch();
}
else {
autonomousCommand = new AutoCrossLine();
}
// schedule the autonomous command (example)
if (autonomousCommand != null) autonomousCommand.start();
Your code is checking for the null or empty string condition, but it still proceeds in that case. You should have a default condition that runs if game data is not received, and only look at the game data if it’s available.
Where are you getting the crash? One general suggestion would be to change your != “” checks to .Length() > 1 checks. Your code is referencing charAt(1) which will fail if the string has only one character.
The other reason to do this is that != doesn’t do string comparison in Java, it compares whether the object references are the same. If you want string comparison you need to use .equals() (and ! it if you want not-equals).
Thanks again. Eventually you guys will help me get past a novice Java programmer. Especially Peter already told me about string compares.
I think I have it working now. What was causing the crash was the auto commands being constructed in OI due to telling Robot Builder to create buttons on the dashboard. Getting rid of those and changing to use the methods for string compares seems to have helped. Here is the code for reference.
public void autonomousInit() {
RobotMap.drivetrainleftFrontMotorController.configOpenloopRamp(RobotConstants.TalonSrxAutoOpenRamp, 10); // Disable motor ramp limiting
RobotMap.drivetrainrightFrontMotorController.configOpenloopRamp(RobotConstants.TalonSrxAutoOpenRamp, 10);
RobotMap.drivetrainleftFrontMotorController.configClosedloopRamp(0, 10); // Disable motor ramp limiting in closed loop
RobotMap.drivetrainrightFrontMotorController.configClosedloopRamp(0, 10);
try {
gameData = DriverStation.getInstance().getGameSpecificMessage();
if(gameData.equals(null)) { gameData = "";}
}catch (Exception e) {
}
int retries = 100;
while (gameData.length() < 2 && retries >0) {
try {
Thread.sleep(5);
gameData = DriverStation.getInstance().getGameSpecificMessage();
if(gameData.equals(null)) { gameData.equals("");}
} catch (Exception e) {
}
retries--;
}
SmartDashboard.putString("TestField", gameData);
String ChooserCommand = chooser.getSelected();
if (ChooserCommand.equals("AutoRedScale")) {
autonomousCommand = new AutoRedScale();
}
else if (ChooserCommand.equals("AutoRedSwitch")) {
autonomousCommand = new AutoRedSwitch();
}
else if (ChooserCommand.equals("AutoBlueScale")) {
autonomousCommand = new AutoBlueScale();
}
else if (ChooserCommand.equals("AutoBlueSwitch")) {
autonomousCommand = new AutoBlueSwitch();
}
else {
autonomousCommand = new AutoCrossLine();
}
// schedule the autonomous command (example)
if (autonomousCommand != null) autonomousCommand.start();
}
Hi, I don’t know about Command based but I will still post what I have for iterative fro others who might read this thread. Here it is:
@Override
public void autonomousPeriodic() {
//this runs the selected auto.
switch (m_autoSelected) {
//the autonomus chooser. it compares m_autoSelected to each case, then runs the code after the semicolin
//if the strings match. to add a new auto, make a new string, and make a case for it here
// make sure to end each case with break.
case leftAuto:
//this is where the left switch auto code goes.
if (timer.get() < 0.5) {
myrobot.drive(-0.5,0.0); //drive forward half speed for .5 second
}else if (timer.get() < (0.5+0.5)){
myrobot.drive(0.0,-0.5); //turn left half speed for .5 seconds
}else if (timer.get() < (0.5+0.5+2)){
myrobot.drive(-0.5,0.0); //drive forward half speed for 2 seconds
}else if (timer.get() < (0.5+0.5+2+.05)){
myrobot.drive(0.0,0.5); // turn right half speed for .5 seconds
}
case rightAuto
// this is where the right switch auto code goes
if (timer.get() < 0.5) {
myRobot.drive(-0.5,0.0); // drive forwards half speed for .5 second
}else{
myRobot.drive(0.0, 0.0); // stop robot
}
if (timer.get() < 1.0) {
myRobot.drive(0.0, 0.5); // turn right half speed for 1 second
}else{
myRobot.drive(0.0,0.0); // stop robot
}
break;
}
case kDefaultAuto:
default: // Put default auto code here
if (timer.get() < 3.0) {
myRobot.drive(-0.5,0.0); //drive forward half speed for 3 seconds
}else{
myRobot.drive(0.0,0.0); // stop robot
}
break;
}
}
The case kDefaultAuto is for if the robot doesn’t receive the FMS data, in our case it will still pass the auto line. Don’t mind the drive code I’ve got in it (unless somethings wrong) I’ve not completed it, and I will probably use thr gyro I found a few days ago.