Announcement

Collapse
No announcement yet.

Calling Methods of Classes within Classes?

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

  • Calling Methods of Classes within Classes?

    I'm attempting to make a robotArm object with various servos as members. I've wrapped the Servo class so I can keep track of things like it's park position, etc. Apparently I am doing somehting wrong, as I get a null pointer exception when trying to set servo positions via an accessor function. I am hoping someone here can see what I've done wrong and point me in the right direction.

    The exact error is:
    User code threw an uncaught exception: NullPointerException - Attempt to read form field 'org.firstinspires.ftc.teamcode.IssueDemoClass$Ser voJoint
    org.firstinspires.ftc.teamcode.IssueDemoClass$Robo tArm.rotator' on a null object reference
    Here is working code to illustrate the intended functionality without my ServoJoint and RobotArm classes (simplified from actual, but tested and working):

    Code:
    package org.firstinspires.ftc.teamcode;
    
    import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
    import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
    import com.qualcomm.robotcore.hardware.Servo;
    
    @TeleOp(name = "IssueDemoDirect", group = "")
    public class IssueDemoDirect extends LinearOpMode {
      private Servo servArmRotate;
    
      @Override
      public void runOpMode() {
        servArmRotate = hardwareMap.servo.get("servArmRotate");
    
        waitForStart();
            if (opModeIsActive()) {
                while (opModeIsActive()) {
                    if (gamepad1.dpad_left) {
                        servArmRotate.setPosition(0.315);
                        ;
                    }
                }
            }
      }
    }

    And here is the failing code attempting to do the same thing via a wrapper class for the servo. I've cut out as much as I can to simplify analysis. But this is also tested and fails exactly as the longer version.
    Code:
    package org.firstinspires.ftc.teamcode;
    
    import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
    import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
    import com.qualcomm.robotcore.hardware.Servo;
    
    @TeleOp(name = "IssueDemoClass", group = "")
    public class IssueDemoClass extends LinearOpMode {
        public RobotArm robotArm;
    
        public class ServoJoint {
            Servo servo;
            double positionBase;
    
            public ServoJoint(Servo servo) {
                this.servo = servo;
                this.positionBase = 0.315;
            }
    
            public void moveToBase() {
                this.servo.setPosition(positionBase);
            }
        }
    
        public class RobotArm {
            ServoJoint rotator;
    
            public void RobotArm() {
                this.rotator = new ServoJoint(hardwareMap.servo.get("servArmRotate"));
            }
        }
    
        @Override
        public void runOpMode() {
            waitForStart();
            if (opModeIsActive()) {
                while (opModeIsActive()) {
                    if (gamepad1.dpad_left) {
                        robotArm.rotator.moveToBase();
                    }
                }
            }
        }
    }
    Thanks in advance for any help.

  • #2
    You have declared robotArm, but have not initialized it. Either add an initialization to your opMode - probably before waitForStart(), or change the declaration to:
    Code:
    private RobotArm robotArm = new RobotArm();

    Comment


    • #3
      Thanks much. Also for those who might find this seeking answers to similar issues, I had the 'void' keyword in my constructor. Thus, I believe I was voiding my own object.

      The working example is:
      Code:
      package org.firstinspires.ftc.teamcode;
      
      import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
      import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
      import com.qualcomm.robotcore.hardware.Servo;
      
      @TeleOp(name = "IssueDemoClass", group = "")
      public class IssueDemoClass extends LinearOpMode {
          public class RobotArm {
              public ServoJoint rotator;
      
              public RobotArm() {
                  this.rotator = new ServoJoint(hardwareMap.servo.get("servArmRotate"));
              }
          }
      
          public class ServoJoint {
              Servo servo;
              double positionBase = 0;
      
              public ServoJoint(Servo servo) {
                  this.servo = servo;
                  this.positionBase = 0.315;
              }
      
              public void moveToBase() {
                  this.servo.setPosition(positionBase);
              }
          }
      
          @Override
          public void runOpMode() {
              RobotArm robotArm = new RobotArm();
              waitForStart();
              if (opModeIsActive()) {
                  while (opModeIsActive()) {
                      if (gamepad1.dpad_left) {
                          robotArm.rotator.moveToBase();
                      }
                  }
              }
          }
      }

      Comment


      • #4
        When you declare that your constructor returns something (even void) then it is no longer a constructor. See here for a good explanation: https://stackoverflow.com/questions/...id-constructor

        Comment

        Working...
        X