[FTC]: (Android Studio) User code threw an uncaught exception: NullPointerException

Hello, world! I’m new to android studio and text based programming in general. I’ve used the K9Teleop as a template for our robot’s code, and whenever I attempt to run it using the Driver Station and Robot Controller, I get the following message:

Error: User code threw an uncaught exception: NullPointerException

I’m assuming this is due to an error in my code not caught by android’s debugging system. I looked through it for an hour or so and can’t find any errors. Here is what I’ve written:

package com.qualcomm.ftcrobotcontroller.opmodes;

import com.qualcomm.robotcore.eventloop.opmode.OpMode;
import com.qualcomm.robotcore.hardware.DcMotor;
import com.qualcomm.robotcore.hardware.Servo;
import com.qualcomm.robotcore.util.Range;

/**
 * Created by Parker on 11/19/2015.
 */

public class TeleOp1 extends OpMode {

    /*
     * Note: the configuration of the servos is such that
     * as the scoopGate servo approaches 0, the scoopGate position moves up (away from the floor).
     * Also, as the mexicanHand servo approaches 0, the mexicanHand opens up (drops the game element).
     */
    // TETRIX VALUES.
    final static double scoopGate_MIN_RANGE = 0;
    final static double scoopGate_MAX_RANGE = 1;
    final static double mexicanHand_MIN_RANGE = 0;
    final static double mexicanHand_MAX_RANGE = 1;

    // position of the scoopGate servo.
    double scoopGatePosition;

    // amount to change the scoopGate servo position.
    double scoopGateDelta = 1;

    // position of the mexicanHand servo
    double mexicanHandPosition;

    // amount to change the mexicanHand servo position by
    double mexicanHandDelta = 1;

    DcMotor driveRight;
    DcMotor driveLeft;

    DcMotor scoopArm;
    DcMotor scoopIntake;
    Servo scoopGate;

    DcMotor liftScissor;
    DcMotor liftWinch;

    Servo mexicanHand;

    /**
     * Constructor
     */
    public TeleOp1() {

    }

    /*
     * Code to run when the op mode is first enabled goes here
     *
     * @see com.qualcomm.robotcore.eventloop.opmode.OpMode#start()
     */
    @Override
    public void init() {
		/*
		 * Use the hardwareMap to get the dc motors and servos by name. Note
		 * that the names of the devices must match the names used when you
		 * configured your robot and created the configuration file.
		 */

        driveRight = hardwareMap.dcMotor.get("motor_2");
        driveLeft = hardwareMap.dcMotor.get("motor_1");
        driveLeft.setDirection(DcMotor.Direction.REVERSE);

        scoopArm = hardwareMap.dcMotor.get("motor_3");
        scoopIntake = hardwareMap.dcMotor.get("motor_4");
        scoopGate = hardwareMap.servo.get("servo_1");
        liftWinch = hardwareMap.dcMotor.get("motor_6");


        mexicanHand = hardwareMap.servo.get("servo_2");

        // assign the starting position of the scoopGate and mexicanHand
        scoopGatePosition = 0;
        mexicanHandPosition = 0;
    }

