Skip to content

Commit

Permalink
Block AutoBone with high error values (#1185)
Browse files Browse the repository at this point in the history
Co-authored-by: lucas lelievre <[email protected]>
  • Loading branch information
ButterscotchV and loucass003 authored Oct 9, 2024
1 parent 449c6f8 commit 1a6560a
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 77 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,12 @@ import { Localized, useLocalization } from '@fluent/react';
import { useForm } from 'react-hook-form';
import { useMemo, useState } from 'react';
import { NumberSelector } from '@/components/commons/NumberSelector';
import {
DEFAULT_HEIGHT,
MIN_HEIGHT,
} from '@/components/onboarding/pages/body-proportions/ProportionsChoose';
import { MIN_HEIGHT } from '@/components/onboarding/pages/body-proportions/ProportionsChoose';
import { useLocaleConfig } from '@/i18n/config';
import { useCountdown } from '@/hooks/countdown';
import { TipBox } from '@/components/commons/TipBox';

interface HeightForm {
height: number;
hmdHeight: number;
}

Expand Down Expand Up @@ -62,18 +58,13 @@ export function CheckHeight({
[currentLocales]
);

useRPCPacket(
RpcMessage.HeightResponse,
({ hmdHeight, estimatedFullHeight }: HeightResponseT) => {
setValue('height', estimatedFullHeight || DEFAULT_HEIGHT);
setValue('hmdHeight', hmdHeight);
}
);
useRPCPacket(RpcMessage.HeightResponse, ({ hmdHeight }: HeightResponseT) => {
setValue('hmdHeight', hmdHeight);
});

const onSubmit = (values: HeightForm) => {
const changeSettings = new ChangeSettingsRequestT();
const autobone = new AutoBoneSettingsT();
autobone.targetFullHeight = values.height;
autobone.targetHmdHeight = values.hmdHeight;
changeSettings.autoBoneSettings = autobone;

Expand Down Expand Up @@ -143,23 +134,6 @@ export function CheckHeight({
step={0.01}
disabled={true}
/>
<NumberSelector
control={control}
name="height"
label={l10n.getString(
'onboarding-automatic_proportions-check_height-height1'
)}
valueLabelFormat={(value) =>
isNaN(value)
? l10n.getString(
'onboarding-automatic_proportions-check_height-unknown'
)
: mFormat.format(value)
}
min={MIN_HEIGHT}
max={4}
step={0.01}
/>
</form>
</div>

Expand Down
10 changes: 9 additions & 1 deletion server/core/src/main/java/dev/slimevr/autobone/AutoBone.kt
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ class AutoBone(server: VRServer) {
// Otherwise if there is no skeleton available, attempt to get the
// max HMD height from the recording
val hmdHeight = frames.maxHmdHeight
if (hmdHeight <= 0.4f) {
if (hmdHeight <= MIN_HEIGHT) {
LogManager
.warning(
"[AutoBone] Max headset height detected (Value seems too low, did you not stand up straight while measuring?): $hmdHeight",
Expand Down Expand Up @@ -195,6 +195,9 @@ class AutoBone(server: VRServer) {
config: AutoBoneConfig = globalConfig,
epochCallback: Consumer<Epoch>? = null,
): AutoBoneResults {
check(frames.frameHolders.isNotEmpty()) { "Recording has no trackers." }
check(frames.maxFrameCount > 0) { "Recording has no frames." }

// Load current values for adjustable configs
loadConfigValues()

Expand All @@ -209,6 +212,7 @@ class AutoBone(server: VRServer) {
} else {
targetHmdHeight / BodyProportionError.eyeHeightToHeightRatio
}
check(targetHmdHeight > MIN_HEIGHT) { "Configured height ($targetHmdHeight) is too small (<= $MIN_HEIGHT)." }

// Set up the current state, making all required players and setting up the
// skeletons appropriately
Expand Down Expand Up @@ -316,6 +320,9 @@ class AutoBone(server: VRServer) {
.info(
"[AutoBone] Target height: ${trainingStep.targetHmdHeight}, Final height: $estimatedHeight",
)
if (trainingStep.errorStats.mean > config.maxFinalError) {
throw AutoBoneException("The final epoch error value (${trainingStep.errorStats.mean}) has exceeded the maximum allowed value (${config.maxFinalError}).")
}

return AutoBoneResults(
estimatedHeight,
Expand Down Expand Up @@ -746,6 +753,7 @@ class AutoBone(server: VRServer) {
}

companion object {
const val MIN_HEIGHT = 0.4f
const val AUTOBONE_FOLDER = "AutoBone Recordings"
const val LOADAUTOBONE_FOLDER = "Load AutoBone Recordings"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,8 +189,8 @@ class AutoBoneHandler(private val server: VRServer) {
if (framesFuture != null) {
announceProcessStatus(AutoBoneProcessType.SAVE, "Waiting for recording...")
val frames = framesFuture.get()
check(frames.frameHolders.isNotEmpty()) { "Recording has no trackers" }
check(frames.maxFrameCount > 0) { "Recording has no frames" }
check(frames.frameHolders.isNotEmpty()) { "Recording has no trackers." }
check(frames.maxFrameCount > 0) { "Recording has no frames." }
announceProcessStatus(AutoBoneProcessType.SAVE, "Saving recording...")
autoBone.saveRecording(frames)
announceProcessStatus(
Expand Down Expand Up @@ -243,8 +243,6 @@ class AutoBoneHandler(private val server: VRServer) {
if (framesFuture != null) {
announceProcessStatus(AutoBoneProcessType.PROCESS, "Waiting for recording...")
val frames = framesFuture.get()
check(frames.frameHolders.isNotEmpty()) { "Recording has no trackers" }
check(frames.maxFrameCount > 0) { "Recording has no frames" }
frameRecordings.add(Pair.of("<Recording>", frames))
} else {
announceProcessStatus(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@ class AutoBoneConfig {
var useSkeletonHeight = false
var randSeed = 4L
var useFrameFiltering = false
var maxFinalError = 0.03f
}
Original file line number Diff line number Diff line change
Expand Up @@ -73,30 +73,26 @@ object PoseFrameIO {
}
}

fun tryWriteFrames(outputStream: DataOutputStream, frames: PoseFrames): Boolean {
try {
writeFrames(outputStream, frames)
} catch (e: Exception) {
LogManager.severe("Error writing frame to stream", e)
return false
}
return true
fun tryWriteFrames(outputStream: DataOutputStream, frames: PoseFrames): Boolean = try {
writeFrames(outputStream, frames)
true
} catch (e: Exception) {
LogManager.severe("Error writing frame to stream.", e)
false
}

fun writeToFile(file: File, frames: PoseFrames) {
DataOutputStream(
BufferedOutputStream(FileOutputStream(file)),
).use { outputStream -> writeFrames(outputStream, frames) }
).use { writeFrames(it, frames) }
}

fun tryWriteToFile(file: File, frames: PoseFrames): Boolean {
try {
writeToFile(file, frames)
} catch (e: Exception) {
LogManager.severe("Error writing frames to file", e)
return false
}
return true
fun tryWriteToFile(file: File, frames: PoseFrames): Boolean = try {
writeToFile(file, frames)
true
} catch (e: Exception) {
LogManager.severe("Error writing frames to file.", e)
false
}

@Throws(IOException::class)
Expand Down Expand Up @@ -166,27 +162,20 @@ object PoseFrameIO {
return PoseFrames(trackers)
}

fun tryReadFrames(inputStream: DataInputStream): PoseFrames? {
return try {
return readFrames(inputStream)
} catch (e: Exception) {
LogManager.severe("Error reading frames from stream", e)
null
}
fun tryReadFrames(inputStream: DataInputStream): PoseFrames? = try {
readFrames(inputStream)
} catch (e: Exception) {
LogManager.severe("Error reading frames from stream.", e)
null
}

fun readFromFile(file: File): PoseFrames = readFrames(
DataInputStream(BufferedInputStream(FileInputStream(file))),
)
fun readFromFile(file: File): PoseFrames =
DataInputStream(BufferedInputStream(FileInputStream(file))).use { readFrames(it) }

fun tryReadFromFile(file: File): PoseFrames? {
return try {
return readFrames(
DataInputStream(BufferedInputStream(FileInputStream(file))),
)
} catch (e: Exception) {
LogManager.severe("Error reading frames from file", e)
null
}
fun tryReadFromFile(file: File): PoseFrames? = try {
readFromFile(file)
} catch (e: Exception) {
LogManager.severe("Error reading frames from file.", e)
null
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,11 @@ class PoseRecorder(private val server: VRServer) {
trackers: List<Tracker?> = server.allTrackers,
frameCallback: Consumer<RecordingProgress>? = null,
): Future<PoseFrames> {
require(numFrames >= 1) { "numFrames must at least have a value of 1" }
require(intervalMs >= 1) { "intervalMs must at least have a value of 1" }
require(trackers.isNotEmpty()) { "trackers must have at least one entry" }
check(isReadyToRecord) { "PoseRecorder isn't ready to record!" }
require(numFrames >= 1) { "numFrames must at least have a value of 1." }
require(intervalMs >= 1) { "intervalMs must at least have a value of 1." }
require(trackers.isNotEmpty()) { "trackers must have at least one entry." }
cancelFrameRecording()
poseFrame = PoseFrames(trackers.size)
val poseFrame = PoseFrames(trackers.size)

// Update tracker list
this.trackers.ensureCapacity(trackers.size)
Expand All @@ -100,12 +99,14 @@ class PoseRecorder(private val server: VRServer) {

// Create a tracker recording
val trackerFrames = TrackerFrames(tracker, numFrames)
poseFrame?.frameHolders?.add(trackerFrames)
poseFrame.frameHolders.add(trackerFrames)

// Pair tracker with recording
this.trackers.add(Pair.of(tracker, trackerFrames))
}
require(this.trackers.isNotEmpty()) { "trackers must have at least one valid tracker." }

this.poseFrame = poseFrame
frameCursor = 0
this.numFrames = numFrames
frameRecordingInterval = intervalMs
Expand Down

0 comments on commit 1a6560a

Please sign in to comment.