Java DifferentialDrive TankDrive problems

So, given the following code fragment, is there any reason we should not be able to switch between currentMode 0 (tank drive on gamepad) and currentMode 2 (tank drive on two big joysticks (like a big team))? currentMode 0 is the default, so as soon as teleop drive is enabled, the robot is on gamepad/tank. Two button clicks down the line, 2 Joystick tank should work. It doesn’t. If we comment everything except the second .tankDrive call, it drives as expected. Am I missing something?

DifferentialDrive robotDrive;
Joystick leftJoystick, rightJoystick, gamepad;
int currentMode;

public void doTeleop() {
if (currentMode == 0) {
double rightValue, leftValue;
rightValue = gamepad.getRawAxis(5);
leftValue = gamepad.getRawAxis(1);
robotDrive.tankDrive(leftValue, rightValue);
} else if (currentMode == 1) {
robotDrive.arcadeDrive(leftJoystick.getY(), leftJoystick.getX());
} else {
robotDrive.tankDrive(leftJoystick.getY(), rightJoystick.getY());

What’s your code for setting currentMode?

public void setDrive() {
// This code is referenced in the to switch modes.
if (currentMode == 0) {
currentMode = 1;
SmartDashboard.putString(“Drive Mode”, “Arcade”);

} else if (currentMode == 1) {
  currentMode = 2;
  SmartDashboard.putString("Drive Mode", "Tank");
} else {
  currentMode = 0;
  SmartDashboard.putString("Drive Mode", "Tank w/ 2 Joysticks");



SwitcheDriveMode is an command attached (whenPressed) to a hard to get at gamepad button.

I knew someone would ask; I’m a little too embarrassed at our branch & merge work at the moment to advertise the repo. But then, that’s where the demons (Damons too, on our team) probably lie…

Yeah, I know, enum/switch/case is the way to go, but the freshman Girls Who Code are just barely understanding HTML is no way to run a robot.; there’s only so many challenges we can throw at them at once. At least when I drew the state diagram on the whiteboard they lit up with understanding.

Firstly, wrap your code blocks in triple backticks so CD can nicely format it,
System.out.println(“Hello, World!”); //Prints “Hello, World!”
Will look like

System.out.println("Hello, World!"); //Prints "Hello, World!"

As I understand your problem, your code is acting as though currentMode is never changed from 0.

How does SwitcheDriveMode reference your code to change the currentMode?
Try putting a System.out.println("Current mode: " + curentMode); call before and after you change the mode to see if it is actually changing, or quickly changing and reverting, currentMode.

If you don’t want to post your repo, could you instead provide the relevant files (OI, [Subsystem], [Command])?

It’s become a running joke on our team that we are executing zombie demons whenever we deploy!

Are you passing currentMode to your command? Java is a pass-by-value language, so reassigning it locally in the command won’t actually change anything in the calling code. You have to either:

a) Use a global variable (easy, but terrible practice)
b) Wrap the variable in an object so you can pass a reference to it (marginally-better practice)
c) Pass a setter as a method reference (by far the best practice)

OK, full open kimono:

subsystem Drive has a private member currentMode, initialized in the ctor to 0. Method setDrive will step through the three possible states in a ring. Method doTeleop is called by the DriveTeleop command, which is the default command for Drive; it is also fired in autonomous. In OI, button 8 on the gamepad fires the InstantCommand SetDriveMode, which executes Drive::setDrive.

Via the SmartDashboard calls in setDrive, we have observed currentMode changing. But when currentMode == 2 (and the code is not commented out), the robot is non-responsive to the joysticks or gamepad. We have observed currentMode == 0 properly driving in tank mode on the gamepad. We have also observed currentMode == 1 driving the robot in arcade mode.

I’m sure this is something really dumb :slight_smile:

Yes, it is something dumb. Drive::setDrive is buggered.
Thanks for making me step through the code. Thursday I’ll have a clue about whether we fixed it.


I’m gonna steal your running joke, except it will be we are unleashing Damon’s demon daemons

1 Like

Assuming your repo (Lucky_ branch you linked) is up to date with your fixes, I wasn’t able to find anything wrong with your mode code, and was able to simulate it and see the state updating as you would expect.

Thanks for checking! Yes, sending out the Lucky_ branch was deliberate. When we need something to work , we get Lucky (& Katie, the Girls Who Code) to go after it.

At the very least, our debugging statements to SM are out of whack, which skews our perception.

Got a link to how to simulate? I’ve been dying for it, but too busy to find the details. Thursday morning at AZ West Build & Electrical are ripping up the robot, so there is time to do some research.

I don’t have a link as as far as I am aware, it’s a feature still in development and isn’t fully supported as of yet.

In saying that, I have managed to get it to work, here’s how:

To setup/enable simulation (first time):

  1. Find the dependencies section in the build.gradle file
  2. Drop this into it:
simulation "edu.wpi.first.halsim:halsim_ds_socket:${wpi.wpilibVersion}:${wpi.platforms.desktop}@zip"
  1. Either (these do the same thing)
    a. Change includeFesktopSupport to true in the same file or
    b. Run Change Desktop Support Enabled Setting from the WPILib console and click Yes
  2. Delete the debug folder from the build directory

To run the simulation

  1. Either (these do the same thing as far as I can tell)
    a. Press F5 (not Shift+F5 as you would to deploy to a robot)
    b. Run Simulate Robot Code on Desktop from the WPILib console
  2. When asked, select halsim_ds_socket.dll and click OK

Any running Driver Station should then connect (regardless of team number)
You may need to change the server for the Smart Dashboard/Shuffleboard to localhost

I remember somewhere about a warning that said not to have desktop support enabled when actually deploying to a robot, I haven’t tried it yet, also don’t remember if that was actually a thing or not.
To disable it either:
Run Change Desktop Support Enabled Setting from the WPILib console and click No
Change includeFesktopSupport to false.

A couple notes:

  • I’ve not as of yet managed to simulate code with Rev Spark MAX objects in it, (I had to comment them all out of your code first).
  • System.out.println(); won’t go to the Driver Station, but will show in the Terminal (ie when it switches to the Debug Console, switch back to Terminal).

There’s also a bunch of cool stuff like looking at what variables are currently set to at runtime and stuff I can go into if you want (Although I think these will work when connected to a robot, I’m yet to test that).


Way cool! I’d heard this stuff was lurking about, but hadn’t dug deep enough to try it. The GWC and I now have stuff to do Thursday. And then we probably start tossing stuff over to Jaci (no-nonsense) (maybe the youngest WFF ever ?) for “what happened?”

I’m not surprised there is trouble with the REV Spark MAX beasties, those guys have been running a bit behind the curve this year.

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.