    /*
     * This method will be called repeatedly in a loop
     *
     * @see com.qualcomm.robotcore.eventloop.opmode.OpMode#run()
     */
    @Override
    public void loop() {

		/*
		 * Gamepad 1
		 *
		 * Gamepad 1 controls the motors via the left and right sticks
		 */

        // tank drive
        // note that if y equal -1 then joystick is pushed all of the way forward.
        float left = -gamepad1.left_stick_y;
        float right = -gamepad1.right_stick_y;

        // clip the right/left values so that the values never exceed +/- 1
        right = Range.clip(right, -1, 1);
        left = Range.clip(left, -1, 1);

        // scale the joystick value to make it easier to control
        // the robot more precisely at slower speeds.
        right = (float)scaleInput(right);
        left =  (float)scaleInput(left);

        // write the values to the motors
        driveRight.setPower(right);
        driveLeft.setPower(left);

        /*
		 * Gamepad 2
		 *
		 * Gamepad 2 controls the motors via the left stick, and it controls the
		 * scoopGate/mexicanHand via the dpad_down, dpad_up/a, b buttons
		 */

        // define leftBumper and rightBumper as boolean variables on gamepad2
        boolean leftBumper = gamepad2.left_bumper;
        boolean rightBumper = gamepad2.right_bumper;

        // update the direction of the liftWinch
        if (leftBumper) {
            // if the right_bumper on gamepad 2 is pushed, extend the liftWinch
            liftWinch.setPower(1);
        } else {
                liftWinch.setPower (0);
        }


        if (rightBumper) {
            // if the right_bumper on gamepad 2 is pushed, retract the liftWinch
            liftWinch.setPower(-1);
        } else {
                liftWinch.setPower(0);
        }

        // define leftTrigger and rightTrigger as float variables on gamepad2
        float leftTrigger = -gamepad2.left_trigger;
        float rightTrigger = gamepad2.right_trigger;

        // clip the trigger values so that the values never exceed +/- 1
        leftTrigger = Range.clip(leftTrigger, -1, 1);
        rightTrigger = Range.clip(rightTrigger, -1, 1);

        // scale the trigger values to make it easier to control
        // the scissor lift
        leftTrigger = (float)scaleInput(leftTrigger);
        rightTrigger =  (float)scaleInput(rightTrigger);

        // write the values to the motors
        liftScissor.setPower(leftTrigger);
        liftScissor.setPower(rightTrigger);

        // update the direction of the scoopIntake
        if (gamepad2.a) {
            // if the A button is pushed on gamepad2, spin the scoopIntake inwards
            scoopIntake.setPower(1);
        } else {
                scoopIntake.setPower(0);
        }

        if (gamepad2.b) {
            // if the B button is pushed on gamepad2, spin the scoopIntake outwards
            scoopIntake.setPower(-1);
        } else {
                scoopIntake.setPower(0);
        }

        // update the position of the scoopArm
        if (gamepad2.dpad_left) {
            // if the dpad_left button is pushed on gamepad 2, move the scoopArm in
            scoopArm.setPower(-0.5);
        } else {
                scoopArm.setPower(0);
        }

        if (gamepad2.dpad_right) {
            // if the dpad_right button is pushed on gamepad 2, move the scoopArm out
            scoopArm.setPower(0.5);
        } else {
                scoopArm.setPower(0);
        }

        // update the position of the scoopGate.
        if (gamepad2.dpad_up) {
            // if the dpad_up button is pushed on gamepad2, increment the position of
            // the scoopGate servo.
            scoopGatePosition += scoopGateDelta;
        }

        if (gamepad2.dpad_down) {
            // if the dpad_down button is pushed on gamepad2, decrease the position of
            // the scoopGate servo.
            scoopGatePosition -= scoopGateDelta;
        }

        // update the position of the mexicanHand
        if (gamepad2.y) {
            // if the Y button is pushed on gamepad2, increment the position of
            // the mexicanHandPosition
            mexicanHandPosition += mexicanHandDelta;
        }

        if (gamepad2.x) {
            // if the X button is pushed on gamepad2, decrease the position of
            // the mexicanHandPosition
            mexicanHandPosition -= mexicanHandDelta;
        }

        // clip the position values so that they never exceed their allowed range.
        scoopGatePosition = Range.clip(scoopGatePosition, scoopGate_MIN_RANGE, scoopGate_MAX_RANGE);
        mexicanHandPosition = Range.clip(mexicanHandPosition, mexicanHand_MIN_RANGE, mexicanHand_MAX_RANGE);

        // write position values to the scoopGate and mexicanHand servo
        scoopGate.setPosition(scoopGatePosition);
        mexicanHand.setPosition(mexicanHandPosition);

		/*
		 * Send telemetry data back to driver station. Note that if we are using
		 * a legacy NXT-compatible motor controller, then the getPower() method
		 * will return a null value. The legacy NXT-compatible motor controllers
		 * are currently write only.
		 */

        telemetry.addData("Text", "*** Robot Data***");
        telemetry.addData("scoopGate", "scoopGate:  " + String.format("%.2f", scoopGatePosition));
        telemetry.addData("mexicanHand", "mexicanHand:  " + String.format("%.2f", mexicanHandPosition));
        telemetry.addData("left tgt pwr",  "left  pwr: " + String.format("%.2f", left));
        telemetry.addData("right tgt pwr", "right pwr: " + String.format("%.2f", right));
    }

    /*
     * Code to run when the op mode is first disabled goes here
     *
     * @see com.qualcomm.robotcore.eventloop.opmode.OpMode#stop()
     */
    @Override
    public void stop() {

    }

    /*
     * This method scales the joystick input so for low joystick values, the
     * scaled value is less than linear.  This is to make it easier to drive
     * the robot more precisely at slower speeds.
     */
    double scaleInput(double dVal)  {
        double] scaleArray = { 0.0, 0.05, 0.09, 0.10, 0.12, 0.15, 0.18, 0.24,
                0.30, 0.36, 0.43, 0.50, 0.60, 0.72, 0.85, 1.00, 1.00 };

        // get the corresponding index for the scaleInput array.
        int index = (int) (dVal * 16.0);

        // index should be positive.
        if (index < 0) {
            index = -index;
        }

        // index cannot exceed size of array minus 1.
        if (index > 16) {
            index = 16;
        }

        // get value from the array.
        double dScale = 0.0;
        if (dVal < 0) {
            dScale = -scaleArray[index];
        } else {
            dScale = scaleArray[index];
        }

        // return scaled value.
        return dScale;
    }

}

Any help provided would be greatly appreciated. Thank you in advance for reading.

Hello! You have created 6 DcMotor objects in your code. But you’re only getting references for 5 of them. If you add a line like the code below, it should fix the error.


        liftScissor = hardwareMap.dcMotor.get("*what you named the motor in the configuration on the phone*");

Hope this helps!
Katie
FTC 3595
Schrödinger’s Hat

I’ve gotten this error whenever the robot phone’s config names for motors don’t match the code. The code will compile, but when the OpMode is run, the error displays on both phones.

Thanks for the help. This fixed the problem and allowed me to move forward.

I don’t write a lot of Java, but I do run a lot of it. I could probably rattle of fifty different ways to get a null pointer exception in a single sitting. The only java run time error message less useful is “unhandled exception”.