mirror of
https://github.com/PhotonVision/photonvision
synced 2026-06-19 00:41:41 +00:00
Fix PhotonCamera typestring checks (#1480)
Previously NT would quietly drop readQueue changes.
This commit is contained in:
@@ -53,7 +53,9 @@ class PhotonCamera:
|
||||
self._cameraTable = photonvision_root_table.getSubTable(cameraName)
|
||||
self._path = self._cameraTable.getPath()
|
||||
self._rawBytesEntry = self._cameraTable.getRawTopic("rawBytes").subscribe(
|
||||
"rawBytes", bytes([]), ntcore.PubSubOptions(periodic=0.01, sendAll=True)
|
||||
f"photonstruct:PhotonPipelineResult:{PhotonPipelineResult.photonStruct.MESSAGE_VERSION}",
|
||||
bytes([]),
|
||||
ntcore.PubSubOptions(periodic=0.01, sendAll=True),
|
||||
)
|
||||
|
||||
self._driverModePublisher = self._cameraTable.getBooleanTopic(
|
||||
@@ -226,6 +228,7 @@ class PhotonCamera:
|
||||
|
||||
versionString = self.versionEntry.get(defaultValue="")
|
||||
localUUID = PhotonPipelineResult.photonStruct.MESSAGE_VERSION
|
||||
|
||||
remoteUUID = self._rawBytesEntry.getTopic().getProperty("message_uuid")
|
||||
|
||||
if remoteUUID is None or len(remoteUUID) == 0:
|
||||
@@ -233,7 +236,11 @@ class PhotonCamera:
|
||||
f"PhotonVision coprocessor at path {self._path} has not reported a message interface UUID - is your coprocessor's camera started?",
|
||||
True,
|
||||
)
|
||||
elif localUUID != remoteUUID:
|
||||
|
||||
# ntcore hands us a JSON string with leading/trailing quotes - remove those
|
||||
remoteUUID = remoteUUID.replace('"', "")
|
||||
|
||||
if localUUID != remoteUUID:
|
||||
# Verified version mismatch
|
||||
|
||||
bfw = """
|
||||
|
||||
@@ -137,7 +137,7 @@ public class PhotonCamera implements AutoCloseable {
|
||||
cameraTable
|
||||
.getRawTopic("rawBytes")
|
||||
.subscribe(
|
||||
"rawBytes",
|
||||
PhotonPipelineResult.photonStruct.getTypeString(),
|
||||
new byte[] {},
|
||||
PubSubOption.periodic(0.01),
|
||||
PubSubOption.sendAll(true),
|
||||
@@ -185,6 +185,8 @@ public class PhotonCamera implements AutoCloseable {
|
||||
* make sure to call this frequently enough to avoid old results being discarded, too!
|
||||
*/
|
||||
public List<PhotonPipelineResult> getAllUnreadResults() {
|
||||
verifyVersion();
|
||||
|
||||
List<PhotonPipelineResult> ret = new ArrayList<>();
|
||||
|
||||
var changes = resultSubscriber.getAllChanges();
|
||||
|
||||
@@ -69,6 +69,10 @@ void PhotonCamera::SetVersionCheckEnabled(bool enabled) {
|
||||
VERSION_CHECK_ENABLED = enabled;
|
||||
}
|
||||
|
||||
static const std::string TYPE_STRING =
|
||||
std::string{"photonstruct:PhotonPipelineResult:"} +
|
||||
std::string{SerdeType<PhotonPipelineResult>::GetSchemaHash()};
|
||||
|
||||
PhotonCamera::PhotonCamera(nt::NetworkTableInstance instance,
|
||||
const std::string_view cameraName)
|
||||
: mainTable(instance.GetTable("photonvision")),
|
||||
@@ -76,7 +80,7 @@ PhotonCamera::PhotonCamera(nt::NetworkTableInstance instance,
|
||||
rawBytesEntry(
|
||||
rootTable->GetRawTopic("rawBytes")
|
||||
.Subscribe(
|
||||
"rawBytes", {},
|
||||
TYPE_STRING, {},
|
||||
{.pollStorage = 20, .periodic = 0.01, .sendAll = true})),
|
||||
inputSaveImgEntry(
|
||||
rootTable->GetIntegerTopic("inputSaveImgCmd").Publish()),
|
||||
@@ -262,17 +266,25 @@ void PhotonCamera::VerifyVersion() {
|
||||
|
||||
std::string cameraNameOutString;
|
||||
for (unsigned int i = 0; i < cameraNames.size(); i++) {
|
||||
cameraNameOutString += "\n" + cameraNames[i];
|
||||
cameraNameOutString += ("\n" + cameraNames[i]);
|
||||
}
|
||||
FRC_ReportError(
|
||||
frc::warn::Warning,
|
||||
"Found the following PhotonVision cameras on NetworkTables:{}",
|
||||
"Found the following PhotonVision cameras on NetworkTables:\n{}",
|
||||
cameraNameOutString);
|
||||
}
|
||||
} else {
|
||||
std::string local_uuid{SerdeType<PhotonPipelineResult>::GetSchemaHash()};
|
||||
std::string remote_uuid =
|
||||
|
||||
// implicit conversion here might throw an exception, so be careful of that
|
||||
wpi::json remote_uuid_json =
|
||||
rawBytesEntry.GetTopic().GetProperty("message_uuid");
|
||||
if (!remote_uuid_json.is_string()) {
|
||||
FRC_ReportError(frc::warn::Warning,
|
||||
"Cannot find property message_uuid for PhotonCamera {}",
|
||||
path);
|
||||
}
|
||||
std::string remote_uuid{remote_uuid_json};
|
||||
|
||||
if (local_uuid != remote_uuid) {
|
||||
FRC_ReportError(frc::warn::Warning, bfw);
|
||||
|
||||
@@ -353,8 +353,7 @@ void PhotonCameraSim::SubmitProcessedFrame(const PhotonPipelineResult& result,
|
||||
ts.targetPitchEntry.Set(0.0, ReceiveTimestamp);
|
||||
ts.targetYawEntry.Set(0.0, ReceiveTimestamp);
|
||||
ts.targetAreaEntry.Set(0.0, ReceiveTimestamp);
|
||||
std::array<double, 3> poseData{0.0, 0.0, 0.0};
|
||||
ts.targetPoseEntry.Set(poseData, ReceiveTimestamp);
|
||||
ts.targetPoseEntry.Set(frc::Transform3d{}, ReceiveTimestamp);
|
||||
ts.targetSkewEntry.Set(0.0, ReceiveTimestamp);
|
||||
} else {
|
||||
PhotonTrackedTarget bestTarget = result.GetBestTarget();
|
||||
@@ -364,11 +363,8 @@ void PhotonCameraSim::SubmitProcessedFrame(const PhotonPipelineResult& result,
|
||||
ts.targetAreaEntry.Set(bestTarget.GetArea(), ReceiveTimestamp);
|
||||
ts.targetSkewEntry.Set(bestTarget.GetSkew(), ReceiveTimestamp);
|
||||
|
||||
frc::Transform3d transform = bestTarget.GetBestCameraToTarget();
|
||||
std::array<double, 4> poseData{
|
||||
transform.X().to<double>(), transform.Y().to<double>(),
|
||||
transform.Rotation().ToRotation2d().Degrees().to<double>()};
|
||||
ts.targetPoseEntry.Set(poseData, ReceiveTimestamp);
|
||||
ts.targetPoseEntry.Set(bestTarget.GetBestCameraToTarget(),
|
||||
ReceiveTimestamp);
|
||||
}
|
||||
|
||||
Eigen::Matrix<double, 3, 3, Eigen::RowMajor> intrinsics =
|
||||
|
||||
@@ -88,7 +88,9 @@ public class PacketSubscriber<T> implements AutoCloseable {
|
||||
|
||||
// TODO - i can see an argument for moving this logic all here instead of keeping in photoncamera
|
||||
public String getInterfaceUUID() {
|
||||
return subscriber.getTopic().getProperty("message_uuid");
|
||||
// ntcore hands us a JSON string with leading/trailing quotes - remove those
|
||||
var uuidStr = subscriber.getTopic().getProperty("message_uuid");
|
||||
return uuidStr.replace("\"", "");
|
||||
}
|
||||
|
||||
public List<PacketResult<T>> getAllChanges() {
|
||||
|
||||
@@ -18,15 +18,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include <frc/geometry/Transform3d.h>
|
||||
#include <networktables/BooleanTopic.h>
|
||||
#include <networktables/DoubleArrayTopic.h>
|
||||
#include <networktables/DoubleTopic.h>
|
||||
#include <networktables/IntegerTopic.h>
|
||||
#include <networktables/NetworkTable.h>
|
||||
#include <networktables/RawTopic.h>
|
||||
#include <networktables/StructTopic.h>
|
||||
|
||||
namespace photon {
|
||||
const std::string PhotonPipelineResult_TYPE_STRING =
|
||||
std::string{"photonstruct:PhotonPipelineResult:"} +
|
||||
std::string{SerdeType<PhotonPipelineResult>::GetSchemaHash()};
|
||||
|
||||
class NTTopicSet {
|
||||
public:
|
||||
std::shared_ptr<nt::NetworkTable> subTable;
|
||||
@@ -44,7 +51,7 @@ class NTTopicSet {
|
||||
nt::DoublePublisher targetPitchEntry;
|
||||
nt::DoublePublisher targetYawEntry;
|
||||
nt::DoublePublisher targetAreaEntry;
|
||||
nt::DoubleArrayPublisher targetPoseEntry;
|
||||
nt::StructPublisher<frc::Transform3d> targetPoseEntry;
|
||||
nt::DoublePublisher targetSkewEntry;
|
||||
|
||||
nt::DoublePublisher bestTargetPosX;
|
||||
@@ -60,8 +67,8 @@ class NTTopicSet {
|
||||
nt::PubSubOptions options;
|
||||
options.periodic = 0.01;
|
||||
options.sendAll = true;
|
||||
rawBytesEntry =
|
||||
subTable->GetRawTopic("rawBytes").Publish("rawBytes", options);
|
||||
rawBytesEntry = subTable->GetRawTopic("rawBytes")
|
||||
.Publish(PhotonPipelineResult_TYPE_STRING, options);
|
||||
|
||||
pipelineIndexPublisher =
|
||||
subTable->GetIntegerTopic("pipelineIndexState").Publish();
|
||||
@@ -80,7 +87,8 @@ class NTTopicSet {
|
||||
targetPitchEntry = subTable->GetDoubleTopic("targetPitch").Publish();
|
||||
targetAreaEntry = subTable->GetDoubleTopic("targetArea").Publish();
|
||||
targetYawEntry = subTable->GetDoubleTopic("targetYaw").Publish();
|
||||
targetPoseEntry = subTable->GetDoubleArrayTopic("targetPose").Publish();
|
||||
targetPoseEntry =
|
||||
subTable->GetStructTopic<frc::Transform3d>("targetPose").Publish();
|
||||
targetSkewEntry = subTable->GetDoubleTopic("targetSkew").Publish();
|
||||
|
||||
bestTargetPosX = subTable->GetDoubleTopic("targetPixelsX").Publish();
|
||||
|
||||
@@ -10,6 +10,10 @@ apply from: "${rootDir}/../shared/examples_common.gradle"
|
||||
|
||||
def ROBOT_MAIN_CLASS = "frc.robot.Main"
|
||||
|
||||
repositories {
|
||||
mavenLocal();
|
||||
}
|
||||
|
||||
wpi.maven.useDevelopment = true
|
||||
wpi.versions.wpilibVersion = "2024.3.2"
|
||||
wpi.versions.wpimathVersion = "2024.3.2"
|
||||
|
||||
Reference in New Issue
Block a user