Compare commits

...

4 Commits

Author SHA1 Message Date
Eiren Rain
9a891a0323 Accel works correctly like this for some magical reason
Still need to figure out why we need to sandwich accel TWICE.. but only if we adjust it by reference, otherwise we can do it once...
2025-05-13 00:47:15 +02:00
Ilia Ki
d3b57048e9 Merge branch 'main' into fixAxis 2025-05-13 02:06:14 +07:00
Ilia Ki
c8a6e2fc0b Update server/core/src/main/java/dev/slimevr/tracking/trackers/Tracker.kt
Co-authored-by: Eiren Rain <Eirenliel@users.noreply.github.com>
2025-05-13 02:06:00 +07:00
Ilia Ki
db68d808dd Fix acceleration axis 2025-05-12 01:19:20 +07:00
6 changed files with 33 additions and 30 deletions

1
.gitignore vendored
View File

@@ -46,3 +46,4 @@ local.properties
# Ignore temporary config
vrconfig.yml.tmp
*.DS_Store

View File

@@ -110,14 +110,14 @@ export function IMUVisualizerWidget({ tracker }: { tracker: TrackerDataT }) {
const rotationRaw = useRawRotationEulerDegrees();
const rotationIdent = useIdentAdjRotationEulerDegrees() || rotationRaw;
const quat =
tracker?.rotationIdentityAdjusted ||
tracker?.rotation ||
new THREE.Quaternion();
const vec =
tracker?.linearAcceleration ||
tracker?.rawAcceleration ||
new THREE.Vector3();
const quat = useMemo(() => {
return tracker?.rotationIdentityAdjusted || tracker?.rotation || new THREE.Quaternion()
}, [tracker])
const vec = useMemo(() => {
return new Vector3().copy(tracker?.linearAcceleration || tracker?.rawAcceleration || {x: 0, y: 0, z: 0}) // .applyQuaternion(new THREE.Quaternion().copy(quat))
}, [tracker, quat])
const mag =
tracker?.rawMagneticVector ||
new THREE.Vector3();

View File

@@ -6,6 +6,7 @@ import dev.slimevr.tracking.trackers.TrackerPosition.Companion.getByDesignation
import dev.slimevr.tracking.trackers.udp.IMUType
import dev.slimevr.tracking.trackers.udp.MagnetometerStatus
import dev.slimevr.tracking.trackers.udp.TrackerDataType
import io.eiren.math.FloatMath.INV_SQRT_TWO
import io.eiren.util.BufferedTimer
import io.github.axisangles.ktmath.Quaternion
import io.github.axisangles.ktmath.Vector3
@@ -383,6 +384,8 @@ class Tracker @JvmOverloads constructor(
* Gets the world-adjusted acceleration
*/
fun getAcceleration(): Vector3 = if (needsReset) {
//_acceleration
//getAdjustedRotation().sandwich(_acceleration)
resetsHandler.getReferenceAdjustedAccel(_rotation, _acceleration)
} else {
_acceleration
@@ -453,4 +456,15 @@ class Tracker @JvmOverloads constructor(
fun resetFilteringQuats(reference: Quaternion) {
filteringHandler.resetMovingAverage(getAdjustedRotation(), reference)
}
companion object {
/**
* Turn 90 degrees around LEFT axis to make the base position of the tracker standing upwards
* instead of laying on the back
*/
private val rotationOffset = Quaternion(INV_SQRT_TWO, -INV_SQRT_TWO, 0f, 0f)
fun axisRemap(v: Vector3): Vector3 = Vector3(v.x, -v.y, -v.z)
fun axisOffset(v: Vector3): Vector3 = axisRemap(v) //rotationOffset.sandwich(rotationOffset.sandwich(v))
fun axisOffset(q: Quaternion): Quaternion = rotationOffset * q
}
}

View File

@@ -1,16 +1,14 @@
package dev.slimevr.tracking.trackers.udp
import com.jme3.math.FastMath
import dev.slimevr.NetworkProtocol
import dev.slimevr.VRServer
import dev.slimevr.config.config
import dev.slimevr.protocol.rpc.MAG_TIMEOUT
import dev.slimevr.tracking.trackers.*
import dev.slimevr.tracking.trackers.Tracker.Companion.axisOffset
import io.eiren.util.Util
import io.eiren.util.collections.FastList
import io.eiren.util.logging.LogManager
import io.github.axisangles.ktmath.Quaternion.Companion.fromRotationVector
import io.github.axisangles.ktmath.Vector3
import kotlinx.coroutines.*
import solarxr_protocol.rpc.ResetType
import java.net.DatagramPacket
@@ -389,13 +387,12 @@ class TrackersUDPServer(private val port: Int, name: String, private val tracker
is RotationPacket -> {
var rot = packet.rotation
rot = AXES_OFFSET.times(rot)
rot = axisOffset(rot)
tracker = connection?.getTracker(packet.sensorId)
if (tracker == null) return
tracker.setRotation(rot)
if (packet is UDPPacket23RotationAndAcceleration) {
// Switch x and y around to adjust for different axes
tracker.setAcceleration(Vector3(packet.acceleration.y, packet.acceleration.x, packet.acceleration.z))
tracker.setAcceleration(axisOffset(packet.acceleration))
}
tracker.dataTick()
}
@@ -404,7 +401,7 @@ class TrackersUDPServer(private val port: Int, name: String, private val tracker
tracker = connection?.getTracker(packet.sensorId)
if (tracker == null) return
var rot17 = packet.rotation
rot17 = AXES_OFFSET * rot17
rot17 = axisOffset(rot17)
when (packet.dataType) {
UDPPacket17RotationData.DATA_TYPE_NORMAL -> {
tracker.setRotation(rot17)
@@ -427,8 +424,7 @@ class TrackersUDPServer(private val port: Int, name: String, private val tracker
is UDPPacket4Acceleration -> {
tracker = connection?.getTracker(packet.sensorId)
if (tracker == null) return
// Switch x and y around to adjust for different axes
tracker.setAcceleration(Vector3(packet.acceleration.y, packet.acceleration.x, packet.acceleration.z))
tracker.setAcceleration(axisOffset(packet.acceleration))
}
is UDPPacket10PingPong -> {
@@ -602,10 +598,6 @@ class TrackersUDPServer(private val port: Int, name: String, private val tracker
}
companion object {
/**
* Change between IMU axes and OpenGL/SteamVR axes
*/
private val AXES_OFFSET = fromRotationVector(-FastMath.HALF_PI, 0f, 0f)
private const val RESET_SOURCE_NAME = "TrackerServer"
private fun packetToString(packet: DatagramPacket?): String {
val sb = StringBuilder()

View File

@@ -17,7 +17,7 @@ object FloatMath {
const val ZERO_TOLERANCE_D: Double = 0.0001
val SQRT_TWO: Float = kotlin.math.sqrt(2.0).toFloat()
val INV_SQRT_TWO: Float = 1f / SQRT_TWO
val INV_SQRT_TWO: Float = (1.0 / kotlin.math.sqrt(2.0)).toFloat()
val SQRT_THREE: Float = kotlin.math.sqrt(3.0).toFloat()
val INV_SQRT_THREE: Float = 1f / SQRT_THREE
const val TWO_FPI: Float = PI * 2

View File

@@ -1,9 +1,9 @@
package dev.slimevr.desktop.tracking.trackers.hid
import com.jme3.math.FastMath
import dev.slimevr.VRServer
import dev.slimevr.tracking.trackers.Device
import dev.slimevr.tracking.trackers.Tracker
import dev.slimevr.tracking.trackers.Tracker.Companion.axisOffset
import dev.slimevr.tracking.trackers.TrackerStatus
import dev.slimevr.tracking.trackers.udp.BoardType
import dev.slimevr.tracking.trackers.udp.IMUType
@@ -11,7 +11,6 @@ import dev.slimevr.tracking.trackers.udp.MCUType
import dev.slimevr.tracking.trackers.udp.MagnetometerStatus
import io.eiren.util.logging.LogManager
import io.github.axisangles.ktmath.Quaternion
import io.github.axisangles.ktmath.Quaternion.Companion.fromRotationVector
import io.github.axisangles.ktmath.Vector3
import org.hid4java.HidDevice
import org.hid4java.HidException
@@ -412,7 +411,7 @@ class TrackersHID(name: String, private val trackersConsumer: Consumer<Tracker>)
// x y z w -> w x y z
var rot = Quaternion(q[3].toFloat(), q[0].toFloat(), q[1].toFloat(), q[2].toFloat())
val scaleRot = 1 / (1 shl 15).toFloat() // compile time evaluation
rot = AXES_OFFSET.times(scaleRot).times(rot) // no division
rot = axisOffset(rot * scaleRot) // no division
tracker.setRotation(rot)
}
if (packetType == 2) {
@@ -431,7 +430,7 @@ class TrackersHID(name: String, private val trackersConsumer: Consumer<Tracker>)
val s = sin(a)
val k = s * invSqrtD
var rot = Quaternion(cos(a), k * v[0], k * v[1], k * v[2])
rot = AXES_OFFSET.times(rot) // no division
rot = axisOffset(rot) // no division
tracker.setRotation(rot)
}
if (packetType == 1 || packetType == 2) {
@@ -444,6 +443,7 @@ class TrackersHID(name: String, private val trackersConsumer: Consumer<Tracker>)
// Front side (facing out) is +Z
val scaleAccel = 1 / (1 shl 7).toFloat() // compile time evaluation
var acceleration = Vector3(a[0].toFloat(), a[1].toFloat(), a[2].toFloat()).times(scaleAccel) // no division
acceleration = axisOffset(acceleration)
tracker.setAcceleration(acceleration)
}
if (packetType == 4) {
@@ -528,10 +528,6 @@ class TrackersHID(name: String, private val trackersConsumer: Consumer<Tracker>)
}
companion object {
/**
* Change between IMU axes and OpenGL/SteamVR axes
*/
private val AXES_OFFSET = fromRotationVector(-FastMath.HALF_PI, 0f, 0f)
private const val resetSourceName = "TrackerServer"
}
}