LogoLogo
  • Introduction
  • Getting Started with Control Hub
    • Connect to the Robot Controller Console
    • Updating Wi-Fi Settings
    • Connecting Driver Station to Control Hub
    • Wiring Diagram
    • Next Steps
  • Getting Started with Driver Hub
  • Adding More Motors
    • SPARKmini Motor Controller
    • Adding an Expansion Hub
  • Troubleshooting the Control System
    • General Troubleshooting
    • Control Hub Troubleshooting
    • Driver Hub Troubleshooting
      • Driver Hub Battery Troubleshooting
    • Expansion Hub Troubleshooting
    • Status LED Blink Codes
  • System Overview
    • Control Hub Specifications
    • Expansion Hub Specifications
    • Driver Hub Specifications
    • Port Pinouts
    • Protection Features
    • Cables and Connectors
      • XT-30 - Power Cable
      • JST VH - Motor Power
      • JST PH - Sensors and RS485
    • Integrated Sensors
    • Dimensions and Important Component Locations
  • Updating and Managing
    • Managing Wi-Fi on the Control Hub
    • REV Hardware Client
    • Updating Firmware
      • Firmware Changelog
    • Updating Operating System
      • Control Hub Operating System Changelog
    • Updating Robot Controller Application
      • Updating Robot Controller Application via Android Studio
    • Updating the Driver Hub
      • Driver Hub OS - Change Log
    • Accessing Log Files
    • Android Studio - Deploying Code Wirelessly
  • Hello Robot - Intro to Blocks Programming
    • Welcome to Hello Robot!
    • Where to Program - Client vs. Browser
      • What is an OpMode?
    • Setting up a Configuration
      • Common Errors in Configuration
    • Using a Gamepad
    • Part 1: Tackling the Basics
      • Tackling the Basics Directory - Blocks
      • Creating an OpMode - Blocks
      • Programming Essentials
      • Programming Servos
        • Programming Servo Basics
        • Using a Gamepad with a Servo
        • Programming Servo Telemetry
      • Programming Motors
        • Programming Motors Basics
        • Programming a Motor with a Gamepad
        • Programming Motor Telemetry
      • Programming Touch Sensors
      • Programming Color Sensors
        • Color Sensor Telemetry
        • Detecting Color
    • Part 2: Robot Control
      • Robot Control Blocks Directory
      • Programming Drivetrain Motors
      • Arcade Style TeleOp - Blocks
        • Establishing Variables in Blocks
        • Motor Power vs. Robot Movement
        • Programming Arcade Drive
      • Arm Control - Blocks
        • Adding a Limit Switch
      • Robot Control Full Program
    • Part 3: Autonomous and Encoders
      • ElapsedTime - Blocks
        • ElapsedTime Setup
        • ElapsedTime Logic
        • ElapsedTime - Multiple Movements
      • Encoder Basics
      • Drivetrain Encoders - Blocks
        • Converting Encoder Ticks to a Distance
        • Moving to a Target Distance
        • Setting Velocity
        • Turning the Drivetrain Using RUN_TO_POSITION
      • Arm Control with Encoders - Blocks
        • Estimating the Position of the Arm
        • Calculating Target Position
        • Using Limits to Control Range of Motion
    • Part 4: Going Beyond!
      • Exploring Functions
      • Programming Mecanum - Simplified
      • Programming Mecanum - Refined
  • Hello Robot - Intro to OnBot Java Programming
    • Welcome to Hello Robot!
    • Where to Program - Client vs. Browser
      • What is an OpMode?
    • Setting up a Configuration
      • Common Errors in Configuration
    • Using a Gamepad
    • Part 1: Tackling the Basics
      • Tackling the Basics Directory - OnBot
      • Creating an OpMode - OnBot
      • Programming Essentials
      • Programming Servos
        • Programming Servo Basics
        • Using a Gamepad with a Servo
        • Programming Servo Telemetry
      • Programming Motors
        • Programming Motor Basics
        • Programming a Motor with a Gamepad
        • Programming Motor Telemetry
      • Programming Touch Sensors
    • Part 2: Robot Control
      • Robot Control OnBot Java Directory
      • Programming Drivetrain Motors
      • Arcade Style TeleOp - OnBot Java
        • Establishing Variables in OnBot Java
        • Motor Power vs. Robot Movement
        • Programming Arcade Drive
      • Arm Control - OnBot Java
        • Adding a Limit Switch
      • Robot Control Full Program
    • Part 3: Autonomous and Encoders
      • ElapsedTime - OnBot Java
        • ElapsedTime Setup
        • ElapsedTime Logic
        • ElapsedTime - Multiple Movements
      • Encoder Basics
      • Drivetrain Encoders - OnBot Java
        • Converting Encoder Ticks to a Distance
        • Moving to a Target Distance
        • Setting Velocity
        • Turning the Drivetrain Using RUN_TO_POSITION
      • Arm Control with Encoders - OnBot Java
        • Estimating the Position of the Arm
        • Calculating Target Position
        • Using Limits to Control Range of Motion
  • Sensors
    • Introduction to Sensors
    • Digital
    • Analog
    • I2C
      • IMU
        • Orientating the IMU
      • Adding an External IMU to your Hub
    • Encoders
      • REV Motor Encoders
      • Through Bore Encoder
    • Using 3rd Party Sensors
      • Sensor Compatibility Chart
  • Useful Links
    • REV DUO Build System
  • Legacy Documentation
    • Configuring Your Android Devices
    • Expansion Hub with Android Device Robot Controller
      • Driver Station and Robot Controller Pairing
      • Wiring Diagram
      • Configuration
    • REV Hub Interface Software
