Plz help with Differential Drive error

package frc.robot;

import edu.wpi.first.cameraserver.CameraServer;
import edu.wpi.first.wpilibj.GenericHID.Hand;
import edu.wpi.first.wpilibj.Spark;
import edu.wpi.first.wpilibj.SpeedControllerGroup;
import edu.wpi.first.wpilibj.TimedRobot;
import edu.wpi.first.wpilibj.XboxController;
import edu.wpi.first.wpilibj.drive.DifferentialDrive;
import edu.wpi.first.wpilibj.Timer;

public class Robot extends TimedRobot {
//Setting up all the PWM Channels
private static final int kRearRightChannel = 0;
private static final int kFrontRightChannel = 1;
private static final int kRearLeftChannel = 2;
private static final int kFrontLeftChannel = 3;
private static final int kBottomJoint = 4;
private static final int kMiddleJoint = 5;
private static final int kTopJoint = 6;
private static final int klauncher = 7;
private static final int kindexer = 8;
private static final int kcolorwheel = 9;

private static final int kJoystickChannel = 0;

private DifferentialDrive m_base;
private XboxController m_xbox;

 //Setting up arm and claw motor contorllers

Spark indexer = new Spark(kindexer);
Spark bottomJoint = new Spark(kBottomJoint);
Spark middleJoint = new Spark(kMiddleJoint);
Spark topJoint = new Spark(kTopJoint);
Spark launcher = new Spark(klauncher);
Spark colorwheel = new Spark(kcolorwheel);

//Setting up driving motor contorllers
Spark frontLeft = new Spark(kFrontLeftChannel);
Spark rearLeft = new Spark(kRearLeftChannel);
Spark frontRight = new Spark(kFrontRightChannel);
Spark rearRight = new Spark(kRearRightChannel);
SpeedControllerGroup m_left = new SpeedControllerGroup(frontLeft, rearLeft);
SpeedControllerGroup m_right = new SpeedControllerGroup(frontRight, rearRight);

//Auton
private double startTime;

@Override
public void robotInit() {
CameraServer.getInstance().startAutomaticCapture(0);
CameraServer.getInstance().startAutomaticCapture(1);

// If the motors are inverted. DO NOT mess with it until it has been tested.
m_left.setInverted(true);
m_right.setInverted(true);

//Setting up the drive train and Xbox controller
m_base = new DifferentialDrive(m_left, m_right);
m_xbox = new XboxController(kJoystickChannel);

}

@Override
public void autonomousInit() {
startTime = Timer.getFPGATimestamp();

m_base = new DifferentialDrive(m_left, m_right);

}

@Override
public void autonomousPeriodic() {
double time = Timer.getFPGATimestamp();
System.out.println(time - startTime);

if (time - startTime > 0 ) {
indexer.set(1.0);
launcher.set(0.8);
}
if (time - startTime > 10 ) {
indexer.set(0);
launcher.set(0);
frontLeft.set(0.5);
rearLeft.set(0.5);
frontRight.set(-0.5);
rearRight.set(-0.5);
}
if (time - startTime > 14) {
frontLeft.set(0);
rearLeft.set(0);
frontRight.set(0);
rearRight.set(0);
}
}

//Remote Controls
@Override
public void teleopPeriodic() {

//DPAD TEST
if(m_xbox.getPOV() == 90){
  colorwheel.set(-1);
  }
if(m_xbox.getPOV() == 180){
  colorwheel.set(1);
  }
if(!(m_xbox.getPOV() == 90)||(m_xbox.getPOV() == 180)){
  colorwheel.set(0.0);


// Left joystick is for the left side
// Right joystick for the right side

m_base.tankDrive(m_xbox.getY(Hand.kLeft)*3/4, m_xbox.getY(Hand.kRight)*3/4);

//Left Stick Pressing rotates the arm counter clockwise
//Right Stick Pressing rotates the arm clockwise
if(m_xbox.getStickButton(Hand.kLeft)){
  launcher.set(-.33);
}
if(m_xbox.getStickButton(Hand.kRight)){
  launcher.set(.33);
}
if(!(m_xbox.getStickButton(Hand.kLeft)||m_xbox.getStickButton(Hand.kRight))){
  launcher.set(0.0);
}

// Left bumper makes the bottom joint bends back
// Left trigger makes the bottom joint bend forward
if(m_xbox.getBumper(Hand.kLeft)){
  bottomJoint.set(-1);
}
if(m_xbox.getTriggerAxis(Hand.kLeft)!=0){
  bottomJoint.set(1);
}
if(!(m_xbox.getBumper(Hand.kLeft)||m_xbox.getTriggerAxis(Hand.kLeft)!=0)){
  bottomJoint.set(0.0);
}

// Right bumper makes the middle joint bends back
// Right trigger makes the middle joint bend forward
if(m_xbox.getBumper(Hand.kRight)){
  middleJoint.set(-1);
}
if(m_xbox.getTriggerAxis(Hand.kRight)!=0){
  middleJoint.set(1);
}
if(!(m_xbox.getBumper(Hand.kRight)||m_xbox.getTriggerAxis(Hand.kRight)!=0)){
  middleJoint.set(0.0);
}

// A button makes the top joint bends back
// B button makes the top joint bend forward
if(m_xbox.getAButton()){
  topJoint.set(-1);
}

// if(m_xbox.getBButton()){
// topJoint.set(1);
// }
if(!(m_xbox.getAButton())){
topJoint.set(0.0);
}

// X button makes the claw close
// Y button makes the claw open
if(m_xbox.getXButton()){
  indexer.set(-1.0);
}
if(m_xbox.getYButton()){
  indexer.set(1.0);
}
if(!(m_xbox.getXButton()||m_xbox.getYButton())){
  indexer.set(0.0);
}

}
}
}

