Announcement

Collapse
No announcement yet.

Motors not stopping with Encoders

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

  • dmssargent
    replied
    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());

    Leave a comment:


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

    Leave a comment:


  • Philbot
    replied
    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);
        }
    }

    Leave a comment:


  • dmssargent
    replied
    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);
        }
    }

    Leave a comment:


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

    Leave a comment:


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

    Leave a comment:


  • FTC8767
    replied
    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?

    Leave a comment:


  • 11053
    replied
    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.

    Leave a comment:


  • FTC8564
    replied
    I think the mode is now STOP_AND_RESET_ENCODERS

    Leave a comment:


  • 11053
    started a topic Motors not stopping with Encoders

    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);
    }

    }
Working...
X