diff --git a/processing/sensorhub-process-universalcontroller/build.gradle b/processing/sensorhub-process-universalcontroller/build.gradle
index 3a683e6e3..dcf518122 100644
--- a/processing/sensorhub-process-universalcontroller/build.gradle
+++ b/processing/sensorhub-process-universalcontroller/build.gradle
@@ -11,8 +11,8 @@ dependencies {
// add info to OSGi manifest
osgi {
manifest {
- attributes('Bundle-Vendor': 'Sensia Software LLC')
- attributes('Bundle-Activator': 'org.sensorhub.process.universalcontroller.Activator')
+ attributes('Bundle-Vendor': 'Botts Innovative Research, Inc.')
+ attributes('Bundle-Activator': 'org.sensorhub.impl.process.universalcontroller.Activator')
}
}
@@ -20,10 +20,10 @@ osgi {
ext.pom >>= {
developers {
developer {
- id 'alexalmanza'
+ id 'earocorn'
name 'Alex Almanza'
- organization 'Botts Innovative Research'
- organizationUrl 'http://www.botts-inc.com'
+ organization 'Botts Innovative Research, Inc.'
+ organizationUrl 'https://www.botts-inc.com'
}
}
}
diff --git a/processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/process/universalcontroller/Activator.java b/processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/impl/process/universalcontroller/Activator.java
similarity index 93%
rename from processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/process/universalcontroller/Activator.java
rename to processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/impl/process/universalcontroller/Activator.java
index 9c6c15599..555a009b7 100644
--- a/processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/process/universalcontroller/Activator.java
+++ b/processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/impl/process/universalcontroller/Activator.java
@@ -12,7 +12,7 @@
******************************* END LICENSE BLOCK ***************************/
-package org.sensorhub.process.universalcontroller;
+package org.sensorhub.impl.process.universalcontroller;
import org.osgi.framework.BundleActivator;
import org.sensorhub.utils.OshBundleActivator;
diff --git a/processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/process/universalcontroller/impl/ControllerMAVLinkProcess.java b/processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/impl/process/universalcontroller/ControllerMAVLinkProcess.java
similarity index 95%
rename from processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/process/universalcontroller/impl/ControllerMAVLinkProcess.java
rename to processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/impl/process/universalcontroller/ControllerMAVLinkProcess.java
index 5ab31a791..68cbaf5d6 100644
--- a/processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/process/universalcontroller/impl/ControllerMAVLinkProcess.java
+++ b/processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/impl/process/universalcontroller/ControllerMAVLinkProcess.java
@@ -1,9 +1,9 @@
-package org.sensorhub.process.universalcontroller.impl;
+package org.sensorhub.impl.process.universalcontroller;
-import com.sample.impl.sensor.universalcontroller.helpers.UniversalControllerComponent;
+import org.sensorhub.impl.sensor.universalcontroller.helpers.UniversalControllerComponent;
import net.opengis.swe.v20.*;
import org.sensorhub.api.processing.OSHProcessInfo;
-import org.sensorhub.process.universalcontroller.helpers.AbstractControllerTaskingProcess;
+import org.sensorhub.impl.process.universalcontroller.helpers.AbstractControllerTaskingProcess;
import org.vast.process.ProcessException;
import org.vast.swe.SWEConstants;
import org.vast.swe.SWEHelper;
diff --git a/processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/process/universalcontroller/impl/ControllerPTZProcess.java b/processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/impl/process/universalcontroller/ControllerPTZProcess.java
similarity index 94%
rename from processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/process/universalcontroller/impl/ControllerPTZProcess.java
rename to processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/impl/process/universalcontroller/ControllerPTZProcess.java
index 83ec9bb2f..c97a53965 100644
--- a/processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/process/universalcontroller/impl/ControllerPTZProcess.java
+++ b/processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/impl/process/universalcontroller/ControllerPTZProcess.java
@@ -1,9 +1,9 @@
-package org.sensorhub.process.universalcontroller.impl;
+package org.sensorhub.impl.process.universalcontroller;
-import com.sample.impl.sensor.universalcontroller.helpers.UniversalControllerComponent;
+import org.sensorhub.impl.sensor.universalcontroller.helpers.UniversalControllerComponent;
import net.opengis.swe.v20.DataType;
import net.opengis.swe.v20.Quantity;
-import org.sensorhub.process.universalcontroller.helpers.AbstractControllerTaskingProcess;
+import org.sensorhub.impl.process.universalcontroller.helpers.AbstractControllerTaskingProcess;
import org.sensorhub.api.processing.OSHProcessInfo;
import org.vast.process.ProcessException;
import org.vast.swe.SWEHelper;
diff --git a/processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/process/universalcontroller/impl/ControllerProcessTemplate.java b/processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/impl/process/universalcontroller/ControllerProcessTemplate.java
similarity index 90%
rename from processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/process/universalcontroller/impl/ControllerProcessTemplate.java
rename to processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/impl/process/universalcontroller/ControllerProcessTemplate.java
index 2d1ef201f..0c43c5c89 100644
--- a/processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/process/universalcontroller/impl/ControllerProcessTemplate.java
+++ b/processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/impl/process/universalcontroller/ControllerProcessTemplate.java
@@ -1,10 +1,9 @@
-package org.sensorhub.process.universalcontroller.impl;
+package org.sensorhub.impl.process.universalcontroller;
-import com.sample.impl.sensor.universalcontroller.helpers.UniversalControllerComponent;
+import org.sensorhub.impl.sensor.universalcontroller.helpers.UniversalControllerComponent;
import org.sensorhub.api.processing.OSHProcessInfo;
-import org.sensorhub.process.universalcontroller.helpers.AbstractControllerTaskingProcess;
+import org.sensorhub.impl.process.universalcontroller.helpers.AbstractControllerTaskingProcess;
import org.vast.process.ProcessException;
-import org.vast.process.ProcessInfo;
public class ControllerProcessTemplate extends AbstractControllerTaskingProcess {
diff --git a/processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/process/universalcontroller/impl/PrimaryControllerSelector.java b/processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/impl/process/universalcontroller/PrimaryControllerSelector.java
similarity index 94%
rename from processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/process/universalcontroller/impl/PrimaryControllerSelector.java
rename to processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/impl/process/universalcontroller/PrimaryControllerSelector.java
index 091ab30c3..5fc00764f 100644
--- a/processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/process/universalcontroller/impl/PrimaryControllerSelector.java
+++ b/processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/impl/process/universalcontroller/PrimaryControllerSelector.java
@@ -1,6 +1,6 @@
-package org.sensorhub.process.universalcontroller.impl;
+package org.sensorhub.impl.process.universalcontroller;
-import com.sample.impl.sensor.universalcontroller.helpers.UniversalControllerProcessHelper;
+import org.sensorhub.impl.sensor.universalcontroller.helpers.UniversalControllerProcessHelper;
import net.opengis.swe.v20.DataRecord;
import org.sensorhub.api.processing.OSHProcessInfo;
import org.vast.data.DataBlockList;
diff --git a/processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/process/universalcontroller/ProcessDescriptors.java b/processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/impl/process/universalcontroller/ProcessDescriptors.java
similarity index 81%
rename from processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/process/universalcontroller/ProcessDescriptors.java
rename to processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/impl/process/universalcontroller/ProcessDescriptors.java
index 60909a42c..3bc2272df 100644
--- a/processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/process/universalcontroller/ProcessDescriptors.java
+++ b/processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/impl/process/universalcontroller/ProcessDescriptors.java
@@ -12,11 +12,9 @@
******************************* END LICENSE BLOCK ***************************/
-package org.sensorhub.process.universalcontroller;
+package org.sensorhub.impl.process.universalcontroller;
import org.sensorhub.impl.processing.AbstractProcessProvider;
-import org.sensorhub.process.universalcontroller.impl.ControllerPTZProcess;
-import org.sensorhub.process.universalcontroller.impl.PrimaryControllerSelector;
public class ProcessDescriptors extends AbstractProcessProvider
diff --git a/processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/process/universalcontroller/helpers/AbstractControllerTaskingProcess.java b/processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/impl/process/universalcontroller/helpers/AbstractControllerTaskingProcess.java
similarity index 86%
rename from processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/process/universalcontroller/helpers/AbstractControllerTaskingProcess.java
rename to processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/impl/process/universalcontroller/helpers/AbstractControllerTaskingProcess.java
index deb25446c..5f7b52e1d 100644
--- a/processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/process/universalcontroller/helpers/AbstractControllerTaskingProcess.java
+++ b/processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/impl/process/universalcontroller/helpers/AbstractControllerTaskingProcess.java
@@ -1,6 +1,6 @@
-package org.sensorhub.process.universalcontroller.helpers;
+package org.sensorhub.impl.process.universalcontroller.helpers;
-import com.sample.impl.sensor.universalcontroller.helpers.UniversalControllerProcessHelper;
+import org.sensorhub.impl.sensor.universalcontroller.helpers.UniversalControllerProcessHelper;
import org.vast.process.ExecutableProcessImpl;
import org.vast.process.ProcessException;
import org.vast.process.ProcessInfo;
diff --git a/processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/process/universalcontroller/helpers/ControllerProcessHelper.java b/processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/impl/process/universalcontroller/helpers/ControllerProcessHelper.java
similarity index 82%
rename from processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/process/universalcontroller/helpers/ControllerProcessHelper.java
rename to processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/impl/process/universalcontroller/helpers/ControllerProcessHelper.java
index 7209c49cc..d004bb853 100644
--- a/processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/process/universalcontroller/helpers/ControllerProcessHelper.java
+++ b/processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/impl/process/universalcontroller/helpers/ControllerProcessHelper.java
@@ -1,4 +1,4 @@
-package org.sensorhub.process.universalcontroller.helpers;
+package org.sensorhub.impl.process.universalcontroller.helpers;
public class ControllerProcessHelper extends ProcessHelper {
diff --git a/processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/process/universalcontroller/helpers/ProcessHelper.java b/processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/impl/process/universalcontroller/helpers/ProcessHelper.java
similarity index 98%
rename from processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/process/universalcontroller/helpers/ProcessHelper.java
rename to processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/impl/process/universalcontroller/helpers/ProcessHelper.java
index 699f1110e..e9188f6f3 100644
--- a/processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/process/universalcontroller/helpers/ProcessHelper.java
+++ b/processing/sensorhub-process-universalcontroller/src/main/java/org/sensorhub/impl/process/universalcontroller/helpers/ProcessHelper.java
@@ -1,4 +1,4 @@
-package org.sensorhub.process.universalcontroller.helpers;
+package org.sensorhub.impl.process.universalcontroller.helpers;
import net.opengis.gml.v32.impl.ReferenceImpl;
import net.opengis.sensorml.v20.AbstractProcess;
diff --git a/processing/sensorhub-process-universalcontroller/src/main/resources/META-INF/services/org.sensorhub.api.processing.IProcessProvider b/processing/sensorhub-process-universalcontroller/src/main/resources/META-INF/services/org.sensorhub.api.processing.IProcessProvider
index 86db9d966..857292146 100644
--- a/processing/sensorhub-process-universalcontroller/src/main/resources/META-INF/services/org.sensorhub.api.processing.IProcessProvider
+++ b/processing/sensorhub-process-universalcontroller/src/main/resources/META-INF/services/org.sensorhub.api.processing.IProcessProvider
@@ -1 +1 @@
-org.sensorhub.process.universalcontroller.ProcessDescriptors
\ No newline at end of file
+org.sensorhub.impl.process.universalcontroller.ProcessDescriptors
\ No newline at end of file
diff --git a/processing/sensorhub-process-universalcontroller/src/test/java/org/sensorhub/process/universalcontroller/TestProcessWriter.java b/processing/sensorhub-process-universalcontroller/src/test/java/org/sensorhub/process/universalcontroller/TestProcessWriter.java
index 05ab7335e..e0ccb7704 100644
--- a/processing/sensorhub-process-universalcontroller/src/test/java/org/sensorhub/process/universalcontroller/TestProcessWriter.java
+++ b/processing/sensorhub-process-universalcontroller/src/test/java/org/sensorhub/process/universalcontroller/TestProcessWriter.java
@@ -1,18 +1,9 @@
package org.sensorhub.process.universalcontroller;
-import net.opengis.gml.v32.impl.ReferenceImpl;
-import net.opengis.sensorml.v20.AbstractProcess;
-import net.opengis.sensorml.v20.SimpleProcess;
-import net.opengis.sensorml.v20.impl.SettingsImpl;
-import net.opengis.swe.v20.AbstractSWEIdentifiable;
-import net.opengis.swe.v20.DataComponent;
import org.junit.Test;
-import org.sensorhub.process.universalcontroller.helpers.ProcessHelper;
-import org.sensorhub.process.universalcontroller.impl.ControllerPTZProcess;
-import org.sensorhub.process.universalcontroller.impl.PrimaryControllerSelector;
-import org.vast.sensorML.*;
-
-import java.util.UUID;
+import org.sensorhub.impl.process.universalcontroller.helpers.ProcessHelper;
+import org.sensorhub.impl.process.universalcontroller.ControllerPTZProcess;
+import org.sensorhub.impl.process.universalcontroller.PrimaryControllerSelector;
import static org.junit.Assert.assertEquals;
diff --git a/processing/sensorhub-process-universalcontroller/src/test/resources/controller-ptz.xml b/processing/sensorhub-process-universalcontroller/src/test/resources/controller-ptz.xml
new file mode 100644
index 000000000..8a092ba2c
--- /dev/null
+++ b/processing/sensorhub-process-universalcontroller/src/test/resources/controller-ptz.xml
@@ -0,0 +1,158 @@
+
+ 861a1f13-aee5-463e-a19e-8f0f9103375f
+
+
+
+
+ Relative Pan
+
+
+
+
+
+ Relative Tilt
+
+
+
+
+
+ Relative Zoom Factor
+
+
+
+
+
+ Sensitivity
+
+
+
+
+
+
+
+
+
+
+
+
+ urn:osh:sensor:universalcontroller001
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ urn:axis:cam:00408CFBA322
+ ptzControl
+
+
+
+
+
+
+
+
+
+ urn:axis:cam:00408CFBA322
+ ptzControl
+
+
+
+
+
+
+
+
+
+ urn:axis:cam:00408CFBA322
+ ptzControl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/processing/sensorhub-process-universalcontroller/src/test/resources/controller-to-mavlink.xml b/processing/sensorhub-process-universalcontroller/src/test/resources/controller-to-mavlink.xml
new file mode 100644
index 000000000..c6d99d9d1
--- /dev/null
+++ b/processing/sensorhub-process-universalcontroller/src/test/resources/controller-to-mavlink.xml
@@ -0,0 +1,94 @@
+
+ 861a1f13-aee5-463e-a19e-8f0f9103375f
+
+
+
+
+ Relative Pan
+
+
+
+
+
+
+
+
+
+
+
+
+ urn:osh:sensor:universalcontroller001
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ urn:osh:template_driver:sensor001
+ offboardControl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/processing/sensorhub-process-universalcontroller/src/test/resources/empty b/processing/sensorhub-process-universalcontroller/src/test/resources/empty
deleted file mode 100644
index e69de29bb..000000000
diff --git a/sensors/others/sensorhub-driver-universalcontroller/build.gradle b/sensors/others/sensorhub-driver-universalcontroller/build.gradle
index 816ad6293..a8bb5cf6f 100644
--- a/sensors/others/sensorhub-driver-universalcontroller/build.gradle
+++ b/sensors/others/sensorhub-driver-universalcontroller/build.gradle
@@ -4,8 +4,8 @@ version = '1.0.0'
dependencies {
implementation 'org.sensorhub:sensorhub-core:' + oshCoreVersion
- implementation 'net.java.jinput:jinput:2.0.10'
- implementation fileTree(dir: 'lib', include: ['*.jar'])
+ embeddedImpl 'net.java.jinput:jinput:2.0.10'
+ embeddedImpl fileTree(dir: 'lib', include: ['*.jar'])
testImplementation('junit:junit:4.13.1')
}
@@ -27,8 +27,8 @@ test {
// add info to OSGi manifest
osgi {
manifest {
- attributes ('Bundle-Vendor': 'Botts Inc')
- attributes ('Bundle-Activator': 'com.sample.impl.sensor.universalcontroller.Activator')
+ attributes ('Bundle-Vendor': 'Botts Innovative Research, Inc.')
+ attributes ('Bundle-Activator': 'org.sensorhub.impl.sensor.universalcontroller.Activator')
}
}
@@ -36,9 +36,9 @@ osgi {
ext.pom >>= {
developers {
developer {
- id 'alexalmanza'
+ id 'earocorn'
name 'Alex Almanza'
- organization 'Botts Innovative Research'
+ organization 'Botts Innovative Research, Inc.'
organizationUrl 'https://botts-inc.com'
}
}
diff --git a/sensors/others/sensorhub-driver-universalcontroller/lib/controllerlibrary.jar b/sensors/others/sensorhub-driver-universalcontroller/lib/controllerlibrary.jar
deleted file mode 100644
index cb12f05a2..000000000
Binary files a/sensors/others/sensorhub-driver-universalcontroller/lib/controllerlibrary.jar and /dev/null differ
diff --git a/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/GamepadUtil.java b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/GamepadUtil.java
new file mode 100644
index 000000000..f0c9cc93d
--- /dev/null
+++ b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/GamepadUtil.java
@@ -0,0 +1,505 @@
+package org.sensorhub.controller;
+
+import org.sensorhub.controller.gamepad.GamepadAxis;
+import org.sensorhub.controller.models.ControllerDirection;
+import org.sensorhub.controller.models.Sensitivity;
+import net.java.games.input.Component;
+import net.java.games.input.Controller;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Class to set up an instance of JInput controller environment and initialize the currently connected gamepad
+ */
+public class GamepadUtil {
+
+ /**
+ * The main gamepad controller
+ */
+ private static Controller gamepad;
+
+ /**
+ * List of gamepad components associated with the main gamepad controller
+ */
+ private Component[] gamepadComponents;
+
+ /**
+ * Map of joystick sensitivities
+ */
+ private Map sensitivityMap;
+ private final String ERR_NOT_CONNECTED = "A gamepad is not connected.";
+
+ /**
+ * Constructor that retrieves the currently connected gamepad controller and gets its components
+ */
+ public GamepadUtil() {
+
+ // https://jinput.github.io/jinput/
+ // Default environment loaded from native library. Currently, to use native libraries, set java.library.path to the path of all native libraries
+ // For example, add argument -Djava.library.path="./jiraw" to launch.* with the jiraw directory containing all the native files
+ gamepad = null;
+ //TODO make sure getting gamepad works
+ if (gamepad == null) {
+ throw new NullPointerException(ERR_NOT_CONNECTED);
+ }
+
+ gamepadComponents = gamepad.getComponents();
+
+ sensitivityMap = new ConcurrentHashMap<>();
+ }
+
+ /**
+ *
+ *
+ * @return current gamepad
+ */
+ public Controller getDefaultGamepad() {
+ if(gamepad == null) {
+ throw new NullPointerException("Gamepad is null.");
+ }
+ return gamepad;
+ }
+
+ /**
+ * Check if gamepad is connected.
+ *
+ * @return True if gamepad is connected, false if gamepad is connected or the gamepad's components are null
+ */
+ public boolean isConnected() {
+ return gamepad != null || gamepadComponents != null;
+ }
+
+ /**
+ * Poll the gamepad for updates, to populate data of each gamepad component
+ */
+ public void pollGamepad() {
+ if (gamepad != null) {
+ gamepad.poll();
+ }
+ }
+
+ /**
+ * Retrieve a list of the current gamepad's components
+ *
+ * @return gamepadComponents
+ */
+ public Component[] getGamepadComponents() {
+ return gamepadComponents;
+ }
+
+ /**
+ * Get the data for a component specified by its Identifier
+ *
+ * @param identifier The component identifier whose data is retrieved
+ * @return Float value of the component's poll data
+ */
+ public float getComponentValue(Component.Identifier identifier) {
+ if (gamepad == null) {
+ throw new NullPointerException(ERR_NOT_CONNECTED);
+ }
+ return gamepad.getComponent(identifier).getPollData();
+ }
+
+ public float getComponentDeadZone(Component.Identifier identifier) {
+ if (gamepad == null) {
+ throw new NullPointerException(ERR_NOT_CONNECTED);
+ }
+ return gamepad.getComponent(identifier).getDeadZone();
+ }
+
+ /**
+ * Retrieve a list of the components under the Axis Identifier
+ *
+ * @return Component array of the current gamepad's Axis components
+ */
+ public Component[] getAxisComponents() {
+ if (!isConnected()) {
+ throw new IllegalStateException(ERR_NOT_CONNECTED);
+ }
+ Component[] components = null;
+ try{
+ components = (Component[]) Arrays.stream(gamepadComponents).filter(x -> x.getIdentifier() instanceof Component.Identifier.Axis).toArray();
+ } catch (Exception e){
+ e.printStackTrace();
+ }
+ return components;
+ }
+
+ /**
+ * Retrieve a list of the components under the Button Identifier
+ *
+ * @return Component array of the current gamepad's Button components
+ */
+ public Component[] getButtonComponents() {
+ if (!isConnected()) {
+ throw new IllegalStateException(ERR_NOT_CONNECTED);
+ }
+ Component[] components = null;
+ try {
+ components = (Component[]) Arrays.stream(gamepadComponents).filter(x -> x.getIdentifier() instanceof Component.Identifier.Button).toArray();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return components;
+ }
+
+ /**
+ * Retrieve a list of the components under the Key Identifier
+ *
+ * @return Component array of the current gamepad's Key components
+ */
+ public Component[] getKeyComponents() {
+ if (!isConnected()) {
+ throw new IllegalStateException(ERR_NOT_CONNECTED);
+ }
+ Component[] components = null;
+ try {
+ components = (Component[]) Arrays.stream(gamepadComponents).filter(x -> x.getIdentifier() instanceof Component.Identifier.Key).toArray();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return components;
+ }
+
+ /**
+ * Check if a component is currently active such as whether a button is being pressed or if a joystick is being moved
+ *
+ * @param identifier Identifier of requested component
+ * @return True if component's value is not default
+ */
+ public boolean isComponentActive(Component.Identifier identifier) {
+ boolean isActive = true;
+ if (!isConnected()) {
+ throw new IllegalStateException(ERR_NOT_CONNECTED);
+ }
+ if (gamepad.getComponent(identifier).getPollData() == gamepad.getComponent(identifier).getDeadZone()) {
+ isActive = false;
+ }
+ return isActive;
+ }
+
+ /**
+ * Check if gamepad has a certain component
+ *
+ * @param identifier Identifier of component
+ * @return True if the gamepad's components includes the identified component
+ */
+ public boolean hasComponent(Component.Identifier identifier) {
+ boolean isInList = false;
+ if (!isConnected()) {
+ throw new IllegalStateException(ERR_NOT_CONNECTED);
+ }
+ for (Component component : gamepadComponents) {
+ if (component.getIdentifier() == identifier) {
+ isInList = true;
+ }
+ }
+ return isInList;
+ }
+
+ /**
+ * Retrieve list of components' names
+ *
+ * @return ArrayList of component names
+ */
+ public ArrayList getComponentsNamesAsList() {
+ if (!isConnected()) {
+ throw new IllegalStateException(ERR_NOT_CONNECTED);
+ }
+ ArrayList array = new ArrayList<>();
+ for (Component component : gamepadComponents) {
+ array.add(component.getName());
+ }
+ return array;
+ }
+
+ /**
+ * Retrieve list of components' identifier values as Strings
+ *
+ * @return ArrayList of identifier Strings
+ */
+ public ArrayList getComponentsIdentifiersAsList() {
+ if (!isConnected()) {
+ throw new IllegalStateException(ERR_NOT_CONNECTED);
+ }
+ ArrayList array = new ArrayList<>();
+ for (Component component : gamepadComponents) {
+ array.add(component.getIdentifier().getName());
+ }
+ return array;
+ }
+
+ /**
+ * Retrieve list of components' float values
+ *
+ * @return ArrayList of raw component data
+ */
+ public ArrayList getComponentsDataAsList() {
+ if (!isConnected()) {
+ throw new IllegalStateException(ERR_NOT_CONNECTED);
+ }
+ ArrayList array = new ArrayList<>();
+ for (Component component : gamepadComponents) {
+ array.add(component.getPollData());
+ }
+ return array;
+ }
+
+ /**
+ * Check if a Button component is currently being pressed
+ *
+ * @param identifier Identify which button component
+ * @return True if button is currently pressed
+ */
+ public boolean isButtonPressed(Component.Identifier identifier) {
+ if (!isConnected()) {
+ throw new IllegalStateException(ERR_NOT_CONNECTED);
+ }
+ boolean pressed = false;
+ if (identifier instanceof Component.Identifier.Button) {
+ if (hasComponent(identifier)) {
+ pressed = gamepad.getComponent(identifier).getPollData() == 1.0f;
+ }
+ }
+ return pressed;
+ }
+
+ /**
+ * Get left or right trigger pressure identified by the Identifier.Axis.Z component
+ *
+ * @param isLeft If left trigger pressure is requested
+ * @return Value of left or right trigger pressure
+ */
+ public float getTriggerPressure(boolean isLeft) {
+ if (!isConnected()) {
+ throw new IllegalStateException(ERR_NOT_CONNECTED);
+ }
+ float pressure = 0.0f;
+ if (hasComponent(Component.Identifier.Axis.Z)) {
+ Component component = gamepad.getComponent(Component.Identifier.Axis.Z);
+ float deadZone = component.getDeadZone();
+ float currentValue = component.getPollData();
+ if (currentValue != deadZone) {
+ if (isLeft) {
+ if (currentValue > deadZone) {
+ pressure = currentValue;
+ }
+ } else {
+ if (currentValue < deadZone) {
+ pressure = currentValue;
+ }
+ }
+ } else {
+ pressure = deadZone;
+ }
+ }
+ return pressure;
+ }
+
+ /**
+ * Return value of component that's passed through sensitivity map
+ *
+ * @param identifier
+ * @return
+ */
+ public float getValueWithSensitivity(Component.Identifier identifier) {
+ float value = 0.0f;
+ float incremental = 0.5f;
+ float componentValue = getComponentValue(identifier);
+ float componentDeadZone = getComponentDeadZone(identifier);
+ if (sensitivityMap == null || sensitivityMap.isEmpty()) {
+ return value;
+ }
+ Sensitivity componentSensitivity = sensitivityMap.get(identifier);
+ if(componentSensitivity == Sensitivity.NULL || componentSensitivity == null) {
+ return value;
+ }
+ value = (componentSensitivity.ordinal() >= Sensitivity.MEDIUM.ordinal ()) ? (float) Math.pow(componentValue, componentSensitivity.getSensitivityModifier()) : componentValue * componentSensitivity.getSensitivityModifier();
+ return (value > componentDeadZone) ? value : componentValue;
+ }
+
+ /**
+ * Set the sensitivity value for the identified component
+ *
+ * @param axis Identifies axis component
+ * @param sensitivity Sensitivity value
+ */
+ public void setSensitivity(GamepadAxis axis, Sensitivity sensitivity) {
+ //TODO: assert only joystick sensitivity to be set
+ if (sensitivityMap == null) {
+ throw new NullPointerException("Sensitivity hashmap is null");
+ }
+ if (axis == GamepadAxis.D_PAD) {
+ throw new IllegalStateException("Sensitivity must only be applied to joysticks");
+ }
+ switch (axis) {
+ case LEFT_JOYSTICK -> {
+ sensitivityMap.put(Component.Identifier.Axis.X, sensitivity);
+ sensitivityMap.put(Component.Identifier.Axis.Y, sensitivity);
+ }
+ case RIGHT_JOYSTICK -> {
+ sensitivityMap.put(Component.Identifier.Axis.RX, sensitivity);
+ sensitivityMap.put(Component.Identifier.Axis.RY, sensitivity);
+ }
+ }
+ }
+
+ /**
+ * Get a component's custom sensitivity value
+ *
+ * @return Sensitivity of component given identifier
+ */
+ public Sensitivity getSensitivity(GamepadAxis axis) {
+ if (sensitivityMap == null || sensitivityMap.isEmpty()) {
+ throw new NullPointerException("Sensitivity hashmap is null");
+ }
+ return sensitivityMap.get(axis == GamepadAxis.LEFT_JOYSTICK ? Component.Identifier.Axis.X : Component.Identifier.Axis.RX);
+ }
+
+ /**
+ * Determine if an Axis Component Value is its initial value which lies somewhere between -0.0001 and -0.0000001
+ *
+ * @param number Axis Component Value
+ * @return True if in range
+ */
+ private boolean isInInitialAxisRange(float number) {
+ return (-0.0001 < number && number < -0.0000001);
+ }
+
+
+ /**
+ * Return directional component for X and Y Axis components
+ *
+ * @param xComponent X Axis Component. Axis.X or Axis.RX
+ * @param yComponent Y Axis Component. Axis.Y or Axis.RY
+ * @return ControllerDirection component for human readable direction component.
+ */
+ private ControllerDirection getAxisDirection(Component xComponent, Component yComponent) {
+ ControllerDirection controllerDirection = ControllerDirection.NULL;
+ float xValue = xComponent.getPollData();
+ float yValue = yComponent.getPollData();
+
+ // 1.0 > X > 0.0
+ if(xValue > 0.0f) {
+ // 1.0 > X > 0.0 AND 1.0 > Y > 0.0
+ if(yValue > 0.0f) {
+ controllerDirection = ControllerDirection.DOWN_RIGHT;
+ }
+ // 1.0 > X > 0.0 AND -1.0 < Y < 0.0
+ else if(yValue < 0.0f) {
+ controllerDirection = ControllerDirection.UP_RIGHT;
+ }
+ }
+ // -1.0 < X < 0.0
+ else {
+ // -1.0 < X < 0.0 AND -1.0 > Y < 0.0
+ if(yValue > 0.0f) {
+ controllerDirection = ControllerDirection.DOWN_LEFT;
+ }
+ // -1.0 < X < 0.0 AND 1.0 > Y > 0.0
+ else if(yValue < 0.0f) {
+ controllerDirection = ControllerDirection.UP_LEFT;
+ }
+ }
+
+ if(xValue == 1.0 && isInInitialAxisRange(yValue)) {
+ controllerDirection = ControllerDirection.RIGHT;
+ } else if (xValue == -1.0 && isInInitialAxisRange(yValue)) {
+ controllerDirection = ControllerDirection.LEFT;
+ } else if(isInInitialAxisRange(xValue)) {
+ if(yValue == 1.0) {
+ controllerDirection = ControllerDirection.DOWN;
+ } else if (yValue == -1.0) {
+ controllerDirection = ControllerDirection.UP;
+ }
+ }
+
+ if(isInInitialAxisRange(xValue) && isInInitialAxisRange(yValue)) {
+ controllerDirection = ControllerDirection.NULL;
+ }
+
+ return controllerDirection;
+ }
+
+ /**
+ * Get minimum possible value for component
+ *
+ * @param identifier Component identifier
+ * @return Minimum value
+ */
+ public float getMinValue(Component.Identifier identifier) {
+ float minValue = 0.0f;
+
+ if(identifier instanceof Component.Identifier.Axis && identifier != Component.Identifier.Axis.POV) {
+ minValue = -1.0f;
+ }
+
+ return minValue;
+ }
+
+ /**
+ * Get maximum possible value for component
+ *
+ * @param identifier Component identifier
+ * @return Maximum value
+ */
+ public float getMaxValue(Component.Identifier identifier) {
+ return 1.0f;
+ }
+
+
+ /**
+ * Retrieve human-readable direction component for any Axis component.
+ *
+ * @param axis Axis Component, LEFT_JOYSTICK, RIGHT_JOYSTICK, or D_PAD
+ * @return Directional component given by enum ControllerDirection
+ */
+ public ControllerDirection getDirection(GamepadAxis axis) {
+ if (!isConnected()) {
+ throw new IllegalStateException(ERR_NOT_CONNECTED);
+ }
+ ControllerDirection controllerDirection = ControllerDirection.NULL;
+ switch (axis) {
+ case LEFT_JOYSTICK:
+ if (!hasComponent(Component.Identifier.Axis.X) || !hasComponent(Component.Identifier.Axis.Y)) {
+ throw new NullPointerException("Left joystick not found");
+ }
+ controllerDirection = getAxisDirection(gamepad.getComponent(Component.Identifier.Axis.X), gamepad.getComponent(Component.Identifier.Axis.Y));
+ break;
+ case RIGHT_JOYSTICK:
+ if (!hasComponent(Component.Identifier.Axis.RX) || !hasComponent(Component.Identifier.Axis.RY)) {
+ throw new NullPointerException("Right joystick not found");
+ }
+ controllerDirection = getAxisDirection(gamepad.getComponent(Component.Identifier.Axis.RX), gamepad.getComponent(Component.Identifier.Axis.RY));
+ break;
+ case D_PAD:
+ if (!hasComponent(Component.Identifier.Axis.POV)) {
+ throw new NullPointerException("D-Pad not found");
+ }
+ float dpadVal = getComponentValue(Component.Identifier.Axis.POV);
+ if (dpadVal == 0.125f) {
+ controllerDirection = ControllerDirection.UP_LEFT;
+ } else if (dpadVal == 0.25f) {
+ controllerDirection = ControllerDirection.UP;
+ } else if (dpadVal == 0.375f) {
+ controllerDirection = ControllerDirection.UP_RIGHT;
+ } else if (dpadVal == 0.5f) {
+ controllerDirection = ControllerDirection.RIGHT;
+ } else if (dpadVal == 0.625f) {
+ controllerDirection = ControllerDirection.DOWN_RIGHT;
+ } else if (dpadVal == 0.75f) {
+ controllerDirection = ControllerDirection.DOWN;
+ } else if (dpadVal == 0.875f) {
+ controllerDirection = ControllerDirection.DOWN_LEFT;
+ } else if (dpadVal == 1.0f) {
+ controllerDirection = ControllerDirection.LEFT;
+ }
+ break;
+ }
+ return controllerDirection;
+ }
+
+}
diff --git a/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/gamepad/Gamepad.java b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/gamepad/Gamepad.java
new file mode 100644
index 000000000..96baa7b7b
--- /dev/null
+++ b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/gamepad/Gamepad.java
@@ -0,0 +1,55 @@
+package org.sensorhub.controller.gamepad;
+
+import org.sensorhub.controller.gamepad.observer.GamepadObserver;
+import org.sensorhub.controller.interfaces.IController;
+import org.sensorhub.controller.interfaces.IObserver;
+import org.sensorhub.controller.models.ControllerComponent;
+import org.sensorhub.controller.models.ControllerData;
+import org.sensorhub.controller.models.ControllerType;
+import net.java.games.input.Component;
+import net.java.games.input.Controller;
+import net.java.games.input.Event;
+
+import java.util.ArrayList;
+
+public class Gamepad implements IController {
+
+ private Controller jinputGamepad;
+ private GamepadObserver gamepadObserver;
+ private ControllerData controllerData;
+
+ public Gamepad(Controller jinputGamepad, Event event, int id) {
+ this.jinputGamepad = jinputGamepad;
+
+ Component[] jinputComponents = jinputGamepad.getComponents();
+ ArrayList components = new ArrayList<>();
+
+ for (Component component : jinputComponents) {
+ components.add(new ControllerComponent(component.getIdentifier().getName(), component.getPollData()));
+ }
+
+ controllerData = new ControllerData(jinputGamepad.getName() + ":" + id, ControllerType.GAMEPAD, components);
+ gamepadObserver = new GamepadObserver(this, jinputGamepad, event);
+ gamepadObserver.doStart();
+ }
+
+ @Override
+ public boolean isConnected() {
+ return jinputGamepad.poll();
+ }
+
+ @Override
+ public void disconnect() {
+
+ }
+
+ @Override
+ public IObserver getObserver() {
+ return gamepadObserver;
+ }
+
+ @Override
+ public ControllerData getControllerData() {
+ return controllerData;
+ }
+}
diff --git a/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/gamepad/GamepadAxis.java b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/gamepad/GamepadAxis.java
new file mode 100644
index 000000000..4ccd8f95c
--- /dev/null
+++ b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/gamepad/GamepadAxis.java
@@ -0,0 +1,7 @@
+package org.sensorhub.controller.gamepad;
+
+public enum GamepadAxis {
+
+ LEFT_JOYSTICK, RIGHT_JOYSTICK, D_PAD
+
+}
diff --git a/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/gamepad/GamepadConnection.java b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/gamepad/GamepadConnection.java
new file mode 100644
index 000000000..9538eb480
--- /dev/null
+++ b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/gamepad/GamepadConnection.java
@@ -0,0 +1,45 @@
+package org.sensorhub.controller.gamepad;
+
+import org.sensorhub.controller.interfaces.IController;
+import org.sensorhub.controller.interfaces.IControllerConnection;
+import net.java.games.input.Controller;
+import net.java.games.input.ControllerEnvironment;
+import net.java.games.input.Event;
+
+import java.util.ArrayList;
+
+public class GamepadConnection implements IControllerConnection {
+
+ ArrayList connectedControllers;
+
+ public GamepadConnection(Event event) {
+ //System.setProperty("net.java.games.input.useDefaultPlugin", "false");
+
+ Controller[] controllers = ControllerEnvironment.getDefaultEnvironment().getControllers();
+ ArrayList gamepadControllers = new ArrayList<>();
+ for (Controller controller : controllers) {
+ if(controller.getType() == Controller.Type.GAMEPAD) {
+ gamepadControllers.add(controller);
+ }
+ }
+ if(gamepadControllers.isEmpty()) {
+ connectedControllers = null;
+ throw new IllegalStateException("No HID Gamepad controllers connected.");
+ }
+ connectedControllers = new ArrayList<>();
+ for (Controller controller : gamepadControllers) {
+ Gamepad gamepad = new Gamepad(controller, event, gamepadControllers.indexOf(controller));
+ connectedControllers.add(gamepad);
+ }
+ }
+
+ @Override
+ public void disconnect() {
+
+ }
+
+ @Override
+ public ArrayList getConnectedControllers() {
+ return connectedControllers;
+ }
+}
diff --git a/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/gamepad/POVDirection.java b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/gamepad/POVDirection.java
new file mode 100644
index 000000000..9315a746f
--- /dev/null
+++ b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/gamepad/POVDirection.java
@@ -0,0 +1,15 @@
+package org.sensorhub.controller.gamepad;
+
+public enum POVDirection {
+ UP_LEFT(0.125f), UP(0.25f), UP_RIGHT(0.375f), RIGHT(0.5f), DOWN_RIGHT(0.625f), DOWN(0.75f), DOWN_LEFT(0.875f), LEFT(1.0f);
+
+ private float povValue;
+
+ POVDirection(float povValue) {
+ this.povValue = povValue;
+ }
+
+ public float getPovValue() {
+ return povValue;
+ }
+}
diff --git a/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/gamepad/observer/GamepadObserver.java b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/gamepad/observer/GamepadObserver.java
new file mode 100644
index 000000000..158941a61
--- /dev/null
+++ b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/gamepad/observer/GamepadObserver.java
@@ -0,0 +1,148 @@
+package org.sensorhub.controller.gamepad.observer;
+
+import org.sensorhub.controller.gamepad.Gamepad;
+import org.sensorhub.controller.interfaces.IObserver;
+import org.sensorhub.controller.interfaces.ControllerUpdateListener;
+import net.java.games.input.*;
+import net.java.games.input.Component.Identifier;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Class to listen for controller input events registered as ControllerUpdateListener objects
+ */
+public class GamepadObserver implements IObserver {
+
+ /**
+ * The list of event listeners registered to this observer
+ */
+ private Map gamepadListeners;
+
+ /**
+ * Event object for underlying plugin to populate
+ */
+ private Event event;
+
+ /**
+ * The controller to which the observer is applied
+ */
+ private Controller gamepad;
+
+ private Gamepad parent;
+
+ /**
+ * Lock for thread safety
+ */
+ private static final Object lock = new Object();
+
+ /**
+ * Worker thread for observing events
+ */
+ private Thread worker;
+
+ private String threadName = "GamepadObserverThread:";
+
+ private boolean running = false;
+
+ /**
+ * Singleton constructor
+ */
+ public GamepadObserver(Gamepad parent, Controller gamepad, Event event) {
+ this.event = event;
+ this.parent = parent;
+ this.gamepad = gamepad;
+
+ threadName += parent.getControllerData().getName();
+
+ gamepadListeners = new ConcurrentHashMap<>();
+ }
+
+ /**
+ * Starts the worker thread to listen for events
+ */
+ @Override
+ public void doStart() {
+ try {
+ if(event == null) {
+ throw new IllegalStateException("Event must be initialized and set using setEvent()");
+ }
+ if(worker != null && worker.isAlive()) {
+ throw new IllegalStateException("Observer is already listening for events");
+ }
+ running = true;
+ worker = new Thread(this, this.threadName);
+ worker.start();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Stop observer's worker thread
+ */
+ @Override
+ public void doStop() {
+ running = false;
+ System.out.println("Observer stopped manually");
+ }
+
+ /**
+ * Check if observer's worker thread is running
+ */
+ @Override
+ public boolean isRunning() {
+ running = worker.isAlive();
+ return running;
+ }
+
+ /**
+ * Adds an event listener to the observer's list of event listeners
+ *
+ * @param listener ControllerUpdateListener object whose callback method onChange() will be executed on notification of change in the controller component identified by the component identifier
+ * @param component Controller component identifier to specify which component update notification needs to update which callback function
+ */
+ @Override
+ public void addListener(ControllerUpdateListener listener, Identifier component) {
+ gamepadListeners.put(component, listener);
+ }
+
+ /**
+ * Removes an event listener to the observer's list of event listeners
+ *
+ * @param listener ControllerUpdateListener object whose callback method onChange() will be executed on notification of change in the controller component identified by the component identifier
+ * @param component Controller component identifier to specify which component update notification needs to update which callback function
+ */
+ @Override
+ public void removeListener(ControllerUpdateListener listener, Identifier component) {
+ gamepadListeners.remove(component, listener);
+ }
+
+ /**
+ * Thread worker used for listening for controller events
+ */
+ @Override
+ public void run() {
+ while(running) {
+ if(event != null && gamepad != null) {
+ synchronized (this) {
+ EventQueue queue = gamepad.getEventQueue();
+ gamepad.poll();
+
+ for (int i = 0; i < gamepad.getComponents().length; i++) {
+ parent.getControllerData().getOutputs().get(i).setValue(gamepad.getComponents()[i].getPollData());
+ }
+
+ if(queue.getNextEvent(event)) {
+ Component eventComponent = event.getComponent();
+ for(Map.Entry entry : gamepadListeners.entrySet()) {
+ if(eventComponent.getIdentifier() == entry.getKey()) {
+ entry.getValue().onChange(String.valueOf(entry.getKey()), eventComponent.getPollData());
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/interfaces/ControllerUpdateListener.java b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/interfaces/ControllerUpdateListener.java
new file mode 100644
index 000000000..c552804af
--- /dev/null
+++ b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/interfaces/ControllerUpdateListener.java
@@ -0,0 +1,16 @@
+package org.sensorhub.controller.interfaces;
+
+/**
+ * Listener interface used with GamepadObserver to perform callbacks
+ */
+public interface ControllerUpdateListener {
+
+ /**
+ * Callback function to execute on update of controller component's state
+ *
+ * @param identifier Identifier of component which triggered the callback
+ * @param currentValue Current value of the component
+ */
+ void onChange(String identifier, float currentValue);
+
+}
diff --git a/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/interfaces/IController.java b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/interfaces/IController.java
new file mode 100644
index 000000000..df087a451
--- /dev/null
+++ b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/interfaces/IController.java
@@ -0,0 +1,12 @@
+package org.sensorhub.controller.interfaces;
+
+import org.sensorhub.controller.models.ControllerData;
+
+public interface IController {
+
+ boolean isConnected();
+ void disconnect();
+ IObserver getObserver();
+ ControllerData getControllerData();
+
+}
diff --git a/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/interfaces/IControllerConnection.java b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/interfaces/IControllerConnection.java
new file mode 100644
index 000000000..2d1605ef8
--- /dev/null
+++ b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/interfaces/IControllerConnection.java
@@ -0,0 +1,9 @@
+package org.sensorhub.controller.interfaces;
+
+import java.util.ArrayList;
+
+public interface IControllerConnection {
+
+ void disconnect();
+ ArrayList getConnectedControllers();
+}
diff --git a/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/interfaces/IObserver.java b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/interfaces/IObserver.java
new file mode 100644
index 000000000..d60fcad4d
--- /dev/null
+++ b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/interfaces/IObserver.java
@@ -0,0 +1,13 @@
+package org.sensorhub.controller.interfaces;
+
+import net.java.games.input.Component;
+
+public interface IObserver extends Runnable {
+
+ //ConcurrentHashMap controllerListeners = null;
+ void addListener(ControllerUpdateListener listener, Component.Identifier component);
+ void removeListener(ControllerUpdateListener listener, Component.Identifier component);
+ void doStart();
+ void doStop();
+ boolean isRunning();
+}
diff --git a/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/models/ControllerComponent.java b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/models/ControllerComponent.java
new file mode 100644
index 000000000..382e9c0a7
--- /dev/null
+++ b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/models/ControllerComponent.java
@@ -0,0 +1,29 @@
+package org.sensorhub.controller.models;
+
+public class ControllerComponent {
+
+ private String name;
+ private float value;
+
+ public ControllerComponent(String name, float initialValue) {
+ this.name = name;
+ this.value = initialValue;
+ }
+
+ public float getValue() {
+ return value;
+ }
+
+ public void setValue(float value) {
+ this.value = value;
+ }
+
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
diff --git a/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/models/ControllerData.java b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/models/ControllerData.java
new file mode 100644
index 000000000..9f52f591e
--- /dev/null
+++ b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/models/ControllerData.java
@@ -0,0 +1,30 @@
+package org.sensorhub.controller.models;
+
+import java.util.ArrayList;
+
+public class ControllerData {
+
+ public ControllerData(String controllerName, ControllerType controllerType, ArrayList components) {
+ this.name = controllerName;
+ this.outputs = components;
+ this.controllerType = controllerType;
+ }
+
+ private String name;
+
+ private ArrayList outputs;
+ private ControllerType controllerType;
+
+ public String getName() {
+ return name;
+ }
+
+ public ArrayList getOutputs() {
+ return outputs;
+ }
+ public ControllerType getControllerType() { return controllerType; }
+ public float getValue(String name) {
+ return outputs.stream().filter((x) -> x.getName().equals(name)).findFirst().get().getValue();
+ }
+
+}
diff --git a/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/models/ControllerDirection.java b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/models/ControllerDirection.java
new file mode 100644
index 000000000..415c0f01d
--- /dev/null
+++ b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/models/ControllerDirection.java
@@ -0,0 +1,16 @@
+package org.sensorhub.controller.models;
+
+public enum ControllerDirection {
+
+ UP_LEFT("UP_LEFT"), UP("UP"), UP_RIGHT("UP_RIGHT"), RIGHT("RIGHT"), DOWN_RIGHT("DOWN_RIGHT"), DOWN("DOWN"), DOWN_LEFT("DOWN_LEFT"), LEFT("LEFT"), NULL("NULL");
+
+ private String direction;
+ ControllerDirection(String direction) {
+ this.direction = direction;
+ }
+
+ @Override
+ public String toString() {
+ return direction;
+ }
+}
diff --git a/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/models/ControllerType.java b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/models/ControllerType.java
new file mode 100644
index 000000000..c69efdba9
--- /dev/null
+++ b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/models/ControllerType.java
@@ -0,0 +1,17 @@
+package org.sensorhub.controller.models;
+
+public enum ControllerType {
+
+ GAMEPAD("GAMEPAD"), WIIMOTE("WIIMOTE");
+
+ private String type;
+ ControllerType(String type) {
+ this.type = type;
+ }
+
+ @Override
+ public String toString() {
+ return type;
+ }
+
+}
diff --git a/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/models/Sensitivity.java b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/models/Sensitivity.java
new file mode 100644
index 000000000..854305a95
--- /dev/null
+++ b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/models/Sensitivity.java
@@ -0,0 +1,16 @@
+package org.sensorhub.controller.models;
+
+public enum Sensitivity {
+
+ NULL(0.0f), VERY_LOW(0.25f), LOW(0.5f), MEDIUM(1.2f), HIGH(1.6f), VERY_HIGH(2.5f);
+
+ private float sensitivityModifier;
+
+ Sensitivity(float sensitivityModifier) {
+ this.sensitivityModifier = sensitivityModifier;
+ }
+
+ public float getSensitivityModifier() {
+ return sensitivityModifier;
+ }
+}
diff --git a/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/util/FindControllers.java b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/util/FindControllers.java
new file mode 100644
index 000000000..3de4c822c
--- /dev/null
+++ b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/util/FindControllers.java
@@ -0,0 +1,107 @@
+package org.sensorhub.controller.util;
+
+import org.sensorhub.controller.gamepad.GamepadConnection;
+import org.sensorhub.controller.wii.WiiMoteConnection;
+import org.sensorhub.controller.interfaces.IController;
+import org.sensorhub.controller.interfaces.IControllerConnection;
+import org.sensorhub.controller.models.ControllerType;
+import net.java.games.input.Event;
+
+import java.util.*;
+
+public class FindControllers {
+
+ // TODO: Search for wii mote or usb controllers
+ private GamepadConnection gamepadConnection;
+ private WiiMoteConnection wiiMoteConnection;
+ private ArrayList controllers;
+ private Event event;
+ private ControllerType[] types;
+ private long searchTime = 5000;
+ public FindControllers(Event event) {
+ controllers = new ArrayList<>();
+
+ try {
+ gamepadConnection = new GamepadConnection(event);
+ if(gamepadConnection.getConnectedControllers() != null && !gamepadConnection.getConnectedControllers().isEmpty()) {
+ controllers.addAll(gamepadConnection.getConnectedControllers());
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ try {
+ wiiMoteConnection = new WiiMoteConnection(searchTime);
+ if(wiiMoteConnection.getConnectedControllers() != null && !wiiMoteConnection.getConnectedControllers().isEmpty()) {
+ controllers.addAll(wiiMoteConnection.getConnectedControllers());
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public FindControllers(long searchTime, Event event, ControllerType... types) {
+ controllers = new ArrayList<>();
+ this.searchTime = searchTime;
+ this.event = event;
+ this.types = types;
+ for(ControllerType type : this.types) {
+ switch(type) {
+ case GAMEPAD -> {
+ try {
+ gamepadConnection = new GamepadConnection(this.event);
+ if (gamepadConnection.getConnectedControllers() != null && !gamepadConnection.getConnectedControllers().isEmpty()) {
+ controllers.addAll(gamepadConnection.getConnectedControllers());
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ case WIIMOTE -> {
+ try {
+ wiiMoteConnection = new WiiMoteConnection(searchTime);
+ if(wiiMoteConnection.getConnectedControllers() != null && !wiiMoteConnection.getConnectedControllers().isEmpty()) {
+ controllers.addAll(wiiMoteConnection.getConnectedControllers());
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ default -> throw new IllegalStateException("No controller connections requested.");
+ }
+ }
+ }
+
+ public IControllerConnection getControllerConnection(ControllerType type) {
+ switch (type) {
+ case WIIMOTE -> {
+ return wiiMoteConnection;
+ }
+ case GAMEPAD -> {
+ return gamepadConnection;
+ }
+ default -> {
+ return null;
+ }
+ }
+ }
+
+ public ArrayList getControllers() {
+ return controllers;
+ }
+
+ public ArrayList getControllers(ControllerType controllerType) {
+ ArrayList filteredControllers = null;
+ try {
+ filteredControllers = (ArrayList) controllers.stream().filter((controller) -> Objects.equals(controller.getControllerData().getControllerType(), controllerType));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return filteredControllers;
+ }
+
+ public IController getController(String controllerName) {
+ return (IController) controllers.stream().filter((controller) -> Objects.equals(controller.getControllerData().getName(), controllerName));
+ }
+
+}
diff --git a/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/wii/WiiMote.java b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/wii/WiiMote.java
new file mode 100644
index 000000000..44dcf0a3d
--- /dev/null
+++ b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/wii/WiiMote.java
@@ -0,0 +1,72 @@
+package org.sensorhub.controller.wii;
+
+import org.sensorhub.controller.wii.identifiers.WiiIdentifier;
+import org.sensorhub.controller.wii.observer.WiiObserver;
+import org.sensorhub.controller.interfaces.IController;
+import org.sensorhub.controller.interfaces.IObserver;
+import org.sensorhub.controller.models.ControllerComponent;
+import org.sensorhub.controller.models.ControllerData;
+import org.sensorhub.controller.models.ControllerType;
+import motej.Mote;
+import motej.request.ReportModeRequest;
+import net.java.games.input.Component;
+
+import java.util.ArrayList;
+
+public class WiiMote implements IController {
+
+ private Mote mote;
+ private WiiObserver wiiObserver;
+ private ControllerData controllerData;
+ private boolean connected = true;
+
+ public WiiMote(Mote mote, int id) {
+ this.mote = mote;
+
+ mote.addMoteDisconnectedListener(moteDisconnectedEvent -> {
+ connected = false;
+ mote.disconnect();
+ wiiObserver.doStop();
+ });
+
+ mote.setPlayerLeds(new boolean[]{id == 0, id == 1, id == 2, id == 3});
+
+ ArrayList components = new ArrayList<>();
+ components.add(new ControllerComponent(WiiIdentifier.A.getName(), 0.0f));
+ components.add(new ControllerComponent(WiiIdentifier.B.getName(), 0.0f));
+ components.add(new ControllerComponent(Component.Identifier.Button.LEFT_THUMB.getName(), 0.0f));
+ components.add(new ControllerComponent(Component.Identifier.Button.RIGHT_THUMB.getName(), 0.0f));
+ components.add(new ControllerComponent(Component.Identifier.Button.MODE.getName(), 0.0f));
+ components.add(new ControllerComponent(WiiIdentifier._1.getName(), 0.0f));
+ components.add(new ControllerComponent(WiiIdentifier._2.getName(), 0.0f));
+ components.add(new ControllerComponent(WiiIdentifier.POV.getName(), 0.0f));
+ components.add(new ControllerComponent(WiiIdentifier.X_ACCELERATION.getName(), 0.0f));
+ components.add(new ControllerComponent(WiiIdentifier.Y_ACCELERATION.getName(), 0.0f));
+ components.add(new ControllerComponent(WiiIdentifier.Z_ACCELERATION.getName(), 0.0f));
+
+ controllerData = new ControllerData("WiiMote:" + id, ControllerType.WIIMOTE, components);
+ wiiObserver = new WiiObserver(this, mote);
+ wiiObserver.doStart();
+ }
+
+ @Override
+ public boolean isConnected() {
+ return mote != null && connected;
+ }
+
+ @Override
+ public void disconnect() {
+ mote.setReportMode(ReportModeRequest.DATA_REPORT_0x30);
+ mote.disconnect();
+ }
+
+ @Override
+ public IObserver getObserver() {
+ return wiiObserver;
+ }
+
+ @Override
+ public ControllerData getControllerData() {
+ return controllerData;
+ }
+}
diff --git a/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/wii/WiiMoteConnection.java b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/wii/WiiMoteConnection.java
new file mode 100644
index 000000000..0a792c70a
--- /dev/null
+++ b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/wii/WiiMoteConnection.java
@@ -0,0 +1,112 @@
+package org.sensorhub.controller.wii;
+
+import org.sensorhub.controller.interfaces.IController;
+import org.sensorhub.controller.interfaces.IControllerConnection;
+import motej.Mote;
+import motej.MoteFinder;
+import motej.MoteFinderListener;
+
+import java.util.ArrayList;
+
+public class WiiMoteConnection implements IControllerConnection {
+
+ private ArrayList motes;
+ private ArrayList connectedControllers;
+ private MoteFinder finder;
+ private long searchTime;
+
+ public WiiMoteConnection(long searchTime) {
+ this.searchTime = searchTime;
+
+ motes = new ArrayList<>();
+
+ // Find 4 WiiMotes
+ MoteFinderListener listener = mote -> {
+ mote.rumble(2000L);
+ System.out.println("WiiMote found!");
+ motes.add(mote);
+ finder = MoteFinder.getMoteFinder();
+ finder.addMoteFinderListener(mote1 -> {
+ motes.add(mote1);
+ finder = MoteFinder.getMoteFinder();
+ finder.addMoteFinderListener(mote2 -> {
+ motes.add(mote2);
+ finder = MoteFinder.getMoteFinder();
+ finder.addMoteFinderListener(mote3 -> {
+ motes.add(mote3);
+ });
+ finder.startDiscovery();
+ try {
+ Thread.sleep(searchTime);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ finder.stopDiscovery();
+ });
+ finder.startDiscovery();
+ try {
+ Thread.sleep(searchTime);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ finder.stopDiscovery();
+ });
+ finder.startDiscovery();
+ try {
+ Thread.sleep(searchTime);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ finder.stopDiscovery();
+ };
+
+ finder = MoteFinder.getMoteFinder();
+ finder.addMoteFinderListener(listener);
+
+ System.out.println("Starting Wii discovery");
+ finder.startDiscovery();
+
+ try {
+ Thread.sleep(searchTime);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ } finally {
+ System.out.println("Stopping Wii discovery. Found " + motes.size() + " wii motes.");
+ finder.stopDiscovery();
+ }
+
+ if(motes.isEmpty()) {
+ connectedControllers = null;
+ throw new IllegalStateException("No connected WiiMotes.");
+ }
+
+ connectedControllers = new ArrayList<>();
+
+ for(Mote mote : motes) {
+ WiiMote connectedMote = new WiiMote(mote, motes.indexOf(mote));
+ connectedControllers.add(connectedMote);
+ }
+ }
+
+ public long getSearchTime() {
+ return this.searchTime;
+ }
+
+ public void cancelSearch() {
+ finder.stopDiscovery();
+ System.out.println("Cancelling discovery");
+ }
+
+ @Override
+ public void disconnect() {
+ cancelSearch();
+ for (Mote mote : motes) {
+ mote.disconnect();
+ }
+ }
+
+ @Override
+ public ArrayList getConnectedControllers() {
+ return connectedControllers;
+ }
+}
diff --git a/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/wii/identifiers/WiiIdentifier.java b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/wii/identifiers/WiiIdentifier.java
new file mode 100644
index 000000000..107102271
--- /dev/null
+++ b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/wii/identifiers/WiiIdentifier.java
@@ -0,0 +1,22 @@
+package org.sensorhub.controller.wii.identifiers;
+
+import net.java.games.input.Component;
+
+public class WiiIdentifier extends Component.Identifier {
+
+ public static final WiiIdentifier MINUS = new WiiIdentifier("Minus");
+ public static final WiiIdentifier PLUS = new WiiIdentifier("Plus");
+ public static final WiiIdentifier HOME = new WiiIdentifier("Home");
+ public static final WiiIdentifier A = new WiiIdentifier("A");
+ public static final WiiIdentifier B = new WiiIdentifier("B");
+ public static final WiiIdentifier _1 = new WiiIdentifier("1");
+ public static final WiiIdentifier _2 = new WiiIdentifier("2");
+ public static final WiiIdentifier NONE = new WiiIdentifier("None");
+ public static final WiiIdentifier POV = new WiiIdentifier("pov");
+ public static final WiiIdentifier X_ACCELERATION = new WiiIdentifier("x-acceleration");
+ public static final WiiIdentifier Y_ACCELERATION = new WiiIdentifier("y-acceleration");
+ public static final WiiIdentifier Z_ACCELERATION = new WiiIdentifier("z-acceleration");
+ protected WiiIdentifier(String name) {
+ super(name);
+ }
+}
diff --git a/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/wii/observer/WiiObserver.java b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/wii/observer/WiiObserver.java
new file mode 100644
index 000000000..aee414b85
--- /dev/null
+++ b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/controller/wii/observer/WiiObserver.java
@@ -0,0 +1,279 @@
+package org.sensorhub.controller.wii.observer;
+
+import org.sensorhub.controller.wii.WiiMote;
+import org.sensorhub.controller.wii.identifiers.WiiIdentifier;
+import org.sensorhub.controller.interfaces.IObserver;
+import org.sensorhub.controller.interfaces.ControllerUpdateListener;
+import org.sensorhub.controller.models.ControllerComponent;
+import motej.Mote;
+import motej.event.*;
+import motej.request.ReportModeRequest;
+import motejx.extensions.nunchuk.*;
+import net.java.games.input.Component;
+
+import java.security.InvalidParameterException;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class WiiObserver implements IObserver, ExtensionListener {
+
+ private ConcurrentHashMap wiiListeners;
+ private WiiMote parent;
+ private Mote mote;
+ private Thread worker;
+ private String threadName = "WiiObserverThread:";
+ private boolean running = false;
+ NunchukCalibrationData nunchukCalibrationData = null;
+ private boolean calibrated = false;
+ private double rawXValue;
+ private double rawYValue;
+ private double xOffset;
+ private double yOffset;
+ private double calibrationConstant;
+ private ControllerComponent[] nunchukComponents = new ControllerComponent[]{
+ new ControllerComponent(Component.Identifier.Button.C.getName(), 0.0f),
+ new ControllerComponent(Component.Identifier.Button.Z.getName(), 0.0f),
+ new ControllerComponent(Component.Identifier.Axis.X.getName(), 0.0f),
+ new ControllerComponent(Component.Identifier.Axis.Y.getName(), 0.0f),
+ new ControllerComponent(Component.Identifier.Axis.RX_ACCELERATION.getName(), 0.0f),
+ new ControllerComponent(Component.Identifier.Axis.RY_ACCELERATION.getName(), 0.0f),
+ new ControllerComponent(Component.Identifier.Axis.RZ_ACCELERATION.getName(), 0.0f)};
+
+ private void applyCallbacks() {
+ for(WiiIdentifier key : wiiListeners.keySet()) {
+ wiiListeners.get(key).onChange(key.getName(), parent.getControllerData().getValue(key.getName()));
+ }
+ }
+ private final CoreButtonListener coreButtonListener = event -> {
+ populateButtonOutput(event);
+ applyCallbacks();
+ };
+
+ private void populateButtonOutput(CoreButtonEvent e) {
+ parent.getControllerData().getOutputs().get(0).setValue(e.isButtonAPressed() ? 1.0f : 0.0f);
+ parent.getControllerData().getOutputs().get(1).setValue(e.isButtonBPressed() ? 1.0f : 0.0f);
+ parent.getControllerData().getOutputs().get(2).setValue(e.isButtonMinusPressed() ? 1.0f : 0.0f);
+ parent.getControllerData().getOutputs().get(3).setValue(e.isButtonPlusPressed() ? 1.0f : 0.0f);
+ parent.getControllerData().getOutputs().get(4).setValue(e.isButtonHomePressed() ? 1.0f : 0.0f);
+ parent.getControllerData().getOutputs().get(5).setValue(e.isButtonOnePressed() ? 1.0f : 0.0f);
+ parent.getControllerData().getOutputs().get(6).setValue(e.isButtonTwoPressed() ? 1.0f : 0.0f);
+
+ if(e.isDPadLeftPressed()) {
+ parent.getControllerData().getOutputs().get(7).setValue(Component.POV.LEFT);
+ } else
+ if(e.isDPadUpPressed()) {
+ parent.getControllerData().getOutputs().get(7).setValue(Component.POV.UP);
+ } else
+ if(e.isDPadRightPressed()) {
+ parent.getControllerData().getOutputs().get(7).setValue(Component.POV.RIGHT);
+ } else
+ if(e.isDPadDownPressed()) {
+ parent.getControllerData().getOutputs().get(7).setValue(Component.POV.DOWN);
+ } else {
+ parent.getControllerData().getOutputs().get(7).setValue(Component.POV.CENTER);
+ }
+ }
+
+ private final AccelerometerListener accelerometerListener = event -> {
+ populateAccelerometerOutput(event);
+ applyCallbacks();
+ };
+
+ private void populateAccelerometerOutput(AccelerometerEvent e) {
+ parent.getControllerData().getOutputs().get(8).setValue(e.getX() & 0xff);
+ parent.getControllerData().getOutputs().get(9).setValue(e.getY() & 0xff);
+ parent.getControllerData().getOutputs().get(10).setValue(e.getZ() & 0xff);
+ }
+
+ private final NunchukButtonListener nunchukButtonListener = event -> {
+ populateNunchukButtonOutput(event);
+ applyCallbacks();
+ };
+
+ private void populateNunchukButtonOutput(NunchukButtonEvent e) {
+ parent.getControllerData().getOutputs().get(11).setValue(e.isButtonCPressed() ? 1.0f : 0.0f);
+ parent.getControllerData().getOutputs().get(12).setValue(e.isButtonZPressed() ? 1.0f : 0.0f);
+ }
+
+ private final AnalogStickListener analogStickListener = event -> {
+ if(!calibrated) {
+ rawXValue = event.getPoint().getX();
+ rawYValue = event.getPoint().getY();
+ }
+ populateNunchukJoystickOutput(event);
+ applyCallbacks();
+ };
+
+ private void populateNunchukJoystickOutput(AnalogStickEvent e) {
+ // Equation to get calibrated value as a number on -1.0 -> 1.0 axis
+ if(nunchukCalibrationData != null) {
+ double calibratedX = calibrationConstant * ((e.getPoint().getX()
+ - (nunchukCalibrationData.getCenterAnalogPoint().getX()
+ - xOffset)))
+ / nunchukCalibrationData.getMaximumAnalogPoint().getX();
+ double calibratedY = calibrationConstant * ((e.getPoint().getY()
+ - (nunchukCalibrationData.getCenterAnalogPoint().getY()
+ - yOffset)))
+ / nunchukCalibrationData.getMaximumAnalogPoint().getY();
+
+ if(calibratedY != 0) {
+ calibratedY = -calibratedY;
+ }
+
+ float cX = (float) calibratedX;
+ float cY = (float) calibratedY;
+
+ // Cap max and min values to 1.0 and -1.0
+ if(cX > 1.0f) {
+ cX = Math.min(1.0f, cX);
+ } else if(cX < -1.0f) {
+ cX = Math.max(-1.0f, cX);
+ }
+ if(cY > 1.0f) {
+ cY = Math.min(1.0f, cY);
+ } else if(cY < -1.0f) {
+ cY = Math.max(-1.0f, cY);
+ }
+
+ // Round numbers that are close to 0 to 0
+ if(cX >= -0.05 && cX <= 0.05) {
+ cX = 0.0f;
+ }
+ if(cY >= -0.05 && cY <= 0.05) {
+ cY = 0.0f;
+ }
+
+ parent.getControllerData().getOutputs().get(13).setValue(cX);
+ parent.getControllerData().getOutputs().get(14).setValue(cY);
+ }
+ }
+
+ private final AccelerometerListener nunchukAccelerometerListener = event -> {
+ populateNunchukAccelerometerOutput(event);
+ applyCallbacks();
+ };
+
+ private void populateNunchukAccelerometerOutput(AccelerometerEvent e) {
+ parent.getControllerData().getOutputs().get(15).setValue(e.getX() & 0xff);
+ parent.getControllerData().getOutputs().get(16).setValue(e.getY() & 0xff);
+ parent.getControllerData().getOutputs().get(17).setValue(e.getZ() & 0xff);
+ }
+
+ public WiiObserver(WiiMote parent, Mote mote) {
+ this.parent = parent;
+ this.mote = mote;
+
+ threadName += parent.getControllerData().getName();
+
+ wiiListeners = new ConcurrentHashMap<>();
+ }
+
+ @Override
+ public void addListener(ControllerUpdateListener listener, Component.Identifier component) {
+ if(component instanceof WiiIdentifier) {
+ wiiListeners.put((WiiIdentifier) component, listener);
+ } else {
+ throw new InvalidParameterException("Identifier cannot be used on WiiMote. Must use WiiIdentifier.");
+ }
+ }
+
+ @Override
+ public void removeListener(ControllerUpdateListener listener, Component.Identifier component) {
+ if(component instanceof WiiIdentifier) {
+ wiiListeners.remove(component, listener);
+ }
+ }
+
+ @Override
+ public void doStart() {
+ try{
+ if(mote == null) {
+ throw new IllegalStateException("WiiMote is not initialized.");
+ }
+ if(worker != null && worker.isAlive()) {
+ throw new IllegalStateException("Observer is already listening for events");
+ }
+
+ synchronized (this) {
+ mote.addExtensionListener(this);
+ mote.addCoreButtonListener(coreButtonListener);
+ mote.addAccelerometerListener(accelerometerListener);
+ }
+
+ // Read Buttons and Accelerometer data from WiiMote
+ mote.setReportMode(ReportModeRequest.DATA_REPORT_0x31, true);
+
+ running = true;
+ worker = new Thread(this, this.threadName);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void doStop() {
+ running = false;
+ mote.setReportMode(ReportModeRequest.DATA_REPORT_0x30);
+ mote.disconnect();
+ System.out.println("Observer stopped");
+ }
+
+ @Override
+ public boolean isRunning() {
+ running = worker.isAlive();
+ return running;
+ }
+
+ @Override
+ public void run() {
+ while(running) {
+ if(mote == null) {
+ doStop();
+ }
+ }
+ }
+
+ @Override
+ public void extensionConnected(ExtensionEvent extensionEvent) {
+ if(extensionEvent.getExtension() instanceof Nunchuk nunchuk) {
+ for(ControllerComponent nunchukComponent : nunchukComponents) {
+ parent.getControllerData().getOutputs().add(nunchukComponent);
+ }
+ mote.setReportMode(ReportModeRequest.DATA_REPORT_0x35, true);
+ nunchuk.addNunchukButtonListener(nunchukButtonListener);
+ nunchuk.addAnalogStickListener(analogStickListener);
+ nunchuk.addAccelerometerListener(nunchukAccelerometerListener);
+
+ Thread calibrationThread = new Thread(() -> {
+ while(nunchuk.getCalibrationData() == null) {
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ if(nunchuk.getCalibrationData() !=null) {
+ this.nunchukCalibrationData = nunchuk.getCalibrationData();
+ if(!calibrated) {
+ if(nunchuk.getCalibrationData().getCenterAnalogPoint() != null && nunchuk.getCalibrationData().getMaximumAnalogPoint() != null) {
+ xOffset = nunchuk.getCalibrationData().getCenterAnalogPoint().getX() - rawXValue;
+ yOffset = nunchuk.getCalibrationData().getCenterAnalogPoint().getY() - rawYValue;
+ calibrationConstant = nunchuk.getCalibrationData().getMaximumAnalogPoint().getX() / 100.00f;
+ calibrated = true;
+ }
+ }
+ } else {
+ System.out.println("Null calibration data");
+ }
+ }, "calibrationThread");
+ calibrationThread.start();
+ }
+ }
+
+ @Override
+ public void extensionDisconnected(ExtensionEvent extensionEvent) {
+ mote.setReportMode(ReportModeRequest.DATA_REPORT_0x31, true);
+ for(ControllerComponent nunchukComponent : nunchukComponents) {
+ parent.getControllerData().getOutputs().remove(nunchukComponent);
+ }
+ }
+}
diff --git a/sensors/others/sensorhub-driver-universalcontroller/src/main/java/com/sample/impl/sensor/universalcontroller/Activator.java b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/impl/sensor/universalcontroller/Activator.java
similarity index 65%
rename from sensors/others/sensorhub-driver-universalcontroller/src/main/java/com/sample/impl/sensor/universalcontroller/Activator.java
rename to sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/impl/sensor/universalcontroller/Activator.java
index 7ccea31f9..60309ac69 100644
--- a/sensors/others/sensorhub-driver-universalcontroller/src/main/java/com/sample/impl/sensor/universalcontroller/Activator.java
+++ b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/impl/sensor/universalcontroller/Activator.java
@@ -1,4 +1,4 @@
-package com.sample.impl.sensor.universalcontroller;
+package org.sensorhub.impl.sensor.universalcontroller;
import org.sensorhub.utils.OshBundleActivator;
diff --git a/sensors/others/sensorhub-driver-universalcontroller/src/main/java/com/sample/impl/sensor/universalcontroller/ControllerLayerConfig.java b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/impl/sensor/universalcontroller/ControllerLayerConfig.java
similarity index 91%
rename from sensors/others/sensorhub-driver-universalcontroller/src/main/java/com/sample/impl/sensor/universalcontroller/ControllerLayerConfig.java
rename to sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/impl/sensor/universalcontroller/ControllerLayerConfig.java
index b49bffccc..bb6894919 100644
--- a/sensors/others/sensorhub-driver-universalcontroller/src/main/java/com/sample/impl/sensor/universalcontroller/ControllerLayerConfig.java
+++ b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/impl/sensor/universalcontroller/ControllerLayerConfig.java
@@ -11,9 +11,9 @@
Copyright (C) 2020-2021 Botts Innovative Research, Inc. All Rights Reserved.
******************************* END LICENSE BLOCK ***************************/
-package com.sample.impl.sensor.universalcontroller;
+package org.sensorhub.impl.sensor.universalcontroller;
-import com.sample.impl.sensor.universalcontroller.helpers.ControllerMappingPreset;
+import org.sensorhub.impl.sensor.universalcontroller.helpers.ControllerMappingPreset;
import org.sensorhub.api.config.DisplayInfo;
import org.sensorhub.api.sensor.SensorConfig;
diff --git a/sensors/others/sensorhub-driver-universalcontroller/src/main/java/com/sample/impl/sensor/universalcontroller/UniversalControllerConfig.java b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/impl/sensor/universalcontroller/UniversalControllerConfig.java
similarity index 96%
rename from sensors/others/sensorhub-driver-universalcontroller/src/main/java/com/sample/impl/sensor/universalcontroller/UniversalControllerConfig.java
rename to sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/impl/sensor/universalcontroller/UniversalControllerConfig.java
index f4e695f40..e00f4dd44 100644
--- a/sensors/others/sensorhub-driver-universalcontroller/src/main/java/com/sample/impl/sensor/universalcontroller/UniversalControllerConfig.java
+++ b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/impl/sensor/universalcontroller/UniversalControllerConfig.java
@@ -11,9 +11,9 @@
Copyright (C) 2020-2021 Botts Innovative Research, Inc. All Rights Reserved.
******************************* END LICENSE BLOCK ***************************/
-package com.sample.impl.sensor.universalcontroller;
+package org.sensorhub.impl.sensor.universalcontroller;
-import com.alexalmanza.models.ControllerType;
+import org.sensorhub.controller.models.ControllerType;
import org.sensorhub.api.config.DisplayInfo;
import org.sensorhub.api.sensor.SensorConfig;
diff --git a/sensors/others/sensorhub-driver-universalcontroller/src/main/java/com/sample/impl/sensor/universalcontroller/UniversalControllerControl.java b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/impl/sensor/universalcontroller/UniversalControllerControl.java
similarity index 97%
rename from sensors/others/sensorhub-driver-universalcontroller/src/main/java/com/sample/impl/sensor/universalcontroller/UniversalControllerControl.java
rename to sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/impl/sensor/universalcontroller/UniversalControllerControl.java
index 9e806679e..732f02930 100644
--- a/sensors/others/sensorhub-driver-universalcontroller/src/main/java/com/sample/impl/sensor/universalcontroller/UniversalControllerControl.java
+++ b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/impl/sensor/universalcontroller/UniversalControllerControl.java
@@ -1,4 +1,4 @@
-package com.sample.impl.sensor.universalcontroller;
+package org.sensorhub.impl.sensor.universalcontroller;
import net.opengis.swe.v20.DataBlock;
diff --git a/sensors/others/sensorhub-driver-universalcontroller/src/main/java/com/sample/impl/sensor/universalcontroller/UniversalControllerDescriptor.java b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/impl/sensor/universalcontroller/UniversalControllerDescriptor.java
similarity index 96%
rename from sensors/others/sensorhub-driver-universalcontroller/src/main/java/com/sample/impl/sensor/universalcontroller/UniversalControllerDescriptor.java
rename to sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/impl/sensor/universalcontroller/UniversalControllerDescriptor.java
index 93402577c..f789fd430 100644
--- a/sensors/others/sensorhub-driver-universalcontroller/src/main/java/com/sample/impl/sensor/universalcontroller/UniversalControllerDescriptor.java
+++ b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/impl/sensor/universalcontroller/UniversalControllerDescriptor.java
@@ -11,7 +11,7 @@
Copyright (C) 2020-2021 Botts Innovative Research, Inc. All Rights Reserved.
******************************* END LICENSE BLOCK ***************************/
-package com.sample.impl.sensor.universalcontroller;
+package org.sensorhub.impl.sensor.universalcontroller;
import org.sensorhub.api.module.IModule;
import org.sensorhub.api.module.IModuleProvider;
diff --git a/sensors/others/sensorhub-driver-universalcontroller/src/main/java/com/sample/impl/sensor/universalcontroller/UniversalControllerOutput.java b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/impl/sensor/universalcontroller/UniversalControllerOutput.java
similarity index 96%
rename from sensors/others/sensorhub-driver-universalcontroller/src/main/java/com/sample/impl/sensor/universalcontroller/UniversalControllerOutput.java
rename to sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/impl/sensor/universalcontroller/UniversalControllerOutput.java
index 8624afec6..c2eab5b89 100644
--- a/sensors/others/sensorhub-driver-universalcontroller/src/main/java/com/sample/impl/sensor/universalcontroller/UniversalControllerOutput.java
+++ b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/impl/sensor/universalcontroller/UniversalControllerOutput.java
@@ -11,16 +11,14 @@
Copyright (C) 2020-2021 Botts Innovative Research, Inc. All Rights Reserved.
******************************* END LICENSE BLOCK ***************************/
-package com.sample.impl.sensor.universalcontroller;
-
-import com.alexalmanza.controller.wii.identifiers.WiiIdentifier;
-import com.alexalmanza.interfaces.IController;
-import com.alexalmanza.models.ControllerComponent;
-import com.alexalmanza.models.ControllerData;
-import com.alexalmanza.models.ControllerType;
-import com.sample.impl.sensor.universalcontroller.helpers.ControllerCyclingAction;
-import com.sample.impl.sensor.universalcontroller.helpers.ControllerMappingPreset;
-import com.sample.impl.sensor.universalcontroller.helpers.UniversalControllerComponent;
+package org.sensorhub.impl.sensor.universalcontroller;
+
+import org.sensorhub.controller.interfaces.IController;
+import org.sensorhub.controller.models.ControllerComponent;
+import org.sensorhub.controller.models.ControllerType;
+import org.sensorhub.impl.sensor.universalcontroller.helpers.ControllerCyclingAction;
+import org.sensorhub.impl.sensor.universalcontroller.helpers.ControllerMappingPreset;
+import org.sensorhub.impl.sensor.universalcontroller.helpers.UniversalControllerComponent;
import net.opengis.swe.v20.*;
import org.sensorhub.api.data.DataEvent;
import org.sensorhub.api.sensor.SensorException;
@@ -28,12 +26,9 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.vast.data.*;
-import org.vast.swe.SWEBuilders;
import org.vast.swe.SWEHelper;
import java.lang.Boolean;
-import java.util.ArrayList;
-import java.util.List;
/**
* Output specification and provider for {@link UniversalControllerSensor}.
diff --git a/sensors/others/sensorhub-driver-universalcontroller/src/main/java/com/sample/impl/sensor/universalcontroller/UniversalControllerSensor.java b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/impl/sensor/universalcontroller/UniversalControllerSensor.java
similarity index 91%
rename from sensors/others/sensorhub-driver-universalcontroller/src/main/java/com/sample/impl/sensor/universalcontroller/UniversalControllerSensor.java
rename to sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/impl/sensor/universalcontroller/UniversalControllerSensor.java
index 8ca2e3430..79f2e0122 100644
--- a/sensors/others/sensorhub-driver-universalcontroller/src/main/java/com/sample/impl/sensor/universalcontroller/UniversalControllerSensor.java
+++ b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/impl/sensor/universalcontroller/UniversalControllerSensor.java
@@ -11,14 +11,12 @@
Copyright (C) 2020-2021 Botts Innovative Research, Inc. All Rights Reserved.
******************************* END LICENSE BLOCK ***************************/
-package com.sample.impl.sensor.universalcontroller;
-
-import com.alexalmanza.controller.wii.WiiMote;
-import com.alexalmanza.controller.wii.WiiMoteConnection;
-import com.alexalmanza.interfaces.IController;
-import com.alexalmanza.interfaces.IControllerConnection;
-import com.alexalmanza.models.ControllerType;
-import com.alexalmanza.util.FindControllers;
+package org.sensorhub.impl.sensor.universalcontroller;
+
+import org.sensorhub.controller.wii.WiiMoteConnection;
+import org.sensorhub.controller.interfaces.IController;
+import org.sensorhub.controller.models.ControllerType;
+import org.sensorhub.controller.util.FindControllers;
import net.java.games.input.Event;
import org.sensorhub.api.common.SensorHubException;
import org.sensorhub.impl.sensor.AbstractSensorModule;
diff --git a/sensors/others/sensorhub-driver-universalcontroller/src/main/java/com/sample/impl/sensor/universalcontroller/helpers/ControllerCyclingAction.java b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/impl/sensor/universalcontroller/helpers/ControllerCyclingAction.java
similarity index 72%
rename from sensors/others/sensorhub-driver-universalcontroller/src/main/java/com/sample/impl/sensor/universalcontroller/helpers/ControllerCyclingAction.java
rename to sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/impl/sensor/universalcontroller/helpers/ControllerCyclingAction.java
index 7c5095bfd..f6b6eecc0 100644
--- a/sensors/others/sensorhub-driver-universalcontroller/src/main/java/com/sample/impl/sensor/universalcontroller/helpers/ControllerCyclingAction.java
+++ b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/impl/sensor/universalcontroller/helpers/ControllerCyclingAction.java
@@ -1,4 +1,4 @@
-package com.sample.impl.sensor.universalcontroller.helpers;
+package org.sensorhub.impl.sensor.universalcontroller.helpers;
public enum ControllerCyclingAction {
diff --git a/sensors/others/sensorhub-driver-universalcontroller/src/main/java/com/sample/impl/sensor/universalcontroller/helpers/ControllerMappingPreset.java b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/impl/sensor/universalcontroller/helpers/ControllerMappingPreset.java
similarity index 68%
rename from sensors/others/sensorhub-driver-universalcontroller/src/main/java/com/sample/impl/sensor/universalcontroller/helpers/ControllerMappingPreset.java
rename to sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/impl/sensor/universalcontroller/helpers/ControllerMappingPreset.java
index 8dd6fe4f1..c5f826a39 100644
--- a/sensors/others/sensorhub-driver-universalcontroller/src/main/java/com/sample/impl/sensor/universalcontroller/helpers/ControllerMappingPreset.java
+++ b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/impl/sensor/universalcontroller/helpers/ControllerMappingPreset.java
@@ -1,6 +1,4 @@
-package com.sample.impl.sensor.universalcontroller.helpers;
-
-import com.alexalmanza.controller.wii.identifiers.WiiIdentifier;
+package org.sensorhub.impl.sensor.universalcontroller.helpers;
import java.util.ArrayList;
diff --git a/sensors/others/sensorhub-driver-universalcontroller/src/main/java/com/sample/impl/sensor/universalcontroller/helpers/UniversalControllerComponent.java b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/impl/sensor/universalcontroller/helpers/UniversalControllerComponent.java
similarity index 96%
rename from sensors/others/sensorhub-driver-universalcontroller/src/main/java/com/sample/impl/sensor/universalcontroller/helpers/UniversalControllerComponent.java
rename to sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/impl/sensor/universalcontroller/helpers/UniversalControllerComponent.java
index 804be03df..90d289ab1 100644
--- a/sensors/others/sensorhub-driver-universalcontroller/src/main/java/com/sample/impl/sensor/universalcontroller/helpers/UniversalControllerComponent.java
+++ b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/impl/sensor/universalcontroller/helpers/UniversalControllerComponent.java
@@ -1,4 +1,4 @@
-package com.sample.impl.sensor.universalcontroller.helpers;
+package org.sensorhub.impl.sensor.universalcontroller.helpers;
public enum UniversalControllerComponent {
A_BUTTON("A"),
diff --git a/sensors/others/sensorhub-driver-universalcontroller/src/main/java/com/sample/impl/sensor/universalcontroller/helpers/UniversalControllerProcessHelper.java b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/impl/sensor/universalcontroller/helpers/UniversalControllerProcessHelper.java
similarity index 99%
rename from sensors/others/sensorhub-driver-universalcontroller/src/main/java/com/sample/impl/sensor/universalcontroller/helpers/UniversalControllerProcessHelper.java
rename to sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/impl/sensor/universalcontroller/helpers/UniversalControllerProcessHelper.java
index 6043f97d6..cff123973 100644
--- a/sensors/others/sensorhub-driver-universalcontroller/src/main/java/com/sample/impl/sensor/universalcontroller/helpers/UniversalControllerProcessHelper.java
+++ b/sensors/others/sensorhub-driver-universalcontroller/src/main/java/org/sensorhub/impl/sensor/universalcontroller/helpers/UniversalControllerProcessHelper.java
@@ -1,4 +1,4 @@
-package com.sample.impl.sensor.universalcontroller.helpers;
+package org.sensorhub.impl.sensor.universalcontroller.helpers;
import net.opengis.swe.v20.*;
import org.vast.data.*;
diff --git a/sensors/others/sensorhub-driver-universalcontroller/src/main/resources/META-INF/services/org.sensorhub.api.module.IModuleProvider b/sensors/others/sensorhub-driver-universalcontroller/src/main/resources/META-INF/services/org.sensorhub.api.module.IModuleProvider
index 2a7a0a89f..5d954fc14 100644
--- a/sensors/others/sensorhub-driver-universalcontroller/src/main/resources/META-INF/services/org.sensorhub.api.module.IModuleProvider
+++ b/sensors/others/sensorhub-driver-universalcontroller/src/main/resources/META-INF/services/org.sensorhub.api.module.IModuleProvider
@@ -1 +1 @@
-com.sample.impl.sensor.universalcontroller.UniversalControllerDescriptor
+org.sensorhub.impl.sensor.universalcontroller.UniversalControllerDescriptor