Skip to content

Commit 966b9e8

Browse files
samfreundmcm001gerth2
authored
Yolo duplication fix (#1713)
Somebody wanted a description, so here I am. This PR fixes an error which caused the discoverModels function to be rerun after each upload of a new model, but without clearing the list of available models. This causes any models that were on the list prior to the import to be duplicated. This PR also makes it so that uploading a model automatically updates the list of available models. --------- Co-authored-by: Matt Morley <[email protected]> Co-authored-by: Chris Gerth <[email protected]>
1 parent 5f75619 commit 966b9e8

File tree

4 files changed

+34
-21
lines changed

4 files changed

+34
-21
lines changed

photon-client/src/components/settings/ObjectDetectionCard.vue

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@ import axios from "axios";
44
import { useStateStore } from "@/stores/StateStore";
55
import { useSettingsStore } from "@/stores/settings/GeneralSettingsStore";
66
7-
const showObjectDetectionImportDialog = ref(false);
7+
const showImportDialog = ref(false);
88
const importRKNNFile = ref<File | null>(null);
99
const importLabelsFile = ref<File | null>(null);
1010
11-
const handleObjectDetectionImport = () => {
11+
// TODO gray out the button when model is uploading
12+
const handleImport = async () => {
1213
if (importRKNNFile.value === null || importLabelsFile.value === null) return;
1314
1415
const formData = new FormData();
@@ -50,7 +51,8 @@ const handleObjectDetectionImport = () => {
5051
}
5152
});
5253
53-
showObjectDetectionImportDialog.value = false;
54+
showImportDialog.value = false;
55+
5456
importRKNNFile.value = null;
5557
importLabelsFile.value = null;
5658
};
@@ -68,12 +70,12 @@ const supportedModels = computed(() => {
6870
<div class="pa-6 pt-0">
6971
<v-row>
7072
<v-col cols="12 ">
71-
<v-btn color="secondary" @click="() => (showObjectDetectionImportDialog = true)" class="justify-center">
73+
<v-btn color="secondary" @click="() => (showImportDialog = true)" class="justify-center">
7274
<v-icon left class="open-icon"> mdi-import </v-icon>
7375
<span class="open-label">Import New Model</span>
7476
</v-btn>
7577
<v-dialog
76-
v-model="showObjectDetectionImportDialog"
78+
v-model="showImportDialog"
7779
width="600"
7880
@input="
7981
() => {
@@ -105,7 +107,7 @@ const supportedModels = computed(() => {
105107
<v-btn
106108
color="secondary"
107109
:disabled="importRKNNFile === null || importLabelsFile === null"
108-
@click="handleObjectDetectionImport"
110+
@click="handleImport"
109111
>
110112
<v-icon left class="open-icon"> mdi-import </v-icon>
111113
<span class="open-label">Import Object Detection Model</span>

photon-core/src/main/java/org/photonvision/common/configuration/NeuralNetworkModelManager.java

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -221,29 +221,28 @@ private void loadModel(File model) {
221221
/**
222222
* Discovers DNN models from the specified folder.
223223
*
224-
* @param modelsFolder The folder where the models are stored
224+
* @param modelsDirectory The folder where the models are stored
225225
*/
226-
public void discoverModels(File modelsFolder) {
226+
public void discoverModels(File modelsDirectory) {
227227
logger.info("Supported backends: " + supportedBackends);
228228

229-
if (!modelsFolder.exists()) {
230-
logger.error("Models folder " + modelsFolder.getAbsolutePath() + " does not exist.");
229+
if (!modelsDirectory.exists()) {
230+
logger.error("Models folder " + modelsDirectory.getAbsolutePath() + " does not exist.");
231231
return;
232232
}
233233

234-
if (models == null) {
235-
models = new HashMap<>();
236-
}
234+
models = new HashMap<>();
237235

238236
try {
239-
Files.walk(modelsFolder.toPath())
237+
Files.walk(modelsDirectory.toPath())
240238
.filter(Files::isRegularFile)
241239
.forEach(path -> loadModel(path.toFile()));
242240
} catch (IOException e) {
243-
logger.error("Failed to discover models at " + modelsFolder.getAbsolutePath(), e);
241+
logger.error("Failed to discover models at " + modelsDirectory.getAbsolutePath(), e);
244242
}
245243

246-
// After loading all of the models, sort them by name to ensure a consistent ordering
244+
// After loading all of the models, sort them by name to ensure a consistent
245+
// ordering
247246
models.forEach(
248247
(backend, backendModels) ->
249248
backendModels.sort((a, b) -> a.getName().compareTo(b.getName())));

photon-server/src/main/java/org/photonvision/server/RequestHandler.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@
4242
import org.photonvision.common.dataflow.DataChangeDestination;
4343
import org.photonvision.common.dataflow.DataChangeService;
4444
import org.photonvision.common.dataflow.events.IncomingWebSocketEvent;
45+
import org.photonvision.common.dataflow.events.OutgoingUIEvent;
4546
import org.photonvision.common.dataflow.networktables.NetworkTablesManager;
47+
import org.photonvision.common.dataflow.websocket.UIPhotonConfiguration;
4648
import org.photonvision.common.hardware.HardwareManager;
4749
import org.photonvision.common.hardware.Platform;
4850
import org.photonvision.common.logging.LogGroup;
@@ -546,7 +548,7 @@ public static void onProgramRestartRequest(Context ctx) {
546548
restartProgram();
547549
}
548550

549-
public static void onObjectDetectionModelImportRequest(Context ctx) {
551+
public static void onImportObjectDetectionModelRequest(Context ctx) {
550552
try {
551553
// Retrieve the uploaded files
552554
var modelFile = ctx.uploadedFile("rknn");
@@ -579,7 +581,11 @@ public static void onObjectDetectionModelImportRequest(Context ctx) {
579581
Pattern.compile("^[a-zA-Z0-9]+-\\d+-\\d+-yolov[58][a-z]*-labels\\.txt$");
580582

581583
if (!modelPattern.matcher(modelFile.filename()).matches()
582-
|| !labelsPattern.matcher(labelsFile.filename()).matches()) {
584+
|| !labelsPattern.matcher(labelsFile.filename()).matches()
585+
|| !(modelFile
586+
.filename()
587+
.substring(0, modelFile.filename().indexOf("-"))
588+
.equals(labelsFile.filename().substring(0, labelsFile.filename().indexOf("-"))))) {
583589
ctx.status(400);
584590
ctx.result("The uploaded files were not named correctly.");
585591
logger.error("The uploaded object detection model files were not named correctly.");
@@ -610,6 +616,12 @@ public static void onObjectDetectionModelImportRequest(Context ctx) {
610616
} catch (Exception e) {
611617
ctx.status(500).result("Error processing files: " + e.getMessage());
612618
}
619+
620+
DataChangeService.getInstance()
621+
.publishEvent(
622+
new OutgoingUIEvent<>(
623+
"fullsettings",
624+
UIPhotonConfiguration.programStateToUi(ConfigManager.getInstance().getConfig())));
613625
}
614626

615627
public static void onDeviceRestartRequest(Context ctx) {

photon-server/src/main/java/org/photonvision/server/Server.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ private static void start(int port) {
102102
});
103103
});
104104

105-
/*Web Socket Events for Data Exchange */
105+
/* Web Socket Events for Data Exchange */
106106
var dsHandler = DataSocketHandler.getInstance();
107107
app.ws(
108108
"/websocket_data",
@@ -112,7 +112,7 @@ private static void start(int port) {
112112
ws.onBinaryMessage(dsHandler::onBinaryMessage);
113113
});
114114

115-
/*API Events*/
115+
/* API Events */
116116
// Settings
117117
app.post("/api/settings", RequestHandler::onSettingsImportRequest);
118118
app.get("/api/settings/photonvision_config.zip", RequestHandler::onSettingsExportRequest);
@@ -129,7 +129,7 @@ private static void start(int port) {
129129
app.post("/api/utils/offlineUpdate", RequestHandler::onOfflineUpdateRequest);
130130
app.post(
131131
"/api/utils/importObjectDetectionModel",
132-
RequestHandler::onObjectDetectionModelImportRequest);
132+
RequestHandler::onImportObjectDetectionModelRequest);
133133
app.get("/api/utils/photonvision-journalctl.txt", RequestHandler::onLogExportRequest);
134134
app.post("/api/utils/restartProgram", RequestHandler::onProgramRestartRequest);
135135
app.post("/api/utils/restartDevice", RequestHandler::onDeviceRestartRequest);

0 commit comments

Comments
 (0)