Skip to content

Commit 30ee913

Browse files
authored
Copy common fields when changing pipeline type (#1461)
Preserve common AdvancedPipelineSettings fields when switching pipeline types. This includes camera resolution, exposure settings, and stuff
1 parent 353a8ea commit 30ee913

File tree

2 files changed

+56
-7
lines changed

2 files changed

+56
-7
lines changed

photon-core/src/main/java/org/photonvision/vision/processes/PipelineManager.java

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
package org.photonvision.vision.processes;
1919

20+
import java.lang.reflect.Field;
2021
import java.util.ArrayList;
2122
import java.util.Arrays;
2223
import java.util.Comparator;
@@ -465,6 +466,17 @@ private static String createUniqueName(
465466
}
466467
}
467468

469+
private static List<Field> getAllFields(Class base) {
470+
List<Field> ret = new ArrayList<>();
471+
ret.addAll(List.of(base.getDeclaredFields()));
472+
var superclazz = base.getSuperclass();
473+
if (superclazz != null) {
474+
ret.addAll(getAllFields(superclazz));
475+
}
476+
477+
return ret;
478+
}
479+
468480
public void changePipelineType(int newType) {
469481
// Find the PipelineType proposed
470482
// To do this we look at all the PipelineType entries and look for one with
@@ -490,21 +502,38 @@ public void changePipelineType(int newType) {
490502
return;
491503
}
492504

493-
// Our new settings will be totally nuked, but that's ok
494-
// We *could* set things in common between the two, if we want
495-
// But they're different enough it shouldn't be an issue
496-
var name = getCurrentPipelineSettings().pipelineNickname;
497-
var newSettings = createSettingsForType(type, name);
498-
499505
var idx = currentPipelineIndex;
500506
if (idx < 0) {
501507
logger.error("Cannot replace non-user pipeline!");
502508
return;
503509
}
504510

511+
// The settings we used to have
512+
var oldSettings = userPipelineSettings.get(idx);
513+
514+
var name = getCurrentPipelineSettings().pipelineNickname;
515+
// Dummy settings to copy common fileds over
516+
var newSettings = createSettingsForType(type, name);
517+
518+
// Copy all fields from AdvancedPipelineSettings/its superclasses from old to new
519+
try {
520+
for (Field field : getAllFields(AdvancedPipelineSettings.class)) {
521+
Object value = field.get(oldSettings);
522+
logger.debug("setting " + field.getName() + " to " + value);
523+
field.set(newSettings, value);
524+
}
525+
} catch (Exception e) {
526+
logger.error("Couldn't copy old settings", e);
527+
}
528+
505529
logger.info("Adding new pipe of type " + type + " at idx " + idx);
530+
531+
// type gets overritten by reflction hackery above
506532
newSettings.pipelineIndex = idx;
533+
newSettings.pipelineType = type;
534+
507535
userPipelineSettings.set(idx, newSettings);
536+
508537
setPipelineInternal(idx);
509538
reassignIndexes();
510539
recreateUserPipeline();

photon-core/src/test/java/org/photonvision/vision/processes/PipelineManagerTest.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,21 @@
2020
import java.util.ArrayList;
2121
import java.util.List;
2222
import org.junit.jupiter.api.Assertions;
23+
import org.junit.jupiter.api.BeforeAll;
2324
import org.junit.jupiter.api.Test;
25+
import org.photonvision.common.configuration.ConfigManager;
2426
import org.photonvision.common.util.TestUtils;
2527
import org.photonvision.vision.pipeline.DriverModePipelineSettings;
2628
import org.photonvision.vision.pipeline.PipelineType;
2729

2830
public class PipelineManagerTest {
31+
@BeforeAll
32+
public static void init() {
33+
TestUtils.loadLibraries();
34+
}
35+
2936
@Test
3037
public void testUniqueName() {
31-
TestUtils.loadLibraries();
3238
PipelineManager manager = new PipelineManager(new DriverModePipelineSettings(), List.of(), -1);
3339
manager.addPipeline(PipelineType.Reflective, "Another");
3440

@@ -58,4 +64,18 @@ public void testUniqueName() {
5864
}
5965
Assertions.assertEquals(expected, nicks);
6066
}
67+
68+
@Test
69+
public void testChangeType() {
70+
// hack since we try to publish to datachangeservice
71+
ConfigManager.getInstance().load();
72+
73+
PipelineManager manager = new PipelineManager(new DriverModePipelineSettings(), List.of(), -1);
74+
// add a reflective pipeline
75+
manager.addPipeline(PipelineType.Reflective, "Another");
76+
manager.setIndex(0);
77+
manager.getCurrentPipeline();
78+
// and change
79+
manager.changePipelineType(PipelineType.Aruco.baseIndex);
80+
}
6181
}

0 commit comments

Comments
 (0)