mirror of
https://github.com/PhotonVision/photonvision
synced 2026-06-19 00:41:41 +00:00
Update mrcal-java (#2214)
## Description Updating to take advantage of the now independent mrcal-java (no longer need to install SuiteSparse and friends!) ## Meta Merge checklist: - [x] Pull Request title is [short, imperative summary](https://cbea.ms/git-commit/) of proposed changes - [x] The description documents the _what_ and _why_ - [ ] If this PR changes behavior or adds a feature, user documentation is updated - [ ] If this PR touches photon-serde, all messages have been regenerated and hashes have not changed unexpectedly - [ ] If this PR touches configuration, this is backwards compatible with settings back to v2025.3.2 - [ ] If this PR touches pipeline settings or anything related to data exchange, the frontend typing is updated - [ ] If this PR addresses a bug, a regression test for it is added --------- Co-authored-by: Matt Morley <matthew.morley.ca@gmail.com>
This commit is contained in:
23
.github/workflows/build.yml
vendored
23
.github/workflows/build.yml
vendored
@@ -50,15 +50,24 @@ jobs:
|
||||
distribution: temurin
|
||||
- name: Install RoboRIO Toolchain
|
||||
run: ./gradlew installRoboRioToolchain
|
||||
- name: Delete duplicate toolchains
|
||||
run: |
|
||||
find ~/.gradle/cache/ -name *roborio-academic* -exec rm -rf {} +
|
||||
du -h . | sort -h
|
||||
if: matrix.os == 'ubuntu-22.04'
|
||||
# Need to publish to maven local first, so that C++ sim can pick it up
|
||||
- name: Publish photonlib to maven local
|
||||
run: ./gradlew photon-targeting:publishtomavenlocal photon-lib:publishtomavenlocal -x check
|
||||
- name: Build Java examples
|
||||
working-directory: photonlib-java-examples
|
||||
run: ./gradlew build
|
||||
run: |
|
||||
./gradlew build
|
||||
./gradlew clean
|
||||
- name: Build C++ examples
|
||||
working-directory: photonlib-cpp-examples
|
||||
run: ./gradlew build
|
||||
run: |
|
||||
./gradlew build
|
||||
./gradlew clean
|
||||
playwright-tests:
|
||||
name: "Playwright E2E tests"
|
||||
runs-on: ubuntu-22.04
|
||||
@@ -84,8 +93,6 @@ jobs:
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22
|
||||
- name: Install mrcal deps
|
||||
run: sudo apt-get update && sudo apt-get install -y libcholmod3 liblapack3 libsuitesparseconfig5
|
||||
- name: Setup tests
|
||||
working-directory: photon-client
|
||||
run: |
|
||||
@@ -127,8 +134,6 @@ jobs:
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22
|
||||
- name: Install mrcal deps
|
||||
run: sudo apt-get update && sudo apt-get install -y libcholmod3 liblapack3 libsuitesparseconfig5
|
||||
- name: Gradle Build
|
||||
run: ./gradlew photon-targeting:build photon-core:build photon-server:build -x check
|
||||
- name: Gradle Tests and Coverage
|
||||
@@ -399,12 +404,6 @@ jobs:
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: ${{ matrix.artifact-name }}
|
||||
# On linux, install mrcal packages
|
||||
- run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install --yes libcholmod3 liblapack3 libsuitesparseconfig5
|
||||
if: ${{ (matrix.os) == 'ubuntu-24.04' }}
|
||||
# and actually run the jar
|
||||
- run: java -jar ${{ matrix.extraOpts }} *.jar --smoketest
|
||||
if: ${{ (matrix.os) != 'windows-latest' }}
|
||||
- run: ls *.jar | %{ Write-Host "Running $($_.Name)"; Start-Process "java" -ArgumentList "-jar `"$($_.FullName)`" --smoketest" -NoNewWindow -Wait; break }
|
||||
|
||||
@@ -58,14 +58,6 @@ PhotonVision uses the following additional out-of-source repositories for buildi
|
||||
- Custom build of OpenCV with GStreamer/Protobuf/other custom flags: https://github.com/PhotonVision/thirdparty-opencv
|
||||
- JNI code for aruco-nano: https://github.com/PhotonVision/aruconano-jni
|
||||
|
||||
## Additional packages
|
||||
|
||||
For now, using mrcal requires installing these additional packages on Linux systems:
|
||||
|
||||
```
|
||||
sudo apt install libcholmod3 liblapack3 libsuitesparseconfig5
|
||||
```
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
PhotonVision was forked from [Chameleon Vision](https://github.com/Chameleon-Vision/chameleon-vision/). Thank you to everyone who worked on the original project.
|
||||
|
||||
@@ -41,7 +41,7 @@ ext {
|
||||
rknnVersion = "dev-v2025.0.0-5-g666c0c6"
|
||||
rubikVersion = "dev-v2025.1.0-6-g4a5e508"
|
||||
frcYear = "2025"
|
||||
mrcalVersion = "v2025.0.0";
|
||||
mrcalVersion = "dev-v2025.0.0-2-g2adb187";
|
||||
|
||||
|
||||
pubVersion = versionString
|
||||
|
||||
@@ -56,7 +56,7 @@ dependencies {
|
||||
"osxx86-64",
|
||||
"osxarm64"
|
||||
])) {
|
||||
implementation("org.photonvision:photon-mrcal-jni:$mrcalVersion:$wpilibNativeName") {
|
||||
wpilibNatives("org.photonvision:photon-mrcal-jni:$mrcalVersion:$wpilibNativeName") {
|
||||
transitive = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.photonvision.common.dataflow.networktables.NetworkTablesManager;
|
||||
import org.photonvision.common.hardware.Platform;
|
||||
import org.photonvision.common.networking.NetworkManager;
|
||||
import org.photonvision.common.networking.NetworkUtils;
|
||||
import org.photonvision.mrcal.MrCalJNILoader;
|
||||
import org.photonvision.common.util.TestUtils;
|
||||
import org.photonvision.raspi.LibCameraJNILoader;
|
||||
import org.photonvision.vision.processes.VisionModule;
|
||||
import org.photonvision.vision.processes.VisionSourceManager;
|
||||
@@ -54,7 +54,7 @@ public class UIPhotonConfiguration {
|
||||
PhotonVersion.versionString,
|
||||
// TODO add support for other types of GPU accel
|
||||
LibCameraJNILoader.getInstance().isSupported() ? "Zerocopy Libcamera Working" : "",
|
||||
MrCalJNILoader.getInstance().isLoaded(),
|
||||
TestUtils.isMrcalLoaded(),
|
||||
c.neuralNetworkPropertyManager().getModels(),
|
||||
NeuralNetworkModelManager.getInstance().getSupportedBackends(),
|
||||
c.getHardwareConfig().deviceName.isEmpty()
|
||||
|
||||
@@ -20,6 +20,7 @@ package org.photonvision.common.util;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import edu.wpi.first.math.geometry.Translation2d;
|
||||
import edu.wpi.first.math.util.Units;
|
||||
import edu.wpi.first.util.CombinedRuntimeLoader;
|
||||
import java.awt.HeadlessException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -32,10 +33,28 @@ import org.photonvision.vision.pipeline.result.CVPipelineResult;
|
||||
import org.photonvision.vision.target.TrackedTarget;
|
||||
|
||||
public class TestUtils {
|
||||
private static boolean hasMrcalLoaded = false;
|
||||
|
||||
public static boolean loadLibraries() {
|
||||
return LibraryLoader.loadWpiLibraries() && LibraryLoader.loadTargeting();
|
||||
}
|
||||
|
||||
public static boolean loadMrcal() {
|
||||
if (hasMrcalLoaded) return true;
|
||||
try {
|
||||
CombinedRuntimeLoader.loadLibraries(TestUtils.class, "mrcal_jni");
|
||||
hasMrcalLoaded = true;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
hasMrcalLoaded = false;
|
||||
}
|
||||
return hasMrcalLoaded;
|
||||
}
|
||||
|
||||
public static boolean isMrcalLoaded() {
|
||||
return hasMrcalLoaded;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public enum WPI2019Image {
|
||||
kCargoAngledDark48in(1.2192),
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Photon Vision.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.photonvision.mrcal;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import org.photonvision.common.hardware.Platform;
|
||||
import org.photonvision.common.util.TestUtils;
|
||||
import org.photonvision.jni.PhotonJNICommon;
|
||||
|
||||
public class MrCalJNILoader extends PhotonJNICommon {
|
||||
private boolean isLoaded;
|
||||
private static MrCalJNILoader instance = null;
|
||||
|
||||
private MrCalJNILoader() {
|
||||
isLoaded = false;
|
||||
}
|
||||
|
||||
public static synchronized MrCalJNILoader getInstance() {
|
||||
if (instance == null) instance = new MrCalJNILoader();
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static synchronized void forceLoad() throws IOException {
|
||||
// Force load opencv
|
||||
TestUtils.loadLibraries();
|
||||
|
||||
// Library naming is dumb and has "lib" appended for Windows when it ought not to
|
||||
if (Platform.isWindows()) {
|
||||
// Order is correct to match dependencies of libraries
|
||||
forceLoad(
|
||||
MrCalJNILoader.getInstance(),
|
||||
MrCalJNILoader.class,
|
||||
List.of(
|
||||
"libamd",
|
||||
"libcamd",
|
||||
"libcolamd",
|
||||
"libccolamd",
|
||||
"openblas",
|
||||
"libwinpthread-1",
|
||||
"libgcc_s_seh-1",
|
||||
"libquadmath-0",
|
||||
"libgfortran-5",
|
||||
"liblapack",
|
||||
"libcholmod",
|
||||
"mrcal_jni"));
|
||||
} else {
|
||||
// Nothing else to do on linux
|
||||
forceLoad(MrCalJNILoader.getInstance(), MrCalJNILoader.class, List.of("mrcal_jni"));
|
||||
}
|
||||
|
||||
if (!MrCalJNILoader.getInstance().isLoaded()) {
|
||||
throw new IOException("Unable to load mrcal JNI!");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLoaded() {
|
||||
return isLoaded;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLoaded(boolean state) {
|
||||
isLoaded = state;
|
||||
}
|
||||
}
|
||||
@@ -29,10 +29,10 @@ import org.opencv.core.*;
|
||||
import org.opencv.imgcodecs.Imgcodecs;
|
||||
import org.photonvision.common.logging.LogGroup;
|
||||
import org.photonvision.common.logging.Logger;
|
||||
import org.photonvision.common.util.TestUtils;
|
||||
import org.photonvision.common.util.math.MathUtils;
|
||||
import org.photonvision.mrcal.MrCalJNI;
|
||||
import org.photonvision.mrcal.MrCalJNI.MrCalResult;
|
||||
import org.photonvision.mrcal.MrCalJNILoader;
|
||||
import org.photonvision.vision.calibration.BoardObservation;
|
||||
import org.photonvision.vision.calibration.CameraCalibrationCoefficients;
|
||||
import org.photonvision.vision.calibration.CameraLensModel;
|
||||
@@ -94,7 +94,7 @@ public class Calibrate3dPipe
|
||||
CameraCalibrationCoefficients ret;
|
||||
var start = System.nanoTime();
|
||||
|
||||
if (MrCalJNILoader.getInstance().isLoaded() && params.useMrCal) {
|
||||
if (TestUtils.isMrcalLoaded() && params.useMrCal) {
|
||||
logger.debug("Calibrating with mrcal!");
|
||||
ret =
|
||||
calibrateMrcal(
|
||||
|
||||
@@ -37,7 +37,6 @@ import org.photonvision.common.logging.LogGroup;
|
||||
import org.photonvision.common.logging.LogLevel;
|
||||
import org.photonvision.common.logging.Logger;
|
||||
import org.photonvision.common.util.TestUtils;
|
||||
import org.photonvision.mrcal.MrCalJNILoader;
|
||||
import org.photonvision.vision.calibration.CameraCalibrationCoefficients;
|
||||
import org.photonvision.vision.camera.QuirkyCamera;
|
||||
import org.photonvision.vision.frame.Frame;
|
||||
@@ -52,7 +51,7 @@ public class Calibrate3dPipeTest {
|
||||
@BeforeAll
|
||||
public static void init() throws IOException {
|
||||
TestUtils.loadLibraries();
|
||||
MrCalJNILoader.forceLoad();
|
||||
TestUtils.loadMrcal();
|
||||
|
||||
var logLevel = LogLevel.DEBUG;
|
||||
Logger.setLevel(LogGroup.Camera, logLevel);
|
||||
|
||||
@@ -35,7 +35,6 @@ import org.photonvision.common.logging.LogLevel;
|
||||
import org.photonvision.common.logging.Logger;
|
||||
import org.photonvision.common.util.TestUtils;
|
||||
import org.photonvision.estimation.OpenCVHelp;
|
||||
import org.photonvision.mrcal.MrCalJNILoader;
|
||||
import org.photonvision.vision.calibration.CameraCalibrationCoefficients;
|
||||
import org.photonvision.vision.calibration.CameraLensModel;
|
||||
import org.photonvision.vision.calibration.JsonMatOfDouble;
|
||||
@@ -50,7 +49,7 @@ public class CalibrationRotationPipeTest {
|
||||
@BeforeAll
|
||||
public static void init() throws IOException {
|
||||
TestUtils.loadLibraries();
|
||||
MrCalJNILoader.forceLoad();
|
||||
TestUtils.loadMrcal();
|
||||
|
||||
var logLevel = LogLevel.DEBUG;
|
||||
Logger.setLevel(LogGroup.Camera, logLevel);
|
||||
|
||||
@@ -41,7 +41,6 @@ import org.photonvision.common.util.TestUtils;
|
||||
import org.photonvision.jni.LibraryLoader;
|
||||
import org.photonvision.jni.RknnDetectorJNI;
|
||||
import org.photonvision.jni.RubikDetectorJNI;
|
||||
import org.photonvision.mrcal.MrCalJNILoader;
|
||||
import org.photonvision.raspi.LibCameraJNILoader;
|
||||
import org.photonvision.server.Server;
|
||||
import org.photonvision.vision.apriltag.AprilTagFamily;
|
||||
@@ -262,8 +261,8 @@ public class Main {
|
||||
logger.error("Failed to load rubik-JNI!", e);
|
||||
}
|
||||
try {
|
||||
MrCalJNILoader.forceLoad();
|
||||
} catch (IOException e) {
|
||||
TestUtils.loadMrcal();
|
||||
} catch (Exception e) {
|
||||
logger.warn(
|
||||
"Failed to load mrcal-JNI! Camera calibration will fall back to opencv\n"
|
||||
+ e.getMessage());
|
||||
|
||||
Reference in New Issue
Block a user