2023-10-17 10:20:00 -04:00
|
|
|
/*
|
|
|
|
|
* Copyright (C) Photon Vision.
|
|
|
|
|
*
|
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
* (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
package org.photonvision.targeting;
|
|
|
|
|
|
2024-01-13 22:35:57 -05:00
|
|
|
import edu.wpi.first.util.protobuf.ProtobufSerializable;
|
2023-10-17 10:20:00 -04:00
|
|
|
import java.util.ArrayList;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import org.photonvision.common.dataflow.structures.Packet;
|
2023-12-24 19:56:08 -05:00
|
|
|
import org.photonvision.common.dataflow.structures.PacketSerde;
|
2023-12-31 00:14:21 -05:00
|
|
|
import org.photonvision.targeting.proto.MultiTargetPNPResultProto;
|
2023-10-17 10:20:00 -04:00
|
|
|
|
2024-01-13 22:35:57 -05:00
|
|
|
public class MultiTargetPNPResult implements ProtobufSerializable {
|
2023-10-17 10:20:00 -04:00
|
|
|
// Seeing 32 apriltags at once seems like a sane limit
|
|
|
|
|
private static final int MAX_IDS = 32;
|
|
|
|
|
|
2023-11-15 18:28:26 -05:00
|
|
|
public PNPResult estimatedPose = new PNPResult();
|
2023-10-17 10:20:00 -04:00
|
|
|
public List<Integer> fiducialIDsUsed = List.of();
|
|
|
|
|
|
2023-11-15 18:28:26 -05:00
|
|
|
public MultiTargetPNPResult() {}
|
2023-10-17 10:20:00 -04:00
|
|
|
|
2023-11-15 18:28:26 -05:00
|
|
|
public MultiTargetPNPResult(PNPResult results, List<Integer> ids) {
|
2023-10-17 10:20:00 -04:00
|
|
|
estimatedPose = results;
|
|
|
|
|
fiducialIDsUsed = ids;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public int hashCode() {
|
|
|
|
|
final int prime = 31;
|
|
|
|
|
int result = 1;
|
|
|
|
|
result = prime * result + ((estimatedPose == null) ? 0 : estimatedPose.hashCode());
|
|
|
|
|
result = prime * result + ((fiducialIDsUsed == null) ? 0 : fiducialIDsUsed.hashCode());
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public boolean equals(Object obj) {
|
|
|
|
|
if (this == obj) return true;
|
|
|
|
|
if (obj == null) return false;
|
|
|
|
|
if (getClass() != obj.getClass()) return false;
|
2023-11-15 18:28:26 -05:00
|
|
|
MultiTargetPNPResult other = (MultiTargetPNPResult) obj;
|
2023-10-17 10:20:00 -04:00
|
|
|
if (estimatedPose == null) {
|
|
|
|
|
if (other.estimatedPose != null) return false;
|
|
|
|
|
} else if (!estimatedPose.equals(other.estimatedPose)) return false;
|
|
|
|
|
if (fiducialIDsUsed == null) {
|
|
|
|
|
if (other.fiducialIDsUsed != null) return false;
|
|
|
|
|
} else if (!fiducialIDsUsed.equals(other.fiducialIDsUsed)) return false;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public String toString() {
|
2023-11-15 18:28:26 -05:00
|
|
|
return "MultiTargetPNPResult [estimatedPose="
|
2023-10-17 10:20:00 -04:00
|
|
|
+ estimatedPose
|
|
|
|
|
+ ", fiducialIDsUsed="
|
|
|
|
|
+ fiducialIDsUsed
|
|
|
|
|
+ "]";
|
|
|
|
|
}
|
2023-12-24 19:56:08 -05:00
|
|
|
|
|
|
|
|
public static final class APacketSerde implements PacketSerde<MultiTargetPNPResult> {
|
|
|
|
|
@Override
|
|
|
|
|
public int getMaxByteSize() {
|
|
|
|
|
// PNPResult + MAX_IDS possible targets (arbitrary upper limit that should never be hit,
|
|
|
|
|
// ideally)
|
|
|
|
|
return PNPResult.serde.getMaxByteSize() + (Short.BYTES * MAX_IDS);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void pack(Packet packet, MultiTargetPNPResult result) {
|
|
|
|
|
PNPResult.serde.pack(packet, result.estimatedPose);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < MAX_IDS; i++) {
|
|
|
|
|
if (i < result.fiducialIDsUsed.size()) {
|
|
|
|
|
packet.encode((short) result.fiducialIDsUsed.get(i).byteValue());
|
|
|
|
|
} else {
|
|
|
|
|
packet.encode((short) -1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public MultiTargetPNPResult unpack(Packet packet) {
|
|
|
|
|
var results = PNPResult.serde.unpack(packet);
|
|
|
|
|
var ids = new ArrayList<Integer>(MAX_IDS);
|
|
|
|
|
for (int i = 0; i < MAX_IDS; i++) {
|
|
|
|
|
int targetId = packet.decodeShort();
|
|
|
|
|
if (targetId > -1) ids.add(targetId);
|
|
|
|
|
}
|
|
|
|
|
return new MultiTargetPNPResult(results, ids);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static final APacketSerde serde = new APacketSerde();
|
2023-12-31 00:14:21 -05:00
|
|
|
public static final MultiTargetPNPResultProto proto = new MultiTargetPNPResultProto();
|
2023-10-17 10:20:00 -04:00
|
|
|
}
|