That is our code but when we run auton the differential drive error keeps coming up.

Error: Differential Drive…Output not updated enough.

You initialize your DifferentialDrive repeatedly, which is not what you normally want to do.

A more robust way of doing this is to just put
private DifferentialDrive m_base = new DifferentialDrive(m_left,m_right); after you declare the 2 SpeedControllerGroups. This sets it up, and you never need to re-initialize it again.

In AutoPeriodic, you also never write to the DifferentialDrive. which is likely where many errors are coming from. You actually just write to both motors. Additionally, you only actually set some of the motors some of the time, leaving them to stop only due to the safety stops and motor timeouts.

It’s better to write that in the form

if (time - startTime > 0 ) {
indexer.set(1.0);
launcher.set(0.8);
}
else if (time - startTime > 10 ) {
indexer.set(0);
launcher.set(0);
m_drive.tankDrive(0.5,0.5);
}
else if (time - startTime > 14) {
  m_drive.tankDrive(0,0);
}
else{
  m_drive.tankDrive(0,0)
}
}

By making sure that you always set the motors to something you avoid these errors.

Ooh okay, Thank you!

Would the auton part be like that?

@Override

public void autonomousInit() {

startTime = Timer.getFPGATimestamp();

m_base = new DifferentialDrive(m_left, m_right);

}

@Override

public void autonomousPeriodic() {

double time = Timer.getFPGATimestamp();

System.out.println(time - startTime);



if (time - startTime > 0 ) {

  indexer.set(1.0);

  launcher.set(0.8);

  }

  else if (time - startTime > 10 ) {

  indexer.set(0);

  launcher.set(0);

  m_base.tankDrive(0.5,-0.5);

  }

  else if (time - startTime > 14) {

    m_base.tankDrive(0,0);

  }

  else{

    m_base.tankDrive(0,0);

  }

  }

Please consider enclosing you code within triple backticks so that is is readable and CD doesn’t try to format it.

Eg
```java
System.out.println(“Example”);
```
Shows as

System.out.println("Example");

Better yet, consider using a link to a GitHub repository or gist or Pastebin.

 
package frc.robot;
 
