Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions gui/public/i18n/en/translation.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -971,6 +971,7 @@ onboarding-connect_tracker-next = I connected all my trackers
onboarding-calibration_tutorial = IMU Calibration Tutorial
onboarding-calibration_tutorial-subtitle = This will help reduce tracker drifting!
onboarding-calibration_tutorial-description-v1 = After turning on your trackers, place them on a stable surface for a moment to allow for calibration. Calibration can be performed at any time after the trackers are powered on—this page simply provides a tutorial. To begin, click the "{ onboarding-calibration_tutorial-calibrate }" button, then <b>do not move your trackers!</b>
onboarding-calibration_tutorial-description-no-ready-v1 = After turning on your trackers, place them on a stable surface for a couple seconds to allow for calibration. Calibration can be performed at any time after the trackers are powered on—this page simply provides a tutorial. To begin, put down your trackers, then <b>do not move them!</b>
onboarding-calibration_tutorial-calibrate = I placed my trackers on a table
onboarding-calibration_tutorial-status-waiting = Waiting for you
onboarding-calibration_tutorial-status-calibrating = Calibrating
Expand Down
58 changes: 55 additions & 3 deletions gui/src/components/onboarding/pages/CalibrationTutorial.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { Vector3 } from 'three';
import { useTimeout } from '@/hooks/timeout';
import { useAtomValue } from 'jotai';
import { connectedIMUTrackersAtom } from '@/store/app-store';
import { RestCalibrationStatus } from 'solarxr-protocol';

