001/* 002 * Copyright (C) Photon Vision. 003 * 004 * This program is free software: you can redistribute it and/or modify 005 * it under the terms of the GNU General Public License as published by 006 * the Free Software Foundation, either version 3 of the License, or 007 * (at your option) any later version. 008 * 009 * This program is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 012 * GNU General Public License for more details. 013 * 014 * You should have received a copy of the GNU General Public License 015 * along with this program. If not, see <https://www.gnu.org/licenses/>. 016 */ 017 018package org.photonvision.targeting; 019 020import org.photonvision.common.dataflow.structures.PacketSerde; 021import org.photonvision.struct.PhotonPipelineMetadataSerde; 022import org.photonvision.targeting.serde.PhotonStructSerializable; 023 024public class PhotonPipelineMetadata implements PhotonStructSerializable<PhotonPipelineMetadata> { 025 // Image capture and NT publish timestamp, in microseconds 026 // The timebase is nt::Now on the time sync server 027 public long captureTimestampMicros; 028 public long publishTimestampMicros; 029 030 // Mirror of the heartbeat entry -- monotonically increasing 031 public long sequenceID; 032 033 // Time from last Time Sync Pong received and the construction of this metadata, in uS 034 public long timeSinceLastPong; 035 036 public PhotonPipelineMetadata( 037 long captureTimestampMicros, 038 long publishTimestampMicros, 039 long sequenceID, 040 long timeSinceLastPong) { 041 this.captureTimestampMicros = captureTimestampMicros; 042 this.publishTimestampMicros = publishTimestampMicros; 043 this.sequenceID = sequenceID; 044 this.timeSinceLastPong = timeSinceLastPong; 045 } 046 047 public PhotonPipelineMetadata() { 048 this(-1, -1, -1, Long.MAX_VALUE); 049 } 050 051 /** Returns the time between image capture and publish to NT */ 052 public double getLatencyMillis() { 053 return (publishTimestampMicros - captureTimestampMicros) / 1e3; 054 } 055 056 /** The time that this image was captured, in the coprocessor's time base. */ 057 public long getCaptureTimestampMicros() { 058 return captureTimestampMicros; 059 } 060 061 /** The time that this result was published to NT, in the coprocessor's time base. */ 062 public long getPublishTimestampMicros() { 063 return publishTimestampMicros; 064 } 065 066 /** 067 * The number of non-empty frames processed by this camera since boot. Useful to checking if a 068 * camera is alive. 069 */ 070 public long getSequenceID() { 071 return sequenceID; 072 } 073 074 @Override 075 public String toString() { 076 return "PhotonPipelineMetadata [captureTimestampMicros=" 077 + captureTimestampMicros 078 + ", publishTimestampMicros=" 079 + publishTimestampMicros 080 + ", sequenceID=" 081 + sequenceID 082 + ", timeSinceLastPong=" 083 + timeSinceLastPong 084 + "]"; 085 } 086 087 @Override 088 public int hashCode() { 089 final int prime = 31; 090 int result = 1; 091 result = prime * result + (int) (captureTimestampMicros ^ (captureTimestampMicros >>> 32)); 092 result = prime * result + (int) (publishTimestampMicros ^ (publishTimestampMicros >>> 32)); 093 result = prime * result + (int) (sequenceID ^ (sequenceID >>> 32)); 094 result = prime * result + (int) (timeSinceLastPong ^ (timeSinceLastPong >>> 32)); 095 return result; 096 } 097 098 @Override 099 public boolean equals(Object obj) { 100 if (this == obj) return true; 101 if (obj == null) return false; 102 if (getClass() != obj.getClass()) return false; 103 PhotonPipelineMetadata other = (PhotonPipelineMetadata) obj; 104 if (captureTimestampMicros != other.captureTimestampMicros) return false; 105 if (publishTimestampMicros != other.publishTimestampMicros) return false; 106 if (sequenceID != other.sequenceID) return false; 107 if (timeSinceLastPong != other.timeSinceLastPong) return false; 108 return true; 109 } 110 111 public static final PhotonPipelineMetadataSerde photonStruct = new PhotonPipelineMetadataSerde(); 112 113 @Override 114 public PacketSerde<PhotonPipelineMetadata> getSerde() { 115 return photonStruct; 116 } 117}