import edu.wpi.first.cameraserver.CameraServer;
import edu.wpi.first.wpilibj.GenericHID.Hand;
import edu.wpi.first.wpilibj.Spark;
import edu.wpi.first.wpilibj.SpeedControllerGroup;
import edu.wpi.first.wpilibj.TimedRobot;
import edu.wpi.first.wpilibj.XboxController;
import edu.wpi.first.wpilibj.drive.DifferentialDrive;
import edu.wpi.first.wpilibj.Timer;
 
public class Robot extends TimedRobot {
  //Setting up all the PWM Channels
  private static final int kRearRightChannel = 0;
  private static final int kFrontRightChannel = 1;
  private static final int kRearLeftChannel = 2;
  private static final int kFrontLeftChannel = 3;
  private static final int kWinch = 4;
  private static final int kArm = 5;
  private static final int kIntake = 6;
  private static final int kLauncher = 7;
  private static final int kIndexer = 8;
  private static final int kColorwheel = 9;
 
  private static final int kJoystickChannel = 0;
  private XboxController m_xbox;
 
     //Setting up arm and claw motor contorllers
  Spark indexer = new Spark(kIndexer);
  Spark winch = new Spark(kWinch);
  Spark arm = new Spark(kArm);
  Spark intake = new Spark(kIntake);
  Spark launcher = new Spark(kLauncher);
  Spark colorwheel = new Spark(kColorwheel);
 
 //Setting up driving motor contorllers
 Spark frontLeft = new Spark(kFrontLeftChannel);
 Spark rearLeft = new Spark(kRearLeftChannel);
 Spark frontRight = new Spark(kFrontRightChannel);
 Spark rearRight = new Spark(kRearRightChannel);
 SpeedControllerGroup m_left = new SpeedControllerGroup(frontLeft, rearLeft);
 SpeedControllerGroup m_right = new SpeedControllerGroup(frontRight, rearRight);
 private DifferentialDrive m_base = new DifferentialDrive(m_left,m_right);

 //Auton
 private double startTime;
  
  @Override
  public void robotInit() {
    CameraServer.getInstance().startAutomaticCapture(0);
    CameraServer.getInstance().startAutomaticCapture(1);
 
 // If the motors are inverted. DO NOT mess with it until it has been tested.
 m_left.setInverted(true);
 m_right.setInverted(true);
 
 //Setting up the drive train and Xbox controller
 m_xbox = new XboxController(kJoystickChannel);
  
  }
    
  @Override
  public void autonomousInit() {
    startTime = Timer.getFPGATimestamp();

m_base = new DifferentialDrive(m_left, m_right);

  }

