Java header for photonvision

Our team can’t get the photonvision data, even though we can see it in shuffleboard.
We are certainly missing some imports from the header of our java code for photon vision. No thanks to the photonVision docs, we found

import org.photonvision.PhotonCamera;

but we cannot get the sample code to work, and we are rather sure that we are missing other import lines.
Do we need network tables?

Did you add the vendor library?

Oh, Yes. It is also quite up-to-date.

Can you share your code? Also, it would be helpful if you would elaborate on your problem. What did you try so far, and what was the outcome? It’s not clear to me if you’re saying the code doesn’t even compile, or if you’re running it on your robot and getting no data.

1 Like

Here is the code … trying to get the result makes the roboRio show that it has no code in the driver station and the error seems to be the code.
Commenting out the lines
var result = camera.getLatestResult();
pHasTarget = result.hasTargets();
lets the robot come alive again, but leaves us without the vision data

// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.

package frc.robot;

import edu.wpi.first.wpilibj.CounterBase;
import edu.wpi.first.wpilibj.Encoder;
import edu.wpi.first.wpilibj.TimedRobot;
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
import edu.wpi.first.wpilibj.Timer;
import edu.wpi.first.wpilibj.drive.DifferentialDrive;
import edu.wpi.first.wpilibj.XboxController;
import edu.wpi.first.wpilibj.motorcontrol.Victor;
import edu.wpi.first.wpilibj.motorcontrol.Spark;
import edu.wpi.first.wpilibj.SPI; // required for ADIS IMUs
//import edu.wpi.first.wpilibj.ADIS16448_IMU;
import edu.wpi.first.wpilibj.ADIS16470_IMU;
import org.photonvision.PhotonCamera; //https://maven.photonvision.org/repository/internal/org/photonvision/PhotonLib-json/1.0/PhotonLib-json-1.0.json

