Skip to content

Commit

Permalink
Merge branch 'master' into 2023-11-08_mrcal
Browse files Browse the repository at this point in the history
  • Loading branch information
mcm001 authored Dec 10, 2023
2 parents e2b8007 + 6db5bc5 commit 70a35a9
Show file tree
Hide file tree
Showing 101 changed files with 2,328 additions and 1,400 deletions.
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Steps to reproduce the behavior:
4. See error

**Screenshots / Videos**
If applicable, add screenshots to help explain your problem. Additionally, provide journalctl logs and settings zip export.
If applicable, add screenshots to help explain your problem. Additionally, provide journalctl logs and settings zip export. If your issue is regarding the web dashboard, please provide screenshots and the output of the browser console.

**Platform:**
- Hardware Platform (ex. Raspberry Pi 4, Windows x64):
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ jobs:
path: build/html
build-photonlib-host:
env:
MACOSX_DEPLOYMENT_TARGET: 11
MACOSX_DEPLOYMENT_TARGET: 12
strategy:
fail-fast: false
matrix:
Expand Down
15 changes: 6 additions & 9 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
plugins {
id "com.diffplug.spotless" version "6.22.0"
id "edu.wpi.first.NativeUtils" version "2024.2.0" apply false
id "edu.wpi.first.NativeUtils" version "2024.3.2" apply false
id "edu.wpi.first.wpilib.repositories.WPILibRepositoriesPlugin" version "2020.2"
id "edu.wpi.first.GradleRIO" version "2024.1.1-beta-3"
id 'edu.wpi.first.WpilibTools' version '1.3.0'
Expand All @@ -22,6 +22,7 @@ apply from: "versioningHelper.gradle"

ext {
wpilibVersion = "2024.1.1-beta-3"
wpimathVersion = wpilibVersion
openCVversion = "4.8.0-2"
joglVersion = "2.4.0-rc-20200307"
javalinVersion = "5.6.2"
Expand All @@ -38,16 +39,12 @@ ext {
if (wpilibNativeName == "macx64") nativeName = "osxx86-64";
if (wpilibNativeName == "macarm64") nativeName = "osxarm64";
jniPlatform = nativeName
println("Building for platform " + jniPlatform + " wpilib: " + wpilibNativeName)

println("Building for platform: " + jniPlatform + " wpilib: " + wpilibNativeName)
println("Using Wpilib: " + wpilibVersion)
println("Using OpenCV: " + openCVversion)
}

wpilibTools.deps.wpilibVersion = wpilibVersion

// Tell gradlerio what version of things to use (that we care about)
// See: https://github.com/wpilibsuite/GradleRIO/blob/main/src/main/java/edu/wpi/first/gradlerio/wpi/WPIVersionsExtension.java
wpi.getVersions().getOpencvVersion().convention(openCVversion);
wpi.getVersions().getWpilibVersion().convention(wpilibVersion);

spotless {
java {
target fileTree('.') {
Expand Down
39 changes: 23 additions & 16 deletions photon-client/src/components/app/photon-camera-stream.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import PvIcon from "@/components/common/pv-icon.vue";
const props = defineProps<{
streamType: "Raw" | "Processed";
id?: string;
id: string;
}>();
const streamSrc = computed<string>(() => {
Expand All @@ -25,8 +25,6 @@ const streamDesc = computed<string>(() => `${props.streamType} Stream View`);
const streamStyle = computed<StyleValue>(() => {
if (useStateStore().colorPickingMode) {
return { width: "100%", cursor: "crosshair" };
} else if (streamSrc.value !== loadingImage) {
return { width: "100%", cursor: "pointer" };
}
return { width: "100%" };
Expand All @@ -40,37 +38,45 @@ const overlayStyle = computed<StyleValue>(() => {
}
});
const handleStreamClick = () => {
if (!useStateStore().colorPickingMode && streamSrc.value !== loadingImage) {
window.open(streamSrc.value);
}
};
const handleCaptureClick = () => {
if (props.streamType === "Raw") {
useCameraSettingsStore().saveInputSnapshot();
} else {
useCameraSettingsStore().saveOutputSnapshot();
}
};
const handlePopoutClick = () => {
window.open(streamSrc.value);
};
const handleFullscreenRequest = () => {
const stream = document.getElementById(props.id);
if (!stream) return;
stream.requestFullscreen();
};
</script>

<template>
<div class="stream-container">
<img
:id="id"
crossorigin="anonymous"
:src="streamSrc"
:alt="streamDesc"
:style="streamStyle"
@click="handleStreamClick"
/>
<img :id="id" crossorigin="anonymous" :src="streamSrc" :alt="streamDesc" :style="streamStyle" />
<div class="stream-overlay" :style="overlayStyle">
<pv-icon
icon-name="mdi-camera-image"
tooltip="Capture and save a frame of this stream"
class="ma-1 mr-2"
@click="handleCaptureClick"
/>
<pv-icon
icon-name="mdi-fullscreen"
tooltip="Open this stream in fullscreen"
class="ma-1 mr-2"
@click="handleFullscreenRequest"
/>
<pv-icon
icon-name="mdi-open-in-new"
tooltip="Open this stream in a new window"
class="ma-1 mr-2"
@click="handlePopoutClick"
/>
</div>
</div>
</template>
Expand All @@ -81,6 +87,7 @@ const handleCaptureClick = () => {
}
.stream-overlay {
display: flex;
opacity: 0;
transition: 0.1s ease;
position: absolute;
Expand Down
14 changes: 12 additions & 2 deletions photon-client/src/components/cameras/CamerasView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,20 @@ const fpsTooLow = computed<boolean>(() => {
</v-card-title>
<div class="stream-container pb-4">
<div class="stream">
<photon-camera-stream v-show="value.includes(0)" stream-type="Raw" style="max-width: 100%" />
<photon-camera-stream
v-show="value.includes(0)"
id="input-camera-stream"
stream-type="Raw"
style="max-width: 100%"
/>
</div>
<div class="stream">
<photon-camera-stream v-show="value.includes(1)" stream-type="Processed" style="max-width: 100%" />
<photon-camera-stream
v-show="value.includes(1)"
id="output-camera-stream"
stream-type="Processed"
style="max-width: 100%"
/>
</div>
</div>
<v-divider />
Expand Down
13 changes: 10 additions & 3 deletions photon-client/src/components/dashboard/tabs/TargetsTab.vue
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ const currentPipelineSettings = useCameraSettingsStore().currentPipelineSettings
useCameraSettingsStore().currentPipelineSettings.solvePNPEnabled
"
>
<th class="text-center">Ambiguity %</th>
<th class="text-center">Ambiguity Ratio</th>
</template>
</tr>
</thead>
Expand Down Expand Up @@ -73,7 +73,7 @@ const currentPipelineSettings = useCameraSettingsStore().currentPipelineSettings
useCameraSettingsStore().currentPipelineSettings.solvePNPEnabled
"
>
<td>{{ target.ambiguity >= 0 ? target.ambiguity?.toFixed(2) + "%" : "(In Multi-Target)" }}</td>
<td>{{ target.ambiguity >= 0 ? target.ambiguity.toFixed(2) : "(In Multi-Target)" }}</td>
</template>
</tr>
</tbody>
Expand Down Expand Up @@ -102,7 +102,14 @@ const currentPipelineSettings = useCameraSettingsStore().currentPipelineSettings
<tbody v-show="useStateStore().currentPipelineResults?.multitagResult">
<td>{{ useStateStore().currentPipelineResults?.multitagResult?.bestTransform.x.toFixed(2) }}&nbsp;m</td>
<td>{{ useStateStore().currentPipelineResults?.multitagResult?.bestTransform.y.toFixed(2) }}&nbsp;m</td>
<td>{{ useStateStore().currentPipelineResults?.multitagResult?.bestTransform.angle_z.toFixed(2) }}&deg;</td>
<td>
{{
(
useStateStore().currentPipelineResults?.multitagResult?.bestTransform.angle_z *
(180.0 / Math.PI)
).toFixed(2)
}}&deg;
</td>
<td>{{ useStateStore().currentPipelineResults?.multitagResult?.fiducialIDsUsed }}</td>
</tbody>
</v-simple-table>
Expand Down
18 changes: 2 additions & 16 deletions photon-core/build.gradle
Original file line number Diff line number Diff line change
@@ -1,41 +1,27 @@
plugins {
id 'edu.wpi.first.WpilibTools' version '1.3.0'
}

import java.nio.file.Path

apply from: "${rootDir}/shared/common.gradle"

dependencies {
implementation project(':photon-targeting')

implementation "io.javalin:javalin:$javalinVersion"

implementation 'org.msgpack:msgpack-core:0.9.0'
implementation 'org.msgpack:jackson-dataformat-msgpack:0.9.0'

// JOGL stuff (currently we only distribute for aarch64, which is Pi 4)
implementation "org.jogamp.gluegen:gluegen-rt:$joglVersion"
implementation "org.jogamp.jogl:jogl-all:$joglVersion"

implementation "org.jogamp.gluegen:gluegen-rt:$joglVersion:natives-linux-aarch64"
implementation "org.jogamp.jogl:jogl-all:$joglVersion:natives-linux-aarch64"

// Zip
implementation 'org.zeroturnaround:zt-zip:1.14'

implementation wpilibTools.deps.wpilibJava("apriltag")

implementation "org.xerial:sqlite-jdbc:3.41.0.0"

implementation "org.photonvision:photon-mrcal-java:dev-Unknown"
implementation "org.photonvision:photon-mrcal-jni:dev-Unknown:" + wpilibNativeName;
}

task writeCurrentVersionJava {
task writeCurrentVersion {
def versionFileIn = file("${rootDir}/shared/PhotonVersion.java.in")
writePhotonVersionFile(versionFileIn, Path.of("$projectDir", "src", "main", "java", "org", "photonvision", "PhotonVersion.java"),
versionString)
}

build.dependsOn writeCurrentVersionJava
build.dependsOn writeCurrentVersion
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ static class TableKeys {
static final String CAM_UNIQUE_NAME = "unique_name";
static final String CONFIG_JSON = "config_json";
static final String DRIVERMODE_JSON = "drivermode_json";
static final String OTHERPATHS_JSON = "otherpaths_json";
static final String PIPELINE_JSONS = "pipeline_jsons";

static final String NETWORK_CONFIG = "networkConfig";
Expand Down Expand Up @@ -147,6 +148,7 @@ private void initDatabase() {
+ " unique_name TINYTEXT PRIMARY KEY,\n"
+ " config_json text NOT NULL,\n"
+ " drivermode_json text NOT NULL,\n"
+ " otherpaths_json text NOT NULL,\n"
+ " pipeline_jsons mediumtext NOT NULL\n"
+ ");";
createCameraTableStatement.execute(sql);
Expand Down Expand Up @@ -295,8 +297,8 @@ private void saveCameras(Connection conn) {
try {
// Replace this camera's row with the new settings
var sqlString =
"REPLACE INTO cameras (unique_name, config_json, drivermode_json, pipeline_jsons) VALUES "
+ "(?,?,?,?);";
"REPLACE INTO cameras (unique_name, config_json, drivermode_json, otherpaths_json, pipeline_jsons) VALUES "
+ "(?,?,?,?,?);";

for (var c : config.getCameraConfigurations().entrySet()) {
PreparedStatement statement = conn.prepareStatement(sqlString);
Expand All @@ -305,6 +307,7 @@ private void saveCameras(Connection conn) {
statement.setString(1, c.getKey());
statement.setString(2, JacksonUtils.serializeToString(config));
statement.setString(3, JacksonUtils.serializeToString(config.driveModeSettings));
statement.setString(4, JacksonUtils.serializeToString(config.otherPaths));

// Serializing a list of abstract classes sucks. Instead, make it into an array
// of strings, which we can later unpack back into individual settings
Expand All @@ -321,7 +324,7 @@ private void saveCameras(Connection conn) {
})
.filter(Objects::nonNull)
.collect(Collectors.toList());
statement.setString(4, JacksonUtils.serializeToString(settings));
statement.setString(5, JacksonUtils.serializeToString(settings));

statement.executeUpdate();
}
Expand Down Expand Up @@ -455,10 +458,11 @@ private HashMap<String, CameraConfiguration> loadCameraConfigs(Connection conn)
query =
conn.prepareStatement(
String.format(
"SELECT %s, %s, %s, %s FROM cameras",
"SELECT %s, %s, %s, %s, %s FROM cameras",
TableKeys.CAM_UNIQUE_NAME,
TableKeys.CONFIG_JSON,
TableKeys.DRIVERMODE_JSON,
TableKeys.OTHERPATHS_JSON,
TableKeys.PIPELINE_JSONS));

var result = query.executeQuery();
Expand All @@ -474,6 +478,8 @@ private HashMap<String, CameraConfiguration> loadCameraConfigs(Connection conn)
var driverMode =
JacksonUtils.deserialize(
result.getString(TableKeys.DRIVERMODE_JSON), DriverModePipelineSettings.class);
var otherPaths =
JacksonUtils.deserialize(result.getString(TableKeys.OTHERPATHS_JSON), String[].class);
List<?> pipelineSettings =
JacksonUtils.deserialize(
result.getString(TableKeys.PIPELINE_JSONS), dummyList.getClass());
Expand All @@ -487,6 +493,7 @@ private HashMap<String, CameraConfiguration> loadCameraConfigs(Connection conn)

config.pipelineSettings = loadedSettings;
config.driveModeSettings = driverMode;
config.otherPaths = otherPaths;
loadedConfigurations.put(uniqueName, config);
}
} catch (SQLException | IOException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public enum PiVersion {
ZERO_2_W("Raspberry Pi Zero 2"),
PI_3("Pi 3"),
PI_4("Pi 4"),
PI_5("Pi 5"),
COMPUTE_MODULE_3("Compute Module 3"),
UNKNOWN("UNKNOWN");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

package org.photonvision.vision.camera;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
Expand Down Expand Up @@ -108,8 +110,20 @@ public static QuirkyCamera getQuirkyCamera(int usbVid, int usbPid, String baseNa
for (var qc : quirkyCameras) {
boolean hasBaseName = !qc.baseName.isEmpty();
boolean matchesBaseName = qc.baseName.equals(baseName) || !hasBaseName;
// If we have a quirkycamera we need to copy the quirks from our predefined object and create
// a quirkycamera object with the baseName.
if (qc.usbVid == usbVid && qc.usbPid == usbPid && matchesBaseName) {
return qc;
List<CameraQuirk> quirks = new ArrayList<CameraQuirk>();
for (var q : CameraQuirk.values()) {
if (qc.hasQuirk(q)) quirks.add(q);
}
QuirkyCamera c =
new QuirkyCamera(
usbVid,
usbPid,
baseName,
Arrays.copyOf(quirks.toArray(), quirks.size(), CameraQuirk[].class));
return c;
}
}
return new QuirkyCamera(usbVid, usbPid, baseName);
Expand Down
Loading

0 comments on commit 70a35a9

Please sign in to comment.