  @Override
  public void autonomousPeriodic() {
    double time = Timer.getFPGATimestamp();
    System.out.println(time - startTime);
 
    if (time - startTime > 0 ) {
      indexer.set(1.0);
      launcher.set(0.8);
      }
      else if (time - startTime > 10 ) {
      indexer.set(0);
      launcher.set(0);
      m_base.tankDrive(0.5,-0.5);
      }
      else if (time - startTime > 14) {
        m_base.tankDrive(0,0);
      }
      else{
        m_base.tankDrive(0,0);
      }
      }
  
 
  //Remote Controls
  @Override
  public void teleopPeriodic() {
 
 
    //DPAD TEST
    if(m_xbox.getPOV() == 90){
      colorwheel.set(-1);
      }
    if(m_xbox.getPOV() == 180){
      colorwheel.set(1);
      }
    if(!(m_xbox.getPOV() == 90)||(m_xbox.getPOV() == 180)){
      colorwheel.set(0.0);
  
 
    // Left joystick is for the left side
    // Right joystick for the right side
 
    m_base.tankDrive(m_xbox.getY(Hand.kLeft)*3/4, m_xbox.getY(Hand.kRight)*3/4);
 
    //Left Stick Pressing rotates the arm counter clockwise
    //Right Stick Pressing rotates the arm clockwise
    if(m_xbox.getStickButton(Hand.kLeft)){
     launcher.set(-1);
    }
    if(m_xbox.getStickButton(Hand.kRight)){
     launcher.set(1);
    }
    if(!(m_xbox.getStickButton(Hand.kLeft)||m_xbox.getStickButton(Hand.kRight))){
      launcher.set(0.0);
    }
 
    // Left bumper makes the bottom joint bends back
    // Left trigger makes the bottom joint bend forward
    if(m_xbox.getBumper(Hand.kLeft)){
      indexer.set(-1);
    }
    if(m_xbox.getTriggerAxis(Hand.kLeft)!=0){
      indexer.set(1);
    }
    if(!(m_xbox.getBumper(Hand.kLeft)||m_xbox.getTriggerAxis(Hand.kLeft)!=0)){
      indexer.set(0.0);
    }
 
    // Right bumper makes the middle joint bends back
    // Right trigger makes the middle joint bend forward
    if(m_xbox.getBumper(Hand.kRight)){
      intake.set(-1);
    }
    if(m_xbox.getTriggerAxis(Hand.kRight)!=0){
      intake.set(1);
    }
    if(!(m_xbox.getBumper(Hand.kRight)||m_xbox.getTriggerAxis(Hand.kRight)!=0)){
      intake.set(0.0);
    }
 
    // A button makes the top joint bends back
    // B button makes the top joint bend forward
    if(m_xbox.getAButton()){
      winch.set(-1);
    }
    //if(m_xbox.getBButton()){
     // topJoint.set(1);
   //}
    if(!(m_xbox.getAButton())){
      winch.set(0.0);
    }
 
    // X button makes the claw close
    // Y button makes the claw open
    if(m_xbox.getXButton()){
      arm.set(-1.0);
    }
    if(m_xbox.getYButton()){
      arm.set(1.0);
    }
    if(!(m_xbox.getXButton()||m_xbox.getYButton())){
      arm.set(0.0);
    }
   }
  }
 }

Okay Thank you, I never knew that

Glad you learnt something new :slight_smile:

While it’s good that you’re now setting your differential drive object all the time (hence keeping it happy and keeping it from stopping your motors), you’re also creating it twice. I would remove the line m_base = new DifferentialDrive(m_left, m_right); from the autonomousInit method, as it is already instantiated at the beginning of your class: you only ever have to do it once.

Also, the if statements in the autonomousPeriodic method won’t execute how you want them to, as time - startTime will always be > 0. Consider writing the statements backwards so as the time increases, the states will cascade up the if statements.

You can also consider using a variable to track what state the motors should be in, then set them all at the end.

e.g.

@Override
public void autonomousPeriodic() {
    double time = Timer.getFPGATimestamp();
    double runTime = time - startTime;
    System.out.println(runTime);
    
    double indexerPower  = 0.0;
    double launcherPower = 0.0;
    double leftPower  = 0.0;
    double rightPower = 0.0;

    if (runTime > 14) {
        indexerPower  = 0.0;
        launcherPower = 0.0;
        leftPower  = 0.0;
        rightPower = 0.0;
    }
    else if (runTime > 10) {
        indexerPower  = 0.0;
        launcherPower = 0.0;
        leftPower  =  0.5;
        rightPower = -0.5;
    } else {
        indexerPower  = 1.0;
        launcherPower = 0.8;
        leftPower  = 0.0;
        rightPower = 0.0;
    }

    indexer.set(indexerPower);
    launcher.set(launcherPower);
    m_base.tankDrive(leftPower, rightPower);
}

I think that would work for what you want to do.

Okay so we tried this way and the other one above but we still get a differential drive error while running auton. I don’t know what is happening.

What is the error you are getting?

The error we are getting is

ERROR  1  DifferentialDrive… Output not updated often enough.  edu.wpi.first.wpilibj.MotorSafety.check(MotorSafety.java:101)

Did you remove that line? I suspect that could cause issues.

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