mirror of
https://github.com/PhotonVision/photonvision
synced 2026-06-29 02:21:41 +00:00
Fix Aruco leak + remove old tag families (#1661)
- Remove 16h5 - Fix leak in ArucoPoseEstimatorPipe
This commit is contained in:
@@ -27,7 +27,7 @@ const interactiveCols = computed(() =>
|
||||
<pv-select
|
||||
v-model="currentPipelineSettings.tagFamily"
|
||||
label="Target family"
|
||||
:items="['AprilTag 36h11 (6.5in)', 'AprilTag 25h9 (6in)', 'AprilTag 16h5 (6in)']"
|
||||
:items="['AprilTag 36h11 (6.5in)', 'AprilTag 16h5 (6in)']"
|
||||
:select-cols="interactiveCols"
|
||||
@input="(value) => useCameraSettingsStore().changeCurrentPipelineSetting({ tagFamily: value }, false)"
|
||||
/>
|
||||
|
||||
@@ -27,7 +27,7 @@ const interactiveCols = computed(() =>
|
||||
<pv-select
|
||||
v-model="currentPipelineSettings.tagFamily"
|
||||
label="Target family"
|
||||
:items="['AprilTag Family 36h11', 'AprilTag Family 25h9', 'AprilTag Family 16h5']"
|
||||
:items="['AprilTag Family 36h11', 'AprilTag Family 16h5']"
|
||||
:select-cols="interactiveCols"
|
||||
@input="(value) => useCameraSettingsStore().changeCurrentPipelineSetting({ tagFamily: value }, false)"
|
||||
/>
|
||||
|
||||
@@ -11,8 +11,7 @@ export enum PipelineType {
|
||||
|
||||
export enum AprilTagFamily {
|
||||
Family36h11 = 0,
|
||||
Family25h9 = 1,
|
||||
Family16h5 = 2
|
||||
Family16h5 = 1
|
||||
}
|
||||
|
||||
export enum RobotOffsetPointMode {
|
||||
|
||||
@@ -19,13 +19,7 @@ package org.photonvision.vision.apriltag;
|
||||
|
||||
public enum AprilTagFamily {
|
||||
kTag36h11,
|
||||
kTag25h9,
|
||||
kTag16h5,
|
||||
kTagCircle21h7,
|
||||
kTagCircle49h12,
|
||||
kTagStandard41h12,
|
||||
kTagStandard52h13,
|
||||
kTagCustom48h11;
|
||||
kTag16h5;
|
||||
|
||||
public String getNativeName() {
|
||||
// We want to strip the leading kT and replace with "t"
|
||||
|
||||
@@ -101,6 +101,7 @@ public class ArucoDetectionPipe
|
||||
@Override
|
||||
public void setParams(ArucoDetectionPipeParams newParams) {
|
||||
if (this.params == null || !this.params.equals(newParams)) {
|
||||
System.out.println("Changing tag family to " + newParams.tagFamily);
|
||||
photonDetector
|
||||
.getDetector()
|
||||
.setDictionary(Objdetect.getPredefinedDictionary(newParams.tagFamily));
|
||||
|
||||
@@ -52,6 +52,9 @@ public class ArucoPoseEstimatorPipe
|
||||
// reprojection error of solvepnp estimations
|
||||
private final Mat reprojectionErrors = Mat.zeros(2, 1, CvType.CV_32F);
|
||||
|
||||
// Tag corner locations in object space - order matters for ippe_square
|
||||
MatOfPoint3f objectPoints = new MatOfPoint3f();
|
||||
|
||||
private final int kNaNRetries = 1;
|
||||
|
||||
private Translation3d tvecToTranslation3d(Mat mat) {
|
||||
@@ -81,7 +84,7 @@ public class ArucoPoseEstimatorPipe
|
||||
for (int i = 0; i < kNaNRetries + 1; i++) {
|
||||
// SolvePnP with SOLVEPNP_IPPE_SQUARE solver
|
||||
Calib3d.solvePnPGeneric(
|
||||
params.objectPoints,
|
||||
objectPoints,
|
||||
imagePoints,
|
||||
params.calibration.getCameraIntrinsicsMat(),
|
||||
params.calibration.getDistCoeffsMat(),
|
||||
@@ -116,6 +119,19 @@ public class ArucoPoseEstimatorPipe
|
||||
|
||||
@Override
|
||||
public void setParams(ArucoPoseEstimatorPipe.ArucoPoseEstimatorPipeParams newParams) {
|
||||
// exact equality check OK here, the number shouldn't change
|
||||
if (this.params == null || this.params.tagSize != newParams.tagSize) {
|
||||
var tagSize = newParams.tagSize;
|
||||
|
||||
// This order is relevant for SOLVEPNP_IPPE_SQUARE
|
||||
// The expected 2d correspondences with a tag facing the camera would be (BR, BL, TL, TR)
|
||||
objectPoints.fromArray(
|
||||
new Point3(-tagSize / 2, tagSize / 2, 0),
|
||||
new Point3(tagSize / 2, tagSize / 2, 0),
|
||||
new Point3(tagSize / 2, -tagSize / 2, 0),
|
||||
new Point3(-tagSize / 2, -tagSize / 2, 0));
|
||||
}
|
||||
|
||||
super.setParams(newParams);
|
||||
}
|
||||
|
||||
@@ -134,21 +150,12 @@ public class ArucoPoseEstimatorPipe
|
||||
public static class ArucoPoseEstimatorPipeParams {
|
||||
final CameraCalibrationCoefficients calibration;
|
||||
final double tagSize;
|
||||
|
||||
// object vertices defined by tag size
|
||||
final MatOfPoint3f objectPoints;
|
||||
|
||||
public ArucoPoseEstimatorPipeParams(CameraCalibrationCoefficients cal, double tagSize) {
|
||||
this.calibration = cal;
|
||||
this.tagSize = tagSize;
|
||||
|
||||
// This order is relevant for SOLVEPNP_IPPE_SQUARE
|
||||
// The expected 2d correspondences with a tag facing the camera would be (BR, BL, TL, TR)
|
||||
objectPoints =
|
||||
new MatOfPoint3f(
|
||||
new Point3(-tagSize / 2, tagSize / 2, 0),
|
||||
new Point3(tagSize / 2, tagSize / 2, 0),
|
||||
new Point3(tagSize / 2, -tagSize / 2, 0),
|
||||
new Point3(-tagSize / 2, -tagSize / 2, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,18 +94,11 @@ public class ArucoPipeline extends CVPipeline<CVPipelineResult, ArucoPipelineSet
|
||||
tagModel = TargetModel.kAprilTag36h11;
|
||||
yield Objdetect.DICT_APRILTAG_36h11;
|
||||
}
|
||||
case kTag25h9 -> Objdetect.DICT_APRILTAG_25h9;
|
||||
// TODO: explicitly drop support for these
|
||||
case kTag16h5,
|
||||
kTagCircle21h7,
|
||||
kTagCircle49h12,
|
||||
kTagCustom48h11,
|
||||
kTagStandard41h12,
|
||||
kTagStandard52h13 -> {
|
||||
case kTag16h5 -> {
|
||||
// 2024 tag, 6.5in
|
||||
tagWidth = Units.inchesToMeters(6.5);
|
||||
tagModel = TargetModel.kAprilTag36h11;
|
||||
yield Objdetect.DICT_APRILTAG_36h11;
|
||||
tagWidth = Units.inchesToMeters(6);
|
||||
tagModel = TargetModel.kAprilTag16h5;
|
||||
yield Objdetect.DICT_APRILTAG_16h5;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -89,8 +89,12 @@ public class VisionModuleChangeSubscriber extends DataChangeSubscriber {
|
||||
var newPropValue = change.getNewPropValue();
|
||||
var currentSettings = change.getCurrentSettings();
|
||||
var originContext = change.getOriginContext();
|
||||
boolean handled = true;
|
||||
switch (propName) {
|
||||
case "pipelineName" -> newPipelineNickname((String) newPropValue);
|
||||
case "pipelineName" -> {
|
||||
newPipelineNickname((String) newPropValue);
|
||||
continue;
|
||||
}
|
||||
case "newPipelineInfo" -> newPipelineInfo((Pair<String, PipelineType>) newPropValue);
|
||||
case "deleteCurrPipeline" -> deleteCurrPipeline();
|
||||
case "changePipeline" -> changePipeline((Integer) newPropValue);
|
||||
@@ -116,6 +120,7 @@ public class VisionModuleChangeSubscriber extends DataChangeSubscriber {
|
||||
parentModule.saveAndBroadcastAll();
|
||||
}
|
||||
case "isDriverMode" -> parentModule.setDriverMode((Boolean) newPropValue);
|
||||
default -> handled = false;
|
||||
}
|
||||
|
||||
// special case for camera settables
|
||||
@@ -133,21 +138,24 @@ public class VisionModuleChangeSubscriber extends DataChangeSubscriber {
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
setProperty(currentSettings, propName, newPropValue);
|
||||
logger.trace("Set prop " + propName + " to value " + newPropValue);
|
||||
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
logger.error(
|
||||
"Could not set prop "
|
||||
+ propName
|
||||
+ " with value "
|
||||
+ newPropValue
|
||||
+ " on "
|
||||
+ currentSettings
|
||||
+ " | "
|
||||
+ e.getClass().getSimpleName());
|
||||
} catch (Exception e) {
|
||||
logger.error("Unknown exception when setting PSC prop!", e);
|
||||
if (!handled) {
|
||||
try {
|
||||
setProperty(currentSettings, propName, newPropValue);
|
||||
logger.trace("Set prop " + propName + " to value " + newPropValue);
|
||||
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
logger.error(
|
||||
"Could not set prop "
|
||||
+ propName
|
||||
+ " with value "
|
||||
+ newPropValue
|
||||
+ " on "
|
||||
+ currentSettings
|
||||
+ " | "
|
||||
+ e.getClass().getSimpleName(),
|
||||
e);
|
||||
} catch (Exception e) {
|
||||
logger.error("Unknown exception when setting PSC prop!", e);
|
||||
}
|
||||
}
|
||||
|
||||
parentModule.saveAndBroadcastSelective(originContext, propName, newPropValue);
|
||||
|
||||
Reference in New Issue
Block a user