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.vision.pipeline.result; 019 020import java.util.Collections; 021import java.util.List; 022import java.util.Optional; 023import org.photonvision.common.util.math.MathUtils; 024import org.photonvision.targeting.MultiTargetPNPResult; 025import org.photonvision.vision.frame.Frame; 026import org.photonvision.vision.opencv.Releasable; 027import org.photonvision.vision.target.TrackedTarget; 028 029public class CVPipelineResult implements Releasable { 030 public final long sequenceID; 031 private long imageCaptureTimestampNanos; 032 public final double processingNanos; 033 public final double fps; 034 public final List<TrackedTarget> targets; 035 public final Frame inputAndOutputFrame; 036 public Optional<MultiTargetPNPResult> multiTagResult; 037 public final List<String> objectDetectionClassNames; 038 039 public CVPipelineResult( 040 long sequenceID, 041 double processingNanos, 042 double fps, 043 List<TrackedTarget> targets, 044 Frame inputFrame) { 045 this(sequenceID, processingNanos, fps, targets, Optional.empty(), inputFrame, List.of()); 046 } 047 048 public CVPipelineResult( 049 long sequenceID, 050 double processingNanos, 051 double fps, 052 List<TrackedTarget> targets, 053 Frame inputFrame, 054 List<String> classNames) { 055 this(sequenceID, processingNanos, fps, targets, Optional.empty(), inputFrame, classNames); 056 } 057 058 public CVPipelineResult( 059 long sequenceID, 060 double processingNanos, 061 double fps, 062 List<TrackedTarget> targets, 063 Optional<MultiTargetPNPResult> multiTagResult, 064 Frame inputFrame) { 065 this(sequenceID, processingNanos, fps, targets, multiTagResult, inputFrame, List.of()); 066 } 067 068 public CVPipelineResult( 069 long sequenceID, 070 double processingNanos, 071 double fps, 072 List<TrackedTarget> targets, 073 Optional<MultiTargetPNPResult> multiTagResult, 074 Frame inputFrame, 075 List<String> classNames) { 076 this.sequenceID = sequenceID; 077 this.processingNanos = processingNanos; 078 this.fps = fps; 079 this.targets = targets != null ? targets : Collections.emptyList(); 080 this.multiTagResult = multiTagResult; 081 this.objectDetectionClassNames = classNames; 082 083 this.inputAndOutputFrame = inputFrame; 084 } 085 086 public CVPipelineResult( 087 long sequenceID, 088 double processingNanos, 089 double fps, 090 List<TrackedTarget> targets, 091 Optional<MultiTargetPNPResult> multiTagResult) { 092 this(sequenceID, processingNanos, fps, targets, multiTagResult, null, List.of()); 093 } 094 095 public boolean hasTargets() { 096 return !targets.isEmpty(); 097 } 098 099 public void release() { 100 for (TrackedTarget tt : targets) { 101 tt.release(); 102 } 103 if (inputAndOutputFrame != null) inputAndOutputFrame.release(); 104 } 105 106 /** 107 * Get the latency between now (wpi::Now) and the time at which the image was captured. FOOTGUN: 108 * the latency is relative to the time at which this method is called. Waiting to call this method 109 * will change the latency this method returns. 110 */ 111 @Deprecated 112 public double getLatencyMillis() { 113 var now = MathUtils.wpiNanoTime(); 114 return MathUtils.nanosToMillis(now - imageCaptureTimestampNanos); 115 } 116 117 public double getProcessingMillis() { 118 return MathUtils.nanosToMillis(processingNanos); 119 } 120 121 public long getImageCaptureTimestampNanos() { 122 return imageCaptureTimestampNanos; 123 } 124 125 public void setImageCaptureTimestampNanos(long imageCaptureTimestampNanos) { 126 this.imageCaptureTimestampNanos = imageCaptureTimestampNanos; 127 } 128}