Announcement

Collapse
No announcement yet.

Using Telemetry outside opmode classes

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

  • Using Telemetry outside opmode classes

    Following the example of another post here I attempted to add the ability to use telemetry in classes that are not in the opmode. Here is the opmode class.

    Code:
    public class OpModeBase extends LinearOpMode {
    
    
        private final static HardwareTestPlatform robot = new HardwareTestPlatform();
        private final static SensorGyro gyro = new SensorGyro(robot);
        private final static SensorTouch touch = new SensorTouch(robot);
        private final static SensorODS ods = new SensorODS(robot);
        private static final SensorColor color = new SensorColor(robot);
        private final static ElapsedTime runtime = new ElapsedTime();
        private final static Telemetry myTelemetry = new Telemetry() {
            @Override
            public Item addData(String caption, String format, Object... args) {
                return null;
            }
    
            @Override
            public Item addData(String caption, Object value) {
                return null;
            }
    
            @Override
            public <T> Item addData(String caption, Func<T> valueProducer) {
                return null;
            }
    
            @Override
            public <T> Item addData(String caption, String format, Func<T> valueProducer) {
                return null;
            }
    
            @Override
            public boolean removeItem(Item item) {
                return false;
            }
    
            @Override
            public void clear() {
    
            }
    
            @Override
            public void clearAll() {
    
            }
    
            @Override
            public Object addAction(Runnable action) {
                return null;
            }
    
            @Override
            public boolean removeAction(Object token) {
                return false;
            }
    
            @Override
            public boolean update() {
                return false;
            }
    
            @Override
            public Line addLine() {
                return null;
            }
    
            @Override
            public Line addLine(String lineCaption) {
                return null;
            }
    
            @Override
            public boolean removeLine(Line line) {
                return false;
            }
    
            @Override
            public boolean isAutoClear() {
                return false;
            }
    
            @Override
            public void setAutoClear(boolean autoClear) {
    
            }
    
            @Override
            public int getMsTransmissionInterval() {
                return 0;
            }
    
            @Override
            public void setMsTransmissionInterval(int msTransmissionInterval) {
    
            }
    
            @Override
            public String getItemSeparator() {
                return null;
            }
    
            @Override
            public void setItemSeparator(String itemSeparator) {
    
            }
    
            @Override
            public String getCaptionValueSeparator() {
                return null;
            }
    
            @Override
            public void setCaptionValueSeparator(String captionValueSeparator) {
    
            }
    
            @Override
            public Log log() {
                return null;
            }
        };
        private final static DriveRobot drive = new DriveRobot(robot, gyro, myTelemetry);
        private State state = State.DRIVE_STRAIGHT;
    
        public void runOpMode() {
            int clicks = 10000; //Encoder clicks to drive
            double power = .6;  //Motor power 1 = 100%
            double mm = 1000;   //Distance to travel in MM
            int target = 90;    //Gyro target in degrees
            int timeout = 15;   //Timeout in seconds
    
            begin();
    
            waitForStart();     //Wait for play to be pressed
            runtime.reset();    //Reset runtime counter
    
            while (opModeIsActive() && state != State.HALT) {       //Loop until State.HALT
                switch (state) {
                    case DRIVE_STRAIGHT:
                        //drive.encoderDrive(power, mm, mm, timeout);
                        //drive.encoderDrive(power, mm, mm, timeout);
                        drive.gyroDriveStraight(mm, power);
                        state = State.HALT;
                        break;
                    case TURN:
                        drive.gyroDrivePivot(target, power);
                        state = State.HALT;
                        break;
                    case GYRO:
                        telemetry.addData("Integrated Z = ", String.valueOf(gyro.getIntegratedZ()));
                        telemetry.addData("Heading", String.valueOf(gyro.getHeading()));
                        telemetry.addData("isCalibrating", String.valueOf(gyro.isCalibrating()));
                        telemetry.addData("X", String.valueOf(gyro.getX()));
                        telemetry.addData("Y", String.valueOf(gyro.getY()));
                        telemetry.addData("Z", String.valueOf(gyro.getZ()));
                        telemetry.addData("Status", String.valueOf(gyro.status()));
                        telemetry.update();
                        break;
                    case TOUCH:
                        telemetry.addData("Force", String.valueOf(touch.force()));
                        telemetry.addData("Is Pressed", String.valueOf(touch.pressed()));
                        telemetry.update();
                        break;
                    case ODS:
                        telemetry.addData("Light Detected", String.valueOf(ods.getLight()));
                        telemetry.addData("Raw Light Detected", String.valueOf(ods.getRawLight()));
                        telemetry.addData("Max Light Detected", String.valueOf(ods.getMaxLight()));
                        telemetry.addData("Status", String.valueOf(ods.status()));
                        telemetry.update();
                        break;
                    case COLOR:
                        //telemetry.addData("Alpha", String.valueOf(color.alpha()));
                        //telemetry.addData("ARGB", String.valueOf(color.argb()));
                        //telemetry.addData("Blue", String.valueOf(color.blue()));
                        //telemetry.addData("Red", String.valueOf(color.red()));
                        //telemetry.addData("Green", String.valueOf(color.green()));
                        //telemetry.addData("I2cAddress", String.valueOf(color.getI2cAddr()));
                        //telemetry.update();
                        break;
                    default:
                        state = State.HALT;
                        break;
                }
    
                idle();
            }
        }
    
        /**
         * This method sets up the hardware so it is ready to use.
         */
        private void begin() {
            robot.init(hardwareMap);
            gyro.calibrate();
            while (gyro.isCalibrating()) {
                telemetry.addData("Waiting on Gyro Calibration", "");
                telemetry.update();
            }
    
            telemetry.addData("Status", "Initialized");
            telemetry.update();
        }
    
        enum State {HALT, DRIVE_STRAIGHT, GYRO, TOUCH, ODS, COLOR, TURN}
    }
    This is the drive class that I am attempting to use telemetry in.

    Code:
    public class DriveRobot {
        HardwareTestPlatform robot = null;
        SensorGyro gyro = null;
        ElapsedTime runtime = new ElapsedTime();
        DataLogger dl = new DataLogger("log");
        Telemetry telemetry;
    
        public DriveRobot(HardwareTestPlatform myRobot, SensorGyro myGyro, Telemetry myTelemetry) {
    
            robot = myRobot;
            gyro = myGyro;
            telemetry = myTelemetry;
        }
    
        public void gyroDriveStraight(double mm, double power) {
            double leftSpeed; //Power to feed the motors
            double rightSpeed;
    
            dl.newLine();
            dl.addField("gyroDriveStraight - ");
            dl.addField(robot.motorLF.getCurrentPosition());
            dl.addField((gyro.getIntegratedZ()));
    
            double travel = robot.motorLF.getCurrentPosition() + (int) (mm * robot.COUNTS_PER_MM);  //Encoder counts to travel
            double target = gyro.getIntegratedZ();  //Starting direction
            double startPosition = robot.motorLF.getCurrentPosition();  //Starting position
    
            dl.newLine();
            dl.addField("gyroDriveStraight - Travel, target, startPosition");
            dl.addField(String.valueOf(travel));
            dl.addField(String.valueOf(target));
            dl.addField(String.valueOf(startPosition));
    
            while (robot.motorLF.getCurrentPosition() < travel &&
                    robot.touchSensor.getValue() == 0) {  //While we have not passed out intended distance
                int zAccumulated = gyro.getIntegratedZ();  //Current direction
    
                telemetry.addData("zAccumulated", String.valueOf(zAccumulated));
                telemetry.addData("motorLF Position", String.valueOf(robot.motorLF.getCurrentPosition()));
                telemetry.update();
    
                dl.newLine();
                dl.addField("gyroDriveStraight - zAccumulated, Current Encoder Position, Travel");
                dl.addField(zAccumulated);
                dl.addField(robot.motorLF.getCurrentPosition());
                dl.addField(travel);
    
                leftSpeed = power + (zAccumulated - target) / 100;  //Calculate speed for each side
                rightSpeed = power - (zAccumulated - target) / 100;  //See GyroNew Straight video for detailed explanation
    
                dl.newLine();
                dl.addField("gyroDriveStraight - LeftSpeed, rightSpeed");
                dl.addField(leftSpeed);
                dl.addField(rightSpeed);
    
                leftSpeed = Range.clip(leftSpeed, -1, 1);
                rightSpeed = Range.clip(rightSpeed, -1, 1);
    
                dl.newLine();
                dl.addField("gyroDriveStraight - LeftSpeed, rightSpeed - Clipped");
                dl.addField(leftSpeed);
                dl.addField(rightSpeed);
    
                robot.motorLF.setPower(leftSpeed);
                robot.motorRF.setPower(rightSpeed);
            }
    
            motorsHalt();
        }
    
        /**
         * Halt power to the motors
         */
        public void motorsHalt() {
            robot.motorLF.setPower(0);
            robot.motorRF.setPower(0);
        }
    }
    The code compiles and runs fine but the telemetry in the drive class never displays. What am I doing wrong?

  • #2
    public class OpModeBase extends LinearOpMode {

    ...
    private final static Telemetry myTelemetry = new Telemetry() {


    I'm new to this, but I have successfully implemented this.
    I think you are adding a new Telemetry to the OpModeBase class and passing that to your robot. You need to pass the Telemetry that the LinearOpMode has, not your new one.

    Comment


    • #3
      You shouldn't be creating those methods for telemetry. Instead, you should pass in LinearOpMode as a parameter in the DriveRobot object like DriveRobot(HardwareTestPlatform myRobot, SensorGyro myGyro, LinearOpMode opMode) and then use telemetry = opMode.telemetry; because you want the telemetry associated with the opmode. If you need references, you can take a look at my team's code although we don't use telemetry in our subsystems. However, I think the setup may help you a bit.

      https://github.com/lockdown8564/Lock...DriveBase.java

      As you can see in the constructor, I pass in LinearOpMode and use the parameter to be able to call methods pertaining to the linear opmode. Let me know if you have additional questions

      Comment


      • #4
        Got it, that makes sense. Thank you.

        Comment


        • #5
          Ok, maybe not so fast. So my OpMode now looks like this

          Code:
          public class OpModeBase extends LinearOpMode {
          
              private final static HardwareTestPlatform robot = new HardwareTestPlatform();
              private final static ElapsedTime runtime = new ElapsedTime();
              private final static LinearOpMode myopmode = new LinearOpMode()
              {
                  @Override
                  public void runOpMode() throws InterruptedException {
          
                  }
              };
              private final static SensorGyro gyro = new SensorGyro(robot, myopmode);
              private final static DriveRobot drive = new DriveRobot(robot, gyro, myopmode);
              private final static SensorTouch touch = new SensorTouch(robot, myopmode);
              private final static SensorODS ods = new SensorODS(robot, myopmode);
              private static final SensorColor color = new SensorColor(robot, myopmode);
              private State state = State.DRIVE_STRAIGHT;
          
              public void runOpMode() {
                  int clicks = 10000; //Encoder clicks to drive
                  double power = .6;  //Motor power 1 = 100%
                  double mm = 1000;   //Distance to travel in MM
                  int target = 90;    //Gyro target in degrees
                  int timeout = 15;   //Timeout in seconds
          
                  begin();
          
                  waitForStart();     //Wait for play to be pressed
                  runtime.reset();    //Reset runtime counter
          
                  while (opModeIsActive() && state != State.HALT) {       //Loop until State.HALT
                      switch (state) {
                          case DRIVE_STRAIGHT:
                              //drive.encoderDrive(power, mm, mm, timeout);
                              //drive.encoderDrive(power, mm, mm, timeout);
                              //drive.gyroDriveStraight(mm, power);
                              drive.strafe(mm, power);
                              state = State.HALT;
                              break;
                          case TURN:
                              drive.gyroDrivePivot(target, power);
                              state = State.HALT;
                              break;
                          case GYRO:
                              telemetry.addData("Integrated Z = ", String.valueOf(gyro.getIntegratedZ()));
                              telemetry.addData("Heading", String.valueOf(gyro.getHeading()));
                              telemetry.addData("isCalibrating", String.valueOf(gyro.isCalibrating()));
                              telemetry.addData("X", String.valueOf(gyro.getX()));
                              telemetry.addData("Y", String.valueOf(gyro.getY()));
                              telemetry.addData("Z", String.valueOf(gyro.getZ()));
                              telemetry.addData("Status", String.valueOf(gyro.status()));
                              telemetry.update();
                              break;
                          case TOUCH:
                              telemetry.addData("Force", String.valueOf(touch.force()));
                              telemetry.addData("Is Pressed", String.valueOf(touch.pressed()));
                              telemetry.update();
                              break;
                          case ODS:
                              telemetry.addData("Light Detected", String.valueOf(ods.getLight()));
                              telemetry.addData("Raw Light Detected", String.valueOf(ods.getRawLight()));
                              telemetry.addData("Max Light Detected", String.valueOf(ods.getMaxLight()));
                              telemetry.addData("Status", String.valueOf(ods.status()));
                              telemetry.update();
                              break;
                          case COLOR:
                              //telemetry.addData("Alpha", String.valueOf(color.alpha()));
                              //telemetry.addData("ARGB", String.valueOf(color.argb()));
                              //telemetry.addData("Blue", String.valueOf(color.blue()));
                              //telemetry.addData("Red", String.valueOf(color.red()));
                              //telemetry.addData("Green", String.valueOf(color.green()));
                              //telemetry.addData("I2cAddress", String.valueOf(color.getI2cAddr()));
                              //telemetry.update();
                              break;
                          default:
                              state = State.HALT;
                              break;
                      }
          
                      idle();
                  }
              }
          
              /**
               * This method sets up the hardware so it is ready to use.
               */
              private void begin() {
                  robot.init(hardwareMap);
                  gyro.calibrate();
                  while (gyro.isCalibrating()) {
                      telemetry.addData("Waiting on Gyro Calibration", "");
                      telemetry.update();
                  }
          
                  telemetry.addData("Status", "Initialized");
                  telemetry.update();
              }
          
              enum State {HALT, DRIVE_STRAIGHT, GYRO, TOUCH, ODS, COLOR, TURN}
          }
          And my drive class looks like this.

          Code:
          public class DriveRobot {
              HardwareTestPlatform robot = null;
              SensorGyro gyro = null;
              ElapsedTime runtime = new ElapsedTime();
              DataLogger dl = new DataLogger("log");
              Telemetry telemetry;
              LinearOpMode opMode;
          
              public DriveRobot(HardwareTestPlatform myRobot, SensorGyro myGyro, LinearOpMode opMode) {
                  this.opMode = opMode;
                  robot = myRobot;
                  gyro = myGyro;
              }
          
              public void strafe(double mm, double power) {
                  double leftSpeed, rightSpeed;
                  int target;
          
                  // Determine new target position, and pass to motor controller
                  target = robot.motorLF.getCurrentPosition() + (int) (mm * robot.COUNTS_PER_MM);
          
                  robot.motorLF.setTargetPosition(target);
          
                  double bearing = gyro.getIntegratedZ();
          
                  while (robot.motorLF.getCurrentPosition() < target
                          && robot.touchSensor.getValue() == 0) {  //While we have not passed out intended distance
          
                      int zAccumulated = gyro.getIntegratedZ();  //Current direction
                      this.opMode.telemetry.addData("zAccumulated", String.valueOf(zAccumulated));
                      this.opMode.telemetry.update();
          
                      leftSpeed = power + (zAccumulated - bearing) / 100;  //Calculate speed for each side
                      rightSpeed = power - (zAccumulated - bearing) / 100;  //See GyroNew Straight video for detailed explanation
          
                      leftSpeed = Range.clip(leftSpeed, -1, 1);
                      rightSpeed = Range.clip(rightSpeed, -1, 1);
          
                      robot.motorLF.setPower(-1 * rightSpeed);
                      robot.motorRF.setPower(rightSpeed);
                      robot.motorLR.setPower(leftSpeed);
                      robot.motorRR.setPower(-1 * leftSpeed);
                  }
          
                  motorsHalt();
              }
          
              /**
               * Halt power to the motors
               */
              public void motorsHalt() {
                  robot.motorLF.setPower(0);
                  robot.motorRF.setPower(0);
              }
          }
          But, including the following lines doesn't show any telemetry on the driver station.

          Code:
          this.opMode.telemetry.addData("zAccumulated", String.valueOf(zAccumulated));
                      this.opMode.telemetry.update();

          Comment


          • #6
            I think it should look like this. Someone told me to use this when using LinearOpMode as a parameter. I still don't know how that works since I'm not terribly familiar with the this usage. I'll try to find that article where I got help with inserting telemetry into a subclass just in case my suggested fix doesn't work.

            Code:
            public class OpModeBase extends LinearOpMode {
            
                private final static HardwareTestPlatform robot = new HardwareTestPlatform();
                private final static ElapsedTime runtime = new ElapsedTime();
                private final static SensorGyro gyro = new SensorGyro(robot, myopmode);
                private final static DriveRobot drive = new DriveRobot(robot, gyro, this); //*** I don't know what myopmode is but I used this (I still don't know how it works XD)
                private final static SensorTouch touch = new SensorTouch(robot, myopmode);
                private final static SensorODS ods = new SensorODS(robot, myopmode);
                private static final SensorColor color = new SensorColor(robot, myopmode);
                private State state = State.DRIVE_STRAIGHT;
            
                public void runOpMode() {
                    int clicks = 10000; //Encoder clicks to drive
                    double power = .6;  //Motor power 1 = 100%
                    double mm = 1000;   //Distance to travel in MM
                    int target = 90;    //Gyro target in degrees
                    int timeout = 15;   //Timeout in seconds
            
                    begin();
            
                    waitForStart();     //Wait for play to be pressed
                    runtime.reset();    //Reset runtime counter
            
                    while (opModeIsActive() && state != State.HALT) {       //Loop until State.HALT
                        switch (state) {
                            case DRIVE_STRAIGHT:
                                //drive.encoderDrive(power, mm, mm, timeout);
                                //drive.encoderDrive(power, mm, mm, timeout);
                                //drive.gyroDriveStraight(mm, power);
                                drive.strafe(mm, power);
                                state = State.HALT;
                                break;
                            case TURN:
                                drive.gyroDrivePivot(target, power);
                                state = State.HALT;
                                break;
                            case GYRO:
                                telemetry.addData("Integrated Z = ", String.valueOf(gyro.getIntegratedZ()));
                                telemetry.addData("Heading", String.valueOf(gyro.getHeading()));
                                telemetry.addData("isCalibrating", String.valueOf(gyro.isCalibrating()));
                                telemetry.addData("X", String.valueOf(gyro.getX()));
                                telemetry.addData("Y", String.valueOf(gyro.getY()));
                                telemetry.addData("Z", String.valueOf(gyro.getZ()));
                                telemetry.addData("Status", String.valueOf(gyro.status()));
                                telemetry.update();
                                break;
                            case TOUCH:
                                telemetry.addData("Force", String.valueOf(touch.force()));
                                telemetry.addData("Is Pressed", String.valueOf(touch.pressed()));
                                telemetry.update();
                                break;
                            case ODS:
                                telemetry.addData("Light Detected", String.valueOf(ods.getLight()));
                                telemetry.addData("Raw Light Detected", String.valueOf(ods.getRawLight()));
                                telemetry.addData("Max Light Detected", String.valueOf(ods.getMaxLight()));
                                telemetry.addData("Status", String.valueOf(ods.status()));
                                telemetry.update();
                                break;
                            case COLOR:
                                //telemetry.addData("Alpha", String.valueOf(color.alpha()));
                                //telemetry.addData("ARGB", String.valueOf(color.argb()));
                                //telemetry.addData("Blue", String.valueOf(color.blue()));
                                //telemetry.addData("Red", String.valueOf(color.red()));
                                //telemetry.addData("Green", String.valueOf(color.green()));
                                //telemetry.addData("I2cAddress", String.valueOf(color.getI2cAddr()));
                                //telemetry.update();
                                break;
                            default:
                                state = State.HALT;
                                break;
                        }
            
                        idle();
                    }
                }
            
                /**
                 * This method sets up the hardware so it is ready to use.
                 */
                private void begin() {
                    robot.init(hardwareMap);
                    gyro.calibrate();
                    while (gyro.isCalibrating()) {
                        telemetry.addData("Waiting on Gyro Calibration", "");
                        telemetry.update();
                    }
            
                    telemetry.addData("Status", "Initialized");
                    telemetry.update();
                }
            
                enum State {HALT, DRIVE_STRAIGHT, GYRO, TOUCH, ODS, COLOR, TURN}
            }
            Code:
            public class DriveRobot {
                HardwareTestPlatform robot = null;
                SensorGyro gyro = null;
                ElapsedTime runtime = new ElapsedTime();
                DataLogger dl = new DataLogger("log");
                Telemetry telemetry;
            
                public DriveRobot(HardwareTestPlatform myRobot, SensorGyro myGyro, LinearOpMode opMode) {
                    telemetry = opMode.telemetry;
                    robot = myRobot;
                    gyro = myGyro;
                }
            
                public void strafe(double mm, double power) {
                    double leftSpeed, rightSpeed;
                    int target;
            
                    // Determine new target position, and pass to motor controller
                    target = robot.motorLF.getCurrentPosition() + (int) (mm * robot.COUNTS_PER_MM);
            
                    robot.motorLF.setTargetPosition(target);
            
                    double bearing = gyro.getIntegratedZ();
            
                    while (robot.motorLF.getCurrentPosition() < target
                            && robot.touchSensor.getValue() == 0) {  //While we have not passed out intended distance
            
                        int zAccumulated = gyro.getIntegratedZ();  //Current direction
                        telemetry.addData("zAccumulated", String.valueOf(zAccumulated));
                        telemetry.update();
            
                        leftSpeed = power + (zAccumulated - bearing) / 100;  //Calculate speed for each side
                        rightSpeed = power - (zAccumulated - bearing) / 100;  //See GyroNew Straight video for detailed explanation
            
                        leftSpeed = Range.clip(leftSpeed, -1, 1);
                        rightSpeed = Range.clip(rightSpeed, -1, 1);
            
                        robot.motorLF.setPower(-1 * rightSpeed);
                        robot.motorRF.setPower(rightSpeed);
                        robot.motorLR.setPower(leftSpeed);
                        robot.motorRR.setPower(-1 * leftSpeed);
                    }
            
                    motorsHalt();
                }
            
                /**
                 * Halt power to the motors
                 */
                public void motorsHalt() {
                    robot.motorLF.setPower(0);
                    robot.motorRF.setPower(0);
                }
            }

            Comment


            • #7
              I took a look at my old thread and I didn't think that it would be extremely helpful. However, here's another thread that perhaps shows what you're looking for if my solution didn't work. http://ftcforum.usfirst.org/showthre...Hardware-Class

              Comment


              • #8
                Originally posted by caseyz View Post
                Ok, maybe not so fast. So my OpMode now looks like this

                Code:
                public class OpModeBase extends LinearOpMode {
                
                    private final static HardwareTestPlatform robot = new HardwareTestPlatform();
                    private final static ElapsedTime runtime = new ElapsedTime();
                    private final static LinearOpMode myopmode = new LinearOpMode()
                    {
                        @Override
                        public void runOpMode() throws InterruptedException {
                
                        }
                    };
                    private final static SensorGyro gyro = new SensorGyro(robot, myopmode);
                    private final static DriveRobot drive = new DriveRobot(robot, gyro, myopmode);
                    ...
                You're still extending the class LinearOpMode with another LinearOpMode...
                I don't think you need or want all this:

                private final static LinearOpMode myopmode = new LinearOpMode()
                {
                @Override
                public void runOpMode() throws InterruptedException {

                }
                };

                Just have "this" passed to your robot.

                My equivalent code is:

                public class Auto20160928 extends LinearOpMode {

                A2016Robot robot = new A2016Robot();

                @Override
                public void runOpMode() throws InterruptedException {
                robot.init(this);

                ....

                and

                class A2016Robot {

                ...

                public void init(LinearOpMode linearOpMode){
                this.linearOpMode = linearOpMode;
                init(linearOpMode.hardwareMap, linearOpMode.telemetry);

                };


                /* Initialize standard Hardware interfaces */
                public void init(HardwareMap hardwareMap, Telemetry telemetry) {
                // Save reference to Hardware map
                this.hardwareMap = hardwareMap;
                this.telemetry = telemetry;

                ...

                Passing "this" into your robot gives it access to everything the main program has access to.

                Comment


                • #9
                  I want to clarify that this is a java keyword describing the current object, so in the case of caseyz myopmode is this as your robot program is an instance of LinearOpMode as long as you are in context of your LinearOpMode.

                  In general, you use this if you are passing your robot code to other classes, you reference this as the parameter to the code, otherwise you need to use a previously acquired reference to the object.

                  More information of this: http://docs.oracle.com/javase/tutori...O/thiskey.html.

                  Comment

                  Working...
                  X