Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Computed head reset #1057

Merged
merged 26 commits into from
Aug 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
7760604
save changes for rebase
ImUrX Mar 18, 2024
955979b
report status on missing hmd
ImUrX Mar 18, 2024
8d84ec4
add hmd status
ImUrX Mar 30, 2024
195b34a
require reset on headset change
ImUrX Mar 30, 2024
2b18764
improve checks in human pose manager
ImUrX Mar 30, 2024
1cb22a3
check for status of tracker
ImUrX Mar 30, 2024
63b2eb5
fix stuff
ImUrX Mar 31, 2024
5af3f62
Merge branch 'main' into hmd-check-status
ImUrX Apr 6, 2024
16ab3ea
fix ts issue
ImUrX Apr 6, 2024
d1cff27
very jank an unorganized prototype
Erimelowo May 3, 2024
b680739
Merge branch 'main' into computed-head-reset
Erimelowo Jun 7, 2024
eb45ad5
gui toggle
Erimelowo Jun 7, 2024
98582bb
refactor
Erimelowo Jun 10, 2024
2865c7e
Merge branch 'pr/962' into computed-head-reset
Erimelowo Jun 10, 2024
ec6fa92
reset hmd pitch
Erimelowo Jun 10, 2024
5dcf91b
hmd on body
Erimelowo Jun 12, 2024
61c4270
non hmd compted head full reset to identity
Erimelowo Jun 13, 2024
7a7611b
remove hacky code that made it not work
Erimelowo Jun 13, 2024
e5e1d53
don't make internal test trackers for unit testing
Erimelowo Jun 13, 2024
d271284
actually assign the result to yawFix
Erimelowo Jun 13, 2024
28dd28a
Update solarxr-protocol
Erimelowo Jun 13, 2024
2b547f7
Merge branch 'main' into computed-head-reset
Erimelowo Jun 20, 2024
8b1ac76
Merge branch 'main' into computed-head-reset
Erimelowo Jul 31, 2024
347c454
Merge branch 'main' into computed-head-reset
Erimelowo Jul 31, 2024
f511283
point solarxr to main
Erimelowo Jul 31, 2024
ceea157
Merge branch 'computed-head-reset' of https://github.com/SlimeVR/Slim…
Erimelowo Jul 31, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions gui/public/i18n/en/translation.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,9 @@ settings-general-fk_settings-leg_fk-reset_mounting_feet = Feet Mounting Reset
settings-general-fk_settings-arm_fk = Arm tracking
settings-general-fk_settings-arm_fk-description = Force arms to be tracked from the headset (HMD) even if positional hand data is available.
settings-general-fk_settings-arm_fk-force_arms = Force arms from HMD
settings-general-fk_settings-reset_settings = Reset settings
settings-general-fk_settings-reset_settings-reset_hmd_pitch-description = Reset the HMD's pitch (vertical rotation) upon doing a full reset. Useful if wearing an HMD on the forehead for VTubing or mocap. Do not enable for VR.
settings-general-fk_settings-reset_settings-reset_hmd_pitch = Reset HMD pitch
settings-general-fk_settings-arm_fk-reset_mode-description = Change which arm pose is expected for mounting reset.
settings-general-fk_settings-arm_fk-back = Back
settings-general-fk_settings-arm_fk-back-description = The default mode, with the upper arms going back and lower arms going forward.
Expand Down
51 changes: 39 additions & 12 deletions gui/src/components/settings/pages/GeneralSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ interface SettingsForm {
armsMountingResetMode: number;
yawResetSmoothTime: number;
saveMountingReset: boolean;
resetHmdPitch: boolean;
};
}

Expand Down Expand Up @@ -158,6 +159,7 @@ const defaultValues: SettingsForm = {
armsMountingResetMode: 0,
yawResetSmoothTime: 0.0,
saveMountingReset: false,
resetHmdPitch: false,
},
};

Expand Down Expand Up @@ -294,6 +296,7 @@ export function GeneralSettings() {
values.resetsSettings.yawResetSmoothTime;
resetsSettings.saveMountingReset =
values.resetsSettings.saveMountingReset;
resetsSettings.resetHmdPitch = values.resetsSettings.resetHmdPitch;
settings.resetsSettings = resetsSettings;
}

Expand Down Expand Up @@ -859,53 +862,76 @@ export function GeneralSettings() {
)}
/>
</div>

<div className="flex flex-col pt-2 pb-3">
<Typography bold>
{l10n.getString('settings-general-fk_settings-arm_fk')}
</Typography>
<Typography color="secondary">
{l10n.getString(
'settings-general-fk_settings-leg_fk-reset_mounting_feet-description'
'settings-general-fk_settings-arm_fk-description'
)}
</Typography>
</div>
<div className="grid sm:grid-cols-1 gap-3 pb-3">
<div className="grid sm:grid-cols-1 pb-3">
<CheckBox
variant="toggle"
outlined
control={control}
name="resetsSettings.resetMountingFeet"
name="toggles.forceArmsFromHmd"
label={l10n.getString(
'settings-general-fk_settings-leg_fk-reset_mounting_feet'
'settings-general-fk_settings-arm_fk-force_arms'
)}
/>
</div>