public class Robot extends TimedRobot {
private final Spark m_rightDrive = new Spark(0);
private final Spark m_leftDrive = new Spark(1);
private final Victor shooter = new Victor(3);
private final DifferentialDrive m_robotDrive = new DifferentialDrive(m_leftDrive, m_rightDrive);
private final XboxController m_stick = new XboxController(0);
private final Timer m_timer = new Timer();
private final Encoder right_encoder = new Encoder(6, 7, true, CounterBase.EncodingType.k4X);
private final Encoder left_encoder = new Encoder(8, 9, false, CounterBase.EncodingType.k4X);
//public static final ADIS16448_IMU imu = new ADIS16448_IMU(ADIS16448_IMU.IMUAxis.kY, SPI.Port.kMXP, ADIS16448_IMU.CalibrationTime._1s);
public static final ADIS16470_IMU imu = new ADIS16470_IMU(ADIS16470_IMU.IMUAxis.kY,ADIS16470_IMU.IMUAxis.kX,ADIS16470_IMU.IMUAxis.kZ, SPI.Port.kOnboardCS0, ADIS16470_IMU.CalibrationTime._1s);
PhotonCamera camera = new PhotonCamera(“Camera_Module_v1”); //wide angle on rPi3 is called “OV5647”
//other camera on rPi4 is called “Camera_Module_v3”
public double SpeedForward,rotationClockwise,cYaw;
public static double pTargetYaw;
public static boolean pHasTarget;
public static double Sharpness = 0.3;
public static double MaxTurnEffort = 0.25;
public static double shooterSpeed = 0.3;
@Override
public void robotInit() {
imu.calibrate();
m_rightDrive.setInverted(true);

right_encoder.setSamplesToAverage(5);
left_encoder.setSamplesToAverage(5);
right_encoder.setDistancePerPulse(6.0 * 0.3048 /8093); // the pulses where averaged from l&r = 8093 of 6' (3 x 2' tiles)
left_encoder.setDistancePerPulse( 6.0 * 0.3048 /8093); // the factor 0.3048 converts feet into metres
right_encoder.setMinRate(1.0);
left_encoder.setMinRate(1.0);
right_encoder.reset();
left_encoder.reset();
SmartDashboard.putNumber("Sharpness", Sharpness);
SmartDashboard.putNumber("MaxTurnEffort", MaxTurnEffort);
SmartDashboard.putNumber("Shooter Speed", shooterSpeed);

}

@Override
public void robotPeriodic(){
var result = camera.getLatestResult();
pHasTarget = result.hasTargets();

if (pHasTarget) {
  pTargetYaw = result.getBestTarget().getYaw();
  SmartDashboard.putBoolean("Has Target",pHasTarget);
  SmartDashboard.putNumber("TargetID", result.getBestTarget().getFiducialId());
  SmartDashboard.putNumber("Target Yaw", pTargetYaw);    
}

cYaw = -imu.getAngle(ADIS16470_IMU.IMUAxis.kY) % 360;


SmartDashboard.putNumber("Angle", -imu.getAngle(ADIS16470_IMU.IMUAxis.kY));
SmartDashboard.putNumber("cYaw", cYaw);
SmartDashboard.putNumber("R_Encoder Distance", right_encoder.getDistance());
SmartDashboard.putNumber("L_Encoder Distance", left_encoder.getDistance());
SmartDashboard.putNumber("R_Encoder", right_encoder.get());
SmartDashboard.putNumber("L_Encoder", left_encoder.get());
SmartDashboard.putNumber("Rotation Clockwise", rotationClockwise);

//Sharpness = SmartDashboard.getNumber("Sharpness",Sharpness);
//MaxTurnEffort = SmartDashboard.getNumber("MaxTurnEffort", MaxTurnEffort);
//shooterSpeed = SmartDashboard.getNumber("Shooter Speed",shooterSpeed);

}
@Override
public void autonomousInit() {
// m_timer.reset();
right_encoder.reset();
left_encoder.reset();
// m_timer.start();
}

/** This function is called periodically during autonomous. */
@Override
public void autonomousPeriodic() {
// if (right_encoder.getDistance() < (1.00)) { //only drive when the encoder reads less than 1.00 m – NEEDS ENCODERS TO PREVENT WILD ROBOT –
if (m_timer.get() < 2) { //only drive when the timer is less than 2 seconds
m_robotDrive.arcadeDrive(0.5, 0.0,false); // drive forwards half speed
} else {
m_robotDrive.stopMotor(); // stop robot
}
}

@Override
public void teleopPeriodic() {
shooter.set(shooterSpeed);
if (m_stick.getLeftBumper()) {
right_encoder.reset();
left_encoder.reset();
}
if (m_stick.getRightBumper()) {
imu.reset();
}
SpeedForward = m_stick.getRightTriggerAxis()-m_stick.getLeftTriggerAxis();
rotationClockwise = m_stick.getLeftX()*0.6;

rotationClockwise = m_stick.getYButton() ?(1-Math.exp(-Sharpness*Math.pow(cYaw,2)))*Math.signum(cYaw)MaxTurnEffort: rotationClockwise;
// rotationClockwise = m_stick.getXButton() ?(1-Math.exp(-Sharpness
Math.pow(pTargetYaw,2)))*Math.signum(pTargetYaw)*MaxTurnEffort: rotationClockwise;

m_robotDrive.arcadeDrive(SpeedForward, rotationClockwise,false);
}
}

Can you share it as a link to a GitHub repo? If you’re having a compile problem, we’ll need to see all of the code, and the project setup (like the vendorlibs folder.)

1 Like

No compile problem. Not sure what a gitHub repo is. Can you share what imports are required? Can you even confirm that I need the following line?

import org.photonvision.PhotonCamera;

Thank you for your time and your replies. I appreciate the marvelous benefit that photon vision provides, and I apologize for my frustration that I cannot get it to work as advertised.

I have created a GitHub account to share this file to help you with the difficulty you are having with the raw text of our source code. I am new to github, so please be patient with me while I try to show you robot.java with GitHub. Can you please give me your GitHub userId for giving you access?

Does photonvision require this line?

import edu.wpi.first.wpilibj.GenericHID;

I think you’re probably debugging this the wrong way. If it was an import problem, the code wouldn’t compile. If you’re successfully deploying it, but no robot code is being reported, then it’s likely the robot program is crashing during startup.

There should be more information (called a stacktrace) in the riolog or driver station log Viewing Console Output — FIRST Robotics Competition documentation. The stack =trace will identify where the issue is occurring in the code. Reading Stacktraces — FIRST Robotics Competition documentation