Powered by GitBook
On this page
  • Creating minPosition and maxPosition
  • Adjusting our If/Else Statement
  • Overriding Limits
  • Adding a Gamepad Override
  • Adding a Touch Sensor Limit

Was this helpful?

Export as PDF
  1. Hello Robot - Intro to OnBot Java Programming
  2. Part 3: Autonomous and Encoders
  3. Arm Control with Encoders - OnBot Java

Using Limits to Control Range of Motion

PreviousCalculating Target PositionNextIntroduction to Sensors

Last updated 5 months ago

Was this helpful?

In the idea of creating a limit switch was introduced using a physical sensor, like a touch sensor. We can make use of our motor's built-in encoder to do something similar. While a physical sensor would be described as a hard limit, using the built-in encoder is called a soft limit.

To set the soft limits we will build off the program created in the last sections (HelloRobot_ArmEncoder)!

@TeleOp

public class HelloRobot_ArmEncoder extends LinearOpMode {
    private DcMotor  arm;

    static final double     COUNTS_PER_MOTOR_REV    = 288; 
    static final double     GEAR_REDUCTION    = 2.7778;   
    static final double     COUNTS_PER_GEAR_REV    = COUNTS_PER_MOTOR_REV * GEAR_REDUCTION;
    static final double     COUNTS_PER_DEGREE    = COUNTS_PER_GEAR_REV/360;
    
    @Override
    public void runOpMode() {
        arm = hardwareMap.get(DcMotor.class, "arm");
        
        
        waitForStart();
    
        while (opModeIsActive()) {
            telemetry.addData("Status", "Running");
            telemetry.update();

        }
    }
}

Creating minPosition and maxPosition

To start, we need to create our upper and lower limits. Create two new variables one called minPosition and one called maxPosition to be added to initialization.

Add both of these to the in the initialization section of the OpMode above the waitForStart(); command.

