Skip to content

Commit

Permalink
review comments pt 1
Browse files Browse the repository at this point in the history
  • Loading branch information
gerth2 committed Dec 12, 2023
1 parent 4be9004 commit 9364d21
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 97 deletions.
14 changes: 9 additions & 5 deletions .github/workflows/python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,22 @@ jobs:

steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v3

- name: Set up Python
uses: actions/setup-python@v2
uses: actions/setup-python@v5
with:
python-version: 3.8 # CHose earliest that robotpy supports

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install setuptools wheel
pip install robotpy
pip install setuptools wheel pytest
- name: Run Unit Tests
working-directory: ./photon-lib/py
run: |
pytest
- name: Build wheel
working-directory: ./photon-lib/py
Expand All @@ -37,7 +41,7 @@ jobs:
python setup.py sdist bdist_wheel
- name: Upload artifacts
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@master
with:
name: dist
path: ./photon-lib/py/dist/
Expand Down
3 changes: 2 additions & 1 deletion photon-lib/py/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
photonlibpy.egg-info/
dist/
build/
build/
.eggs/
33 changes: 14 additions & 19 deletions photon-lib/py/photonlibpy/multiTargetPNPResult.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
from dataclasses import dataclass
from wpimath.geometry import Transform3d
from photonlibpy.packet import Packet

@dataclass
class PNPResult:

_NUM_BYTES_IN_FLOAT = 8
PACK_SIZE_BYTES = 1 + (_NUM_BYTES_IN_FLOAT * 7 * 2) + (_NUM_BYTES_IN_FLOAT* 3)

def __init__(self):
self.isPresent = False
self.best = Transform3d()
self.alt = Transform3d()
self.ambiguity = 0.0
self.bestReprojError = 0.0
self.altReprojError = 0.0
isPresent:bool = False
best:Transform3d = Transform3d()
alt:Transform3d = Transform3d()
ambiguity:float = 0.0
bestReprojError:float = 0.0
altReprojError:float = 0.0

def createFromPacket(self, packet:Packet) -> Packet:
self.isPresent = packet.decodeBoolean()
Expand All @@ -23,29 +24,23 @@ def createFromPacket(self, packet:Packet) -> Packet:
self.ambiguity = packet.decodeDouble()
return packet

def __str__(self) -> str:
return f"PNPResult {{isPresent={self.isPresent}, best={self.best}, bestReprojError={self.bestReprojError}, alt={self.alt}, altReprojError={self.altReprojError}, ambiguity={self.ambiguity}}}"


@dataclass
class MultiTargetPNPResult:

MAX_IDS = 32
_MAX_IDS = 32
# pnpresult + MAX_IDS possible targets (arbitrary upper limit that should never be hit, ideally)
PACK_SIZE_BYTES = PNPResult.PACK_SIZE_BYTES + (1 * MAX_IDS)
_PACK_SIZE_BYTES = PNPResult.PACK_SIZE_BYTES + (1 * _MAX_IDS)

def __init__(self):
self.estimatedPose = PNPResult()
self.fiducialIDsUsed = []
estimatedPose:PNPResult = PNPResult()
fiducialIDsUsed:list[int] = []

def createFromPacket(self, packet:Packet) -> Packet:
self.estimatedPose = PNPResult()
self.estimatedPose.createFromPacket(packet)
self.fiducialIDsUsed = []
for _ in range(MultiTargetPNPResult.MAX_IDS):
for _ in range(MultiTargetPNPResult._MAX_IDS):
fidId = packet.decode16()
if(fidId >= 0):
self.fiducialIDsUsed.append(fidId)
return packet

def __str__(self) -> str:
return f"MultiTargetPNPResult {{estimatedPose={self.estimatedPose},fiducialIDsUsed={self.fiducialIDsUsed}}}"
99 changes: 54 additions & 45 deletions photon-lib/py/photonlibpy/packet.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,21 @@

class Packet:

"""
* Constructs an empty packet.
*
* @param self.size The self.size of the packet buffer.
"""

def __init__(self, data:list[int]):
"""
* Constructs an empty packet.
*
* @param self.size The self.size of the packet buffer.
"""
self.packetData = data
self.size = len(data)
self.readPos = 0
self.outOfBytes = False


""" Clears the packet and resets the read and write positions."""
def clear(self):
""" Clears the packet and resets the read and write positions."""
self.packetData = [0]*self.size
self.readPos = 0
self.outOfBytes = False
Expand Down Expand Up @@ -45,21 +46,20 @@ def _getNextByte(self) -> int:

return retVal

"""
* Returns the packet data.
*
* @return The packet data.
"""
def getData(self) -> list[int]:
def getData(self) -> list[int]:
"""
* Returns the packet data.
*
* @return The packet data.
"""
return self.packetData


"""
* Sets the packet data.
*
* @param data The packet data.
"""
def setData(self, data:list[int]):
"""
* Sets the packet data.
*
* @param data The packet data.
"""
self.clear()
self.packetData = data
self.size = len(self.packetData)
Expand All @@ -76,55 +76,64 @@ def _decodeGeneric(self, unpackFormat, numBytes):

return value


"""
* Returns a single decoded byte from the packet.
*
* @return A decoded byte from the packet.
"""
def decode8(self) -> int:
"""
* Returns a single decoded byte from the packet.
*
* @return A decoded byte from the packet.
"""
return self._decodeGeneric(">b", 1)

"""
* Returns a single decoded byte from the packet.
*
* @return A decoded byte from the packet.
"""
def decode16(self) -> int:
"""
* Returns a single decoded byte from the packet.
*
* @return A decoded byte from the packet.
"""
return self._decodeGeneric(">h", 2)