<div className="flex flex-col pt-2 pb-3">
<div className="flex flex-col pt-2">
<Typography bold>
{l10n.getString('settings-general-fk_settings-arm_fk')}
{l10n.getString('settings-general-fk_settings-reset_settings')}
</Typography>
</div>
<div className="flex flex-col pt-2 pb-3">
<Typography color="secondary">
{l10n.getString(
'settings-general-fk_settings-arm_fk-description'
'settings-general-fk_settings-reset_settings-reset_hmd_pitch-description'
)}
</Typography>
</div>
<div className="grid sm:grid-cols-1 pb-3">
<div className="grid sm:grid-cols-1 gap-3 pb-3">
<CheckBox
variant="toggle"
outlined
control={control}
name="toggles.forceArmsFromHmd"
name="resetsSettings.resetHmdPitch"
label={l10n.getString(
'settings-general-fk_settings-arm_fk-force_arms'
'settings-general-fk_settings-reset_settings-reset_hmd_pitch'
)}
/>
</div>
<div className="flex flex-col pt-2 pb-3">
<Typography color="secondary">
{l10n.getString(
'settings-general-fk_settings-leg_fk-reset_mounting_feet-description'
)}
</Typography>
</div>
<div className="grid sm:grid-cols-1 gap-3 pb-3">
<CheckBox
variant="toggle"
outlined
control={control}
name="resetsSettings.resetMountingFeet"
label={l10n.getString(
'settings-general-fk_settings-leg_fk-reset_mounting_feet'
)}
/>
</div>

