Update PhotonCamera error messages to be more specific (#697)

Closes #692
This commit is contained in:
Nick Hadley
2023-01-05 19:28:32 -05:00
committed by GitHub
parent 05198ef294
commit 0f427bb52b
6 changed files with 68 additions and 23 deletions

View File

@@ -114,7 +114,6 @@ public class Draw3dTargetsPipe
// Distort the points so they match the image they're being overlaid on
distortPoints(tempMat, tempMat);
}
var topPoints = tempMat.toList();
dividePointList(bottomPoints);

View File

@@ -31,18 +31,23 @@ import edu.wpi.first.networktables.DoubleArrayPublisher;
import edu.wpi.first.networktables.DoublePublisher;
import edu.wpi.first.networktables.IntegerEntry;
import edu.wpi.first.networktables.IntegerSubscriber;
import edu.wpi.first.networktables.MultiSubscriber;
import edu.wpi.first.networktables.NetworkTable;
import edu.wpi.first.networktables.NetworkTableInstance;
import edu.wpi.first.networktables.PubSubOption;
import edu.wpi.first.networktables.RawSubscriber;
import edu.wpi.first.networktables.StringSubscriber;
import edu.wpi.first.wpilibj.DriverStation;
import edu.wpi.first.wpilibj.Timer;
import java.util.Set;
import org.photonvision.common.dataflow.structures.Packet;
import org.photonvision.common.hardware.VisionLEDMode;
import org.photonvision.targeting.PhotonPipelineResult;
/** Represents a camera that is connected to PhotonVision. */
public class PhotonCamera {
static final String kTableName = "photonvision";
protected final NetworkTable rootTable;
RawSubscriber rawBytesEntry;
BooleanEntry driverModeEntry;
@@ -96,6 +101,8 @@ public class PhotonCamera {
Packet packet = new Packet(1);
private final MultiSubscriber m_topicNameSubscriber;
/**
* Constructs a PhotonCamera from a root table.
*
@@ -106,7 +113,7 @@ public class PhotonCamera {
*/
public PhotonCamera(NetworkTableInstance instance, String cameraName) {
name = cameraName;
var mainTable = instance.getTable("photonvision");
var mainTable = instance.getTable(kTableName);
this.rootTable = mainTable.getSubTable(cameraName);
path = rootTable.getPath();
rawBytesEntry = rootTable.getRawTopic("rawBytes").subscribe("rawBytes", new byte[] {});
@@ -117,6 +124,12 @@ public class PhotonCamera {
heartbeatEntry = rootTable.getIntegerTopic("heartbeat").subscribe(-1);
ledModeEntry = mainTable.getIntegerTopic("ledMode").getEntry(-1);
versionEntry = mainTable.getStringTopic("version").subscribe("");
m_topicNameSubscriber =
new MultiSubscriber(
instance,
new String[] {"/photonvision/"},
new PubSubOption[] {PubSubOption.topicsOnly(true)});
}
/**
@@ -280,7 +293,7 @@ public class PhotonCamera {
prevHeartbeatValue = curHeartbeat;
}
return ((now - prevHeartbeatChangeTime) < HEARBEAT_DEBOUNCE_SEC);
return (now - prevHeartbeatChangeTime) < HEARBEAT_DEBOUNCE_SEC;
}
private void verifyVersion() {
@@ -292,12 +305,25 @@ public class PhotonCamera {
// Heartbeat entry is assumed to always be present. If it's not present, we
// assume that a camera with that name was never connected in the first place.
if (!heartbeatEntry.exists()) {
DriverStation.reportError(
"PhotonVision coprocessor at path " + path + " not found on NetworkTables!", true);
Set<String> cameraNames = rootTable.getInstance().getTable(kTableName).getSubTables();
if (cameraNames.isEmpty()) {
DriverStation.reportError(
"Could not find any PhotonVision coprocessors on NetworkTables. Double check that PhotonVision is running, and that your camera is connected!",
false);
} else {
DriverStation.reportError(
"PhotonVision coprocessor at path "
+ path
+ " not found on NetworkTables. Double check that your camera names match!",
true);
DriverStation.reportError(
"Found the following PhotonVision cameras on NetworkTables:\n"
+ String.join("\n", cameraNames),
false);
}
}
// Check for connection status. Warn if disconnected.
if (!isConnected()) {
else if (!isConnected()) {
DriverStation.reportWarning(
"PhotonVision coprocessor at path " + path + " is not sending new data.", true);
}

View File

@@ -48,7 +48,7 @@ public class SimPhotonCamera {
*/
public SimPhotonCamera(NetworkTableInstance instance, String cameraName) {
ts.removeEntries();
ts.subTable = instance.getTable("/photonvision").getSubTable(cameraName);
ts.subTable = instance.getTable(PhotonCamera.kTableName).getSubTable(cameraName);
ts.updateEntries();
}

View File

@@ -33,10 +33,11 @@
namespace photonlib {
constexpr const units::second_t VERSION_CHECK_INTERVAL = 5_s;
static const std::vector<std::string_view> PHOTON_PREFIX = {"/photonvision/"};
PhotonCamera::PhotonCamera(std::shared_ptr<nt::NetworkTableInstance> instance,
PhotonCamera::PhotonCamera(nt::NetworkTableInstance instance,
const std::string_view cameraName)
: mainTable(instance->GetTable("photonvision")),
: mainTable(instance.GetTable("photonvision")),
rootTable(mainTable->GetSubTable(cameraName)),
rawBytesEntry(rootTable->GetRawTopic("rawBytes").Subscribe("raw", {})),
driverModeEntry(rootTable->GetBooleanTopic("driverMode").Publish()),
@@ -56,13 +57,12 @@ PhotonCamera::PhotonCamera(std::shared_ptr<nt::NetworkTableInstance> instance,
pipelineIndexSubscriber(
rootTable->GetIntegerTopic("pipelineIndex").Subscribe(-1)),
ledModeSubscriber(mainTable->GetIntegerTopic("ledMode").Subscribe(0)),
m_topicNameSubscriber(instance, PHOTON_PREFIX, {.topicsOnly = true}),
path(rootTable->GetPath()),
m_cameraName(cameraName) {}
PhotonCamera::PhotonCamera(const std::string_view cameraName)
: PhotonCamera(std::make_shared<nt::NetworkTableInstance>(
nt::NetworkTableInstance::GetDefault()),
cameraName) {}
: PhotonCamera(nt::NetworkTableInstance::GetDefault(), cameraName) {}
PhotonPipelineResult PhotonCamera::GetLatestResult() {
if (test) return testResult;
@@ -134,10 +134,29 @@ void PhotonCamera::VerifyVersion() {
const std::string& versionString = versionEntry.Get("");
if (versionString.empty()) {
std::string path_ = path;
FRC_ReportError(
frc::warn::Warning,
"PhotonVision coprocessor at path {} not found on NetworkTables!",
path_);
std::vector<std::string> cameraNames =
rootTable->GetInstance().GetTable("photonvision")->GetSubTables();
if (cameraNames.empty()) {
FRC_ReportError(frc::warn::Warning,
"Could not find any PhotonVision coprocessors on "
"NetworkTables. Double check that PhotonVision is "
"running, and that your camera is connected!");
} else {
FRC_ReportError(
frc::warn::Warning,
"PhotonVision coprocessor at path {} not found on NetworkTables. "
"Double check that your camera names match!",
path_);
std::string cameraNameOutString;
for (unsigned int i = 0; i < cameraNames.size(); i++) {
cameraNameOutString += "\n" + cameraNames[i];
}
FRC_ReportError(
frc::warn::Warning,
"Found the following PhotonVision cameras on NetworkTables:{}",
cameraNameOutString);
}
} else if (!VersionMatches(versionString)) {
FRC_ReportError(frc::warn::Warning,
"Photon version {} does not match coprocessor version {}!",

View File

@@ -30,6 +30,7 @@
#include <networktables/BooleanTopic.h>
#include <networktables/DoubleTopic.h>
#include <networktables/IntegerTopic.h>
#include <networktables/MultiSubscriber.h>
#include <networktables/NetworkTable.h>
#include <networktables/NetworkTableInstance.h>
#include <networktables/RawTopic.h>
@@ -57,7 +58,7 @@ class PhotonCamera {
* @param cameraName The name of the camera, as seen in the UI.
* over.
*/
explicit PhotonCamera(std::shared_ptr<nt::NetworkTableInstance> instance,
explicit PhotonCamera(nt::NetworkTableInstance instance,
const std::string_view cameraName);
/**
@@ -178,6 +179,8 @@ class PhotonCamera {
nt::IntegerSubscriber pipelineIndexSubscriber;
nt::IntegerSubscriber ledModeSubscriber;
nt::MultiSubscriber m_topicNameSubscriber;
std::string path;
std::string m_cameraName;

View File

@@ -37,7 +37,7 @@
namespace photonlib {
class SimPhotonCamera : public PhotonCamera {
public:
SimPhotonCamera(std::shared_ptr<nt::NetworkTableInstance> instance,
SimPhotonCamera(nt::NetworkTableInstance instance,
const std::string& cameraName)
: PhotonCamera(instance, cameraName) {
latencyMillisEntry = rootTable->GetEntry("latencyMillis");
@@ -48,14 +48,12 @@ class SimPhotonCamera : public PhotonCamera {
targetSkewEntry = rootTable->GetEntry("targetSkewEntry");
targetPoseEntry = rootTable->GetEntry("targetPoseEntry");
rawBytesPublisher = rootTable->GetRawTopic("rawBytes").Publish("raw");
versionEntry = instance->GetTable("photonvision")->GetEntry("version");
versionEntry = instance.GetTable("photonvision")->GetEntry("version");
// versionEntry.SetString(PhotonVersion.versionString);
}
explicit SimPhotonCamera(const std::string& cameraName)
: SimPhotonCamera(std::make_shared<nt::NetworkTableInstance>(
nt::NetworkTableInstance::GetDefault()),
cameraName) {}
: SimPhotonCamera(nt::NetworkTableInstance::GetDefault(), cameraName) {}
virtual ~SimPhotonCamera() = default;