Thank you! I think you are right … this seems like the road we should be going down. I will post details that we get from the stacktrace when we get back at it tomorrow.

I tried to create a new project and add your code, and it doesn’t compile. There’s a syntax error:

Regarding imports, I usually let VS Code help me with that using it’s intellisense feature. If you start typing “PhotonVision”, it will make suggestions. If you choose the selection, it will automatically add the import. If it isn’t making suggestions, you have a different problem, most likely that the vendor library didn’t install properly.

I created a new project, added the PhotonVision vendor library, and pasted your code from GitHub over my Robot.java file. Here it is on GitHub.

I’m able to start it up and run it in the simulator. It even worked when I connected it to PhotonVision running on my laptop and held up an AprilTag. You’re going to have to share more information about what you’re seeing that indicates it’s not working.

One idea is maybe you don’t have a matching version of PhotonVision and PhotonLib. I had that the first time I ran it and it crashed, but there was a clear message in the console telling me my versions were not compatible. I just had to update my PhotonVision JAR.

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>> !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
>>>
>>> You are running an incompatible version
>>> of PhotonVision on your coprocessor!
>>>
>>> This is neither tested nor supported.
>>> You MUST update PhotonVision,
>>> PhotonLib, or both.
>>>
>>> Your code will now crash.
>>> We hope your day gets better.
>>>
>>> !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

Error at org.photonvision.PhotonCamera.verifyVersion(PhotonCamera.java:403): Photon version v2024.2.2 does not match coprocessor version v2024.2.0!
Error at org.photonvision.PhotonCamera.verifyVersion(PhotonCamera.java:404): Unhandled exception: java.lang.UnsupportedOperationException: Photon version v2024.2.2 does not match coprocessor version v2024.2.0!    
        at org.photonvision.PhotonCamera.verifyVersion(PhotonCamera.java:404)
        at org.photonvision.PhotonCamera.getLatestResult(PhotonCamera.java:178)
        at frc.robot.Robot.robotPeriodic(Robot.java:60)
        at edu.wpi.first.wpilibj.IterativeRobotBase.loopFunc(IterativeRobotBase.java:381)
        at edu.wpi.first.wpilibj.TimedRobot.startCompetition(TimedRobot.java:131)
        at edu.wpi.first.wpilibj.RobotBase.runRobot(RobotBase.java:365)
        at edu.wpi.first.wpilibj.RobotBase.lambda$startRobot$0(RobotBase.java:433)
        at java.base/java.lang.Thread.run(Thread.java:833)

Warning at edu.wpi.first.wpilibj.RobotBase.runRobot(RobotBase.java:379): The robot program quit unexpectedly. This is usually due to a code error.
  The above stacktrace can help determine where the error occurred.
  See https://wpilib.org/stacktrace for more information.
Error at edu.wpi.first.wpilibj.RobotBase.runRobot(RobotBase.java:386): The startCompetition() method (or methods called by it) should have handled the exception above.
Warning at edu.wpi.first.wpilibj.IterativeRobotBase.printLoopOverrunMessage(IterativeRobotBase.java:412): Loop time of 0.02s overrun

FYI - Raw text isn’t actually the issue, I can always copy-paste that into my editor of choice if needed.

What Github solves is making sure others can reproduce the error.

FRC projects are designed to be self-contained. That is to say that to run your robot code, the only things I should have to do are:

  1. Install WPILib
  2. Get a copy of the folder you have on your hard drive
  3. Run the code

Github helps solve # 2 - it provieds you a mechanism to use git to upload an exact copy of your folder as it is right now, and lets others verify they’re working on the same set of files as you. As you or others make changes to the code, those changes can be tracked, compared, and shared.

Solved! Thank you both so much!
Here is what happened.
I had the same problem coming from two very similar robots with nearly identical hardware and software configurations. The photon vision library was updated for the wrong folder on one computer, and the other mysteriously worked well after turning everything off and then back on again. Thank you for the intro to github. Now that I can use it however, I learned that my students can’t because my board blocks it. Oh well.
Thank you for you time, and good luck at the competitions.

1 Like

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.