<Typography color="secondary">
{l10n.getString(
'settings-general-fk_settings-arm_fk-reset_mode-description'
)}
</Typography>
<div className="grid md:grid-cols-2 flex-col gap-3 pt-2">
<div className="grid md:grid-cols-2 flex-col gap-3 pt-2 pb-3">
<Radio
control={control}
name="resetsSettings.armsMountingResetMode"
Expand Down Expand Up @@ -951,6 +977,7 @@ export function GeneralSettings() {
value={'3'}
></Radio>
</div>

{config?.debug && (
<>
<div className="flex flex-col pt-2 pb-3">
Expand Down
3 changes: 2 additions & 1 deletion server/core/src/main/java/dev/slimevr/VRServer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ class VRServer @JvmOverloads constructor(

init {
// UwU
instance = this

configManager = ConfigManager(configPath)
configManager.loadConfig()
deviceManager = DeviceManager(this)
Expand Down Expand Up @@ -161,7 +163,6 @@ class VRServer @JvmOverloads constructor(
for (tracker in computedTrackers) {
registerTracker(tracker)
}
instance = this
}

fun hasBridge(bridgeClass: Class<out Bridge?>): Boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,12 @@ class ResetsConfig {
// Save automatic mounting reset calibration
var saveMountingReset = false

// Reset the HMD's pitch upon full reset
var resetHmdPitch = false

fun updateTrackersResetsSettings() {
for (t in VRServer.instance.allTrackers) {
if (t.needsReset) {
t.resetsHandler.readResetConfig(this)
}
t.resetsHandler.readResetConfig(this)
}
}
}
2 changes: 1 addition & 1 deletion server/core/src/main/java/dev/slimevr/config/VRConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ class VRConfig {
val config = getTracker(tracker)
tracker.readConfig(config)
if (tracker.isImu()) tracker.resetsHandler.readDriftCompensationConfig(driftCompensation)
tracker.resetsHandler.readResetConfig(resetsConfig)
if (tracker.needsReset) {
tracker.resetsHandler.readResetConfig(resetsConfig)
tracker.saveMountingResetOrientation(config)
}
if (tracker.allowFiltering) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,8 @@ public static int createModelSettings(
humanPoseManager.getToggle(SkeletonConfigToggles.VIVE_EMULATION),
humanPoseManager.getToggle(SkeletonConfigToggles.TOE_SNAP),
humanPoseManager.getToggle(SkeletonConfigToggles.FOOT_PLANT),
humanPoseManager.getToggle(SkeletonConfigToggles.SELF_LOCALIZATION)
humanPoseManager.getToggle(SkeletonConfigToggles.SELF_LOCALIZATION),
false
);
int ratiosOffset = ModelRatios
.createModelRatios(
Expand Down Expand Up @@ -342,7 +343,8 @@ public static int createArmsResetModeSettings(
resetsConfig.getResetMountingFeet(),
resetsConfig.getMode().getId(),
resetsConfig.getYawResetSmoothTime(),
resetsConfig.getSaveMountingReset()
resetsConfig.getSaveMountingReset(),
resetsConfig.getResetHmdPitch()
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@ class RPCSettingsHandler(var rpcHandler: RPCHandler, var api: ProtocolAPI) {
resetsConfig.resetMountingFeet = req.resetsSettings().resetMountingFeet()
resetsConfig.saveMountingReset = req.resetsSettings().saveMountingReset()
resetsConfig.yawResetSmoothTime = req.resetsSettings().yawResetSmoothTime()
resetsConfig.resetHmdPitch = req.resetsSettings().resetHmdPitch()
resetsConfig.updateTrackersResetsSettings()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -340,16 +340,6 @@ class HumanPoseManager(val server: VRServer?) {
@ThreadSafe
fun getComputedTracker(trackerRole: TrackerRole): Tracker = skeleton.getComputedTracker(trackerRole)

/**
* Returns all trackers if VRServer is non-null. Else, returns the
* skeleton's assigned trackers.
*
* @return a list of trackers to use for reset.
*/
val trackersToReset: List<Tracker?>
get() =
server?.allTrackers ?: skeleton.localTrackers

/**
* @return the head bone, which is the root of the skeleton
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -784,8 +784,8 @@ class HumanSkeleton(
}

/**
* Rotates the first Quaternion to match its yaw and roll to the rotation of
* the average of the second and third quaternions.
* Rotates the third Quaternion to match its yaw and roll to the rotation of
* the average of the first and second quaternions.
*
* @param leftKnee the first Quaternion
* @param rightKnee the second Quaternion
Expand Down Expand Up @@ -1033,7 +1033,8 @@ class HumanSkeleton(
*/
val isTrackingRightArmFromController: Boolean
get() = rightHandTracker != null && rightHandTracker!!.hasPosition && !forceArmsFromHMD
val localTrackers: List<Tracker?>

val trackersToReset: List<Tracker?>
get() = listOf(
neckTracker,
chestTracker,
Expand All @@ -1056,19 +1057,16 @@ class HumanSkeleton(
)

fun resetTrackersFull(resetSourceName: String?) {
val trackersToReset = humanPoseManager.trackersToReset

// Resets all axis of the trackers with the HMD as reference.
var referenceRotation = IDENTITY
headTracker?.let {
if (it.needsReset) {
it.resetsHandler.resetFull(referenceRotation)
} else {
referenceRotation = it.getRotation()
}
// Always reset the head (ifs in resetsHandler)
it.resetsHandler.resetFull(referenceRotation)
referenceRotation = it.getRotation()
}
// Resets all axes of the trackers with the HMD as reference.
for (tracker in trackersToReset) {
if (tracker != null && tracker.needsReset) {
// Only reset if tracker needsReset
if (tracker != null && (tracker.needsReset || tracker.isHmd)) {
tracker.resetsHandler.resetFull(referenceRotation)
}
}
Expand All @@ -1085,18 +1083,17 @@ class HumanSkeleton(

@VRServerThread
fun resetTrackersYaw(resetSourceName: String?) {
val trackersToReset = humanPoseManager.trackersToReset

// Resets the yaw of the trackers with the head as reference.
var referenceRotation = IDENTITY
headTracker?.let {
if (it.needsReset) {
// Only reset if head needsReset and isn't computed
if (it.needsReset && !it.isComputed) {
it.resetsHandler.resetYaw(referenceRotation)
} else {
referenceRotation = it.getRotation()
}
referenceRotation = it.getRotation()
}
for (tracker in trackersToReset) {
// Only reset if tracker needsReset
if (tracker != null && tracker.needsReset) {
tracker.resetsHandler.resetYaw(referenceRotation)
}
Expand All @@ -1107,19 +1104,17 @@ class HumanSkeleton(

@VRServerThread
fun resetTrackersMounting(resetSourceName: String?) {
val trackersToReset = humanPoseManager.trackersToReset

// Resets the mounting orientation of the trackers with the HMD as
// reference.
// Resets the mounting orientation of the trackers with the HMD as reference.
var referenceRotation = IDENTITY
headTracker?.let {
if (it.needsMounting) {
// Only reset if head needsMounting or is computed but not HMD
if (it.needsMounting || (it.isComputed && !it.isHmd)) {
it.resetsHandler.resetMounting(referenceRotation)
} else {
referenceRotation = it.getRotation()
}
referenceRotation = it.getRotation()
}
for (tracker in trackersToReset) {
// Only reset if tracker needsMounting
if (tracker != null && tracker.needsMounting) {
tracker.resetsHandler.resetMounting(referenceRotation)
}
Expand All @@ -1131,7 +1126,6 @@ class HumanSkeleton(

@VRServerThread
fun clearTrackersMounting(resetSourceName: String?) {
val trackersToReset = humanPoseManager.trackersToReset
headTracker?.let {
if (it.needsMounting) it.resetsHandler.clearMounting()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ class Tracker @JvmOverloads constructor(
_rotation
}

if (needsReset && !(isComputed && trackerPosition == TrackerPosition.HEAD)) {
if (needsReset || (isComputed && !isInternal)) {
// Adjust to reset, mounting and drift compensation
rot = resetsHandler.getReferenceAdjustedDriftRotationFrom(rot)
}
Expand Down Expand Up @@ -354,7 +354,7 @@ class Tracker @JvmOverloads constructor(
_rotation
}

if (needsReset && trackerPosition != TrackerPosition.HEAD) {
if (needsReset || (isComputed && trackerPosition == TrackerPosition.HEAD)) {
// Adjust to reset and mounting
rot = resetsHandler.getIdentityAdjustedDriftRotationFrom(rot)
}
Expand Down
Loading