0

Hello StackOverflow users. This is related to the Java instead of the robot itself. What i was trying to do is to seperate the sensors from the movement methods to make the code easily readable, but I've ran into one problem.

Sensor.java

package sensors;

import lejos.hardware.sensor.EV3ColorSensor;
import lejos.hardware.sensor.EV3GyroSensor;
import lejos.hardware.sensor.EV3TouchSensor;
import lejos.hardware.sensor.EV3UltrasonicSensor;

public class Sensors {

    EV3TouchSensor touchSensor;
    EV3ColorSensor colorSensor;
    EV3GyroSensor gyroSensor;
    EV3UltrasonicSensor ultrasonicSensor;

    public Sensors(EV3TouchSensor t, EV3ColorSensor c, EV3GyroSensor g, EV3UltrasonicSensor u) {
        touchSensor = t;
        colorSensor = c;
        gyroSensor = g;
        ultrasonicSensor = u;
    }

    public int getColorSample(){
        int sample = colorSensor.getColorID();
        return sample;
    }

}

Movement.java

public class Movement {

    RegulatedMotor left;
    RegulatedMotor right;
    EV3TouchSensor touchSensor;
    EV3ColorSensor colorSensor;
    EV3GyroSensor gyroSensor;
    EV3UltrasonicSensor ultrasonicSensor;

    public Movement(RegulatedMotor l, RegulatedMotor r, EV3TouchSensor t,  EV3ColorSensor c, EV3GyroSensor g,
            EV3UltrasonicSensor u) {
        left = l;
        right = r;
        touchSensor = t;
        colorSensor = c;
        gyroSensor = g;
        ultrasonicSensor = u;
    }

    //initialize sensors

    Sensors sensors = new Sensors(touchSensor, colorSensor, gyroSensor, ultrasonicSensor);

    public void moveForward() {
        // get the color sample of the ground
        //int sample = colorSensor.getColorID();
        int sample = sensors.getColorSample();

        // while machine is on the ground color
        while (sample != 7) {

            // get new sample
            //sample = colorSensor.getColorID();
            sample = sensors.getColorSample();

            // move forward
            syncForward();
        }
        // if on black, stop motors.
        syncStop();
    }

Don't look at the other methods, because these work fluently, but the error comes at the line 30, where it tries to get the sample from the sensors class. I have no idea, I've given the commented out lines as well, which work fluently. The error comes from accessing the sensors class and i can' think out a solution.

I'll be in your debt!

yAnTar
  • 4,269
  • 9
  • 47
  • 73
Egert Aia
  • 459
  • 2
  • 12
  • 1
    Could you please mark the line #30 in your code snippet? – AlexR Nov 25 '15 at 15:28
  • 2
    And could you post your stacktrace? – stuXnet Nov 25 '15 at 15:29
  • Are there any other assignments to sensor, other than the initialization? – DBug Nov 25 '15 at 15:30
  • line 30 is `sample = sensors.getColorSample();` Which refers to ` public int getColorSample(){ ` `int sample = colorSensor.getColorID();` `return sample; ` Gonna take some time to write down the stacktrace – Egert Aia Nov 25 '15 at 15:33
  • @EgertAia you don't have to write it down, you could just copy it ;) But I think I fixed it, see my answer. – stuXnet Nov 25 '15 at 15:37
  • sensors.Sensors.getColorSample(Sensors.java:24) movement.Movement.moveForward(Movement.java:40) main.Runner.main(Runner.java:42) sun.reflect.NativeMethodAccessorImpl.invoke0(NativeMethodAccessorImpl.java:57) And so on. I made a mistake before. The line 40 is faulty, sorry :) – Egert Aia Nov 25 '15 at 15:37

2 Answers2

2

Ah, took me a while to catch that.

The problem is this line: Sensors sensors = new Sensors(touchSensor, colorSensor, gyroSensor, ultrasonicSensor);

You've written this initialization after the constructor, but nevertheless, sensors will be assigned before you initialize your fields in the constructor. This way, an object of Sensors will be created with only null values, and when calling sensors.getColorSample(), the line int sample = colorSensor.getColorID(); in the Sensors class will throw a NullPointerException.

To fix it, try to change the Movement class like so:

public class Movement {

    RegulatedMotor left;
    RegulatedMotor right;
    EV3TouchSensor touchSensor;
    EV3ColorSensor colorSensor;
    EV3GyroSensor gyroSensor;
    EV3UltrasonicSensor ultrasonicSensor;

    // like in your code, sensors is still a field, but won't be initialized yet
    Sensors sensors;

    public Movement(RegulatedMotor l, RegulatedMotor r, EV3TouchSensor t,  EV3ColorSensor c, EV3GyroSensor g,
            EV3UltrasonicSensor u) {
        left = l;
        right = r;
        touchSensor = t;
        colorSensor = c;
        gyroSensor = g;
        ultrasonicSensor = u;

        // here is the initialization of sensors - at this point, the arguments shouldn't be null anymore (unless they are passed as null to the constructor)
        sensors = new Sensors(touchSensor, colorSensor, gyroSensor, ultrasonicSensor);
    }

    public void moveForward() {
        // this method should be okay, you don't need to change it

        // ...
    }

A few tips for the future:

  • Make your fields private - see Declaring Member Variables in the Java Tutorials
  • If a null value isn't allowed for a field (for example, when it could lead to a NullPointerException), check your arguments for null values and throw an exception if there is some illegal value.
  • Try to learn to debug your code - you could haven seen quickly that the fields in your sensors are all null, then you could debug again and see why that's the case. For further reading about NullPointerExceptions, I recommend What is a Null Pointer Exception, and how do I fix it?.
Community
  • 1
  • 1
stuXnet
  • 4,309
  • 3
  • 22
  • 31
  • Thank you @stuXnet. You really saved my day again. Tell me is it possible to delete the sensors from the constructor of movement class and just leave everything to sensors.java instead? What do you mean by private. In the main or just in the movement and sensors? – Egert Aia Nov 25 '15 at 16:07
  • ad "private": I added a link to Java Tutorials in my answer. And you could refactor your Movements constructor in a way that it only takes the two motor arguments and your (previously initialized) sensor object. – stuXnet Nov 25 '15 at 16:34
0

The Class Movement, the object EV3ColorSensor is defined in the constructor .... which class is using the Movement object?

null reference to the Sensor Constructor.

ΦXocę 웃 Пepeúpa ツ
  • 47,427
  • 17
  • 69
  • 97