export enum CalibrationStatus {
SUCCESS,
Expand All @@ -40,9 +41,25 @@ export function CalibrationTutorialPage() {
const connectedIMUTrackers = useAtomValue(connectedIMUTrackersAtom);
const restCalibrationTrackers =
useRestCalibrationTrackers(connectedIMUTrackers);

const useRestCalibrationFlag = useMemo(
() =>
restCalibrationTrackers.length > 0 &&
restCalibrationTrackers.every(
(tracker) =>
tracker.tracker.info?.restCalibrationStatus !==
RestCalibrationStatus.NOT_SUPPORTED
),
[restCalibrationTrackers]
);

const [rested, setRested] = useState(false);
const lastValueMap = useRef(new Map<number, Vector3[]>());
useEffect(() => {
if (useRestCalibrationFlag) {
return;
}

const accelLength = restCalibrationTrackers.every((x) => {
if (
x.tracker.trackerId?.trackerNum === undefined ||
Expand Down Expand Up @@ -71,6 +88,29 @@ export function CalibrationTutorialPage() {
}, [restCalibrationTrackers]);

useEffect(() => {
if (!useRestCalibrationFlag) {
return;
}

if (
restCalibrationTrackers.some(
(tracker) =>
tracker.tracker.info?.restCalibrationStatus !==
RestCalibrationStatus.CALIBRATED
)
) {
return;
}

setCalibrationStatus(CalibrationStatus.SUCCESS);
abortCountdown();
}, [restCalibrationTrackers]);

useEffect(() => {
if (useRestCalibrationFlag) {
return;
}

if (calibrationStatus === CalibrationStatus.CALIBRATING && !rested) {
setCalibrationStatus(CalibrationStatus.ERROR);
abortCountdown();
Expand Down Expand Up @@ -129,7 +169,11 @@ export function CalibrationTutorialPage() {
</Typography>
</div>
<Localized
id="onboarding-calibration_tutorial-description-v1"
id={
useRestCalibrationFlag
? 'onboarding-calibration_tutorial-description-no-ready-v1'
: 'onboarding-calibration_tutorial-description-v1'
}
elems={{ b: <b></b> }}
>
<Typography>Description on calibration of IMU</Typography>
Expand Down Expand Up @@ -177,7 +221,9 @@ export function CalibrationTutorialPage() {
disabled={isCounting || !rested}
className={classNames(
'xs:ml-auto',
CalibrationStatus.SUCCESS === calibrationStatus && 'hidden'
(CalibrationStatus.SUCCESS === calibrationStatus ||
useRestCalibrationFlag) &&
'hidden'
)}
>
{l10n.getString('onboarding-calibration_tutorial-calibrate')}
Expand All @@ -187,8 +233,14 @@ export function CalibrationTutorialPage() {
to="/onboarding/assign-tutorial"
className={classNames(
'xs:ml-auto',
CalibrationStatus.SUCCESS !== calibrationStatus && 'hidden'
CalibrationStatus.SUCCESS !== calibrationStatus &&
!useRestCalibrationFlag &&
'hidden'
)}
disabled={
useRestCalibrationFlag &&
calibrationStatus !== CalibrationStatus.SUCCESS
}
>
{l10n.getString('onboarding-continue')}
</Button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,12 @@ public static int createTrackerInfos(

TrackerInfo.addDataSupport(fbb, tracker.getTrackerDataType().getSolarType());

TrackerInfo
.addRestCalibrationStatus(
fbb,
tracker.getRestCalibrationStatus().getSolarType()
);

return TrackerInfo.endTrackerInfo(fbb);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import dev.slimevr.tracking.processor.stayaligned.trackers.StayAlignedTrackerSta
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.RestCalibrationStatus
import dev.slimevr.tracking.trackers.udp.TrackerDataType
import dev.slimevr.util.InterpolationHandler
import io.eiren.util.BufferedTimer
Expand Down Expand Up @@ -84,6 +85,7 @@ class Tracker @JvmOverloads constructor(
*/
val trackRotDirection: Boolean = true,
magStatus: MagnetometerStatus = MagnetometerStatus.NOT_SUPPORTED,
restCalibrationStatus: RestCalibrationStatus = RestCalibrationStatus.NOT_SUPPORTED,
/**
* Rotation by default.
* NOT the same as hasRotation (other data types emulate rotation)
Expand All @@ -107,6 +109,8 @@ class Tracker @JvmOverloads constructor(
var customName: String? = null
var magStatus: MagnetometerStatus = magStatus
private set
var restCalibrationStatus: RestCalibrationStatus = restCalibrationStatus
private set

/**
* If the tracker has gotten disconnected after it was initialized first time
Expand Down Expand Up @@ -474,6 +478,10 @@ class Tracker @JvmOverloads constructor(
}
}

internal fun setRestCalibrationPrivate(status: RestCalibrationStatus) {
restCalibrationStatus = status
}

/**
* Gets the magnetic field vector, in mGauss.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,30 @@ enum class MagnetometerStatus {
}
}

enum class RestCalibrationStatus {
NOT_SUPPORTED,
NOT_CALIBRATED,
CALIBRATED,
;

fun getSolarType(): Int = this.ordinal

companion object {
private val byId = entries.associateBy { it.ordinal.toUByte() }

@JvmStatic
fun getById(id: UByte): RestCalibrationStatus? = byId[id]

@JvmStatic
fun fromBoolean(value: Boolean?): RestCalibrationStatus =
when (value) {
null -> NOT_SUPPORTED
true -> CALIBRATED
false -> NOT_CALIBRATED
}
}
}

@JvmInline
value class SensorConfig(val v: UShort) {
val magStatus
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,16 @@ class TrackersUDPServer(private val port: Int, name: String, private val tracker
// Set up new sensor for older firmware.
// Firmware after 7 should send sensor status packet and sensor
// will be created when it's received
setUpSensor(connection, 0, handshake.imuType, 1, MagnetometerStatus.NOT_SUPPORTED, null, TrackerDataType.ROTATION)
setUpSensor(
connection,
0,
handshake.imuType,
1,
MagnetometerStatus.NOT_SUPPORTED,
RestCalibrationStatus.NOT_SUPPORTED,
null,
TrackerDataType.ROTATION,
)
}
connection
}
Expand All @@ -186,7 +195,7 @@ class TrackersUDPServer(private val port: Int, name: String, private val tracker
}

private val mainScope = CoroutineScope(SupervisorJob())
private fun setUpSensor(connection: UDPDevice, trackerId: Int, sensorType: IMUType, sensorStatus: Int, magStatus: MagnetometerStatus, trackerPosition: TrackerPosition?, trackerDataType: TrackerDataType) {
private fun setUpSensor(connection: UDPDevice, trackerId: Int, sensorType: IMUType, sensorStatus: Int, magStatus: MagnetometerStatus, restCalibrationStatus: RestCalibrationStatus, trackerPosition: TrackerPosition?, trackerDataType: TrackerDataType) {
LogManager.info("[TrackerServer] Sensor $trackerId for ${connection.name} status: $sensorStatus")
var imuTracker = connection.getTracker(trackerId)
if (imuTracker == null) {
Expand Down Expand Up @@ -214,6 +223,7 @@ class TrackersUDPServer(private val port: Int, name: String, private val tracker
needsMounting = true,
usesTimeout = true,
magStatus = magStatus,
restCalibrationStatus = restCalibrationStatus,
trackerDataType = trackerDataType,
)
connection.trackers[trackerId] = imuTracker
Expand All @@ -223,7 +233,6 @@ class TrackersUDPServer(private val port: Int, name: String, private val tracker
val status = UDPPacket15SensorInfo.getStatus(sensorStatus)
if (status != null) imuTracker.status = status

if (magStatus == MagnetometerStatus.NOT_SUPPORTED) return
if (magStatus == MagnetometerStatus.ENABLED &&
(!VRServer.instance.configManager.vrConfig.server.useMagnetometerOnAllTrackers || imuTracker.config.shouldHaveMagEnabled == false)
) {
Expand All @@ -241,6 +250,8 @@ class TrackersUDPServer(private val port: Int, name: String, private val tracker
}
}
}

imuTracker.setRestCalibrationPrivate(restCalibrationStatus)
}

private data class ConfigStateWaiter(
Expand Down Expand Up @@ -475,12 +486,14 @@ class TrackersUDPServer(private val port: Int, name: String, private val tracker
is UDPPacket15SensorInfo -> {
if (connection == null) return
val magStatus = packet.sensorConfig?.magStatus ?: MagnetometerStatus.NOT_SUPPORTED
val restCalibrationStatus = RestCalibrationStatus.fromBoolean(packet.hasCompletedRestCalibration)
setUpSensor(
connection,
packet.sensorId,
packet.sensorType,
packet.sensorStatus,
magStatus,
restCalibrationStatus,
packet.trackerPosition,
packet.trackerDataType,
)
Expand Down
Loading