diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index dcc3a543..00000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,12 +0,0 @@ -version: 2 -updates: - - package-ecosystem: "gradle" # See documentation for possible values - directory: "/" # Location of package manifests - target-branch: "dev" - schedule: - interval: "daily" - - package-ecosystem: "github-actions" - directory: "/" # Location of package manifests - target-branch: "dev" - schedule: - interval: "weekly" diff --git a/EOCV-Sim/build.gradle b/EOCV-Sim/build.gradle index e8ddbc7c..21e3bf35 100644 --- a/EOCV-Sim/build.gradle +++ b/EOCV-Sim/build.gradle @@ -38,8 +38,14 @@ dependencies { implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' + implementation "org.eclipse.jdt:ecj:3.21.0" + implementation "org.openpnp:opencv:$opencv_version" + implementation 'com.github.sarxos:webcam-capture:0.3.12' + implementation 'com.github.sarxos:webcam-capture-driver-openimaj:0.3.12' + implementation 'com.github.sarxos:webcam-capture-driver-v4l4j:0.3.12' + implementation "com.github.deltacv:AprilTagDesktop:$apriltag_plugin_version" implementation 'info.picocli:picocli:4.6.1' diff --git a/EOCV-Sim/src/main/java/com/github/serivesmejia/eocvsim/EOCVSim.kt b/EOCV-Sim/src/main/java/com/github/serivesmejia/eocvsim/EOCVSim.kt index 7c6828d4..3240ddb1 100644 --- a/EOCV-Sim/src/main/java/com/github/serivesmejia/eocvsim/EOCVSim.kt +++ b/EOCV-Sim/src/main/java/com/github/serivesmejia/eocvsim/EOCVSim.kt @@ -23,6 +23,9 @@ package com.github.serivesmejia.eocvsim +import com.github.sarxos.webcam.Webcam +import com.github.sarxos.webcam.ds.openimaj.OpenImajDriver +import com.github.sarxos.webcam.ds.v4l4j.V4l4jDriver import com.github.serivesmejia.eocvsim.config.Config import com.github.serivesmejia.eocvsim.config.ConfigManager import com.github.serivesmejia.eocvsim.gui.DialogFactory @@ -39,6 +42,7 @@ import com.github.serivesmejia.eocvsim.util.Log import com.github.serivesmejia.eocvsim.util.SysUtil import com.github.serivesmejia.eocvsim.util.event.EventHandler import com.github.serivesmejia.eocvsim.util.exception.MaxActiveContextsException +import com.github.serivesmejia.eocvsim.util.exception.handling.CrashReport import com.github.serivesmejia.eocvsim.util.exception.handling.EOCVSimUncaughtExceptionHandler import com.github.serivesmejia.eocvsim.util.extension.plus import com.github.serivesmejia.eocvsim.util.fps.FpsLimiter @@ -73,12 +77,14 @@ class EOCVSim(val params: Parameters = Parameters()) { try { OpenCV.loadLocally() - Log.info(TAG, "Successfully loaded native lib") + Log.info(TAG, "Successfully loaded the OpenCV native lib") } catch (ex: Throwable) { - Log.error(TAG, "Failure loading native lib", ex) - Log.info(TAG, "Retrying with old method...") + Log.error(TAG, "Failure loading the OpenCV native lib", ex) + Log.error(TAG, "The sim will exit now as it's impossible to continue execution without OpenCV") - if (!SysUtil.loadCvNativeLib()) exitProcess(-1) + CrashReport(ex).saveCrashReport() + + exitProcess(-1) } isNativeLibLoaded = true @@ -148,6 +154,16 @@ class EOCVSim(val params: Parameters = Parameters()) { classpathScan.asyncScan() + try { + Webcam.setDriver(OpenImajDriver()) + Log.info(TAG, "Using the OpenIMAJ webcam driver") + } catch(e: Exception) { + Log.warn(TAG, "The OpenIMAJ webcam driver failed to load", e) + + Webcam.setDriver(V4l4jDriver()) + Log.info(TAG, "Using the V4L4j webcam driver") + } + configManager.init() //load config workspaceManager.init() diff --git a/EOCV-Sim/src/main/java/com/github/serivesmejia/eocvsim/input/source/CameraSource.java b/EOCV-Sim/src/main/java/com/github/serivesmejia/eocvsim/input/source/CameraSource.java index b19f06dc..eaae61db 100644 --- a/EOCV-Sim/src/main/java/com/github/serivesmejia/eocvsim/input/source/CameraSource.java +++ b/EOCV-Sim/src/main/java/com/github/serivesmejia/eocvsim/input/source/CameraSource.java @@ -83,16 +83,27 @@ public boolean init() { initialized = true; if(webcamName != null) { + Webcam.resetDriver(); List webcams = Webcam.getWebcams(); + boolean foundWebcam = false; + for(int i = 0 ; i < webcams.size() ; i++) { String name = webcams.get(i).getName(); + double similarity = StrUtil.similarity(name, webcamName); - if(name.equals(webcamName) || StrUtil.similarity(name, webcamName) > 0.6) { + if(name.equals(webcamName) || similarity > 0.6) { + System.out.println(name + " " + webcamName + " similarity " + similarity + " " + i); webcamIndex = i; + foundWebcam = true; break; } } + + if(!foundWebcam) { + Log.error("CameraSource", "Could not find webcam " + webcamName); + return false; + } } camera = new VideoCapture(); @@ -235,7 +246,7 @@ public long getCaptureTimeNanos() { @Override public String toString() { if (size == null) size = new Size(); - return "CameraSource(" + webcamIndex + ", " + (size != null ? size.toString() : "null") + ")"; + return "CameraSource(" + webcamName + ", " + (size != null ? size.toString() : "null") + ")"; } } \ No newline at end of file diff --git a/EOCV-Sim/src/main/java/com/github/serivesmejia/eocvsim/input/source/CameraSourceAdapter.java b/EOCV-Sim/src/main/java/com/github/serivesmejia/eocvsim/input/source/CameraSourceAdapter.java index d8722f75..a19b379f 100644 --- a/EOCV-Sim/src/main/java/com/github/serivesmejia/eocvsim/input/source/CameraSourceAdapter.java +++ b/EOCV-Sim/src/main/java/com/github/serivesmejia/eocvsim/input/source/CameraSourceAdapter.java @@ -18,11 +18,7 @@ public JsonElement serialize(CameraSource src, Type typeOfSrc, JsonSerialization obj.addProperty("webcamIndex", src.webcamIndex); } - JsonObject sizeObj = new JsonObject(); - sizeObj.addProperty("width", src.size.width); - sizeObj.addProperty("height", src.size.width); - - obj.add("size", sizeObj); + obj.add("size", context.serialize(src.size)); obj.addProperty("createdOn", src.getCreationTime()); return obj; diff --git a/EOCV-Sim/src/main/java/com/github/serivesmejia/eocvsim/pipeline/compiler/PipelineCompiler.kt b/EOCV-Sim/src/main/java/com/github/serivesmejia/eocvsim/pipeline/compiler/PipelineCompiler.kt index bae0fe06..ca85b861 100644 --- a/EOCV-Sim/src/main/java/com/github/serivesmejia/eocvsim/pipeline/compiler/PipelineCompiler.kt +++ b/EOCV-Sim/src/main/java/com/github/serivesmejia/eocvsim/pipeline/compiler/PipelineCompiler.kt @@ -24,10 +24,15 @@ package com.github.serivesmejia.eocvsim.pipeline.compiler import com.github.serivesmejia.eocvsim.util.Log +import com.github.serivesmejia.eocvsim.util.ReflectUtil import com.github.serivesmejia.eocvsim.util.SysUtil import com.github.serivesmejia.eocvsim.util.compiler.JarPacker +import com.github.serivesmejia.eocvsim.util.compiler.compiler +import org.eclipse.jdt.internal.compiler.tool.EclipseCompiler import java.io.File import java.io.PrintWriter +import java.lang.reflect.Field +import java.nio.charset.Charset import java.util.* import javax.tools.* @@ -51,7 +56,7 @@ class PipelineCompiler( usable } - val COMPILER = ToolProvider.getSystemJavaCompiler() + val COMPILER = compiler val INDENT = " " val TAG = "PipelineCompiler" @@ -62,6 +67,7 @@ class PipelineCompiler( val latestDiagnostic: String get() { val diagnostic = StringBuilder() + diagnostic.appendLine("Using the ${COMPILER!!.name} compiler").appendLine() for((_, builder) in diagnosticBuilders) { diagnostic.appendLine(builder) diagnostic.appendLine("") @@ -83,9 +89,9 @@ class PipelineCompiler( constructor(inputPath: File) : this(inputPath, SysUtil.filesUnder(inputPath, ".java")) fun compile(outputJar: File): PipelineCompileResult { - val javac = COMPILER + val javac = COMPILER!!.javaCompiler - val fileManager = PipelineStandardFileManager(javac.getStandardFileManager(this, null, null)) + val fileManager = PipelineStandardFileManager(javac.getStandardFileManager(this, Locale.getDefault(), Charset.defaultCharset())) fileManager.sourcePath = Collections.singleton(sourcesInputPath) val javaFileObjects = fileManager.getJavaFileObjects(*sourceFiles.toTypedArray()) @@ -121,17 +127,45 @@ class PipelineCompiler( } override fun report(diagnostic: Diagnostic) { + // kinda stupid but eclipse compiler wraps exceptions in a "ExceptionDiagnostic" which is protected + // and we can't access the exception directly in any way, so we have to use reflection. ExceptionDiagnostic + // only returns the exception message, so we have to get the exception and rethrow it to get the full information on what went wrong + if(diagnostic::class.java.typeName == "org.eclipse.jdt.internal.compiler.tool.ExceptionDiagnostic") { + val eField = ReflectUtil.getDeclaredFieldDeep(diagnostic::class.java, "exception")!! + eField.isAccessible = true + + val value = eField.get(diagnostic) + + if(value is Exception) + throw value + } + val locale = Locale.getDefault() - val relativeFile = SysUtil.getRelativePath(sourcesInputPath, File(diagnostic.source.name)) + val source = diagnostic.source + + val builder = if(source != null) { + val relativeFile = SysUtil.getRelativePath(sourcesInputPath, File(source.name)) - val builder = diagnosticBuilders[relativeFile.path] ?: StringBuilder() + val builder = diagnosticBuilders[relativeFile.path] ?: StringBuilder() + + if (!diagnosticBuilders.containsKey(relativeFile.path)) { + builder.appendLine("> ${relativeFile.path}") + diagnosticBuilders[relativeFile.path] = builder + } + builder + } else { + val builder = diagnosticBuilders["other"] ?: StringBuilder() + + if (!diagnosticBuilders.containsKey("other")) { + builder.appendLine("> Other") + diagnosticBuilders["other"] = builder + } - if(!diagnosticBuilders.containsKey(relativeFile.path)) { - builder.appendLine("> ${relativeFile.path}") - diagnosticBuilders[relativeFile.path] = builder + builder } val formattedMessage = diagnostic.getMessage(locale).replace("\n", "\n$INDENT") + diagnostic.source builder.appendLine(String.format(locale, "$INDENT(%d:%d): %s: %s", diagnostic.lineNumber, diagnostic.columnNumber, diagnostic.kind, formattedMessage diff --git a/EOCV-Sim/src/main/java/com/github/serivesmejia/eocvsim/util/ReflectUtil.java b/EOCV-Sim/src/main/java/com/github/serivesmejia/eocvsim/util/ReflectUtil.java index 7a592526..250c8f44 100644 --- a/EOCV-Sim/src/main/java/com/github/serivesmejia/eocvsim/util/ReflectUtil.java +++ b/EOCV-Sim/src/main/java/com/github/serivesmejia/eocvsim/util/ReflectUtil.java @@ -25,11 +25,25 @@ import java.lang.annotation.Annotation; import java.lang.invoke.MethodType; +import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; public class ReflectUtil { + public static Field getDeclaredFieldDeep(Class clazz, String fieldName) { + Field field = null; + + while (clazz != null && field == null) { + try { + field = clazz.getDeclaredField(fieldName); + } catch (Exception ignored) { } + clazz = clazz.getSuperclass(); + } + + return field; + } + public static boolean hasSuperclass(Class clazz, Class superClass) { try { clazz.asSubclass(superClass); diff --git a/EOCV-Sim/src/main/java/com/github/serivesmejia/eocvsim/util/compiler/CompilerProvider.kt b/EOCV-Sim/src/main/java/com/github/serivesmejia/eocvsim/util/compiler/CompilerProvider.kt new file mode 100644 index 00000000..ad13dd0e --- /dev/null +++ b/EOCV-Sim/src/main/java/com/github/serivesmejia/eocvsim/util/compiler/CompilerProvider.kt @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2021 Sebastian Erives + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +package com.github.serivesmejia.eocvsim.util.compiler + +import org.eclipse.jdt.internal.compiler.tool.EclipseCompiler +import javax.tools.JavaCompiler +import javax.tools.ToolProvider + +val compiler by lazy { + val toolProviderCompiler = ToolProvider.getSystemJavaCompiler() + + try { + if (toolProviderCompiler == null) { + Compiler("Eclipse", EclipseCompiler()) + } else { + Compiler("JDK", toolProviderCompiler) + } + } catch(e: Exception) { + null + } +} + +data class Compiler(val name: String, val javaCompiler: JavaCompiler) \ No newline at end of file diff --git a/EOCV-Sim/src/main/java/com/github/serivesmejia/eocvsim/util/compiler/DelegatingStandardFileManager.kt b/EOCV-Sim/src/main/java/com/github/serivesmejia/eocvsim/util/compiler/DelegatingStandardFileManager.kt index 59c120b6..28787dfe 100644 --- a/EOCV-Sim/src/main/java/com/github/serivesmejia/eocvsim/util/compiler/DelegatingStandardFileManager.kt +++ b/EOCV-Sim/src/main/java/com/github/serivesmejia/eocvsim/util/compiler/DelegatingStandardFileManager.kt @@ -26,6 +26,7 @@ package com.github.serivesmejia.eocvsim.util.compiler import java.io.File +import java.util.* import javax.tools.ForwardingJavaFileManager import javax.tools.JavaFileManager import javax.tools.JavaFileObject @@ -36,21 +37,21 @@ open class DelegatingStandardFileManager( ) : ForwardingJavaFileManager(delegate), StandardJavaFileManager { override fun getJavaFileObjectsFromFiles(files: MutableIterable): MutableIterable = - delegate.getJavaFileObjectsFromFiles(files) + delegate.getJavaFileObjectsFromFiles(files) ?: Collections.emptyList() override fun getJavaFileObjects(vararg files: File): MutableIterable = - delegate.getJavaFileObjects(*files) + delegate.getJavaFileObjects(*files) ?: Collections.emptyList() override fun getJavaFileObjects(vararg names: String): MutableIterable = - delegate.getJavaFileObjects(*names) + delegate.getJavaFileObjects(*names) ?: Collections.emptyList() override fun getJavaFileObjectsFromStrings(names: MutableIterable): MutableIterable = - delegate.getJavaFileObjectsFromStrings(names) + delegate.getJavaFileObjectsFromStrings(names) ?: Collections.emptyList() override fun setLocation(location: JavaFileManager.Location, files: MutableIterable) = delegate.setLocation(location, files) override fun getLocation(location: JavaFileManager.Location): MutableIterable = - delegate.getLocation(location) + delegate.getLocation(location) ?: Collections.emptyList() } \ No newline at end of file diff --git a/README.md b/README.md index c9a96b29..c02d2f86 100644 --- a/README.md +++ b/README.md @@ -20,10 +20,11 @@ transfer it onto your robot! Since OpenCV in Java uses a native library, which is platform specific, the simulator is currently limited to the following platforms: -* Windows x64 (tested) -* Windows x32 (untested) -* MacOS x64 (tested) -* Linux x64 (tested for Ubuntu 20.04)
+* Windows x86_64 (tested) +* Windows x86 (untested) +* MacOS x86_64 (tested) +* Linux x86_64 (tested for Ubuntu 20.04) +* Linux ARMv7 & ARMv8 (partially tested in Raspbian but not officially endorsed)
## Downloading and documentation @@ -38,7 +39,7 @@ Follow the steps in [this page](https://deltacv.gitbook.io/eocv-sim/basics/downl } dependencies { - implementation 'com.github.deltacv:EOCV-Sim:3.2.0' //add the EOCV-Sim dependency + implementation 'com.github.deltacv:EOCV-Sim:3.3.2' //add the EOCV-Sim dependency } ``` @@ -59,7 +60,7 @@ Follow the steps in [this page](https://deltacv.gitbook.io/eocv-sim/basics/downl com.github.deltacv EOCV-Sim - 3.2.0 + 3.3.2 ``` @@ -70,6 +71,16 @@ For bug reporting or feature requesting, use the [issues tab](https://github.com ### Formerly, EOCV-Sim was hosted on a [personal account repo](https://github.com/serivesmejia/EOCV-Sim/). Released prior to 3.0.0 can be found there for historic purposes. +### [v3.3.2 - Better compiler support](https://github.com/deltacv/EOCV-Sim/releases/tag/v3.3.1) + + - This is the 13th release for EOCV-Sim + + - Changelog: + - Provides support for compiling in any Java virtual machine by using the Eclipse ecj compiler if a JDK compiler isn't found. + - Provided a fallback webcam driver in case OpenIMAJ fails to load. + - Bug fixes: + - Fixes camera source sizes serialization where the height was replaced by the width + ### [v3.3.1 - Common module hotfix](https://github.com/deltacv/EOCV-Sim/releases/tag/v3.3.0) - This is the 12th release for EOCV-Sim diff --git a/build.gradle b/build.gradle index c9e747e7..8289637a 100644 --- a/build.gradle +++ b/build.gradle @@ -28,7 +28,7 @@ buildscript { allprojects { group 'com.github.deltacv' - version '3.3.1' + version '3.3.2' ext { standardVersion = version