mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 11:48:09 +02:00
Added OutOfRangeDataStrategy parameter to Controller Settings
The openvr SDK provides a way to gauge the quality of tracking on a given device via the eTrackingResult enum. * Drop - Only Running_OK is considered valid, all other eTrackingResults will return invalid poses. * Freeze - Only Running_OK is considered valid, but other valid TrackingResults will return the last Running_OK pose. In esseces this will freeze the puck in place at the last good value. * None - All valid eTrackingResults will be valid, including OutOfRange and Calibrating results. This is the default.
This commit is contained in:
parent
d15cc86735
commit
7777f3edd0
4 changed files with 118 additions and 39 deletions
|
@ -51,17 +51,8 @@
|
||||||
{ "from": "Vive.RSCenter", "to": "Standard.RightPrimaryThumb" },
|
{ "from": "Vive.RSCenter", "to": "Standard.RightPrimaryThumb" },
|
||||||
{ "from": "Vive.RightApplicationMenu", "to": "Standard.RightSecondaryThumb" },
|
{ "from": "Vive.RightApplicationMenu", "to": "Standard.RightSecondaryThumb" },
|
||||||
|
|
||||||
{ "from": "Vive.LeftHand", "to": "Standard.LeftHand",
|
{ "from": "Vive.LeftHand", "to": "Standard.LeftHand"},
|
||||||
"filters" : [{"type" : "accelerationLimiter",
|
{ "from": "Vive.RightHand", "to": "Standard.RightHand"},
|
||||||
"rotationAccelerationLimit" : 4000.0, "rotationDecelerationLimit" : 8000.0,
|
|
||||||
"translationAccelerationLimit": 200.0, "translationDecelerationLimit": 400.0}]
|
|
||||||
},
|
|
||||||
|
|
||||||
{ "from": "Vive.RightHand", "to": "Standard.RightHand",
|
|
||||||
"filters" : [{"type" : "accelerationLimiter",
|
|
||||||
"rotationAccelerationLimit" : 2000.0, "rotationDecelerationLimit" : 4000.0,
|
|
||||||
"translationAccelerationLimit": 100.0, "translationDecelerationLimit": 200.0}]
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
{
|
||||||
"from": "Vive.LeftFoot", "to" : "Standard.LeftFoot",
|
"from": "Vive.LeftFoot", "to" : "Standard.LeftFoot",
|
||||||
|
|
|
@ -822,11 +822,44 @@ Flickable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: outOfRangeDataStrategyRow
|
||||||
|
anchors.top: viveInDesktop.bottom
|
||||||
|
anchors.topMargin: 5
|
||||||
|
anchors.left: openVrConfiguration.left
|
||||||
|
anchors.leftMargin: leftMargin + 10
|
||||||
|
spacing: 15
|
||||||
|
|
||||||
|
RalewayRegular {
|
||||||
|
id: outOfRangeDataStrategyLabel
|
||||||
|
size: 12
|
||||||
|
text: "Out Of Range Data Strategy:"
|
||||||
|
color: hifi.colors.lightGrayText
|
||||||
|
topPadding: 5
|
||||||
|
}
|
||||||
|
|
||||||
|
HifiControls.ComboBox {
|
||||||
|
id: outOfRangeDataStrategyComboBox
|
||||||
|
|
||||||
|
height: 25
|
||||||
|
width: 100
|
||||||
|
|
||||||
|
editable: true
|
||||||
|
colorScheme: hifi.colorSchemes.dark
|
||||||
|
model: ["None", "Freeze", "Drop"]
|
||||||
|
label: ""
|
||||||
|
|
||||||
|
onCurrentIndexChanged: {
|
||||||
|
sendConfigurationSettings();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RalewayBold {
|
RalewayBold {
|
||||||
id: viveDesktopText
|
id: viveDesktopText
|
||||||
size: 10
|
size: 12
|
||||||
text: "Use " + stack.selectedPlugin + " devices in desktop mode"
|
text: "Use " + stack.selectedPlugin + " devices in desktop mode"
|
||||||
color: hifi.colors.white
|
color: hifi.colors.lightGrayText
|
||||||
|
|
||||||
anchors {
|
anchors {
|
||||||
left: viveInDesktop.right
|
left: viveInDesktop.right
|
||||||
|
@ -946,6 +979,7 @@ Flickable {
|
||||||
|
|
||||||
viveInDesktop.checked = desktopMode;
|
viveInDesktop.checked = desktopMode;
|
||||||
hmdInDesktop.checked = hmdDesktopPosition;
|
hmdInDesktop.checked = hmdDesktopPosition;
|
||||||
|
outOfRangeDataStrategyComboBox.currentIndex = outOfRangeDataStrategyComboBox.model.indexOf(settings.outOfRangeDataStrategy);
|
||||||
|
|
||||||
initializeButtonState();
|
initializeButtonState();
|
||||||
updateCalibrationText();
|
updateCalibrationText();
|
||||||
|
@ -1107,7 +1141,8 @@ Flickable {
|
||||||
"armCircumference": armCircumference.realValue,
|
"armCircumference": armCircumference.realValue,
|
||||||
"shoulderWidth": shoulderWidth.realValue,
|
"shoulderWidth": shoulderWidth.realValue,
|
||||||
"desktopMode": viveInDesktop.checked,
|
"desktopMode": viveInDesktop.checked,
|
||||||
"hmdDesktopTracking": hmdInDesktop.checked
|
"hmdDesktopTracking": hmdInDesktop.checked,
|
||||||
|
"outOfRangeDataStrategy": outOfRangeDataStrategyComboBox.model[outOfRangeDataStrategyComboBox.currentIndex]
|
||||||
}
|
}
|
||||||
|
|
||||||
return settingsObject;
|
return settingsObject;
|
||||||
|
|
|
@ -129,6 +129,28 @@ static glm::mat4 calculateResetMat() {
|
||||||
return glm::mat4();
|
return glm::mat4();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static QString outOfRangeDataStrategyToString(ViveControllerManager::OutOfRangeDataStrategy strategy) {
|
||||||
|
switch (strategy) {
|
||||||
|
default:
|
||||||
|
case ViveControllerManager::OutOfRangeDataStrategy::None:
|
||||||
|
return "None";
|
||||||
|
case ViveControllerManager::OutOfRangeDataStrategy::Freeze:
|
||||||
|
return "Freeze";
|
||||||
|
case ViveControllerManager::OutOfRangeDataStrategy::Drop:
|
||||||
|
return "Drop";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static ViveControllerManager::OutOfRangeDataStrategy stringToOutOfRangeDataStrategy(const QString& string) {
|
||||||
|
if (string == "Drop") {
|
||||||
|
return ViveControllerManager::OutOfRangeDataStrategy::Drop;
|
||||||
|
} else if (string == "Freeze") {
|
||||||
|
return ViveControllerManager::OutOfRangeDataStrategy::Freeze;
|
||||||
|
} else {
|
||||||
|
return ViveControllerManager::OutOfRangeDataStrategy::None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool ViveControllerManager::isDesktopMode() {
|
bool ViveControllerManager::isDesktopMode() {
|
||||||
if (_container) {
|
if (_container) {
|
||||||
return !_container->getActiveDisplayPlugin()->isHmd();
|
return !_container->getActiveDisplayPlugin()->isHmd();
|
||||||
|
@ -288,8 +310,10 @@ void ViveControllerManager::loadSettings() {
|
||||||
if (_inputDevice) {
|
if (_inputDevice) {
|
||||||
const double DEFAULT_ARM_CIRCUMFERENCE = 0.33;
|
const double DEFAULT_ARM_CIRCUMFERENCE = 0.33;
|
||||||
const double DEFAULT_SHOULDER_WIDTH = 0.48;
|
const double DEFAULT_SHOULDER_WIDTH = 0.48;
|
||||||
|
const QString DEFAULT_OUT_OF_RANGE_STRATEGY = "None";
|
||||||
_inputDevice->_armCircumference = settings.value("armCircumference", QVariant(DEFAULT_ARM_CIRCUMFERENCE)).toDouble();
|
_inputDevice->_armCircumference = settings.value("armCircumference", QVariant(DEFAULT_ARM_CIRCUMFERENCE)).toDouble();
|
||||||
_inputDevice->_shoulderWidth = settings.value("shoulderWidth", QVariant(DEFAULT_SHOULDER_WIDTH)).toDouble();
|
_inputDevice->_shoulderWidth = settings.value("shoulderWidth", QVariant(DEFAULT_SHOULDER_WIDTH)).toDouble();
|
||||||
|
_inputDevice->_outOfRangeDataStrategy = stringToOutOfRangeDataStrategy(settings.value("outOfRangeDataStrategy", QVariant(DEFAULT_OUT_OF_RANGE_STRATEGY)).toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
|
@ -303,6 +327,7 @@ void ViveControllerManager::saveSettings() const {
|
||||||
if (_inputDevice) {
|
if (_inputDevice) {
|
||||||
settings.setValue(QString("armCircumference"), _inputDevice->_armCircumference);
|
settings.setValue(QString("armCircumference"), _inputDevice->_armCircumference);
|
||||||
settings.setValue(QString("shoulderWidth"), _inputDevice->_shoulderWidth);
|
settings.setValue(QString("shoulderWidth"), _inputDevice->_shoulderWidth);
|
||||||
|
settings.setValue(QString("outOfRangeDataStrategy"), outOfRangeDataStrategyToString(_inputDevice->_outOfRangeDataStrategy));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
|
@ -446,6 +471,8 @@ void ViveControllerManager::InputDevice::configureCalibrationSettings(const QJso
|
||||||
hmdDesktopTracking = iter.value().toBool();
|
hmdDesktopTracking = iter.value().toBool();
|
||||||
} else if (iter.key() == "desktopMode") {
|
} else if (iter.key() == "desktopMode") {
|
||||||
hmdDesktopMode = iter.value().toBool();
|
hmdDesktopMode = iter.value().toBool();
|
||||||
|
} else if (iter.key() == "outOfRangeDataStrategy") {
|
||||||
|
_outOfRangeDataStrategy = stringToOutOfRangeDataStrategy(iter.value().toString());
|
||||||
}
|
}
|
||||||
iter++;
|
iter++;
|
||||||
}
|
}
|
||||||
|
@ -468,6 +495,7 @@ QJsonObject ViveControllerManager::InputDevice::configurationSettings() {
|
||||||
configurationSettings["puckCount"] = (int)_validTrackedObjects.size();
|
configurationSettings["puckCount"] = (int)_validTrackedObjects.size();
|
||||||
configurationSettings["armCircumference"] = (double)_armCircumference * M_TO_CM;
|
configurationSettings["armCircumference"] = (double)_armCircumference * M_TO_CM;
|
||||||
configurationSettings["shoulderWidth"] = (double)_shoulderWidth * M_TO_CM;
|
configurationSettings["shoulderWidth"] = (double)_shoulderWidth * M_TO_CM;
|
||||||
|
configurationSettings["outOfRangeDataStrategy"] = outOfRangeDataStrategyToString(_outOfRangeDataStrategy);
|
||||||
return configurationSettings;
|
return configurationSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -484,6 +512,10 @@ void ViveControllerManager::InputDevice::emitCalibrationStatus() {
|
||||||
emit inputConfiguration->calibrationStatus(status);
|
emit inputConfiguration->calibrationStatus(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static controller::Pose buildPose(const glm::mat4& mat, const glm::vec3& linearVelocity, const glm::vec3& angularVelocity) {
|
||||||
|
return controller::Pose(extractTranslation(mat), glmExtractRotation(mat), linearVelocity, angularVelocity);
|
||||||
|
}
|
||||||
|
|
||||||
void ViveControllerManager::InputDevice::handleTrackedObject(uint32_t deviceIndex, const controller::InputCalibrationData& inputCalibrationData) {
|
void ViveControllerManager::InputDevice::handleTrackedObject(uint32_t deviceIndex, const controller::InputCalibrationData& inputCalibrationData) {
|
||||||
uint32_t poseIndex = controller::TRACKED_OBJECT_00 + deviceIndex;
|
uint32_t poseIndex = controller::TRACKED_OBJECT_00 + deviceIndex;
|
||||||
printDeviceTrackingResultChange(deviceIndex);
|
printDeviceTrackingResultChange(deviceIndex);
|
||||||
|
@ -492,28 +524,37 @@ void ViveControllerManager::InputDevice::handleTrackedObject(uint32_t deviceInde
|
||||||
_nextSimPoseData.vrPoses[deviceIndex].bPoseIsValid &&
|
_nextSimPoseData.vrPoses[deviceIndex].bPoseIsValid &&
|
||||||
poseIndex <= controller::TRACKED_OBJECT_15) {
|
poseIndex <= controller::TRACKED_OBJECT_15) {
|
||||||
|
|
||||||
mat4& mat = mat4();
|
controller::Pose pose;
|
||||||
vec3 linearVelocity = vec3();
|
switch (_outOfRangeDataStrategy) {
|
||||||
vec3 angularVelocity = vec3();
|
case OutOfRangeDataStrategy::Drop:
|
||||||
// check if the device is tracking out of range, then process the correct pose depending on the result.
|
default:
|
||||||
if (_nextSimPoseData.vrPoses[deviceIndex].eTrackingResult != vr::TrackingResult_Running_OutOfRange) {
|
// Drop - Mark all non Running_OK results as invald
|
||||||
mat = _nextSimPoseData.poses[deviceIndex];
|
if (_nextSimPoseData.vrPoses[deviceIndex].eTrackingResult == vr::TrackingResult_Running_OK) {
|
||||||
linearVelocity = _nextSimPoseData.linearVelocities[deviceIndex];
|
pose = buildPose(_nextSimPoseData.poses[deviceIndex], _nextSimPoseData.linearVelocities[deviceIndex], _nextSimPoseData.angularVelocities[deviceIndex]);
|
||||||
angularVelocity = _nextSimPoseData.angularVelocities[deviceIndex];
|
|
||||||
} else {
|
} else {
|
||||||
mat = _lastSimPoseData.poses[deviceIndex];
|
pose.valid = false;
|
||||||
linearVelocity = _lastSimPoseData.linearVelocities[deviceIndex];
|
}
|
||||||
angularVelocity = _lastSimPoseData.angularVelocities[deviceIndex];
|
break;
|
||||||
|
case OutOfRangeDataStrategy::None:
|
||||||
|
// None - Ignore eTrackingResult all together
|
||||||
|
pose = buildPose(_nextSimPoseData.poses[deviceIndex], _nextSimPoseData.linearVelocities[deviceIndex], _nextSimPoseData.angularVelocities[deviceIndex]);
|
||||||
|
break;
|
||||||
|
case OutOfRangeDataStrategy::Freeze:
|
||||||
|
// Freeze - Dont invalide non Running_OK poses, instead just return the last good pose.
|
||||||
|
if (_nextSimPoseData.vrPoses[deviceIndex].eTrackingResult == vr::TrackingResult_Running_OK) {
|
||||||
|
pose = buildPose(_nextSimPoseData.poses[deviceIndex], _nextSimPoseData.linearVelocities[deviceIndex], _nextSimPoseData.angularVelocities[deviceIndex]);
|
||||||
|
} else {
|
||||||
|
pose = buildPose(_lastSimPoseData.poses[deviceIndex], _lastSimPoseData.linearVelocities[deviceIndex], _lastSimPoseData.angularVelocities[deviceIndex]);
|
||||||
|
|
||||||
// make sure that we do not overwrite the pose in the _lastSimPose with incorrect data.
|
// make sure that we do not overwrite the pose in the _lastSimPose with incorrect data.
|
||||||
_nextSimPoseData.poses[deviceIndex] = _lastSimPoseData.poses[deviceIndex];
|
_nextSimPoseData.poses[deviceIndex] = _lastSimPoseData.poses[deviceIndex];
|
||||||
_nextSimPoseData.linearVelocities[deviceIndex] = _lastSimPoseData.linearVelocities[deviceIndex];
|
_nextSimPoseData.linearVelocities[deviceIndex] = _lastSimPoseData.linearVelocities[deviceIndex];
|
||||||
_nextSimPoseData.angularVelocities[deviceIndex] = _lastSimPoseData.angularVelocities[deviceIndex];
|
_nextSimPoseData.angularVelocities[deviceIndex] = _lastSimPoseData.angularVelocities[deviceIndex];
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
controller::Pose pose(extractTranslation(mat), glmExtractRotation(mat), linearVelocity, angularVelocity);
|
if (pose.valid) {
|
||||||
|
|
||||||
// transform into avatar frame
|
// transform into avatar frame
|
||||||
glm::mat4 controllerToAvatar = glm::inverse(inputCalibrationData.avatarMat) * inputCalibrationData.sensorToWorldMat;
|
glm::mat4 controllerToAvatar = glm::inverse(inputCalibrationData.avatarMat) * inputCalibrationData.sensorToWorldMat;
|
||||||
_poseStateMap[poseIndex] = pose.transform(controllerToAvatar);
|
_poseStateMap[poseIndex] = pose.transform(controllerToAvatar);
|
||||||
|
@ -521,6 +562,10 @@ void ViveControllerManager::InputDevice::handleTrackedObject(uint32_t deviceInde
|
||||||
// but _validTrackedObjects remain in sensor frame
|
// but _validTrackedObjects remain in sensor frame
|
||||||
_validTrackedObjects.push_back(std::make_pair(poseIndex, pose));
|
_validTrackedObjects.push_back(std::make_pair(poseIndex, pose));
|
||||||
_trackedControllers++;
|
_trackedControllers++;
|
||||||
|
} else {
|
||||||
|
// insert invalid pose into state map
|
||||||
|
_poseStateMap[poseIndex] = pose;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
controller::Pose invalidPose;
|
controller::Pose invalidPose;
|
||||||
_poseStateMap[poseIndex] = invalidPose;
|
_poseStateMap[poseIndex] = invalidPose;
|
||||||
|
|
|
@ -60,11 +60,18 @@ public:
|
||||||
virtual void saveSettings() const override;
|
virtual void saveSettings() const override;
|
||||||
virtual void loadSettings() override;
|
virtual void loadSettings() override;
|
||||||
|
|
||||||
|
enum class OutOfRangeDataStrategy {
|
||||||
|
None,
|
||||||
|
Freeze,
|
||||||
|
Drop
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class InputDevice : public controller::InputDevice {
|
class InputDevice : public controller::InputDevice {
|
||||||
public:
|
public:
|
||||||
InputDevice(vr::IVRSystem*& system);
|
InputDevice(vr::IVRSystem*& system);
|
||||||
bool isHeadControllerMounted() const { return _overrideHead; }
|
bool isHeadControllerMounted() const { return _overrideHead; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Device functions
|
// Device functions
|
||||||
controller::Input::NamedVector getAvailableInputs() const override;
|
controller::Input::NamedVector getAvailableInputs() const override;
|
||||||
|
@ -162,6 +169,7 @@ private:
|
||||||
FilteredStick _filteredLeftStick;
|
FilteredStick _filteredLeftStick;
|
||||||
FilteredStick _filteredRightStick;
|
FilteredStick _filteredRightStick;
|
||||||
std::string _headsetName {""};
|
std::string _headsetName {""};
|
||||||
|
OutOfRangeDataStrategy _outOfRangeDataStrategy { OutOfRangeDataStrategy::None };
|
||||||
|
|
||||||
std::vector<PuckPosePair> _validTrackedObjects;
|
std::vector<PuckPosePair> _validTrackedObjects;
|
||||||
std::map<uint32_t, glm::mat4> _pucksPostOffset;
|
std::map<uint32_t, glm::mat4> _pucksPostOffset;
|
||||||
|
|
Loading…
Reference in a new issue