Added shoulder config to Controller Settings UI

All offset values in Controller Settings UI are now in cm.
This commit is contained in:
Anthony J. Thibault 2017-07-25 17:05:07 -07:00
parent c81875a280
commit 572213daaf
3 changed files with 95 additions and 33 deletions

View file

@ -145,12 +145,13 @@ Rectangle {
visible: headPuckBox.checked
HifiControls.SpinBox {
id: headYOffset
decimals: 4
decimals: 1
width: 112
label: "Y: offset"
label: "Y Offset"
suffix: " cm"
minimumValue: -10
stepSize: 0.0254
value: -0.05
stepSize: 1
value: -5
colorScheme: hifi.colorSchemes.dark
onEditingFinished: {
@ -162,11 +163,12 @@ Rectangle {
HifiControls.SpinBox {
id: headZOffset
width: 112
label: "Z: offset"
label: "Z Offset"
minimumValue: -10
stepSize: 0.0254
decimals: 4
value: -0.05
stepSize: 1
decimals: 1
suffix: " cm"
value: -5
colorScheme: hifi.colorSchemes.dark
onEditingFinished: {
@ -175,7 +177,6 @@ Rectangle {
}
}
RalewayBold {
id: hands
@ -254,11 +255,12 @@ Rectangle {
HifiControls.SpinBox {
id: handYOffset
decimals: 4
decimals: 1
width: 112
label: "Y: offset"
suffix: " cm"
label: "Y Offset"
minimumValue: -10
stepSize: 0.0254
stepSize: 1
colorScheme: hifi.colorSchemes.dark
onEditingFinished: {
@ -270,10 +272,11 @@ Rectangle {
HifiControls.SpinBox {
id: handZOffset
width: 112
label: "Z: offset"
label: "Z Offset"
suffix: " cm"
minimumValue: -10
stepSize: 0.0254
decimals: 4
stepSize: 1
decimals: 1
colorScheme: hifi.colorSchemes.dark
onEditingFinished: {
@ -488,15 +491,55 @@ Rectangle {
}
}
Row {
id: shoulderAdditionalConfig
visible: shoulderBox.checked
anchors.top: shoulderConfig.bottom
anchors.topMargin: 5
anchors.left: openVrConfiguration.left
anchors.leftMargin: leftMargin + 20
spacing: 10
HifiControls.SpinBox {
id: armCircumference
decimals: 1
width: 160
suffix: " cm"
label: "Arm Circumference"
minimumValue: 0
stepSize: 1.0
colorScheme: hifi.colorSchemes.dark
value: 33.0
onEditingFinished: {
sendConfigurationSettings();
}
}
HifiControls.SpinBox {
id: shoulderWidth
width: 160
label: "Shoulder Width"
suffix: " cm"
minimumValue: 0
stepSize: 1.0
decimals: 1
colorScheme: hifi.colorSchemes.dark
value: 48
onEditingFinished: {
sendConfigurationSettings();
}
}
}
Separator {
id: bottomSeperator
width: parent.width
anchors.top: shoulderConfig.bottom
anchors.topMargin: 10
anchors.top: shoulderAdditionalConfig.visible ? shoulderAdditionalConfig.bottom : shoulderConfig.bottom
anchors.topMargin: (shoulderAdditionalConfig.visible ? 25 : 10)
}
Rectangle {
id: calibrationButton
property int color: hifi.buttons.blue
@ -1006,10 +1049,17 @@ Rectangle {
"Z": handZOffset.value
}
var shoulderObject = {
"override": shouldersChecked,
"armCircumference": armCircumference.value,
"shoulderWidth": shoulderWidth.value
}
var settingsObject = {
"bodyConfiguration": trackerConfiguration,
"headConfiguration": headObject,
"handConfiguration": handObject,
"shoulderConfiguration": shoulderObject,
"desktopMode": viveInDesktop.checked
}

View file

@ -378,6 +378,8 @@ void ViveControllerManager::InputDevice::calibrateFromUI(const controller::Input
}
}
static const float CM_TO_M = 0.01f;
void ViveControllerManager::InputDevice::configureCalibrationSettings(const QJsonObject configurationSettings) {
Locker locker(_lock);
if (!configurationSettings.empty()) {
@ -391,8 +393,8 @@ void ViveControllerManager::InputDevice::configureCalibrationSettings(const QJso
bool overrideHead = headObject["override"].toBool();
if (overrideHead) {
_headConfig = HeadConfig::Puck;
_headPuckYOffset = headObject["Y"].toDouble();
_headPuckZOffset = headObject["Z"].toDouble();
_headPuckYOffset = headObject["Y"].toDouble() * CM_TO_M;
_headPuckZOffset = headObject["Z"].toDouble() * CM_TO_M;
} else {
_headConfig = HeadConfig::HMD;
}
@ -401,11 +403,18 @@ void ViveControllerManager::InputDevice::configureCalibrationSettings(const QJso
bool overrideHands = handsObject["override"].toBool();
if (overrideHands) {
_handConfig = HandConfig::Pucks;
_handPuckYOffset = handsObject["Y"].toDouble();
_handPuckZOffset = handsObject["Z"].toDouble();
_handPuckYOffset = handsObject["Y"].toDouble() * CM_TO_M;
_handPuckZOffset = handsObject["Z"].toDouble() * CM_TO_M;
} else {
_handConfig = HandConfig::HandController;
}
} else if (iter.key() == "shoulderConfiguration") {
QJsonObject shoulderObj = iter.value().toObject();
bool shouldersChecked = shoulderObj["override"].toBool();
if (shouldersChecked) {
_armCircumference = shoulderObj["armCircumference"].toDouble() * CM_TO_M;
_shoulderWidth = shoulderObj["shoulderWidth"].toDouble() * CM_TO_M;
}
}
iter++;
}
@ -1139,15 +1148,12 @@ static glm::vec3 computeUserShoulderPositionFromHistory(const glm::mat4& headMat
// y axis comes out of puck usb port/green light
// -z axis comes out of puck center/vive logo
static glm::vec3 computeUserShoulderPositionFromMeasurements(const glm::mat4& headMat, const controller::Pose& armPuck, bool isLeftHand) {
// AJT: TODO measurments are hard coded!
const float ARM_CIRC = 0.33f; // 13 inches
const float SHOULDER_SPAN = 0.4826; // 19 inches
static glm::vec3 computeUserShoulderPositionFromMeasurements(float armCirc, float shoulderSpan, const glm::mat4& headMat, const controller::Pose& armPuck, bool isLeftHand) {
float armRadius = ARM_CIRC / TWO_PI;
float armRadius = armCirc / TWO_PI;
float sign = isLeftHand ? 1.0f : -1.0f;
float localArmX = sign * SHOULDER_SPAN / 2.0f;
float localArmX = sign * shoulderSpan / 2.0f;
controller::Pose localPuck = armPuck.transform(glm::inverse(headMat));
glm::mat4 localPuckMat = localPuck.getMatrix();
@ -1179,8 +1185,10 @@ void ViveControllerManager::InputDevice::calibrateShoulders(const glm::mat4& def
_jointToPuckMap[controller::LEFT_ARM] = firstShoulder.first;
_jointToPuckMap[controller::RIGHT_ARM] = secondShoulder.first;
userRefLeftArm[3] = glm::vec4(computeUserShoulderPositionFromMeasurements(headMat, firstShoulderPose, true), 1.0f);
userRefRightArm[3] = glm::vec4(computeUserShoulderPositionFromMeasurements(headMat, secondShoulderPose, false), 1.0f);
glm::vec3 leftPos = computeUserShoulderPositionFromMeasurements(_armCircumference, _shoulderWidth, headMat, firstShoulderPose, true);
userRefLeftArm[3] = glm::vec4(leftPos, 1.0f);
glm::vec3 rightPos = computeUserShoulderPositionFromMeasurements(_armCircumference, _shoulderWidth, headMat, secondShoulderPose, false);
userRefRightArm[3] = glm::vec4(rightPos, 1.0f);
// compute the post offset from the userRefArm
_pucksPostOffset[firstShoulder.first] = computeOffset(Matrices::IDENTITY, userRefLeftArm, firstShoulderPose);
@ -1194,8 +1202,10 @@ void ViveControllerManager::InputDevice::calibrateShoulders(const glm::mat4& def
_jointToPuckMap[controller::LEFT_ARM] = secondShoulder.first;
_jointToPuckMap[controller::RIGHT_ARM] = firstShoulder.first;
userRefLeftArm[3] = glm::vec4(computeUserShoulderPositionFromMeasurements(headMat, secondShoulderPose, true), 1.0f);
userRefRightArm[3] = glm::vec4(computeUserShoulderPositionFromMeasurements(headMat, firstShoulderPose, false), 1.0f);
glm::vec3 leftPos = computeUserShoulderPositionFromMeasurements(_armCircumference, _shoulderWidth, headMat, secondShoulderPose, true);
userRefLeftArm[3] = glm::vec4(leftPos, 1.0f);
glm::vec3 rightPos = computeUserShoulderPositionFromMeasurements(_armCircumference, _shoulderWidth, headMat, firstShoulderPose, false);
userRefRightArm[3] = glm::vec4(rightPos, 1.0f);
// compute the post offset from the userRefArm
_pucksPostOffset[secondShoulder.first] = computeOffset(Matrices::IDENTITY, userRefLeftArm, secondShoulderPose);

View file

@ -182,6 +182,8 @@ private:
float _headPuckZOffset { -0.05f };
float _handPuckYOffset { 0.0f };
float _handPuckZOffset { 0.0f };
float _armCircumference { 0.33f };
float _shoulderWidth { 0.48f };
bool _triggersPressedHandled { false };
bool _calibrated { false };
bool _timeTilCalibrationSet { false };