Announcement

Collapse
No announcement yet.

Error Opmode (opmode name) is stuck in stop()

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • #16
    Originally posted by BSV View Post
    They tried removing the "throws InterruptedException" and it made no difference.

    Even if they push the stop button right after they push the init button it crashes with that error.

    It runs fine if they never hit the stop button, otherwise the robot controller crashes.
    It seems like you MUST have some loops in your code that are not protected with a call to isOpModeActive(), or isStopRequested().
    Check everywhere that you have a while loop and make sure it has a way to exit if stop is pressed.

    Can you post some code?

    Phil.

    Comment


    • #17
      I am experiencing a similar problem, where the opmode is stuck in stop() every time the stop button is pressed. My code is below. Does anyone have suggestions for a fix? All loops have either opModeIsActive() or !isStopRequested. This error occurs whether the opmode is stopped when the gyroscope is configuring, the program is waiting for start, or during the turn, move, or driveToWhiteLine methods. The program runs fine if the stop button on the DS has not been pressed.

      Code:
      package org.firstinspires.ftc.teamcode;
      
      import android.content.SharedPreferences;
      import android.graphics.Color;
      import android.preference.PreferenceManager;
      import android.util.Log;
      
      import com.qualcomm.hardware.modernrobotics.ModernRoboticsI2cGyro;
      import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
      import com.qualcomm.robotcore.eventloop.opmode.Autonomous;
      import com.qualcomm.robotcore.hardware.ColorSensor;
      import com.qualcomm.robotcore.hardware.DcMotor;
      import com.qualcomm.robotcore.hardware.DcMotorSimple;
      import com.qualcomm.robotcore.hardware.OpticalDistanceSensor;
      import com.qualcomm.robotcore.hardware.Servo;
      
      import org.firstinspires.ftc.robotcontroller.internal.FtcRobotControllerActivity;
      
      import java.io.InterruptedIOException;
      
      @Autonomous(name = "Autonomous", group = "Main Code")
      public class AutonomousCode extends LinearOpMode {
      
          //Hardware Declaration
      private DcMotor motorLeft1;
          private DcMotor motorLeft2;
          private DcMotor motorRight1;
          private DcMotor motorRight2;
      
          private Servo buttonPresserLeft;
          private Servo buttonPresserRight;
      
          private ModernRoboticsI2cGyro gyro;
          private ColorSensor colorSensor;
          private OpticalDistanceSensor ods;
      
          //Variables
      private final double ENCODER_RATIO = 89.4575644937; //ticks / in
      private final double BUTTON_PRESSER_LEFT_UP = 0;
          private final double BUTTON_PRESSER_RIGHT_UP = 1;
      
          private final double BUTTON_PRESSER_LEFT_DOWN = 1;
          private final double BUTTON_PRESSER_RIGHT_DOWN = 0;
      
          private String turnDirection;
          private double moveSpeed = .4;
          private double turnSpeed = .3;
      
          private float[] hsv = {0F, 0F, 0F};
      
          SharedPreferences sharedPreferences;
      
          public void runOpMode() {
      
              sharedPreferences = PreferenceManager.getDefaultSharedPreferences(hardwareMap.appContext);
      
              //Hardware Instantiation
      motorLeft1 = hardwareMap.dcMotor.get("left1");
              motorLeft2 = hardwareMap.dcMotor.get("left2");
              motorRight1 = hardwareMap.dcMotor.get("right1");
              motorRight2 = hardwareMap.dcMotor.get("right2");
      
              buttonPresserLeft = hardwareMap.servo.get("button_left");
              buttonPresserRight = hardwareMap.servo.get("button_right");
      
              gyro = (ModernRoboticsI2cGyro) hardwareMap.gyroSensor.get("gyro");
      
              colorSensor = hardwareMap.colorSensor.get("color_front");
              ods = hardwareMap.opticalDistanceSensor.get("ods");
      
              //Position Servoes
      buttonPresserLeft.setPosition(BUTTON_PRESSER_LEFT_UP);
              buttonPresserRight.setPosition(BUTTON_PRESSER_RIGHT_UP);
      
              //Motor Direction
      motorLeft1.setDirection(DcMotorSimple.Direction.FORWARD);
              motorLeft2.setDirection(DcMotorSimple.Direction.FORWARD);
              motorRight1.setDirection(DcMotorSimple.Direction.REVERSE);
              motorRight2.setDirection(DcMotorSimple.Direction.REVERSE);
      
              //Motor RunMode
      motorLeft1.setMode(DcMotor.RunMode.STOP_AND_RESET_ENCODER);
              motorLeft2.setMode(DcMotor.RunMode.STOP_AND_RESET_ENCODER);
              motorRight1.setMode(DcMotor.RunMode.STOP_AND_RESET_ENCODER);
              motorRight2.setMode(DcMotor.RunMode.STOP_AND_RESET_ENCODER);
      
              motorLeft1.setMode(DcMotor.RunMode.RUN_TO_POSITION);
              motorLeft2.setMode(DcMotor.RunMode.RUN_TO_POSITION);
              motorRight1.setMode(DcMotor.RunMode.RUN_TO_POSITION);
              motorRight2.setMode(DcMotor.RunMode.RUN_TO_POSITION);
      
              telemetry.addData("Encoders are reset", "");
              telemetry.update();
      
              //Gyro Calibration
      gyro.calibrate();
      
              //Wait while gyro is calibrating
      while (gyro.isCalibrating() && !isStopRequested()) {
                  telemetry.addData("Gyroscope is currently calibrating.", "");
                  telemetry.update();
                  idle();
                  sleep(50);
              }
      
              telemetry.addData("Gyroscope is calibrated.", "");
              telemetry.update();
      
              //Disable Color Sensor LED
      colorSensor.enableLed(false);
      
              String allianceColor = sharedPreferences.getString("com.qualcomm.ftcrobotcontroller.Autonomous.Color", "null");
              String location = sharedPreferences.getString("com.qualcomm.ftcrobotcontroller.Autonomous.Location", "null");
              int delay = sharedPreferences.getInt("com.qualcomm.ftcrobotcontroller.Autonomous.Delay", 0);
      
              telemetry.addData("Ready to Start Program", "");
              telemetry.update();
      
              waitForStart();
      
              sleep(delay);
      
              //Beginning of Actual Code
      
      if(allianceColor.equals("Blue")) {
                  turnDirection = "right";
              } else turnDirection = "left";
      
              //Robot begins third tile away from corner vortex wall, wheels touching next full tile next to vortex
      if(location.equals("Close")) {
                  move(24, moveSpeed);
                  turn(55, turnDirection, turnSpeed);
                  move(27, .3);
                  driveToWhiteLine(.3);
                  move(6, moveSpeed);
                  turn(35, turnDirection, turnSpeed);
                  move(10, moveSpeed);
      
                  Color.RGBToHSV(colorSensor.red() * 8, colorSensor.green() * 8, colorSensor.blue() * 8, hsv);
                  String beaconColor = getColorName(hsv);
      
                  if(beaconColor.equals(allianceColor)) {
                      buttonPresserRight.setPosition(BUTTON_PRESSER_RIGHT_DOWN);
                  } else {
                      buttonPresserLeft.setPosition(BUTTON_PRESSER_LEFT_DOWN);
                  }
      
                  move(4, moveSpeed);
                  move(-4, moveSpeed);
                  turn(90, "left", turnSpeed);
                  move(30, moveSpeed);
                  driveToWhiteLine(.3);
                  move(4, moveSpeed);
                  turn(90, "right", turnSpeed);
              }
          }
      
          public void turn(int degrees, String direction, double maxSpeed) {
              if(direction.equals("right")) degrees *= -1; //Negative degree for turning right
      int targetHeading = gyro.getIntegratedZValue() + degrees;
      
              //Change mode because turn() uses motor power and not motor position
      motorLeft1.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
              motorLeft2.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
              motorRight1.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
              motorRight2.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
      
              if(degrees < 0) {
                  while(gyro.getIntegratedZValue() > targetHeading && opModeIsActive()) {
                      motorLeft1.setPower(-maxSpeed);
                      motorLeft2.setPower(-maxSpeed);
                      motorRight1.setPower(maxSpeed);
                      motorRight2.setPower(maxSpeed);
      
                      telemetry.addData("Distance to turn: ", Math.abs(gyro.getIntegratedZValue() - targetHeading));
                      telemetry.addData("Heading", gyro.getIntegratedZValue());
                      telemetry.update();
                      idle();
                  }
              } else { //Left
      while (gyro.getIntegratedZValue() < targetHeading && opModeIsActive()) {
                      motorLeft1.setPower(maxSpeed);
                      motorLeft2.setPower(maxSpeed);
                      motorRight1.setPower(-maxSpeed);
                      motorRight2.setPower(-maxSpeed);
      
                      telemetry.addData("Distance to turn: ", Math.abs(gyro.getIntegratedZValue() - targetHeading));
                      telemetry.addData("Heading", gyro.getIntegratedZValue());
                      telemetry.update();
                      idle();
                  }
              }
      
              motorLeft1.setPower(0);
              motorLeft2.setPower(0);
              motorRight1.setPower(0);
              motorRight2.setPower(0);
              sleep((maxSpeed < .2) ? 300 : 1000); //Wait for less time for lower powers
      
      telemetry.addData("Distance to turn", Math.abs(gyro.getIntegratedZValue() - targetHeading));
              telemetry.addData("Direction", -1 * (int) Math.signum(degrees));
              telemetry.update();
      
              if(Math.abs(gyro.getIntegratedZValue() - targetHeading) > 0) {
                  //Recurse to correct turn
      turn(Math.abs(gyro.getIntegratedZValue() - targetHeading), direction.equals("right") ? "left" : "right", .1);
              }
          }
      
          public void move(double distance, double maxSpeed) {
              distance *= ENCODER_RATIO;
              int initialHeading = gyro.getIntegratedZValue();
      
              //Change mode because move() uses setTargetPosition()
      motorLeft1.setMode(DcMotor.RunMode.RUN_TO_POSITION);
              motorLeft2.setMode(DcMotor.RunMode.RUN_TO_POSITION);
              motorRight1.setMode(DcMotor.RunMode.RUN_TO_POSITION);
              motorRight2.setMode(DcMotor.RunMode.RUN_TO_POSITION);
      
              motorLeft1.setTargetPosition((int) (motorLeft1.getCurrentPosition() + distance));
              motorLeft2.setTargetPosition((int) (motorLeft2.getCurrentPosition() + distance));
              motorRight1.setTargetPosition((int) (motorRight1.getCurrentPosition() + distance));
              motorRight2.setTargetPosition((int) (motorRight2.getCurrentPosition() + distance));
      
              sleep(100);
      
              motorLeft1.setPower(maxSpeed);
              motorLeft2.setPower(maxSpeed);
              motorRight1.setPower(maxSpeed);
              motorRight2.setPower(maxSpeed);
      
              while(motorLeft1.isBusy() && motorLeft2.isBusy() && motorRight1.isBusy() && motorRight2.isBusy() && opModeIsActive()) {
                  //One encoder target must be reached
      telemetry.addData("Gyroscope Heading", gyro.getIntegratedZValue());
                  telemetry.addData("Left 1 Distance", Math.abs(motorLeft1.getCurrentPosition() - motorLeft1.getTargetPosition()));
                  telemetry.addData("Left 2 Distance", Math.abs(motorLeft2.getCurrentPosition() - motorLeft2.getTargetPosition()));
                  telemetry.addData("Right 1 Distance", Math.abs(motorRight1.getCurrentPosition() - motorRight1.getTargetPosition()));
                  telemetry.addData("Right 2 Distance", Math.abs(motorRight2.getCurrentPosition() - motorRight2.getTargetPosition()));
                  telemetry.update();
                  idle();
              }
      
              motorLeft1.setPower(0);
              motorLeft2.setPower(0);
              motorRight1.setPower(0);
              motorRight2.setPower(0);
              sleep(300);
              turn(Math.abs(gyro.getIntegratedZValue() - initialHeading), gyro.getIntegratedZValue() > initialHeading ? "right" : "left", .2); //TODO: Check for accuracy
      }
      
          public void driveToWhiteLine(double power) {
              //Uses encoders for PID, no target for RUN_TO_POSITION
      motorLeft1.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
              motorLeft2.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
              motorRight1.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
              motorRight2.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
      
              while(ods.getRawLightDetected() < .60 && opModeIsActive()) { //.8-.9 is white, ODS averages values it sees
      motorLeft1.setPower(power);
                  motorLeft2.setPower(power);
                  motorRight1.setPower(power);
                  motorRight2.setPower(power);
                  telemetry.addData("ODS Reading", ods.getRawLightDetected());
                  Log.d("ODS DATA", String.valueOf(ods.getRawLightDetected()));
                  telemetry.update();
                  idle();
              }
      
              motorLeft1.setPower(0);
              motorLeft2.setPower(0);
              motorRight1.setPower(0);
              motorRight2.setPower(0);
              sleep(100);
          }
      
          public String getColorName(float[] hsv) {
              if ((hsv[0] < 30 || hsv[0] > 340) && hsv[1] > .2) return "Red";
              else if ((hsv[0] > 170 && hsv[0] < 260) && hsv[1] > .2) return "Blue";
              return "undefined";
          }
      }
      Lead programmer for team 6287, Vertigo

      Comment


      • #18
        Originally posted by Bchay View Post
        I am experiencing a similar problem, where the opmode is stuck in stop() every time the stop button is pressed. My code is below. Does anyone have suggestions for a fix? All loops have either opModeIsActive() or !isStopRequested. This error occurs whether the opmode is stopped when the gyroscope is configuring, the program is waiting for start, or during the turn, move, or driveToWhiteLine methods. The program runs fine if the stop button on the DS has not been pressed.
        Hi Bchay.

        It looks like you did actually have a loop that wasn't checking for a stop condition, but it wasn't a simple while loop.

        In your case, the problem is that you have a reentrancy loop that isn't isn't protected by an opModeIsActive() test.
        Since your turn() method calls turn() (itself) reentantly at the end, you can get stuck in a loop that just toggles back and forward forever.

        I detected this by determining that turn() was the problem (by determining what part of the code caused the error to appear).
        Then, with only one turn() programmed, I could see the direction toggling back and forward after stop was pressed, which didn't seem at all reasonable.

        So I put the following code at the beginning of the turn() method:

        if (!opModeIsActive())
        return;

        This then breaks any reentrancy loop when stop is pressed and everything seems to work now.

        note: I'm not sure why this reentrancy code is looping as it does, so you may want to look into that. It could cause other problems later on.

        Phil.

        Comment


        • #19
          Originally posted by patfanman101 View Post
          Well, during the actual autonomous period in the competition, you can't press stop so you shouldn't have an issue. Because no matter what, it is illegal to stop autonomous mode during the autonomous period.
          You must always be able to stop Autonomous from running. This is a safety issue, if your robot starts to damage the field, another robot, or a person in the pits.
          It's also one of the things that is tested during Field Inspections.

          Comment


          • #20
            The answer is:

            Yes, it looks like they have some loops that are not protected by opModeIsActive().

            We decided not to bother with it until after the qualifier last weekend. It annoyed the robot inspector and FTA that it crashed when stop was pushed, but but since the robot stopped when stop was pushed they let us play with that issue.

            If it turns out to not be fixed after they add that to their loops, then I'll post the example code.

            Thanks!

            Travis
            FTC 4962 / 3638
            FLL 11 / 21 / 9293

            Comment

            Working...
            X