Log in

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


Fedoros
28-11-2015, 15:19
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#sta rt()
*/
@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#sto p()
*/
@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.

Saphira
28-11-2015, 17:01
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

DavisDad
28-11-2015, 18:09
...I get the following message:

Error: User code threw an uncaught exception: NullPointerException...

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.

Fedoros
01-12-2015, 20:09
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

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

GeeTwo
01-12-2015, 22:46
I get the following message:

Error: User code threw an uncaught exception: NullPointerException


I've gotten this error whenever the robot phone's config names for motors don't match the code.

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".