Compare commits

...

1 Commits

Author SHA1 Message Date
Eiren Rain
12354f0a95 Implement crude CSV tracker data collection 2026-01-27 10:45:48 +01:00
4 changed files with 139 additions and 0 deletions

View File

@@ -32,6 +32,7 @@ import dev.slimevr.tracking.processor.skeleton.HumanSkeleton
import dev.slimevr.tracking.trackers.*
import dev.slimevr.tracking.trackers.udp.TrackersUDPServer
import dev.slimevr.trackingchecklist.TrackingChecklistManager
import dev.slimevr.util.TrackerLogger
import dev.slimevr.util.ann.VRServerThread
import dev.slimevr.websocketapi.WebSocketVRBridge
import io.eiren.util.ann.ThreadSafe
@@ -125,6 +126,8 @@ class VRServer @JvmOverloads constructor(
val serverGuards = ServerGuards()
val trackerLogger = TrackerLogger()
init {
// UwU
deviceManager = DeviceManager(this)
@@ -179,6 +182,8 @@ class VRServer @JvmOverloads constructor(
registerTracker(tracker)
}
addNewTrackerConsumer(trackerLogger)
instance = this
}
@@ -259,6 +264,7 @@ class VRServer @JvmOverloads constructor(
}
vrcOSCHandler.update()
vMCHandler.update()
trackerLogger.update()
// final long time = System.currentTimeMillis() - start;
try {
sleep(1) // 1000Hz

View File

@@ -120,6 +120,8 @@ class Tracker @JvmOverloads constructor(
var packetsReceived: Int? = null
var packetsLost: Int? = null
var packetLoss: Float? = null
var windowsHit: Int? = null
var windowsMiss: Int? = null
var customName: String? = null
var magStatus: MagnetometerStatus = magStatus
private set

View File

@@ -321,6 +321,8 @@ class HIDCommon {
tracker.packetsReceived = packets_received
tracker.packetsLost = packets_lost
tracker.packetLoss = if (packets_lost == 0) 0.0f else packets_lost.toFloat() / (packets_received + packets_lost).toFloat()
tracker.windowsHit = windows_hit
tracker.windowsMiss = windows_missed
}
// Assign rotation and acceleration

View File

@@ -0,0 +1,129 @@
package dev.slimevr.util
import dev.slimevr.SLIMEVR_IDENTIFIER
import dev.slimevr.VRServer
import dev.slimevr.tracking.trackers.Tracker
import io.eiren.util.OperatingSystem
import io.eiren.util.Util
import java.io.File
import java.io.FileWriter
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import java.util.function.Consumer
class TrackerLogger : Consumer<Tracker> {
var saveLogs = true
private var file: FileWriter? = null
private var lastSaved = 0L
val saveInterval = 100
fun update() {
if (saveLogs) {
if (file == null) {
val dir = OperatingSystem.resolveLogDirectory(SLIMEVR_IDENTIFIER)
?.toFile()?.absoluteFile
?: File("").absoluteFile
file = FileWriter(
File(
dir,
DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm-ss").format(
LocalDateTime.now()
) + ".csv"
)
)
writeCSVHeader()
}
if(lastSaved + saveInterval < System.currentTimeMillis() && VRServer.instance.allTrackers.isNotEmpty()) {
lastSaved = System.currentTimeMillis()
var isFirst = true
VRServer.instance.allTrackers.forEach {
if(it.isInternal || it.isComputed)
return@forEach
if (!isFirst) {
file!!.write(';'.code)
}
isFirst = false
file!!.write(
"\"" + it.position.x + "\";"
+ "\"" + it.position.y + "\";"
+ "\"" + it.position.z + "\";"
+ "\"" + it.getRotation().w + "\";"
+ "\"" + it.getRotation().x + "\";"
+ "\"" + it.getRotation().y + "\";"
+ "\"" + it.getRotation().z + "\";"
+ "\"" + it.getAcceleration().x + "\";"
+ "\"" + it.getAcceleration().y + "\";"
+ "\"" + it.getAcceleration().z + "\";"
+ "\"" + it.getMagVector().x + "\";"
+ "\"" + it.getMagVector().y + "\";"
+ "\"" + it.getMagVector().z + "\";"
+ "\"" + it.batteryVoltage + "\";"
+ "\"" + it.batteryLevel + "\";"
+ "\"" + it.signalStrength + "\";"
+ "\"" + it.ping + "\";"
+ "\"" + it.packetsReceived + "\";"
+ "\"" + it.packetsLost + "\";"
+ "\"" + it.packetLoss + "\";"
+ "\"" + it.windowsHit + "\";"
+ "\"" + it.windowsMiss + "\""
)
}
file!!.write('\n'.code)
file!!.flush()
}
} else {
if(file != null) {
saveCSVAndClose()
}
}
}
private fun saveCSVAndClose() {
if (file != null) {
Util.close(file)
file = null
}
}
private fun writeCSVHeader() {
var isFirst = true
VRServer.instance.allTrackers.forEach {
if(it.isInternal || it.isComputed)
return@forEach
if (!isFirst) {
file!!.write(';'.code)
}
isFirst = false
val tid = it.id.toString()
file!!.write("\"" + tid + "_x\";"
+ "\"" + tid + "_y\";"
+ "\"" + tid + "_z\";"
+ "\"" + tid + "_qw\";"
+ "\"" + tid + "_qx\";"
+ "\"" + tid + "_qy\";"
+ "\"" + tid + "_qz\";"
+ "\"" + tid + "_ax\";"
+ "\"" + tid + "_ay\";"
+ "\"" + tid + "_az\";"
+ "\"" + tid + "_mx\";"
+ "\"" + tid + "_my\";"
+ "\"" + tid + "_mz\";"
+ "\"" + tid + "_batv\";"
+ "\"" + tid + "_batp\";"
+ "\"" + tid + "_signal\";"
+ "\"" + tid + "_ping\";"
+ "\"" + tid + "_p_rcv\";"
+ "\"" + tid + "_p_lost\";"
+ "\"" + tid + "_p_loss\";"
+ "\"" + tid + "_w_hit\";"
+ "\"" + tid + "_w_miss\"")
}
file!!.write('\n'.code)
}
override fun accept(t: Tracker) {
// New tracker appeared, re-create the log file
saveCSVAndClose()
}
}