public void runOpMode() {
        arm = hardwareMap.get(DcMotor.class, "arm");
        
        int minPostion;
        int maxPosition;
        waitForStart();
    

For now we want the minPosition set as our starting position and the maxPosition set to our 90 degree position. Set minPosition equal to 0 and set maxPosition equal to COUNTS_PER_DEGREE times 45.

Remember you need to make a data type conversion!

int minPostion = 0;
int maxPosition = (int)(COUNTS_PER_DEGREE *45);

Adjusting our If/Else Statement

while(opModeIsActive()){
     if(gamepad1.dpad_up){
            arm.setPower(0.5);         
            }
     else if (gamepad1.dpad_down){
            arm.setPower(-0.5); 
            }   
     else { 
            arm.setPower(0); 
            }   
     } 

To set the limit we need to edit our if/else statement to include our limits:

  • If up on the Dpad is pressed and the position of the arm is less than the maxPosition, then the arm will move to the maxPosition.

  • If down on the Dpad is pressed and the position of the arm is greater than the minPosition then the arm will move towards the minPosition.

while (opModeIsActive()) {
    if (gamepad1.dpad_up && arm.getCurrentPosition() < maxPosition) {
            arm.setPower(0.5);
            } 
    else if (gamepad1.dpad_down && arm.getCurrentPosition() > minPosition) {
            arm.setPower(-0.5);
            } 
    else {
            arm.setPower(0);
            }
    }

The current code configuration will stop the motor at any point that the conditions to power the motor are not met. Depending to factors like the weight of the mechanism and any load that it is bearing, when the motor stops the arm may drop below the maxPosition. Take time to test out the code and confirm that it behaves in the way you expect it to.

Overriding Limits

One of the benefits of having a soft limit is being able to exceed that limit.

Remember that the encoders zero tick position is determined by the position of the arm when the Control Hub powers on! So if we aren't careful to reset the arm before powering on our robot this will effect the arm's range of motion. For instance, if we have to reset the Control Hub while the arm is in the 90 degree position, the 90 degree position will become equal to 0 encoder ticks.

As a back up, we can create an override for the range of motion. There are a few different ways an override can be created, but in our case we are going to use the "A" button and touch sensor to help reset our range.

Adding a Gamepad Override

Start by editing the if/else if statement to add another else if condition. Use the line gamepad1.a as the condition. Add a the line arm.setPower(-0.5); as the action item.

while (opModeIsActive()) {
    if (gamepad1.dpad_up && arm.getCurrentPosition() < maxPosition) {
            arm.setPower(0.5);
            } 
    else if (gamepad1.dpad_down && arm.getCurrentPosition() > minPosition) {
            arm.setPower(-0.5);
            } 
    else if(gamepad1.a){
            arm.setPower(-0.5);
    else {
            arm.setPower(0);
            }
    }

Now that we have this change in place, when the "A" button is pressed the arm will move toward the starting position.

Adding a Touch Sensor Limit

When the arm reaches and presses the touch sensor we want to STOP_AND_RESET_ENCODER.

We can create another if statement that focuses on performing this stop and reset when the Touch Sensor is pressed.

if (touch.isPressed()) {
          arm.setMode(DcMotor.RunMode.STOP_AND_RESET_ENCODER);
        }

So, if the Touch Sensor returns true (or is pressed) the motor run mode STOP_AND_RESET_ENCODER will be activated causing the motor encoder to reset to 0 ticks.

Now that this code is done, try testing it!

@TeleOp

public class HelloRobot_ArmEncoder extends LinearOpMode {
    private DcMotor arm;
    private Servo claw;
    private DcMotor leftmotor;
    private DcMotor rightmotor;
    private TouchSensor touch;
    
    static final double     COUNTS_PER_MOTOR_REV    = 288; 
    static final double     GEAR_REDUCTION    = 2.7778;   
    static final double     COUNTS_PER_GEAR_REV    = COUNTS_PER_MOTOR_REV * GEAR_REDUCTION;
    static final double     COUNTS_PER_DEGREE    = COUNTS_PER_GEAR_REV/360;


    @Override
    public void runOpMode() {
        arm = hardwareMap.get(DcMotor.class, "arm");
        claw = hardwareMap.get(Servo.class, "claw");
        leftmotor = hardwareMap.get(DcMotor.class, "leftmotor");
        rightmotor = hardwareMap.get(DcMotor.class, "rightmotor");
        touch = hardwareMap.get(TouchSensor.class, "touch");
        
        int minPostion = 0;
        int maxPosition = (int)(COUNTS_PER_DEGREE *45);
        
        waitForStart();
            
        // run until the end of the match (driver presses STOP)
        while (opModeIsActive()) {
            if (gamepad1.dpad_up && arm.getCurrentPosition() < maxPosition) {
                arm.setPower(0.5);
                    } 
            else if (gamepad1.dpad_down && arm.getCurrentPosition() > minPosition) {
                arm.setPower(-0.5);
                    } 
            else if (gamepad1.a) {
                arm.setPower(-0.5);
                    } 
            else {
                arm.setPower(0);
                }
            if (touch.isPressed()) {
              arm.setMode(DcMotor.RunMode.STOP_AND_RESET_ENCODER);
                    }
        telemetry.addData("Arm Test", arm.getCurrentPosition());
        telemetry.update(); 
        }
    }
}

To start, our If/Else Statement will be changed back to a simplified format like we had at the beginning of .

Part 2: Robot Control
estimating the position of the arm