Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create photon-core JNI #1067

Draft
wants to merge 11 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Note that these are case sensitive!
* x86
- `-PtgtIp`: Specifies where `./gradlew deploy` should try to copy the fat JAR to
- `-Pprofile`: enables JVM profiling
- `doJniCheck`: Enables checking JNI symbol matching between Java/C++

## Building

Expand Down Expand Up @@ -59,6 +60,10 @@ To run them, use the commands listed below. Photonlib must first be published to
~/photonvision/photonlib-cpp-examples$ ./gradlew <example-name>:simulateNative
```

## Installing cross-toolchains

Install cross toolchains using `./gradlew installArm64Toolchain`/`./gradlew installRoboRioToolchain`. Needed for building for arm64 or rio targets.


## Acknowledgments
PhotonVision was forked from [Chameleon Vision](https://github.com/Chameleon-Vision/chameleon-vision/). Thank you to everyone who worked on the original project.
Expand Down
8 changes: 8 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
plugins {
id "java"
id "cpp"
id "com.diffplug.spotless" version "6.22.0"
id "edu.wpi.first.NativeUtils" version "2024.6.1" apply false
id "edu.wpi.first.wpilib.repositories.WPILibRepositoriesPlugin" version "2020.2"
id "edu.wpi.first.GradleRIO" version "2024.1.1-beta-4"
id 'edu.wpi.first.WpilibTools' version '1.3.0'
id 'edu.wpi.first.GradleJni' version '1.1.0'
}

allprojects {
Expand Down Expand Up @@ -90,3 +93,8 @@ spotless {
wrapper {
gradleVersion '8.4'
}

import edu.wpi.first.toolchain.NativePlatforms
ext.getCurrentArch = {
return NativePlatforms.desktop
}
136 changes: 136 additions & 0 deletions photon-core/build.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,27 @@
plugins {
id 'edu.wpi.first.WpilibTools' version '1.3.0'
}

import java.nio.file.Path

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

ext {
nativeName = "photoncore"

main_native_libs = ["opencv_shared"]

test_native_libs = ["opencv_shared"]

dev_native_libs = [
"opencv_shared",
]
}

def sharedCvConfigs = [photoncore: []]
def staticCvConfigs = [:]


dependencies {
// JOGL stuff (currently we only distribute for aarch64, which is Pi 4)
implementation "org.jogamp.gluegen:gluegen-rt:$joglVersion"
Expand All @@ -22,3 +42,119 @@ task writeCurrentVersion {
}

build.dependsOn writeCurrentVersion

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

apply plugin: 'edu.wpi.first.GradleJni'

def nativeOutputDir = file("$buildDir/${nativeName}_outs")
println("Saving to $nativeOutputDir")

model {
components {
"${nativeName}JNI"(JniNativeLibrarySpec) {
baseName = nativeName + 'jni'

enableCheckTask project.hasProperty('doJniCheck')
javaCompileTasks << compileJava
jniCrossCompileOptions << JniCrossCompileOptions(nativeUtils.wpi.platforms.roborio)
jniCrossCompileOptions << JniCrossCompileOptions(nativeUtils.wpi.platforms.linuxarm32)
jniCrossCompileOptions << JniCrossCompileOptions(nativeUtils.wpi.platforms.linuxarm64)

sources {
cpp {
source {
srcDirs 'src/main/native/jni'
if (project.hasProperty('generatedSources')) {
srcDir generatedSources
}
include '**/*.cpp'
}
exportedHeaders {
srcDir 'src/main/native/include'
if (project.hasProperty('generatedHeaders')) {
srcDir generatedHeaders
}
include '**/*.h'
}
}
}

binaries.all {
if (it instanceof StaticLibraryBinarySpec) {
it.buildable = false
return
}
lib library: "${nativeName}", linkage: 'static'
if (project.hasProperty('jniSplitSetup')) {
jniSplitSetup(it)
}
}

if(project.hasProperty("jni_native_libs")) jni_native_libs.each { name ->
nativeUtils.useRequiredLibrary(it, name)
}

appendDebugPathToBinaries(binaries)
}
}

tasks {
def ts = $.components
project.tasks.register('copyPhotonCoreNative') { testTask->
// println("Hello!")
def systemArch = wpilibTools.getCurrentPlatform().platformName
def sharedLibs = []
ts.each {
// println("=========")
// println it.baseName
it.binaries.each {
def arch = it.targetPlatform.name
// println("checking $arch against $systemArch")
if (arch == systemArch && it.buildType.name == 'release' && it instanceof SharedLibraryBinarySpec) {
testTask.dependsOn it.tasks.build

println "Selecting ${it}"
// println it.tasks
// println it.getSharedLibraryFile()
// println it.tasks.build.class
// def f = it.sharedLibraryFile.parentFile;


sharedLibs << it
testTask.dependsOn it
}
}
}

doLast {
sharedLibs.each { so ->
def arch = so.targetPlatform.architecture.name
def os = so.targetPlatform.operatingSystem.name

copy {
from so.sharedLibraryFile
// We know all should be shared libs only at this point
into file(nativeOutputDir.path + "/${nativeUtils.getPlatformPath(so)}/shared")
}
}
}
}
}
}

// yay misdirection
// tasks.register('testDesktop') {
// dependsOn copyPhotonCoreNative
// }
// jar.dependsOn tasks.named('testDesktop')

// jar {
// from nativeOutputDir
// println("Adding to JAR $nativeOutputDir")
// }


// Make sure our files get added to resources, and that build happens before JAR does
// sourceSets.main.resources.srcDirs += nativeOutputDir
// println sourceSets.main.resources.srcDirs
31 changes: 31 additions & 0 deletions photon-core/src/dev/native/cpp/devmain.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* 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/>.
*/

#include <cstdio>

// Includes to test opencv linkage
#include <opencv2/core.hpp>
#include <opencv2/core/mat.hpp>
#include <opencv2/imgcodecs.hpp>

#include "test.h"

int main() {
// Just empty to check library linking happens

return 1;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* 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.jni;

public class CalibrationHelper {
public static class CalResult {}

public static native long Create(int width, int height, long overlayMatPtr, double tolerance);

public static native long Destroy();

public static native CalResult Detect(long inputImg, long outputImg);

public static void main(String[] args) {
System.load(
"/home/matt/Documents/GitHub/photonvision/photon-core/build/libs/photoncoreJNI/shared/linuxx86-64/release/libphotoncorejni.so");
System.out.println(Create(1, 2, 3, 4));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ public static boolean isSupported() {
*
* @param width Camera video mode width in pixels
* @param height Camera video mode height in pixels
* @param fps Camera video mode FPS
* @param rotation Asdf
* @return success of creating a camera object
*/
public static native boolean createCamera(int width, int height, int rotation);
Expand Down
34 changes: 34 additions & 0 deletions photon-core/src/main/native/cpp/test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* 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/>.
*/

#include "test.h"

#include <cstdio>

#include <opencv2/core.hpp>
#include <opencv2/core/mat.hpp>
#include <opencv2/imgcodecs.hpp>

int some_test() {
cv::Mat mat = cv::imread(
"/home/matt/Documents/GitHub/photonvision/test-resources/testimages/2022/"
"WPI/FarLaunchpad13ft10in.png");

std::printf("mat size %i %i\n", mat.rows, mat.cols);

return 1;
}
19 changes: 19 additions & 0 deletions photon-core/src/main/native/include/test.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* 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/>.
*/

#pragma once
int some_test();
34 changes: 34 additions & 0 deletions photon-core/src/main/native/jni/CalibrationHelperJni.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* 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/>.
*/

#include <org_photonvision_jni_CalibrationHelper.h>

extern "C" {

/*
* Class: org_photonvision_jni_CalibrationHelper
* Method: Create
* Signature: (IIJD)J
*/
JNIEXPORT jlong JNICALL
Java_org_photonvision_jni_CalibrationHelper_Create
(JNIEnv*, jclass, jint, jint, jlong, jdouble)
{
return 0;
}

} // extern "C"
23 changes: 23 additions & 0 deletions photon-core/src/main/native/jni/TestJni.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* 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/>.
*/

#include <jni.h>
#include "test.h"

extern "C" {
JNIEXPORT jint JNICALL some_native_function(void) { return some_test(); }
} // extern "C"
Loading