Announcement

Collapse
No announcement yet.

Motors not stopping with Encoders

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

  • Motors not stopping with Encoders

    Hi, I am from Team 11053 from South Africa. We are a rooky team and we have no programming experience. This year we want to run Autonomous but we Encountered a problem using the encoders, the motors just keep spinning.
    The RESET_ENCODERS is crossed out in android studios.
    DriveLeft.setMode(DcMotor.RunMode.RESET_ENCODERS);
    DriveRight.setMode(DcMotor.RunMode.RESET_ENCODERS) ;


    Our code:

    package org.firstinspires.ftc.teamcode;

    import com.qualcomm.robotcore.eventloop.opmode.LinearOpMo de;
    import com.qualcomm.robotcore.hardware.DcMotor;
    import com.qualcomm.robotcore.hardware.DcMotorController;

    /**
    * Created by Edrich on 11/1/2016.
    */

    public class Encoders extends LinearOpMode
    {

    //Declare motors

    DcMotor DriveLeft;
    DcMotor DriveRight;


    double DriveSpeed;
    // double Ticks;











    public void runOpMode() throws InterruptedException {


    initSystem();

    waitForStart();


    while (opModeIsActive())
    {

    DriveForwardDistance(0.2, 10);
    Thread.sleep(1000);
    DriveForwardDistance(0.2, -10);



    }
    }







    public void initSystem() throws InterruptedException {

    DriveLeft = hardwareMap.dcMotor.get("DriveLeft");
    DriveRight = hardwareMap.dcMotor.get("DriveRight");


    DriveRight.setDirection(DcMotor.Direction.REVERSE) ;



    DriveSpeed = 0;



    DriveLeft.setPower(DriveSpeed);
    DriveRight.setPower(DriveSpeed);

    DriveLeft.setMode(DcMotor.RunMode.RUN_USING_ENCODE R);
    DriveRight.setMode(DcMotor.RunMode.RUN_USING_ENCOD ER);


    }









    public void DriveForwardDistance(double power, int distance)
    {

    // Reset encoders
    DriveLeft.setMode(DcMotor.RunMode.RESET_ENCODERS);
    DriveRight.setMode(DcMotor.RunMode.RESET_ENCODERS) ;

    // Set targert possition
    DriveLeft.setTargetPosition(distance);
    DriveRight.setTargetPosition(distance);



    // Run to possition
    DriveLeft.setMode(DcMotor.RunMode.RUN_TO_POSITION) ;
    DriveRight.setMode(DcMotor.RunMode.RUN_TO_POSITION );

    // Set drive power
    DriveForward(power);

    while (DriveLeft.isBusy() && DriveRight.isBusy())
    {
    //wait until possition is reached
    }


    //stop and change modes back to normal
    Stop(0);
    DriveLeft.setMode(DcMotor.RunMode.RUN_USING_ENCODE RS);
    DriveRight.setMode(DcMotor.RunMode.RUN_USING_ENCOD ERS);

    }









    private void DriveForward(double power)
    {
    DriveLeft.setPower(power);
    DriveRight.setPower(power);
    }














    public void Stop(double Power)
    {

    DriveLeft.setPower(Power);
    DriveRight.setPower(Power);

    }














    public void TurnLeft(double Power)
    {
    DriveLeft.setPower(-Power);
    DriveRight.setPower(Power);
    }









    public void TurnRight(double Power)
    {
    DriveLeft.setPower(Power);
    DriveRight.setPower(-Power);
    }

    }

  • #2
    I think the mode is now STOP_AND_RESET_ENCODERS

    Comment


    • #3
      Originally posted by FTC8564 View Post
      I think the mode is now STOP_AND_RESET_ENCODERS
      I changed it in the meantime but it still doesn't stop it also crashes the robot controller.

      Comment


      • #4
        I would suspect a hardware issue. Are you getting any errors or warnings?
        Make sure your configuration names are "DriveLeft" & "DriveRight" - these are case sensitive.
        Double check your wiring to the motors. Do you have the encoders in the slot corresponding to the correct power cables?

        Comment


        • #5
          Originally posted by 11053 View Post
          ... The RESET_ENCODERS is crossed out in android studio.
          That means that the method is deprecated.

          Comment


          • #6
            Also put out some telemetry data so you can keep track of what the encoders are actually doing.

            Comment


            • #7
              This is a cleaned up copy of the OP's code to follow Google Java styleguides, https://google.github.io/styleguide/javaguide.html. I also addressed one possible long-running loop in the driveForward method, inlined one field, changed the ordering of setting the encoder targets and the motor mode setting, and refactored stop(double) to be stopRobot().

              Feel free to ask me about anything I did, or why I did it, but I left a comment explaining most of the why's I think.

              Code:
              /**
               * Created by Edrich on 11/1/2016.
               */
              public class Encoders extends LinearOpMode {
                  //Declare motors
                  private DcMotor driveLeft; // lower camel-case field names, made private
                  private DcMotor driveRight;
              
                  // double Ticks;
              
                  public void runOpMode() throws InterruptedException {
                      initSystem();
                      waitForStart();
              
                      while (opModeIsActive()) {
                          driveForwardDistance(0.2, 10); // lower camel case method names
                          Thread.sleep(1000);
                          driveForwardDistance(0.2, -10);
                      }
                  }
              
                  // you don't need to make this method public, declare methods in the minimalistic scope possible
                  private void initSystem() throws InterruptedException {
                      driveLeft = hardwareMap.dcMotor.get("driveLeft");
                      driveRight = hardwareMap.dcMotor.get("driveRight");
                      driveRight.setDirection(DcMotor.Direction.REVERSE);
                      driveLeft.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
                      driveRight.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
              
                      // Use a single blank line to separate logical groups
                      double driveSpeed = 0;
                      // Brake left and right drive motors
                      driveLeft.setPower(driveSpeed);
                      driveRight.setPower(driveSpeed);
              
                      // // The above can be replaced with the following line:
                      // stopRobot();
                  }
              
                  private void driveForwardDistance(double power, int distance) throws InterruptedException {
                      // Reset encoders
                      driveLeft.setMode(DcMotor.RunMode.STOP_AND_RESET_ENCODER);
                      driveRight.setMode(DcMotor.RunMode.STOP_AND_RESET_ENCODER);
              
                      // Change to run to position prior to setting target
                      // Run to position
                      driveLeft.setMode(DcMotor.RunMode.RUN_TO_POSITION);
                      driveRight.setMode(DcMotor.RunMode.RUN_TO_POSITION);
              
                      // Set target position
                      driveLeft.setTargetPosition(distance);
                      driveRight.setTargetPosition(distance);
              
                      // Set drive power
                      driveForward(power);
              
                      while (driveLeft.isBusy() && driveRight.isBusy()) {
                          // wait until position is reached
                          idle(); // prevent unnecessary cpu usage, since we don't need to constantly poll the motors
                          if (!opModeIsActive() || Thread.currentThread().isInterrupted()) {
                              throw new InterruptedException(); // this is the simplest method to not crash your robot controller, due to this loop
                          }
                      }
              
                      //stopRobot and change modes back to normal
                      stopRobot();
                      driveLeft.setMode(DcMotor.RunMode.STOP_AND_RESET_ENCODER);
                      driveRight.setMode(DcMotor.RunMode.STOP_AND_RESET_ENCODER);
              
                  }
              
                  private void driveForward(double power) {
                      driveLeft.setPower(power);
                      driveRight.setPower(power);
                  }
              
                  // stop means stop, you shouldn't need to specify the power to stop
                  // since stop() is in use by FIRST, I renamed this to stop robotRobot()
                  private void stopRobot() {
                      driveLeft.setPower(0);
                      driveRight.setPower(0);
                  }
              
                  private void turnLeft(double power) {
                      driveLeft.setPower(-power);
                      driveRight.setPower(power);
                  }
              
                  private void turnRight(double power) {
                      driveLeft.setPower(power);
                      driveRight.setPower(-power);
                  }
              }

              Comment


              • #8
                Hi dmssarget.

                That was a really nice piece of cleanup. I know your are an excellent programmer, so I'm not questioning anything you did here. However, since the last SDK update, the method of terminating a linearOpMode.runOpMode() has changed somewhat, so I just wanted to point out an alternative (slightly simpler) approach. This mainly relates to the throws InterruptedException portion. My understanding is that this is no longer necessary/desired for a clean exit and dependable cleanup at the end of a run.

                opModeIsActive() is now able to detect the desire to stop the opmode from running, and also includes an idle() call.

                So this would be your code with these removed/simplified. (I also added a few zeros because 10 encoder counts is a tiny distance
                Note the driveForward loop is much simplified, and the coder does not need to know/understand about interruptedException handling.

                I'm, also interested to hear any feedback re this suggestion.

                Code:
                /**
                 * Created by Edrich on 11/1/2016.
                 */
                public class Encoders extends LinearOpMode {
                    //Declare motors
                    private DcMotor driveLeft; // lower camel-case field names, made private
                    private DcMotor driveRight;
                
                    // double Ticks;
                
                    public void runOpMode() {
                        initSystem();
                        waitForStart();
                
                        while (opModeIsActive()) {
                            driveForwardDistance(0.2, 1000); // lower camel case method names
                            Thread.sleep(1000);
                            driveForwardDistance(0.2, -1000);
                        }
                    }
                
                    // you don't need to make this method public, declare methods in the minimalistic scope possible
                    private void initSystem() {
                        driveLeft = hardwareMap.dcMotor.get("driveLeft");
                        driveRight = hardwareMap.dcMotor.get("driveRight");
                        driveRight.setDirection(DcMotor.Direction.REVERSE);
                        driveLeft.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
                        driveRight.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
                
                        // Use a single blank line to separate logical groups
                        double driveSpeed = 0;
                        // Brake left and right drive motors
                        driveLeft.setPower(driveSpeed);
                        driveRight.setPower(driveSpeed);
                
                        // // The above can be replaced with the following line:
                        // stopRobot();
                    }
                
                    private void driveForwardDistance(double power, int distance) {
                        // Reset encoders
                        driveLeft.setMode(DcMotor.RunMode.STOP_AND_RESET_ENCODER);
                        driveRight.setMode(DcMotor.RunMode.STOP_AND_RESET_ENCODER);
                
                        // Change to run to position prior to setting target
                        // Run to position
                        driveLeft.setMode(DcMotor.RunMode.RUN_TO_POSITION);
                        driveRight.setMode(DcMotor.RunMode.RUN_TO_POSITION);
                
                        // Set target position
                        driveLeft.setTargetPosition(distance);
                        driveRight.setTargetPosition(distance);
                
                        // Set drive power
                        driveForward(power);
                
                        while (opModeIsActive()  && driveLeft.isBusy() && driveRight.isBusy()) {
                            // wait until position is reached
                        }
                
                        //stopRobot and change modes back to normal
                        stopRobot();
                        driveLeft.setMode(DcMotor.RunMode.STOP_AND_RESET_ENCODER);
                        driveRight.setMode(DcMotor.RunMode.STOP_AND_RESET_ENCODER);
                
                    }
                
                    private void driveForward(double power) {
                        driveLeft.setPower(power);
                        driveRight.setPower(power);
                    }
                
                    // stop means stop, you shouldn't need to specify the power to stop
                    // since stop() is in use by FIRST, I renamed this to stop robotRobot()
                    private void stopRobot() {
                        driveLeft.setPower(0);
                        driveRight.setPower(0);
                    }
                
                    private void turnLeft(double power) {
                        driveLeft.setPower(-power);
                        driveRight.setPower(power);
                    }
                
                    private void turnRight(double power) {
                        driveLeft.setPower(power);
                        driveRight.setPower(-power);
                    }
                }

                Comment


                • #9
                  Thank you, I will test the code the next time my team and I come together.

                  Comment


                  • #10
                    Originally posted by Philbot View Post
                    Hi dmssarget.

                    That was a really nice piece of cleanup. I know your are an excellent programmer, so I'm not questioning anything you did here. However, since the last SDK update, the method of terminating a linearOpMode.runOpMode() has changed somewhat, so I just wanted to point out an alternative (slightly simpler) approach. This mainly relates to the throws InterruptedException portion. My understanding is that this is no longer necessary/desired for a clean exit and dependable cleanup at the end of a run.

                    opModeIsActive() is now able to detect the desire to stop the opmode from running, and also includes an idle() call.

                    So this would be your code with these removed/simplified. (I also added a few zeros because 10 encoder counts is a tiny distance
                    Note the driveForward loop is much simplified, and the coder does not need to know/understand about interruptedException handling.

                    I'm, also interested to hear any feedback re this suggestion.

                    Code:
                    /**
                     * Created by Edrich on 11/1/2016.
                     */
                    public class Encoders extends LinearOpMode {
                        //Declare motors
                        private DcMotor driveLeft; // lower camel-case field names, made private
                        private DcMotor driveRight;
                    
                        // double Ticks;
                    
                        public void runOpMode() {
                            initSystem();
                            waitForStart();
                    
                            while (opModeIsActive()) {
                                driveForwardDistance(0.2, 1000); // lower camel case method names
                                Thread.sleep(1000);
                                driveForwardDistance(0.2, -1000);
                            }
                        }
                    
                        // you don't need to make this method public, declare methods in the minimalistic scope possible
                        private void initSystem() {
                            driveLeft = hardwareMap.dcMotor.get("driveLeft");
                            driveRight = hardwareMap.dcMotor.get("driveRight");
                            driveRight.setDirection(DcMotor.Direction.REVERSE);
                            driveLeft.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
                            driveRight.setMode(DcMotor.RunMode.RUN_USING_ENCODER);
                    
                            // Use a single blank line to separate logical groups
                            double driveSpeed = 0;
                            // Brake left and right drive motors
                            driveLeft.setPower(driveSpeed);
                            driveRight.setPower(driveSpeed);
                    
                            // // The above can be replaced with the following line:
                            // stopRobot();
                        }
                    
                        private void driveForwardDistance(double power, int distance) {
                            // Reset encoders
                            driveLeft.setMode(DcMotor.RunMode.STOP_AND_RESET_ENCODER);
                            driveRight.setMode(DcMotor.RunMode.STOP_AND_RESET_ENCODER);
                    
                            // Change to run to position prior to setting target
                            // Run to position
                            driveLeft.setMode(DcMotor.RunMode.RUN_TO_POSITION);
                            driveRight.setMode(DcMotor.RunMode.RUN_TO_POSITION);
                    
                            // Set target position
                            driveLeft.setTargetPosition(distance);
                            driveRight.setTargetPosition(distance);
                    
                            // Set drive power
                            driveForward(power);
                    
                            while (opModeIsActive()  && driveLeft.isBusy() && driveRight.isBusy()) {
                                // wait until position is reached
                            }
                    
                            //stopRobot and change modes back to normal
                            stopRobot();
                            driveLeft.setMode(DcMotor.RunMode.STOP_AND_RESET_ENCODER);
                            driveRight.setMode(DcMotor.RunMode.STOP_AND_RESET_ENCODER);
                    
                        }
                    
                        private void driveForward(double power) {
                            driveLeft.setPower(power);
                            driveRight.setPower(power);
                        }
                    
                        // stop means stop, you shouldn't need to specify the power to stop
                        // since stop() is in use by FIRST, I renamed this to stop robotRobot()
                        private void stopRobot() {
                            driveLeft.setPower(0);
                            driveRight.setPower(0);
                        }
                    
                        private void turnLeft(double power) {
                            driveLeft.setPower(-power);
                            driveRight.setPower(power);
                        }
                    
                        private void turnRight(double power) {
                            driveLeft.setPower(power);
                            driveRight.setPower(-power);
                        }
                    }
                    Philbot, I will agree that your code is better suited to the changes made in the current SDK. However, I could point out that idle() as it stands is not a no-op, it does do something to potentia.lly make the system a bit more responsive. However, as per the current Android SDK it only gives a suggestion that the thread should "idle." Without detailed profiling of the application running the OpMode, I can only be paranoid by requesting such as statement in the loop.

                    For those interested in the details of syntax, the loop:
                    Code:
                    while (opModeIsActive()  && driveLeft.isBusy() && driveRight.isBusy()) {
                                // wait until position is reached
                    }
                    is functionally equivalent to:
                    Code:
                    // wait until position is reached
                    while (opModeIsActive()  && driveLeft.isBusy() && driveRight.isBusy());

                    Comment

                    Working...
                    X