"""
* Returns a decoded int (32 bytes) from the packet.
*
* @return A decoded int from the packet.
"""
def decode32(self) -> int:
"""
* Returns a decoded int (32 bytes) from the packet.
*
* @return A decoded int from the packet.
"""
return self._decodeGeneric(">l", 4)

"""
* Returns a decoded double from the packet.
*
* @return A decoded double from the packet.
"""
def decodeDouble(self) -> float:
"""
* Returns a decoded double from the packet.
*
* @return A decoded double from the packet.
"""
return self._decodeGeneric(">d", 8)

"""
* Returns a decoded boolean from the packet.
*
* @return A decoded boolean from the packet.
"""

def decodeBoolean(self) -> bool:
"""
* Returns a decoded boolean from the packet.
*
* @return A decoded boolean from the packet.
"""
return (self.decode8() == 1)

def decodeDoubleArray(self, length:int) -> list[float]:
"""
* Returns a decoded array of floats from the packet.
*
* @return A decoded array of floats from the packet.
"""
ret = []
for _ in range(length):
ret.append(self.decodeDouble())
return ret

def decodeTransform(self) -> Transform3d:
"""
* Returns a decoded Transform3d
*
* @return A decoded Tansform3d from the packet.
"""
x = self.decodeDouble()
y = self.decodeDouble()
z = self.decodeDouble()
Expand Down
12 changes: 7 additions & 5 deletions photon-lib/py/photonlibpy/photonPipelineResult.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
from dataclasses import dataclass

from photonlibpy.multiTargetPNPResult import MultiTargetPNPResult
from photonlibpy.packet import Packet
from photonlibpy.photonTrackedTarget import PhotonTrackedTarget

@dataclass
class PhotonPipelineResult:
def __init__(self):
self.latencyMillis = -0.0
self.timestampSec = -1.0
self.targets:list[PhotonTrackedTarget] = []
self.multiTagResult = MultiTargetPNPResult()
latencyMillis:float = -1.0
timestampSec:float = -1.0
targets:list[PhotonTrackedTarget] = []
multiTagResult:MultiTargetPNPResult = MultiTargetPNPResult()

def populateFromPacket(self, packet:Packet) -> Packet:
self.targets = []
Expand Down
37 changes: 16 additions & 21 deletions photon-lib/py/photonlibpy/photonTrackedTarget.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,31 @@
from dataclasses import dataclass
from wpimath.geometry import Transform3d
from photonlibpy.packet import Packet


@dataclass
class TargetCorner:
def __init__(self, x:float, y:float):
self.x = x
self.y = y
x:float
y:float

@dataclass
class PhotonTrackedTarget:

_MAX_CORNERS = 8
_NUM_BYTES_IN_FLOAT = 8
_PACK_SIZE_BYTES = _NUM_BYTES_IN_FLOAT * (5 + 7 + 2 * 4 + 1 + 7 + 2 * _MAX_CORNERS)

def __init__(self, yaw:float=0, pitch:float=0, area:float=0, skew:float=0,
id:int=0, pose:Transform3d=Transform3d(), altPose: Transform3d=Transform3d(),
ambiguity:float=0,
minAreaRectCorners: list[TargetCorner]|None = None,
detectedCorners: list[TargetCorner]|None = None):
self.yaw = yaw
self.pitch = pitch
self.area = area
self.skew = skew
self.fiducialId = id
self.bestCameraToTarget = pose
self.altCameraToTarget = altPose
self.minAreaRectCorners = minAreaRectCorners
self.detectedCorners = detectedCorners
self.poseAmbiguity = ambiguity

yaw:float = 0.0
pitch:float = 0.0
area:float = 0.0
skew:float = 0.0
fiducialId:int = -1
bestCameraToTarget:Transform3d = Transform3d()
altCameraToTarget:Transform3d = Transform3d()
minAreaRectCorners:list[TargetCorner]|None = None
detectedCorners:list[TargetCorner]|None = None
poseAmbiguity:float = 0.0

def getYaw(self) -> float:
return self.yaw
Expand Down Expand Up @@ -83,6 +81,3 @@ def createFromPacket(self, packet:Packet) -> Packet:
numCorners = packet.decode8()
self.detectedCorners = self._decodeTargetList(packet, numCorners)
return packet

def __str__(self) -> str:
return f"PhotonTrackedTarget{{yaw={self.yaw},pitch={self.pitch},area={self.area},skew={self.skew},fiducialId={self.fiducialId},bestCameraToTarget={self.bestCameraToTarget}}}"
2 changes: 1 addition & 1 deletion photon-server/src/main/resources/web/index.html
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<p>UI has not been copied!</p>
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="/favicon.svg" type="image/png"><title>PhotonVision Client</title><link href="/js/chunk-2d216214.abe86b4f.js" rel="prefetch"><link href="/js/chunk-2d216257.69e90091.js" rel="prefetch"><link href="/js/chunk-4d2ae93b.899a385b.js" rel="prefetch"><link href="/css/app.31df8921.css" rel="preload" as="style"><link href="/css/chunk-vendors.cde03e66.css" rel="preload" as="style"><link href="/js/app.8657bc11.js" rel="preload" as="script"><link href="/js/chunk-vendors.8465e9af.js" rel="preload" as="script"><link href="/css/chunk-vendors.cde03e66.css" rel="stylesheet"><link href="/css/app.31df8921.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but PhotonVision doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="/js/chunk-vendors.8465e9af.js"></script><script src="/js/app.8657bc11.js"></script></body></html>

0 comments on commit 9364d21

Please sign in to comment.