SparkMAX soft limit help needed

Hello! We are a new team and try to use SparkMax soft limit feature this year. We see below example from RevRobotics:

We are not sure how it should be ported into our command-based code structure. We see in robotInit() that restoreFactoryDefaults() is called followed by softlimits setup; the latter is then repeated in teleopPeriodic() after m_motor.set()…so:

  1. Why is the soft limit setup code repeated in teleop even though it’s done already in robotInit?
  2. Following the example’s “pattern”, should we port the code as following?

Please advise.

Thank!

RobotContainer:

private void configureButtonBindings() {
  btnArmDown.whenPressed(new ArmDown(m_arm, () -> (!btnArmDown.get())));
  btnArmUp.whenPressed(new ArmUp(m_arm, () -> (!btnArmUp.get())));
}

Subsystem:

public class Arm extends SubsystemBase {
    private final CANSparkMax m_spark = new CANSparkMax(1, MotorType.kBrushless);
    public void raise() {
        m_spark.set(-ARM_MAX_SPEED);
    }

    public void lower() {
        m_spark.set(ARM_MAX_SPEED);
    }

    public void stop() {
        m_spark.set(0);
    }

    public void setSoftLimits(){
        m_spark.enableSoftLimit(SoftLimitDirection.kForward, true);
        m_spark.enableSoftLimit(SoftLimitDirection.kReverse, true);
        m_spark.setSoftLimit(SoftLimitDirection.kForward, ARM_SOFT_LIMIT_FWD);		// 15
        m_spark.setSoftLimit(SoftLimitDirection.kReverse, ARM_SOFT_LIMIT_BKW);		// 0
    }

    public void reset() {
        m_spark.restoreFactoryDefaults();
    }

    @Override
    public void periodic() {
        // This method will be called once per scheduler run
    }
}

Command (one direction shown here only):

public class ArmUp extends WaitUntilCommand {
  private Arm m_arm;
  public ArmUp(Arm subsystem, BooleanSupplier btnState) {
    super(btnState);
    addRequirements(subsystem);
    m_arm = subsystem;
  }

  @Override
  public void initialize() {
    m_arm.reset();
    m_arm.setSoftLimits();
  }

  @Override
  public void execute() {
    m_arm.raise();
    m_arm.setSoftLimits();
  }

  @Override
  public void end(boolean interrupted) {
    m_arm.stop();
    m_arm.reset();
  }
}

It looks like they are setting the soft limit again in periodic, as they are getting values from SmartDashboard to enable/disable the limit and also change the soft limit position. I would think that this is so you could test the code and see how the soft limit works and be able to test a motor with it enabled and disabled. Your implementation looks pretty good, but I’m not sure you would want to reset the SparkMaxes to default settings in the command. I would recommend only resetting them in the class where they are defined, as you might later give it settings that you want it to keep.

1 Like

Thanks, Mike. I’m going to test it out on a test bed with the motor hooked up to roboRio.

You only need to set the soft limits once after restoreFactoryDefaults() you do not need to call it each command initialization.

So you mean we just need to call it once when bringing up the Arm subsystem, after restoreFactoryDefaults(). Will try that. Thanks!

Well we’re having more issues here…see the other thread I just posted:

You don’t need to set the set the softlimits in the execute() method. Just move it over to the initialize() method, or the constructor of the subystem.