mirror of
https://github.com/PhotonVision/photonvision
synced 2026-06-19 00:41:41 +00:00
Add disabled param for PhotonCamera (#2484)
This commit is contained in:
@@ -91,6 +91,9 @@ export const useCameraSettingsStore = defineStore("cameraSettings", {
|
||||
fpsLimit(): number {
|
||||
return this.currentCameraSettings.fpsLimit;
|
||||
},
|
||||
isEnabled(): boolean {
|
||||
return this.currentCameraSettings.isEnabled;
|
||||
},
|
||||
isConnected(): boolean {
|
||||
return this.currentCameraSettings.isConnected;
|
||||
},
|
||||
@@ -142,6 +145,7 @@ export const useCameraSettingsStore = defineStore("cameraSettings", {
|
||||
maxWhiteBalanceTemp: d.maxWhiteBalanceTemp,
|
||||
matchedCameraInfo: d.matchedCameraInfo,
|
||||
fpsLimit: d.fpsLimit,
|
||||
isEnabled: d.isEnabled,
|
||||
isConnected: d.isConnected,
|
||||
hasConnected: d.hasConnected,
|
||||
mismatch: d.mismatch
|
||||
|
||||
@@ -276,6 +276,7 @@ export interface UiCameraConfiguration {
|
||||
maxWhiteBalanceTemp: number;
|
||||
|
||||
fpsLimit: number;
|
||||
isEnabled: boolean;
|
||||
|
||||
matchedCameraInfo: PVCameraInfo;
|
||||
isConnected: boolean;
|
||||
@@ -447,6 +448,7 @@ export const PlaceholderCameraSettings: UiCameraConfiguration = reactive({
|
||||
PVUsbCameraInfo: undefined
|
||||
},
|
||||
fpsLimit: -1,
|
||||
isEnabled: true,
|
||||
isConnected: true,
|
||||
hasConnected: true,
|
||||
mismatch: false
|
||||
|
||||
@@ -68,6 +68,7 @@ export interface WebsocketCameraSettingsUpdate {
|
||||
maxWhiteBalanceTemp: number;
|
||||
matchedCameraInfo: PVCameraInfo;
|
||||
fpsLimit: number;
|
||||
isEnabled: boolean;
|
||||
isConnected: boolean;
|
||||
hasConnected: boolean;
|
||||
mismatch: boolean;
|
||||
|
||||
@@ -77,8 +77,18 @@ const conflictingCameraShown = computed<boolean>(() => {
|
||||
return useSettingsStore().general.conflictingCameras.length > 0;
|
||||
});
|
||||
|
||||
const fpsLimitWarningShown = computed<boolean>(() => {
|
||||
return Object.values(useCameraSettingsStore().cameras).some((c) => c.fpsLimit > 0);
|
||||
const fpsLimitedCameras = computed<string>(() => {
|
||||
return Object.values(useCameraSettingsStore().cameras)
|
||||
.filter((c) => c.fpsLimit > 0)
|
||||
.map((c) => c.nickname)
|
||||
.join(", ");
|
||||
});
|
||||
|
||||
const disabledCameras = computed<string>(() => {
|
||||
return Object.values(useCameraSettingsStore().cameras)
|
||||
.filter((c) => !c.isEnabled)
|
||||
.map((c) => c.nickname)
|
||||
.join(", ");
|
||||
});
|
||||
|
||||
const showCameraSetupDialog = ref(useCameraSettingsStore().needsCameraConfiguration);
|
||||
@@ -111,7 +121,7 @@ const showCameraSetupDialog = ref(useCameraSettingsStore().needsCameraConfigurat
|
||||
</span>
|
||||
</v-alert>
|
||||
<v-alert
|
||||
v-if="fpsLimitWarningShown"
|
||||
v-if="fpsLimitedCameras"
|
||||
class="mb-3"
|
||||
color="error"
|
||||
density="compact"
|
||||
@@ -119,10 +129,22 @@ const showCameraSetupDialog = ref(useCameraSettingsStore().needsCameraConfigurat
|
||||
:variant="theme.global.current.value.dark ? 'tonal' : 'elevated'"
|
||||
>
|
||||
<span
|
||||
>One or more cameras have an FPS limit set! This may cause performance issues. Check your logs for more
|
||||
>{{ fpsLimitedCameras }} have an FPS limit set! This may cause performance issues. Check your logs for more
|
||||
information.
|
||||
</span>
|
||||
</v-alert>
|
||||
<v-alert
|
||||
v-if="disabledCameras"
|
||||
class="mb-3"
|
||||
color="error"
|
||||
density="compact"
|
||||
icon="mdi-alert-circle-outline"
|
||||
:variant="theme.global.current.value.dark ? 'tonal' : 'elevated'"
|
||||
>
|
||||
<span
|
||||
>{{ disabledCameras }} are disabled! This may cause performance issues. Check your logs for more information.
|
||||
</span>
|
||||
</v-alert>
|
||||
<v-alert
|
||||
v-if="conflictingCameraShown"
|
||||
class="mb-3"
|
||||
|
||||
@@ -55,6 +55,10 @@ public class NTDataPublisher implements CVPipelineResultConsumer {
|
||||
private final Consumer<Integer> fpsLimitConsumer;
|
||||
private final Supplier<Integer> fpsLimitSupplier;
|
||||
|
||||
NTDataChangeListener isEnabledListener;
|
||||
private final Consumer<Boolean> isEnabledConsumer;
|
||||
private final BooleanSupplier enabledSupplier;
|
||||
|
||||
public NTDataPublisher(
|
||||
String cameraNickname,
|
||||
Supplier<Integer> pipelineIndexSupplier,
|
||||
@@ -62,13 +66,17 @@ public class NTDataPublisher implements CVPipelineResultConsumer {
|
||||
BooleanSupplier driverModeSupplier,
|
||||
Consumer<Boolean> driverModeConsumer,
|
||||
Supplier<Integer> fpsLimitSupplier,
|
||||
Consumer<Integer> fpsLimitConsumer) {
|
||||
Consumer<Integer> fpsLimitConsumer,
|
||||
BooleanSupplier enabledSupplier,
|
||||
Consumer<Boolean> isEnabledConsumer) {
|
||||
this.pipelineIndexSupplier = pipelineIndexSupplier;
|
||||
this.pipelineIndexConsumer = pipelineIndexConsumer;
|
||||
this.driverModeSupplier = driverModeSupplier;
|
||||
this.driverModeConsumer = driverModeConsumer;
|
||||
this.fpsLimitSupplier = fpsLimitSupplier;
|
||||
this.fpsLimitConsumer = fpsLimitConsumer;
|
||||
this.enabledSupplier = enabledSupplier;
|
||||
this.isEnabledConsumer = isEnabledConsumer;
|
||||
|
||||
updateCameraNickname(cameraNickname);
|
||||
updateEntries();
|
||||
@@ -124,6 +132,19 @@ public class NTDataPublisher implements CVPipelineResultConsumer {
|
||||
logger.debug("Set FPS limit to " + newFPSLimit);
|
||||
}
|
||||
|
||||
private void onEnabledChange(NetworkTableEvent entryNotification) {
|
||||
var newEnabled = entryNotification.valueData.value.getBoolean();
|
||||
var originalEnabled = enabledSupplier.getAsBoolean();
|
||||
|
||||
if (newEnabled == originalEnabled) {
|
||||
logger.debug("Enabled value is already " + newEnabled);
|
||||
return;
|
||||
}
|
||||
|
||||
isEnabledConsumer.accept(newEnabled);
|
||||
logger.debug("Set is enabled to " + newEnabled);
|
||||
}
|
||||
|
||||
private void removeEntries() {
|
||||
if (pipelineIndexListener != null) pipelineIndexListener.remove();
|
||||
if (driverModeListener != null) driverModeListener.remove();
|
||||
@@ -148,6 +169,10 @@ public class NTDataPublisher implements CVPipelineResultConsumer {
|
||||
fpsLimitListener =
|
||||
new NTDataChangeListener(
|
||||
ts.subTable.getInstance(), ts.fpsLimitSubscriber, this::onFPSLimitChange);
|
||||
|
||||
isEnabledListener =
|
||||
new NTDataChangeListener(
|
||||
ts.subTable.getInstance(), ts.enabledSubscriber, this::onEnabledChange);
|
||||
}
|
||||
|
||||
public void updateCameraNickname(String newCameraNickname) {
|
||||
@@ -198,6 +223,7 @@ public class NTDataPublisher implements CVPipelineResultConsumer {
|
||||
ts.pipelineIndexPublisher.set(pipelineIndexSupplier.get());
|
||||
ts.driverModePublisher.set(driverModeSupplier.getAsBoolean());
|
||||
ts.fpsLimitPublisher.set(fpsLimitSupplier.get());
|
||||
ts.enabledPublisher.set(enabledSupplier.getAsBoolean());
|
||||
ts.latencyMillisEntry.set(acceptedResult.getLatencyMillis());
|
||||
ts.fpsEntry.set(acceptedResult.fps);
|
||||
ts.hasTargetEntry.set(acceptedResult.hasTargets());
|
||||
|
||||
@@ -55,6 +55,7 @@ public class UICameraConfiguration {
|
||||
public boolean mismatch;
|
||||
|
||||
public int fpsLimit;
|
||||
public boolean isEnabled;
|
||||
|
||||
// Status for if the underlying device is present and such
|
||||
public boolean isConnected;
|
||||
|
||||
@@ -88,6 +88,7 @@ public class VisionModule {
|
||||
private int outputStreamPort = -1;
|
||||
|
||||
private int fpsLimit = -1;
|
||||
private boolean enabled = true;
|
||||
|
||||
FileSaveFrameConsumer inputFrameSaver;
|
||||
FileSaveFrameConsumer outputFrameSaver;
|
||||
@@ -137,7 +138,8 @@ public class VisionModule {
|
||||
this::consumeResult,
|
||||
this.cameraQuirks,
|
||||
getChangeSubscriber(),
|
||||
this::getFPSLimit);
|
||||
this::getFPSLimit,
|
||||
this::getEnabled);
|
||||
this.streamRunnable = new StreamRunnable(new OutputStreamPipeline());
|
||||
changeSubscriberHandle = DataChangeService.getInstance().addSubscriber(changeSubscriber);
|
||||
|
||||
@@ -153,7 +155,9 @@ public class VisionModule {
|
||||
pipelineManager::getDriverMode,
|
||||
this::setDriverMode,
|
||||
this::getFPSLimit,
|
||||
this::setFPSLimit);
|
||||
this::setFPSLimit,
|
||||
this::getEnabled,
|
||||
this::setEnabled);
|
||||
uiDataConsumer = new UIDataPublisher(visionSource.getSettables().getConfiguration().uniqueName);
|
||||
statusLEDsConsumer =
|
||||
new StatusLEDConsumer(visionSource.getSettables().getConfiguration().uniqueName);
|
||||
@@ -645,6 +649,25 @@ public class VisionModule {
|
||||
return fpsLimit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the camera is enabled/disabled, disabling the camera allows you to reduce util
|
||||
* while keeping the vision runner up for fast toggling.
|
||||
*/
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
saveAndBroadcastAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether the camera is enabled or disabled, if disabled the vision runner will still be
|
||||
* running but the camera will not capture frames, allowing for fast toggling.
|
||||
*
|
||||
* @return the enabled state of the camera
|
||||
*/
|
||||
public boolean getEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public CameraConfiguration getStateAsCameraConfig() {
|
||||
var config = visionSource.getSettables().getConfiguration();
|
||||
config.setPipelineSettings(pipelineManager.userPipelineSettings);
|
||||
|
||||
@@ -50,6 +50,7 @@ public class VisionRunner {
|
||||
private final List<Runnable> runnableList = new ArrayList<Runnable>();
|
||||
private final QuirkyCamera cameraQuirks;
|
||||
private final Supplier<Integer> fpsLimitSupplier;
|
||||
private final Supplier<Boolean> enabledSupplier;
|
||||
|
||||
private long loopCount;
|
||||
|
||||
@@ -57,9 +58,14 @@ public class VisionRunner {
|
||||
* VisionRunner contains a thread to run a pipeline, given a frame, and will give the result to
|
||||
* the consumer.
|
||||
*
|
||||
* @param frameSupplier The supplier of the latest frame.
|
||||
* @param pipelineSupplier The supplier of the current pipeline.
|
||||
* @param pipelineResultConsumer The consumer of the latest result.
|
||||
* @param frameSupplier
|
||||
* @param pipelineSupplier
|
||||
* @param pipelineResultConsumer
|
||||
* @param cameraQuirks
|
||||
* @param changeSubscriber The subscriber to setting changes for this VisionRunner, so it can
|
||||
* update its settings when they change.
|
||||
* @param fpsLimitSupplier
|
||||
* @param enabledSupplier
|
||||
*/
|
||||
public VisionRunner(
|
||||
FrameProvider frameSupplier,
|
||||
@@ -67,13 +73,15 @@ public class VisionRunner {
|
||||
Consumer<CVPipelineResult> pipelineResultConsumer,
|
||||
QuirkyCamera cameraQuirks,
|
||||
VisionModuleChangeSubscriber changeSubscriber,
|
||||
Supplier<Integer> fpsLimitSupplier) {
|
||||
Supplier<Integer> fpsLimitSupplier,
|
||||
Supplier<Boolean> enabledSupplier) {
|
||||
this.frameSupplier = frameSupplier;
|
||||
this.pipelineSupplier = pipelineSupplier;
|
||||
this.pipelineResultConsumer = pipelineResultConsumer;
|
||||
this.cameraQuirks = cameraQuirks;
|
||||
this.changeSubscriber = changeSubscriber;
|
||||
this.fpsLimitSupplier = fpsLimitSupplier;
|
||||
this.enabledSupplier = enabledSupplier;
|
||||
|
||||
visionProcessThread = new Thread(this::update);
|
||||
visionProcessThread.setName("VisionRunner - " + frameSupplier.getName());
|
||||
@@ -130,6 +138,28 @@ public class VisionRunner {
|
||||
return future;
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits until the next time this VisionRunner should run its pipeline, based on current FPS limit
|
||||
*/
|
||||
private void waitUntilNextTick(long start) {
|
||||
int fpsLimit = fpsLimitSupplier.get();
|
||||
|
||||
if (fpsLimit > 0) {
|
||||
long sleepTime = (long) (1000 / fpsLimit - (System.currentTimeMillis() - start));
|
||||
|
||||
if (sleepTime > 0) {
|
||||
try {
|
||||
Thread.sleep(sleepTime);
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
// Fall through to no limit
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private void update() {
|
||||
// wait for the camera to connect
|
||||
while (!frameSupplier.isConnected() && !Thread.interrupted()) {
|
||||
@@ -194,11 +224,23 @@ public class VisionRunner {
|
||||
frame.release();
|
||||
pipelineResultConsumer.accept(new CVPipelineResult(0l, 0, 0, null, new Frame()));
|
||||
} else if (pipeline == pipelineSupplier.get()) {
|
||||
if (!enabledSupplier.get()) {
|
||||
// If we are skipping processing due to the camera being disabled, we still want to send a
|
||||
// result with the new frame and settings, just with a null pipeline result
|
||||
pipelineResultConsumer.accept(new CVPipelineResult(0l, 0, 0, null, new Frame()));
|
||||
frame.release();
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the pipeline has changed while we are getting our frame we should scrap
|
||||
// that frame it may result in incorrect frame settings like hsv values
|
||||
|
||||
// There's no guarantee the processing type change will occur this tick, so
|
||||
// pipelines should check themselves
|
||||
|
||||
// If we have an FPS limit, check if it's 0, in which case we skip processing and just send
|
||||
// a blank frame, otherwise we sleep until the next tick
|
||||
waitUntilNextTick(start);
|
||||
try {
|
||||
var pipelineResult = pipeline.run(frame, cameraQuirks);
|
||||
pipelineResultConsumer.accept(pipelineResult);
|
||||
@@ -207,18 +249,6 @@ public class VisionRunner {
|
||||
}
|
||||
loopCount++;
|
||||
}
|
||||
int fpsLimit = fpsLimitSupplier.get();
|
||||
if (fpsLimit > 0) {
|
||||
long sleepTime = (long) (1000 / fpsLimit - (System.currentTimeMillis() - start));
|
||||
|
||||
if (sleepTime > 0) {
|
||||
try {
|
||||
Thread.sleep(sleepTime);
|
||||
} catch (InterruptedException e) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,6 +54,13 @@ class NTTopicSet:
|
||||
|
||||
self.fpsLimitSubscriber.getTopic().publish().setDefault(-1)
|
||||
|
||||
self.enabledPublisher = self.subTable.getBooleanTopic("enabled").publish()
|
||||
self.enabledSubscriber = self.subTable.getBooleanTopic(
|
||||
"enabledRequest"
|
||||
).subscribe(True)
|
||||
|
||||
self.enabledSubscriber.getTopic().publish().setDefault(True)
|
||||
|
||||
self.latencyMillisEntry = self.subTable.getDoubleTopic(
|
||||
"latencyMillis"
|
||||
).publish()
|
||||
|
||||
@@ -80,6 +80,12 @@ class PhotonCamera:
|
||||
self._fpsLimitSubscriber = self._cameraTable.getIntegerTopic(
|
||||
"fpsLimit"
|
||||
).subscribe(-1)
|
||||
self._enabledPublisher = self._cameraTable.getBooleanTopic(
|
||||
"enabledRequest"
|
||||
).publish()
|
||||
self._enabledSubscriber = self._cameraTable.getBooleanTopic(
|
||||
"enabled"
|
||||
).subscribe(True)
|
||||
self._inputSaveImgEntry = self._cameraTable.getIntegerTopic(
|
||||
"inputSaveImgCmd"
|
||||
).getEntry(0)
|
||||
@@ -204,11 +210,28 @@ class PhotonCamera:
|
||||
def setFPSLimit(self, fpsLimit: int) -> None:
|
||||
"""Sets the FPS limit on the camera.
|
||||
|
||||
:param fpsLimit: The FPS limit to set. Set to -1 for unlimited FPS.
|
||||
<p>A negative FPS limit is treated as no FPS limit, and will run as fast as possible.
|
||||
|
||||
<p>Otherwise, will limit processing to at most the provided FPS limit
|
||||
|
||||
:param fpsLimit: The FPS limit to set.
|
||||
"""
|
||||
|
||||
self._fpsLimitPublisher.set(fpsLimit)
|
||||
|
||||
def getEnabled(self) -> bool:
|
||||
""":returns: Whether the camera is enabled."""
|
||||
|
||||
return self._enabledSubscriber.get()
|
||||
|
||||
def setEnabled(self, enabled: bool) -> None:
|
||||
"""Sets whether the camera is enabled, default is true.
|
||||
|
||||
:param enabled: Whether to enable the camera.
|
||||
"""
|
||||
|
||||
self._enabledPublisher.set(enabled)
|
||||
|
||||
def takeInputSnapshot(self) -> None:
|
||||
"""Request the camera to save a new image file from the input camera stream with overlays. Images
|
||||
take up space in the filesystem of the PhotonCamera. Calling it frequently will fill up disk
|
||||
|
||||
@@ -65,6 +65,8 @@ public class PhotonCamera implements AutoCloseable {
|
||||
BooleanSubscriber driverModeSubscriber;
|
||||
IntegerPublisher fpsLimitPublisher;
|
||||
IntegerSubscriber fpsLimitSubscriber;
|
||||
BooleanSubscriber enabledSubscriber;
|
||||
BooleanPublisher enabledPublisher;
|
||||
StringSubscriber versionEntry;
|
||||
IntegerEntry inputSaveImgEntry, outputSaveImgEntry;
|
||||
IntegerPublisher pipelineIndexRequest, ledModeRequest;
|
||||
@@ -82,6 +84,8 @@ public class PhotonCamera implements AutoCloseable {
|
||||
driverModeSubscriber.close();
|
||||
fpsLimitPublisher.close();
|
||||
fpsLimitSubscriber.close();
|
||||
enabledPublisher.close();
|
||||
enabledSubscriber.close();
|
||||
versionEntry.close();
|
||||
inputSaveImgEntry.close();
|
||||
outputSaveImgEntry.close();
|
||||
@@ -155,6 +159,8 @@ public class PhotonCamera implements AutoCloseable {
|
||||
driverModeSubscriber = cameraTable.getBooleanTopic("driverMode").subscribe(false);
|
||||
fpsLimitPublisher = cameraTable.getIntegerTopic("fpsLimitRequest").publish();
|
||||
fpsLimitSubscriber = cameraTable.getIntegerTopic("fpsLimit").subscribe(-1);
|
||||
enabledPublisher = cameraTable.getBooleanTopic("enabledRequest").publish();
|
||||
enabledSubscriber = cameraTable.getBooleanTopic("enabled").subscribe(true);
|
||||
inputSaveImgEntry = cameraTable.getIntegerTopic("inputSaveImgCmd").getEntry(0);
|
||||
outputSaveImgEntry = cameraTable.getIntegerTopic("outputSaveImgCmd").getEntry(0);
|
||||
pipelineIndexRequest = cameraTable.getIntegerTopic("pipelineIndexRequest").publish();
|
||||
@@ -344,8 +350,6 @@ public class PhotonCamera implements AutoCloseable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the FPS limit set on the camera.
|
||||
*
|
||||
* @return The current FPS limit.
|
||||
*/
|
||||
public int getFPSLimit() {
|
||||
@@ -355,12 +359,32 @@ public class PhotonCamera implements AutoCloseable {
|
||||
/**
|
||||
* Sets the FPS limit on the camera.
|
||||
*
|
||||
* @param fps The FPS limit to set. Set to -1 for unlimited FPS.
|
||||
* <p>A negative FPS limit is treated as no FPS limit, and will run as fast as possible.
|
||||
*
|
||||
* <p>Otherwise, will limit processing to at most the provided FPS limit
|
||||
*
|
||||
* @param fps The FPS limit to set.
|
||||
*/
|
||||
public void setFPSLimit(int fps) {
|
||||
fpsLimitPublisher.set(fps);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the camera is enabled, default is true.
|
||||
*
|
||||
* @param enabled Whether to enable the camera.
|
||||
*/
|
||||
public void setEnabled(boolean enabled) {
|
||||
enabledPublisher.set(enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether the camera is enabled.
|
||||
*/
|
||||
public boolean getEnabled() {
|
||||
return enabledSubscriber.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Request the camera to save a new image file from the input camera stream with overlays. Images
|
||||
* take up space in the filesystem of the PhotonCamera. Calling it frequently will fill up disk
|
||||
|
||||
@@ -157,6 +157,8 @@ PhotonCamera::PhotonCamera(wpi::nt::NetworkTableInstance instance,
|
||||
fpsLimitSubscriber(rootTable->GetIntegerTopic("fpsLimit").Subscribe(-1)),
|
||||
fpsLimitPublisher(
|
||||
rootTable->GetIntegerTopic("fpsLimitRequest").Publish()),
|
||||
enabledSubscriber(rootTable->GetBooleanTopic("enabled").Subscribe(true)),
|
||||
enabledPublisher(rootTable->GetBooleanTopic("enabledRequest").Publish()),
|
||||
heartbeatSubscriber(
|
||||
rootTable->GetIntegerTopic("heartbeat").Subscribe(-1)),
|
||||
topicNameSubscriber(instance, PHOTON_PREFIX, {.topicsOnly = true}),
|
||||
@@ -291,6 +293,10 @@ void PhotonCamera::SetFPSLimit(int fpsLimit) {
|
||||
fpsLimitPublisher.Set(fpsLimit);
|
||||
}
|
||||
|
||||
bool PhotonCamera::GetEnabled() const { return enabledSubscriber.Get(); }
|
||||
|
||||
void PhotonCamera::SetEnabled(bool enabled) { enabledPublisher.Set(enabled); }
|
||||
|
||||
void PhotonCamera::TakeInputSnapshot() {
|
||||
inputSaveImgEntry.Set(inputSaveImgSubscriber.Get() + 1);
|
||||
}
|
||||
|
||||
@@ -104,7 +104,17 @@ class PhotonCamera {
|
||||
bool GetDriverMode() const;
|
||||
|
||||
/**
|
||||
* @param fpsLimit The FPS limit to set. Use -1 for unlimited FPS.
|
||||
* Sets the FPS limit on the camera.
|
||||
*
|
||||
* <p>An FPS of 0 means to pause processing until a FPS limit greater than 0
|
||||
* is set.
|
||||
*
|
||||
* <p>A negative FPS limit is treated as no FPS limit, and will run as fast as
|
||||
* possible.
|
||||
*
|
||||
* <p>Otherwise, will limit processing to at most the provided FPS limit
|
||||
*
|
||||
* @param fps The FPS limit to set.
|
||||
*/
|
||||
void SetFPSLimit(int fpsLimit);
|
||||
|
||||
@@ -113,6 +123,17 @@ class PhotonCamera {
|
||||
*/
|
||||
int GetFPSLimit() const;
|
||||
|
||||
/**
|
||||
* Sets whether the camera is enabled, default is true.
|
||||
* @param enabled Whether to enable the camera.
|
||||
*/
|
||||
void SetEnabled(bool enabled);
|
||||
|
||||
/**
|
||||
* @return Whether the camera is enabled.
|
||||
*/
|
||||
bool GetEnabled() const;
|
||||
|
||||
/**
|
||||
* Request the camera to save a new image file from the input
|
||||
* camera stream with overlays.
|
||||
@@ -233,6 +254,8 @@ class PhotonCamera {
|
||||
wpi::nt::BooleanPublisher driverModePublisher;
|
||||
wpi::nt::IntegerSubscriber fpsLimitSubscriber;
|
||||
wpi::nt::IntegerPublisher fpsLimitPublisher;
|
||||
wpi::nt::BooleanSubscriber enabledSubscriber;
|
||||
wpi::nt::BooleanPublisher enabledPublisher;
|
||||
|
||||
wpi::nt::IntegerSubscriber ledModeSubscriber;
|
||||
|
||||
|
||||
@@ -57,6 +57,9 @@ public class NTTopicSet {
|
||||
public IntegerPublisher fpsLimitPublisher;
|
||||
public IntegerSubscriber fpsLimitSubscriber;
|
||||
|
||||
public BooleanPublisher enabledPublisher;
|
||||
public BooleanSubscriber enabledSubscriber;
|
||||
|
||||
public DoublePublisher latencyMillisEntry;
|
||||
public DoublePublisher fpsEntry;
|
||||
public BooleanPublisher hasTargetEntry;
|
||||
@@ -109,6 +112,11 @@ public class NTTopicSet {
|
||||
|
||||
fpsLimitSubscriber.getTopic().publish().setDefault(-1);
|
||||
|
||||
enabledPublisher = subTable.getBooleanTopic("enabled").publish();
|
||||
enabledSubscriber = subTable.getBooleanTopic("enabledRequest").subscribe(true);
|
||||
|
||||
enabledSubscriber.getTopic().publish().setDefault(true);
|
||||
|
||||
latencyMillisEntry = subTable.getDoubleTopic("latencyMillis").publish();
|
||||
fpsEntry = subTable.getDoubleTopic("fps").publish();
|
||||
hasTargetEntry = subTable.getBooleanTopic("hasTarget").publish();
|
||||
@@ -141,6 +149,9 @@ public class NTTopicSet {
|
||||
if (fpsLimitPublisher != null) fpsLimitPublisher.close();
|
||||
if (fpsLimitSubscriber != null) fpsLimitSubscriber.close();
|
||||
|
||||
if (enabledPublisher != null) enabledPublisher.close();
|
||||
if (enabledSubscriber != null) enabledSubscriber.close();
|
||||
|
||||
if (latencyMillisEntry != null) latencyMillisEntry.close();
|
||||
if (fpsEntry != null) fpsEntry.close();
|
||||
if (hasTargetEntry != null) hasTargetEntry.close();
|
||||
|
||||
Reference in New Issue
Block a user