photonlibpy 2025.0.0b4__py3-none-any.whl → 2025.0.0b6__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- photonlibpy/estimation/openCVHelp.py +5 -1
- photonlibpy/generated/PhotonPipelineResultSerde.py +1 -3
- photonlibpy/networktables/NTTopicSet.py +5 -4
- photonlibpy/photonCamera.py +34 -35
- photonlibpy/py.typed +1 -0
- photonlibpy/simulation/photonCameraSim.py +38 -36
- photonlibpy/simulation/simCameraProperties.py +9 -8
- photonlibpy/simulation/visionSystemSim.py +3 -2
- photonlibpy/version.py +2 -2
- {photonlibpy-2025.0.0b4.dist-info → photonlibpy-2025.0.0b6.dist-info}/METADATA +2 -2
- {photonlibpy-2025.0.0b4.dist-info → photonlibpy-2025.0.0b6.dist-info}/RECORD +13 -12
- {photonlibpy-2025.0.0b4.dist-info → photonlibpy-2025.0.0b6.dist-info}/WHEEL +1 -1
- {photonlibpy-2025.0.0b4.dist-info → photonlibpy-2025.0.0b6.dist-info}/top_level.txt +0 -0
@@ -1,3 +1,4 @@
|
|
1
|
+
import logging
|
1
2
|
import math
|
2
3
|
from typing import Any
|
3
4
|
|
@@ -11,6 +12,8 @@ from .rotTrlTransform3d import RotTrlTransform3d
|
|
11
12
|
NWU_TO_EDN = Rotation3d(np.array([[0, -1, 0], [0, 0, -1], [1, 0, 0]]))
|
12
13
|
EDN_TO_NWU = Rotation3d(np.array([[0, 0, 1], [-1, 0, 0], [0, -1, 0]]))
|
13
14
|
|
15
|
+
logger = logging.getLogger(__name__)
|
16
|
+
|
14
17
|
|
15
18
|
class OpenCVHelp:
|
16
19
|
@staticmethod
|
@@ -243,7 +246,7 @@ class OpenCVHelp:
|
|
243
246
|
|
244
247
|
# solvePnP failed
|
245
248
|
if reprojectionError is None or math.isnan(reprojectionError[0, 0]):
|
246
|
-
|
249
|
+
logger.error("SolvePNP_Square failed!")
|
247
250
|
return None
|
248
251
|
|
249
252
|
if alt:
|
@@ -303,6 +306,7 @@ class OpenCVHelp:
|
|
303
306
|
)
|
304
307
|
|
305
308
|
if math.isnan(error):
|
309
|
+
logger.error("SolvePNP_SQPNP failed!")
|
306
310
|
return None
|
307
311
|
|
308
312
|
# We have no alternative so set it to best as well
|
@@ -42,9 +42,7 @@ class PhotonPipelineResultSerde:
|
|
42
42
|
ret = Packet()
|
43
43
|
|
44
44
|
# metadata is of non-intrinsic type PhotonPipelineMetadata
|
45
|
-
ret.encodeBytes(
|
46
|
-
PhotonPipelineMetadata.photonStruct.pack(value.metadata).getData()
|
47
|
-
)
|
45
|
+
ret.encodeBytes(PhotonPipelineMetadata.photonStruct.pack(value.metadata).getData())
|
48
46
|
|
49
47
|
# targets is a custom VLA!
|
50
48
|
ret.encodeList(value.targets, PhotonTrackedTarget.photonStruct)
|
@@ -17,10 +17,11 @@ class NTTopicSet:
|
|
17
17
|
different for sim vs. real camera
|
18
18
|
"""
|
19
19
|
|
20
|
-
def __init__(
|
21
|
-
|
22
|
-
|
23
|
-
|
20
|
+
def __init__(
|
21
|
+
self,
|
22
|
+
ntSubTable: nt.NetworkTable,
|
23
|
+
) -> None:
|
24
|
+
self.subTable = ntSubTable
|
24
25
|
|
25
26
|
def updateEntries(self) -> None:
|
26
27
|
options = nt.PubSubOptions()
|
photonlibpy/photonCamera.py
CHANGED
@@ -298,43 +298,42 @@ class PhotonCamera:
|
|
298
298
|
|
299
299
|
# Check mdef UUID
|
300
300
|
localUUID = PhotonPipelineResult.photonStruct.MESSAGE_VERSION
|
301
|
-
remoteUUID =
|
301
|
+
remoteUUID = self._rawBytesEntry.getTopic().getProperty("message_uuid")
|
302
302
|
|
303
|
-
if
|
303
|
+
if remoteUUID is None:
|
304
304
|
wpilib.reportWarning(
|
305
305
|
f"PhotonVision coprocessor at path {self._path} has not reported a message interface UUID - is your coprocessor's camera started?",
|
306
306
|
True,
|
307
307
|
)
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
raise Exception(errText)
|
308
|
+
else:
|
309
|
+
# ntcore hands us a JSON string with leading/trailing quotes - remove those
|
310
|
+
remoteUUID = str(remoteUUID).replace('"', "")
|
311
|
+
|
312
|
+
if localUUID != remoteUUID:
|
313
|
+
# Verified version mismatch
|
314
|
+
|
315
|
+
bfw = """
|
316
|
+
\n\n\n
|
317
|
+
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
318
|
+
>>> !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
319
|
+
>>>
|
320
|
+
>>> You are running an incompatible version
|
321
|
+
>>> of PhotonVision on your coprocessor!
|
322
|
+
>>>
|
323
|
+
>>> This is neither tested nor supported.
|
324
|
+
>>> You MUST update PhotonVision,
|
325
|
+
>>> PhotonLib, or both.
|
326
|
+
>>>
|
327
|
+
>>> Your code will now crash.
|
328
|
+
>>> We hope your day gets better.
|
329
|
+
>>>
|
330
|
+
>>> !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
331
|
+
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
332
|
+
\n\n
|
333
|
+
"""
|
334
|
+
|
335
|
+
wpilib.reportWarning(bfw)
|
336
|
+
|
337
|
+
errText = f"Photonlibpy version {PHOTONLIB_VERSION} (With message UUID {localUUID}) does not match coprocessor version {versionString} (with message UUID {remoteUUID}). Please install photonlibpy version {versionString}, or update your coprocessor to {PHOTONLIB_VERSION}."
|
338
|
+
wpilib.reportError(errText, True)
|
339
|
+
raise Exception(errText)
|
photonlibpy/py.typed
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
|
@@ -60,11 +60,10 @@ class PhotonCameraSim:
|
|
60
60
|
self.videoSimRawEnabled: bool = False
|
61
61
|
self.videoSimWireframeEnabled: bool = False
|
62
62
|
self.videoSimWireframeResolution: float = 0.1
|
63
|
-
|
64
|
-
|
65
|
-
)
|
63
|
+
# TODO switch this back to default True when the functionality is enabled
|
64
|
+
self.videoSimProcEnabled: bool = False
|
66
65
|
self.heartbeatCounter: int = 0
|
67
|
-
self.nextNtEntryTime =
|
66
|
+
self.nextNtEntryTime = wpilib.Timer.getFPGATimestamp()
|
68
67
|
self.tagLayout = AprilTagFieldLayout.loadField(AprilTagField.k2024Crescendo)
|
69
68
|
|
70
69
|
self.cam = camera
|
@@ -95,7 +94,7 @@ class PhotonCameraSim:
|
|
95
94
|
(self.prop.getResWidth(), self.prop.getResHeight())
|
96
95
|
)
|
97
96
|
|
98
|
-
self.ts = NTTopicSet(
|
97
|
+
self.ts = NTTopicSet(self.cam._cameraTable)
|
99
98
|
self.ts.updateEntries()
|
100
99
|
|
101
100
|
# Handle this last explicitly for this function signature because the other constructor is called in the initialiser list
|
@@ -173,20 +172,20 @@ class PhotonCameraSim:
|
|
173
172
|
def consumeNextEntryTime(self) -> float | None:
|
174
173
|
"""Determine if this camera should process a new frame based on performance metrics and the time
|
175
174
|
since the last update. This returns an Optional which is either empty if no update should occur
|
176
|
-
or a
|
175
|
+
or a float of the timestamp in seconds of when the frame which should be received by NT. If
|
177
176
|
a timestamp is returned, the last frame update time becomes that timestamp.
|
178
177
|
|
179
|
-
:returns: Optional
|
178
|
+
:returns: Optional float which is empty while blocked or the NT entry timestamp in seconds if
|
180
179
|
ready
|
181
180
|
"""
|
182
181
|
# check if this camera is ready for another frame update
|
183
|
-
now =
|
184
|
-
timestamp = 0
|
182
|
+
now = wpilib.Timer.getFPGATimestamp()
|
183
|
+
timestamp = 0.0
|
185
184
|
iter = 0
|
186
185
|
# prepare next latest update
|
187
186
|
while now >= self.nextNtEntryTime:
|
188
|
-
timestamp =
|
189
|
-
frameTime =
|
187
|
+
timestamp = self.nextNtEntryTime
|
188
|
+
frameTime = self.prop.estSecUntilNextFrame()
|
190
189
|
self.nextNtEntryTime += frameTime
|
191
190
|
|
192
191
|
# if frame time is very small, avoid blocking
|
@@ -432,7 +431,9 @@ class PhotonCameraSim:
|
|
432
431
|
)
|
433
432
|
|
434
433
|
def submitProcessedFrame(
|
435
|
-
self,
|
434
|
+
self,
|
435
|
+
result: PhotonPipelineResult,
|
436
|
+
receiveTimestamp_us: float | None = None,
|
436
437
|
):
|
437
438
|
"""Simulate one processed frame of vision data, putting one result to NT. Image capture timestamp
|
438
439
|
overrides :meth:`.PhotonPipelineResult.getTimestampSeconds` for more
|
@@ -441,44 +442,45 @@ class PhotonCameraSim:
|
|
441
442
|
:param result: The pipeline result to submit
|
442
443
|
:param receiveTimestamp: The (sim) timestamp when this result was read by NT in microseconds. If not passed image capture time is assumed be (current time - latency)
|
443
444
|
"""
|
444
|
-
if
|
445
|
-
|
446
|
-
|
445
|
+
if receiveTimestamp_us is None:
|
446
|
+
receiveTimestamp_us = wpilib.Timer.getFPGATimestamp() * 1e6
|
447
|
+
receiveTimestamp_us = int(receiveTimestamp_us)
|
447
448
|
|
448
|
-
self.ts.latencyMillisEntry.set(result.getLatencyMillis(),
|
449
|
+
self.ts.latencyMillisEntry.set(result.getLatencyMillis(), receiveTimestamp_us)
|
449
450
|
|
450
451
|
newPacket = PhotonPipelineResult.photonStruct.pack(result)
|
451
|
-
self.ts.rawBytesEntry.set(newPacket.getData(),
|
452
|
+
self.ts.rawBytesEntry.set(newPacket.getData(), receiveTimestamp_us)
|
452
453
|
|
453
454
|
hasTargets = result.hasTargets()
|
454
|
-
self.ts.hasTargetEntry.set(hasTargets,
|
455
|
+
self.ts.hasTargetEntry.set(hasTargets, receiveTimestamp_us)
|
455
456
|
if not hasTargets:
|
456
|
-
self.ts.targetPitchEntry.set(0.0,
|
457
|
-
self.ts.targetYawEntry.set(0.0,
|
458
|
-
self.ts.targetAreaEntry.set(0.0,
|
459
|
-
self.ts.targetPoseEntry.set(Transform3d(),
|
460
|
-
self.ts.targetSkewEntry.set(0.0,
|
457
|
+
self.ts.targetPitchEntry.set(0.0, receiveTimestamp_us)
|
458
|
+
self.ts.targetYawEntry.set(0.0, receiveTimestamp_us)
|
459
|
+
self.ts.targetAreaEntry.set(0.0, receiveTimestamp_us)
|
460
|
+
self.ts.targetPoseEntry.set(Transform3d(), receiveTimestamp_us)
|
461
|
+
self.ts.targetSkewEntry.set(0.0, receiveTimestamp_us)
|
461
462
|
else:
|
462
463
|
bestTarget = result.getBestTarget()
|
463
464
|
assert bestTarget
|
464
465
|
|
465
|
-
self.ts.targetPitchEntry.set(bestTarget.getPitch(),
|
466
|
-
self.ts.targetYawEntry.set(bestTarget.getYaw(),
|
467
|
-
self.ts.targetAreaEntry.set(bestTarget.getArea(),
|
468
|
-
self.ts.targetSkewEntry.set(bestTarget.getSkew(),
|
466
|
+
self.ts.targetPitchEntry.set(bestTarget.getPitch(), receiveTimestamp_us)
|
467
|
+
self.ts.targetYawEntry.set(bestTarget.getYaw(), receiveTimestamp_us)
|
468
|
+
self.ts.targetAreaEntry.set(bestTarget.getArea(), receiveTimestamp_us)
|
469
|
+
self.ts.targetSkewEntry.set(bestTarget.getSkew(), receiveTimestamp_us)
|
469
470
|
|
470
471
|
self.ts.targetPoseEntry.set(
|
471
|
-
bestTarget.getBestCameraToTarget(),
|
472
|
+
bestTarget.getBestCameraToTarget(), receiveTimestamp_us
|
472
473
|
)
|
473
474
|
|
474
|
-
|
475
|
-
|
476
|
-
|
475
|
+
intrinsics = self.prop.getIntrinsics()
|
476
|
+
intrinsicsView = intrinsics.flatten().tolist()
|
477
|
+
self.ts.cameraIntrinsicsPublisher.set(intrinsicsView, receiveTimestamp_us)
|
477
478
|
|
478
|
-
|
479
|
-
|
480
|
-
|
479
|
+
distortion = self.prop.getDistCoeffs()
|
480
|
+
distortionView = distortion.flatten().tolist()
|
481
|
+
self.ts.cameraDistortionPublisher.set(distortionView, receiveTimestamp_us)
|
481
482
|
|
482
|
-
|
483
|
+
self.ts.heartbeatPublisher.set(self.heartbeatCounter, receiveTimestamp_us)
|
484
|
+
self.heartbeatCounter += 1
|
483
485
|
|
484
|
-
|
486
|
+
self.ts.subTable.getInstance().flush()
|
@@ -4,11 +4,14 @@ import typing
|
|
4
4
|
|
5
5
|
import cv2 as cv
|
6
6
|
import numpy as np
|
7
|
+
import numpy.typing as npt
|
7
8
|
from wpimath.geometry import Rotation2d, Rotation3d, Translation3d
|
8
9
|
from wpimath.units import hertz, seconds
|
9
10
|
|
10
11
|
from ..estimation import RotTrlTransform3d
|
11
12
|
|
13
|
+
logger = logging.getLogger(__name__)
|
14
|
+
|
12
15
|
|
13
16
|
class SimCameraProperties:
|
14
17
|
"""Calibration and performance values for this camera.
|
@@ -29,8 +32,8 @@ class SimCameraProperties:
|
|
29
32
|
"""Default constructor which is the same as {@link #PERFECT_90DEG}"""
|
30
33
|
self.resWidth: int = -1
|
31
34
|
self.resHeight: int = -1
|
32
|
-
self.camIntrinsics: np.
|
33
|
-
self.distCoeffs: np.
|
35
|
+
self.camIntrinsics: npt.NDArray[np.floating] = np.zeros((3, 3)) # [3,3]
|
36
|
+
self.distCoeffs: npt.NDArray[np.floating] = np.zeros((8, 1)) # [8,1]
|
34
37
|
self.avgErrorPx: float = 0.0
|
35
38
|
self.errorStdDevPx: float = 0.0
|
36
39
|
self.frameSpeed: seconds = 0.0
|
@@ -46,7 +49,7 @@ class SimCameraProperties:
|
|
46
49
|
) -> None:
|
47
50
|
if fovDiag.degrees() < 1.0 or fovDiag.degrees() > 179.0:
|
48
51
|
fovDiag = Rotation2d.fromDegrees(max(min(fovDiag.degrees(), 179.0), 1.0))
|
49
|
-
|
52
|
+
logger.error("Requested invalid FOV! Clamping between (1, 179) degrees...")
|
50
53
|
|
51
54
|
resDiag = math.sqrt(width * width + height * height)
|
52
55
|
diagRatio = math.tan(fovDiag.radians() / 2.0)
|
@@ -78,7 +81,6 @@ class SimCameraProperties:
|
|
78
81
|
newCamIntrinsics: np.ndarray,
|
79
82
|
newDistCoeffs: np.ndarray,
|
80
83
|
) -> None:
|
81
|
-
|
82
84
|
self.resWidth = width
|
83
85
|
self.resHeight = height
|
84
86
|
self.camIntrinsics = newCamIntrinsics
|
@@ -171,10 +173,10 @@ class SimCameraProperties:
|
|
171
173
|
def getAspectRatio(self) -> float:
|
172
174
|
return 1.0 * self.resWidth / self.resHeight
|
173
175
|
|
174
|
-
def getIntrinsics(self) -> np.
|
176
|
+
def getIntrinsics(self) -> npt.NDArray[np.floating]:
|
175
177
|
return self.camIntrinsics
|
176
178
|
|
177
|
-
def getDistCoeffs(self) -> np.
|
179
|
+
def getDistCoeffs(self) -> npt.NDArray[np.floating]:
|
178
180
|
return self.distCoeffs
|
179
181
|
|
180
182
|
def getFPS(self) -> hertz:
|
@@ -353,7 +355,6 @@ class SimCameraProperties:
|
|
353
355
|
|
354
356
|
# find intersections
|
355
357
|
for i, normal in enumerate(self.viewplanes):
|
356
|
-
|
357
358
|
# // we want to know the value of t when the line intercepts this plane
|
358
359
|
# // parametrized: v = t * ab + a, where v lies on the plane
|
359
360
|
# // we can find the projection of a onto the plane normal
|
@@ -465,7 +466,7 @@ class SimCameraProperties:
|
|
465
466
|
|
466
467
|
def estSecUntilNextFrame(self) -> seconds:
|
467
468
|
"""
|
468
|
-
:returns: Estimate how long until the next frame should be processed in
|
469
|
+
:returns: Estimate how long until the next frame should be processed in seconds
|
469
470
|
"""
|
470
471
|
# // exceptional processing latency blocks the next frame
|
471
472
|
return self.frameSpeed + max(0.0, self.estLatency() - self.frameSpeed)
|
@@ -305,7 +305,7 @@ class VisionSystemSim:
|
|
305
305
|
timestampNt = optTimestamp
|
306
306
|
latency = camSim.prop.estLatency()
|
307
307
|
# the image capture timestamp in seconds of this result
|
308
|
-
timestampCapture = timestampNt
|
308
|
+
timestampCapture = timestampNt - latency
|
309
309
|
|
310
310
|
# use camera pose from the image capture timestamp
|
311
311
|
lateRobotPose = self.getRobotPose(timestampCapture)
|
@@ -318,7 +318,8 @@ class VisionSystemSim:
|
|
318
318
|
# process a PhotonPipelineResult with visible targets
|
319
319
|
camResult = camSim.process(latency, lateCameraPose, allTargets)
|
320
320
|
# publish this info to NT at estimated timestamp of receive
|
321
|
-
|
321
|
+
# needs a timestamp in microseconds
|
322
|
+
camSim.submitProcessedFrame(camResult, timestampNt * 1.0e6)
|
322
323
|
# display debug results
|
323
324
|
for tgt in camResult.getTargets():
|
324
325
|
trf = tgt.getBestCameraToTarget()
|
photonlibpy/version.py
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
PHOTONLIB_VERSION="v2025.0.0.beta.
|
2
|
-
PHOTONVISION_VERSION="v2025.0.0-beta-
|
1
|
+
PHOTONLIB_VERSION="v2025.0.0.beta.6"
|
2
|
+
PHOTONVISION_VERSION="v2025.0.0-beta-6"
|
@@ -1,7 +1,7 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: photonlibpy
|
3
|
-
Version: 2025.0.
|
4
|
-
Summary: Pure-python implementation of PhotonLib for interfacing with PhotonVision on coprocessors. Implemented with PhotonVision version v2025.0.0-beta-
|
3
|
+
Version: 2025.0.0b6
|
4
|
+
Summary: Pure-python implementation of PhotonLib for interfacing with PhotonVision on coprocessors. Implemented with PhotonVision version v2025.0.0-beta-6 .
|
5
5
|
Home-page: https://photonvision.org
|
6
6
|
Author: Photonvision Development Team
|
7
7
|
Description-Content-Type: text/markdown
|
@@ -1,36 +1,37 @@
|
|
1
1
|
photonlibpy/__init__.py,sha256=WW1OGrrcNXwwxaHSZlkxmhH2GYiQIHHxSxGVTJZhZbY,1136
|
2
2
|
photonlibpy/estimatedRobotPose.py,sha256=X7wF9xdPXGKSVy0MY0qrWZJOEbuZPd721lYp0KXKlP0,1603
|
3
3
|
photonlibpy/packet.py,sha256=5YomViVFwOljL2FGOetWM9FbPc_yCQ15ylzkYlgLIs8,9724
|
4
|
-
photonlibpy/photonCamera.py,sha256=
|
4
|
+
photonlibpy/photonCamera.py,sha256=ENBHp959it4aLnFtV66rHoAIYCvK4bTflZMrGSCwnZ8,12905
|
5
5
|
photonlibpy/photonPoseEstimator.py,sha256=2iMqxPFsQHTsq95yv-WCSv1a6wXNcHPqOyMc4Bu6IG0,12584
|
6
|
-
photonlibpy/
|
6
|
+
photonlibpy/py.typed,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
7
|
+
photonlibpy/version.py,sha256=YY1V7rjUvCOJd1hvNe4-JTENvAM9Hze8avCtEHLsp_8,77
|
7
8
|
photonlibpy/estimation/__init__.py,sha256=pZ-d6fN1DJvT-lRl4FfIos5HAvlzmetIOrGIinrdv7k,223
|
8
9
|
photonlibpy/estimation/cameraTargetRelation.py,sha256=i7DPBXtkZve4ToXQscEIe-5F1oGQ1Qmf5QBaE__EeMQ,1158
|
9
|
-
photonlibpy/estimation/openCVHelp.py,sha256=
|
10
|
+
photonlibpy/estimation/openCVHelp.py,sha256=O1dV7v7RHSyw7l5L0QXbal6t9K7iyvEG76tG-t4AFVg,12388
|
10
11
|
photonlibpy/estimation/rotTrlTransform3d.py,sha256=oRYk4V1XF7guNxefJsCPcBWPIkKZl0HYD_Gs86wwToE,2671
|
11
12
|
photonlibpy/estimation/targetModel.py,sha256=fIhkf0-_Sfv-KhYEBnhFWMF4Xu84FfF6B-KUEsuuGjQ,6459
|
12
13
|
photonlibpy/estimation/visionEstimation.py,sha256=Q4KWdLCV1H0wJUJCzG7OYNhVmk2jR1iPUmX_PFylLdA,4174
|
13
14
|
photonlibpy/generated/MultiTargetPNPResultSerde.py,sha256=CzsCosHUnzxAoSC_sSAqpsXsDp54KW-BClnIXdzfMPc,2506
|
14
15
|
photonlibpy/generated/PhotonPipelineMetadataSerde.py,sha256=9pq5XUEDEoRowCd7sRnuGV7xtugu5HZCRrnwqZG2xXc,2887
|
15
|
-
photonlibpy/generated/PhotonPipelineResultSerde.py,sha256=
|
16
|
+
photonlibpy/generated/PhotonPipelineResultSerde.py,sha256=8_YhW1icdhPOx5eAqwKadvnR29NABmhHr6ERAWK8wEo,3115
|
16
17
|
photonlibpy/generated/PhotonTrackedTargetSerde.py,sha256=-6vKir_ABDVBGbg8ktM48IKm_nBMFBbiyuZLiO_fP9U,4437
|
17
18
|
photonlibpy/generated/PnpResultSerde.py,sha256=YoTKdQ51oSdxC-7Poy6hunL0-zkMKvP5uedqaHWPudY,2693
|
18
19
|
photonlibpy/generated/TargetCornerSerde.py,sha256=kziD_rQIwyhzPfgOaDgn-3d87tvtXiAYbBjzu76biYU,2190
|
19
20
|
photonlibpy/generated/__init__.py,sha256=mElM8M88---wxTWO-SRqIJ4EfxN0fdIUwZBZ-UIGuRw,428
|
20
|
-
photonlibpy/networktables/NTTopicSet.py,sha256=
|
21
|
+
photonlibpy/networktables/NTTopicSet.py,sha256=29wPgXcuqT-u72-YXwSjRHWhECNzU8eDsexcqlA8KQ0,2967
|
21
22
|
photonlibpy/networktables/__init__.py,sha256=o_LxTdyIylAszMy_zhUtTkXHyu6jqxccccj78d44OrI,35
|
22
23
|
photonlibpy/simulation/__init__.py,sha256=HKJV02of5d8bOnuI7syLzSYtOYge7XUrHSaLvawh99M,227
|
23
|
-
photonlibpy/simulation/photonCameraSim.py,sha256=
|
24
|
-
photonlibpy/simulation/simCameraProperties.py,sha256=
|
24
|
+
photonlibpy/simulation/photonCameraSim.py,sha256=8ELLcOXUtDftV_OYzGG03wigANimJs2SehV-fluWy3k,19907
|
25
|
+
photonlibpy/simulation/simCameraProperties.py,sha256=ODVxnylF8zw9HZSbw0PzG_OEtUo9ChRo-G_iEgADOCg,27195
|
25
26
|
photonlibpy/simulation/videoSimUtil.py,sha256=xMuTvJ2Jx9IoQqmAJi_zUm06MdEwhVpIz9OyzYQp0k4,29
|
26
|
-
photonlibpy/simulation/visionSystemSim.py,sha256=
|
27
|
+
photonlibpy/simulation/visionSystemSim.py,sha256=GmKs0d32WE8B020YEWnj-0dQuCnVv1ScGdcFl1fOsKo,13835
|
27
28
|
photonlibpy/simulation/visionTargetSim.py,sha256=FH85fKE4NntowUvssfgZ1KlE-I_3Z-QuAgb2bFqvfdY,2219
|
28
29
|
photonlibpy/targeting/TargetCorner.py,sha256=ouKj3E5uD76OZSNHHuSDzKOY65a8HqtcOsuejH-MVsU,276
|
29
30
|
photonlibpy/targeting/__init__.py,sha256=YzINSpq6A0cjr-yAQcFqHoiYdLGKPFXThlVYlMjY11w,295
|
30
31
|
photonlibpy/targeting/multiTargetPNPResult.py,sha256=Y9rweHtMzoCZ6mv6F8CutQi2Thq5pHN0ydBWvTCsOwY,806
|
31
32
|
photonlibpy/targeting/photonPipelineResult.py,sha256=MbaSyHZTJpoKTtLOZztpSGSt9xWWFqhzgwj8medObVA,2732
|
32
33
|
photonlibpy/targeting/photonTrackedTarget.py,sha256=zCoFp32hX-3GmBYEmsYBQieBoMzXtP2F_55_q0zPOXA,1956
|
33
|
-
photonlibpy-2025.0.
|
34
|
-
photonlibpy-2025.0.
|
35
|
-
photonlibpy-2025.0.
|
36
|
-
photonlibpy-2025.0.
|
34
|
+
photonlibpy-2025.0.0b6.dist-info/METADATA,sha256=luAf2JXb3eVzyqShMDsi_X0ulP9SRGVEsV1KpmYfo2w,689
|
35
|
+
photonlibpy-2025.0.0b6.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
|
36
|
+
photonlibpy-2025.0.0b6.dist-info/top_level.txt,sha256=T8Xc6U6he2VjKUAca6zawSkHdUZuLanxYIc4nxw2ctc,12
|
37
|
+
photonlibpy-2025.0.0b6.dist-info/RECORD,,
|
File without changes
|