diff --git a/gui/public/i18n/en/translation.ftl b/gui/public/i18n/en/translation.ftl
index 914783abe..b39105e05 100644
--- a/gui/public/i18n/en/translation.ftl
+++ b/gui/public/i18n/en/translation.ftl
@@ -573,6 +573,10 @@ settings-general-tracker_mechanics-use_mag_on_all_trackers-description =
Uses magnetometer on all trackers that have a compatible firmware for it, reducing drift in stable magnetic environments.
Can be disabled per tracker in the tracker's settings. Please don't shutdown any of the trackers while toggling this!
settings-general-tracker_mechanics-use_mag_on_all_trackers-label = Use magnetometer on trackers
+settings-general-tracker_mechanics-trackers_over_usb = Trackers over USB
+settings-general-tracker_mechanics-trackers_over_usb-description =
+ Enables receiving HID tracker data over USB. Make sure connected trackers have connection over HID enabled!
+settings-general-tracker_mechanics-trackers_over_usb-enabled-label = Allow HID trackers to connect directly over USB
settings-stay_aligned = Stay Aligned
settings-stay_aligned-description = Stay Aligned reduces drift by gradually adjusting your trackers to match your relaxed poses.
diff --git a/gui/src/components/settings/pages/GeneralSettings.tsx b/gui/src/components/settings/pages/GeneralSettings.tsx
index d55478deb..174601a93 100644
--- a/gui/src/components/settings/pages/GeneralSettings.tsx
+++ b/gui/src/components/settings/pages/GeneralSettings.tsx
@@ -14,6 +14,7 @@ import {
SettingsResponseT,
SteamVRTrackersSettingT,
TapDetectionSettingsT,
+ HIDSettingsT,
} from 'solarxr-protocol';
import { useConfig } from '@/hooks/config';
import { useWebsocketAPI } from '@/hooks/websocket-api';
@@ -101,6 +102,9 @@ export type SettingsForm = {
};
resetsSettings: ResetSettingsForm;
stayAligned: StayAlignedSettingsForm;
+ hidSettings: {
+ trackersOverHID: boolean;
+ };
};
const defaultValues: SettingsForm = {
@@ -156,6 +160,7 @@ const defaultValues: SettingsForm = {
legTweaks: { correctionStrength: 0.3 },
resetsSettings: defaultResetSettings,
stayAligned: defaultStayAlignedSettings,
+ hidSettings: { trackersOverHID: false },
};
export function GeneralSettings() {
@@ -277,6 +282,10 @@ export function GeneralSettings() {
settings.stayAligned = serializeStayAlignedSettings(values.stayAligned);
+ const hidSettings = new HIDSettingsT();
+ hidSettings.trackersOverHid = values.hidSettings.trackersOverHID;
+ settings.hidSettings = hidSettings;
+
if (values.resetsSettings) {
settings.resetsSettings = loadResetSettings(values.resetsSettings);
}
@@ -392,6 +401,12 @@ export function GeneralSettings() {
);
}
+ if (settings.hidSettings) {
+ formData.hidSettings = {
+ trackersOverHID: settings.hidSettings.trackersOverHid,
+ };
+ }
+
reset({ ...getValues(), ...formData });
});
@@ -689,6 +704,28 @@ export function GeneralSettings() {
settingType="general"
id="mechanics-magnetometer"
/>
+
+
+ {l10n.getString(
+ 'settings-general-tracker_mechanics-trackers_over_usb'
+ )}
+
+ }}
+ >
+
+
+
+
>
} id="fksettings">
diff --git a/server/android/src/main/java/dev/slimevr/android/tracking/trackers/hid/AndroidHIDManager.kt b/server/android/src/main/java/dev/slimevr/android/tracking/trackers/hid/AndroidHIDManager.kt
index 40fa6ad9b..22b537a90 100644
--- a/server/android/src/main/java/dev/slimevr/android/tracking/trackers/hid/AndroidHIDManager.kt
+++ b/server/android/src/main/java/dev/slimevr/android/tracking/trackers/hid/AndroidHIDManager.kt
@@ -8,10 +8,13 @@ import android.content.IntentFilter
import android.hardware.usb.UsbDevice
import android.hardware.usb.UsbManager
import androidx.core.content.ContextCompat
+import dev.slimevr.VRServer
+import dev.slimevr.config.config
import dev.slimevr.tracking.trackers.Device
import dev.slimevr.tracking.trackers.Tracker
import dev.slimevr.tracking.trackers.TrackerStatus
import dev.slimevr.tracking.trackers.hid.HIDCommon
+import dev.slimevr.tracking.trackers.hid.HIDCommon.Companion.HID_TRACKER_PID
import dev.slimevr.tracking.trackers.hid.HIDCommon.Companion.HID_TRACKER_RECEIVER_PID
import dev.slimevr.tracking.trackers.hid.HIDCommon.Companion.HID_TRACKER_RECEIVER_VID
import dev.slimevr.tracking.trackers.hid.HIDCommon.Companion.PACKET_SIZE
@@ -91,7 +94,7 @@ class AndroidHIDManager(
}
fun checkConfigureDevice(usbDevice: UsbDevice, requestPermission: Boolean = false) {
- if (usbDevice.vendorId == HID_TRACKER_RECEIVER_VID && usbDevice.productId == HID_TRACKER_RECEIVER_PID) {
+ if (usbDevice.vendorId == HID_TRACKER_RECEIVER_VID && (usbDevice.productId == HID_TRACKER_RECEIVER_PID || usbDevice.productId == HID_TRACKER_PID)) {
if (usbManager.hasPermission(usbDevice)) {
LogManager.info("[TrackerServer] Already have permission for ${usbDevice.deviceName}")
proceedWithDeviceConfiguration(usbDevice)
@@ -199,8 +202,9 @@ class AndroidHIDManager(
}
private fun deviceEnumerate(requestPermission: Boolean = false) {
+ val trackersOverHID: Boolean = VRServer.instance.configManager.vrConfig.hidConfig.trackersOverHID
val hidDeviceList: MutableList = usbManager.deviceList.values.filter {
- it.vendorId == HID_TRACKER_RECEIVER_VID && it.productId == HID_TRACKER_RECEIVER_PID
+ it.vendorId == HID_TRACKER_RECEIVER_VID && (it.productId == HID_TRACKER_RECEIVER_PID || (trackersOverHID && it.productId == HID_TRACKER_PID))
}.toMutableList()
synchronized(devicesByHID) {
// Work on devicesByHid and add/remove as necessary
diff --git a/server/core/src/main/java/dev/slimevr/config/HIDConfig.kt b/server/core/src/main/java/dev/slimevr/config/HIDConfig.kt
new file mode 100644
index 000000000..2945ee314
--- /dev/null
+++ b/server/core/src/main/java/dev/slimevr/config/HIDConfig.kt
@@ -0,0 +1,7 @@
+package dev.slimevr.config
+
+import com.fasterxml.jackson.annotation.JsonIgnore
+
+class HIDConfig {
+ var trackersOverHID = false
+}
diff --git a/server/core/src/main/java/dev/slimevr/config/VRConfig.kt b/server/core/src/main/java/dev/slimevr/config/VRConfig.kt
index 9ad2756f0..9ef33f5e0 100644
--- a/server/core/src/main/java/dev/slimevr/config/VRConfig.kt
+++ b/server/core/src/main/java/dev/slimevr/config/VRConfig.kt
@@ -42,6 +42,8 @@ class VRConfig {
val stayAlignedConfig = StayAlignedConfig()
+ val hidConfig = HIDConfig()
+
@JsonDeserialize(using = TrackerConfigMapDeserializer::class)
@JsonSerialize(keyUsing = StdKeySerializers.StringKeySerializer::class)
private val trackers: MutableMap = HashMap()
diff --git a/server/core/src/main/java/dev/slimevr/protocol/rpc/settings/RPCSettingsBuilder.java b/server/core/src/main/java/dev/slimevr/protocol/rpc/settings/RPCSettingsBuilder.java
index 650f4b098..a06870e9f 100644
--- a/server/core/src/main/java/dev/slimevr/protocol/rpc/settings/RPCSettingsBuilder.java
+++ b/server/core/src/main/java/dev/slimevr/protocol/rpc/settings/RPCSettingsBuilder.java
@@ -412,6 +412,11 @@ public class RPCSettingsBuilder {
.createStayAlignedSettings(
fbb,
server.configManager.getVrConfig().getStayAlignedConfig()
+ ),
+ RPCSettingsBuilderKotlin.INSTANCE
+ .createHIDSettings(
+ fbb,
+ server.configManager.getVrConfig().getHidConfig()
)
);
}
diff --git a/server/core/src/main/java/dev/slimevr/protocol/rpc/settings/RPCSettingsBuilderKotlin.kt b/server/core/src/main/java/dev/slimevr/protocol/rpc/settings/RPCSettingsBuilderKotlin.kt
index 701da7438..3efe9d48e 100644
--- a/server/core/src/main/java/dev/slimevr/protocol/rpc/settings/RPCSettingsBuilderKotlin.kt
+++ b/server/core/src/main/java/dev/slimevr/protocol/rpc/settings/RPCSettingsBuilderKotlin.kt
@@ -1,7 +1,9 @@
package dev.slimevr.protocol.rpc.settings
import com.google.flatbuffers.FlatBufferBuilder
+import dev.slimevr.config.HIDConfig
import dev.slimevr.config.StayAlignedConfig
+import solarxr_protocol.rpc.HIDSettings
import solarxr_protocol.rpc.StayAlignedSettings
object RPCSettingsBuilderKotlin {
@@ -29,4 +31,13 @@ object RPCSettingsBuilderKotlin {
config.flatRelaxedPose.footAngleInDeg,
config.setupComplete,
)
+
+ fun createHIDSettings(
+ fbb: FlatBufferBuilder,
+ config: HIDConfig,
+ ): Int = HIDSettings
+ .createHIDSettings(
+ fbb,
+ config.trackersOverHID,
+ )
}
diff --git a/server/core/src/main/java/dev/slimevr/protocol/rpc/settings/RPCSettingsHandler.kt b/server/core/src/main/java/dev/slimevr/protocol/rpc/settings/RPCSettingsHandler.kt
index 2f4861aab..f2c882a04 100644
--- a/server/core/src/main/java/dev/slimevr/protocol/rpc/settings/RPCSettingsHandler.kt
+++ b/server/core/src/main/java/dev/slimevr/protocol/rpc/settings/RPCSettingsHandler.kt
@@ -369,6 +369,12 @@ class RPCSettingsHandler(var rpcHandler: RPCHandler, var api: ProtocolAPI) {
config.flatRelaxedPose.footAngleInDeg = requestConfig.flatFootAngle()
}
+ if (req.hidSettings() != null) {
+ val config = api.server.configManager.vrConfig.hidConfig
+ val requestConfig = req.hidSettings()
+ config.trackersOverHID = requestConfig.trackersOverHid()
+ }
+
api.server.configManager.saveConfig()
}
@@ -385,7 +391,7 @@ class RPCSettingsHandler(var rpcHandler: RPCHandler, var api: ProtocolAPI) {
val settings = SettingsResponse
.createSettingsResponse(
fbb,
- RPCSettingsBuilder.createSteamVRSettings(fbb, bridge), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RPCSettingsBuilder.createSteamVRSettings(fbb, bridge), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
)
val outbound =
rpcHandler.createRPCMessage(fbb, RpcMessage.SettingsResponse, settings)
diff --git a/server/core/src/main/java/dev/slimevr/tracking/trackers/hid/HIDCommon.kt b/server/core/src/main/java/dev/slimevr/tracking/trackers/hid/HIDCommon.kt
index 558256840..8d9d4ce33 100644
--- a/server/core/src/main/java/dev/slimevr/tracking/trackers/hid/HIDCommon.kt
+++ b/server/core/src/main/java/dev/slimevr/tracking/trackers/hid/HIDCommon.kt
@@ -27,6 +27,7 @@ class HIDCommon {
companion object {
const val HID_TRACKER_RECEIVER_VID = 0x1209
const val HID_TRACKER_RECEIVER_PID = 0x7690
+ const val HID_TRACKER_PID = 0x7692
const val PACKET_SIZE = 16
diff --git a/server/desktop/src/main/java/dev/slimevr/desktop/tracking/trackers/hid/DesktopHIDManager.kt b/server/desktop/src/main/java/dev/slimevr/desktop/tracking/trackers/hid/DesktopHIDManager.kt
index b571157d8..3f89940a1 100644
--- a/server/desktop/src/main/java/dev/slimevr/desktop/tracking/trackers/hid/DesktopHIDManager.kt
+++ b/server/desktop/src/main/java/dev/slimevr/desktop/tracking/trackers/hid/DesktopHIDManager.kt
@@ -1,9 +1,12 @@
package dev.slimevr.desktop.tracking.trackers.hid
+import dev.slimevr.VRServer
+import dev.slimevr.config.config
import dev.slimevr.tracking.trackers.Device
import dev.slimevr.tracking.trackers.Tracker
import dev.slimevr.tracking.trackers.TrackerStatus
import dev.slimevr.tracking.trackers.hid.HIDCommon
+import dev.slimevr.tracking.trackers.hid.HIDCommon.Companion.HID_TRACKER_PID
import dev.slimevr.tracking.trackers.hid.HIDCommon.Companion.HID_TRACKER_RECEIVER_PID
import dev.slimevr.tracking.trackers.hid.HIDCommon.Companion.HID_TRACKER_RECEIVER_VID
import dev.slimevr.tracking.trackers.hid.HIDCommon.Companion.PACKET_SIZE
@@ -55,7 +58,7 @@ class DesktopHIDManager(name: String, private val trackersConsumer: Consumer = mutableListOf()
if (root != null) {
var hidDeviceInfoStructure: HidDeviceInfoStructure? = root
diff --git a/solarxr-protocol b/solarxr-protocol
index 3400a6e6d..10a0ea778 160000
--- a/solarxr-protocol
+++ b/solarxr-protocol
@@ -1 +1 @@
-Subproject commit 3400a6e6dd4c66a0924b46b77445699d44a120e2
+Subproject commit 10a0ea778cff8a50f7985f41f97541bbe30d2469