Skip to content

Commit

Permalink
Added vel/acc compensation modes & some bugfixes.
Browse files Browse the repository at this point in the history
  • Loading branch information
matzman666 committed May 15, 2017
1 parent c31a14e commit 1dc083e
Show file tree
Hide file tree
Showing 15 changed files with 279 additions and 43 deletions.
6 changes: 5 additions & 1 deletion Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,11 @@ Redirect mode can be temporarily suspended by pressing the system button on eith

![Motion Compensation Settings Page](https://raw.githubusercontent.com/matzman666/OpenVR-InputEmulator/master/docs/screenshots/MotionCompensationPage.png)

- **Center Point**: Set the center point of the motion platform.
- **Vel/Acc Compensation Mode**: How should reported velocities and acceleration values be adjusted. The problem with only adjusting the headset position is that pose prediction also takes velocity and acceleration into accound. As long as the reported values to not differ too much from the real values, pose prediction errors are hardly noticeable. But with fast movements of the motion platform the pose prediction error can be noticeable. Available modes are:
- **Disabled**: Do not adjust velocity/acceration values.
- **Set Zero**: Set all velocity/acceleration values to zero. Most simple form of velocity/acceleration compensation.
- **Use Reference Tracker**: Substract the velocity/acceleration values of the motion compensation reference tracker/controller from the values reported from the headset. Most accurate form of velocity/acceleration compensation. However, it requires that the reference tracker/controller is as closely mounted to the head position as possible. The further away it is from the head position the larger the error.
- **Linear Approximation (Experimental)**: Uses linear approximation to estimate the velocity/acceleration values. The used formula is: (current_position - last_position) / time_difference, however the resulting values do cause a lot of jitter and therefore they are divided by four to reduce jitter to an acceptable level.

## client_commandline commands:

Expand Down
Binary file modified client_overlay/bin/win64/openvr_api.dll
Binary file not shown.
7 changes: 3 additions & 4 deletions client_overlay/bin/win64/res/qml/DeviceManipulationPage.qml
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,7 @@ MyStackViewPage {
Layout.preferredWidth: 555
Layout.fillWidth: true
model: [
"Device Offsets",
"Motion Compensation Settings",
"Device Offsets"
]
currentIndex: 0
}
Expand Down Expand Up @@ -451,7 +450,7 @@ MyStackViewPage {
deviceSelectionComboBox.currentIndex = -1
deviceModeSelectionComboBox.enabled = false
deviceModeApplyButton.enabled = false
//motionCompensationButton.enabled = false
motionCompensationButton.enabled = false
deviceManipulationOffsetButton.enabled = false
deviceIdentifyButton.enabled = false
deviceRenderModelComboBox.enabled = false
Expand All @@ -461,7 +460,7 @@ MyStackViewPage {
} else {
deviceModeSelectionComboBox.enabled = true
deviceManipulationOffsetButton.enabled = true
//motionCompensationButton.enabled = true
motionCompensationButton.enabled = true
deviceModeApplyButton.enabled = true
deviceIdentifyButton.enabled = true
deviceRenderModelComboBox.enabled = true
Expand Down
39 changes: 38 additions & 1 deletion client_overlay/bin/win64/res/qml/MotionCompensationPage.qml
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,54 @@ MyStackViewPage {

headerText: "Motion Compensation Settings"

property bool setupFinished: false

content: ColumnLayout {
spacing: 18

RowLayout {
spacing: 18
Layout.bottomMargin: 64

MyText {
text: "Vel/Acc Compensation Mode:"
}

MyComboBox {
id: deviceSelectionComboBox
Layout.maximumWidth: 750
Layout.minimumWidth: 750
Layout.preferredWidth: 750
Layout.fillWidth: true
model: [
"Disabled",
"Set Zero",
"Use Reference Tracker",
"Linear Approximation (Experimental)"
]
onCurrentIndexChanged: {
if (setupFinished) {
DeviceManipulationTabController.setMotionCompensationVelAccMode(currentIndex)
}
}
}
}

Item {
Layout.fillWidth: true
Layout.fillHeight: true
}


Component.onCompleted: {
deviceSelectionComboBox.currentIndex = DeviceManipulationTabController.getMotionCompensationVelAccMode()
setupFinished = true
}

Connections {
target: DeviceManipulationTabController
onDeviceInfoChanged: {
onMotionCompensationVelAccModeChanged: {
deviceSelectionComboBox.currentIndex = mode
}
}

Expand Down
2 changes: 1 addition & 1 deletion client_overlay/src/overlaycontroller.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class OverlayController : public QObject {
public:
static constexpr const char* applicationKey = "matzman666.VRInputEmulator";
static constexpr const char* applicationName = "VR Input Emulator";
static constexpr const char* applicationVersionString = "v1.0";
static constexpr const char* applicationVersionString = "v1.0.3";

private:
vr::VROverlayHandle_t m_ulOverlayHandle = vr::k_ulOverlayHandleInvalid;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,10 @@ double DeviceManipulationTabController::getDriverTranslationOffset(unsigned inde
}
}

unsigned DeviceManipulationTabController::getMotionCompensationVelAccMode() {
return motionCompensationVelAccMode;
}


#define DEVICEMANIPULATIONSETTINGS_GETTRANSLATIONVECTOR(name) { \
double valueX = settings->value(#name ## "_x", 0.0).toDouble(); \
Expand All @@ -255,9 +259,10 @@ double DeviceManipulationTabController::getDriverTranslationOffset(unsigned inde
}

void DeviceManipulationTabController::reloadDeviceManipulationSettings() {
/*auto settings = OverlayController::appSettings();
auto settings = OverlayController::appSettings();
settings->beginGroup("deviceManipulationSettings");
settings->endGroup();*/
motionCompensationVelAccMode = settings->value("motionCompensationVelAccMode").toUInt();
settings->endGroup();
}

void DeviceManipulationTabController::reloadDeviceManipulationProfiles() {
Expand Down Expand Up @@ -286,10 +291,11 @@ void DeviceManipulationTabController::reloadDeviceManipulationProfiles() {
}

void DeviceManipulationTabController::saveDeviceManipulationSettings() {
/*auto settings = OverlayController::appSettings();
auto settings = OverlayController::appSettings();
settings->beginGroup("deviceManipulationSettings");
settings->setValue("motionCompensationVelAccMode", motionCompensationVelAccMode);
settings->endGroup();
settings->sync();*/
settings->sync();
}


Expand Down Expand Up @@ -410,6 +416,17 @@ void DeviceManipulationTabController::deleteDeviceManipulationProfile(unsigned i
}
}

void DeviceManipulationTabController::setMotionCompensationVelAccMode(unsigned mode, bool notify) {
if (motionCompensationVelAccMode != mode) {
motionCompensationVelAccMode = mode;
vrInputEmulator.setMotionVelAccCompensationMode(mode);
saveDeviceManipulationSettings();
if (notify) {
emit motionCompensationVelAccModeChanged(mode);
}
}
}

unsigned DeviceManipulationTabController::getRenderModelCount() {
return (unsigned)vr::VRRenderModels()->GetRenderModelCount();
}
Expand Down Expand Up @@ -555,7 +572,7 @@ void DeviceManipulationTabController::setDeviceMode(unsigned index, unsigned mod
vrInputEmulator.setDeviceSwapMode(deviceInfos[index]->openvrId, deviceInfos[targedIndex]->openvrId);
break;
case 4:
vrInputEmulator.setDeviceMotionCompensationMode(deviceInfos[index]->openvrId);
vrInputEmulator.setDeviceMotionCompensationMode(deviceInfos[index]->openvrId, motionCompensationVelAccMode);
break;
default:
LOG(ERROR) << "Unkown device mode";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ class DeviceManipulationTabController : public QObject {

std::vector<DeviceManipulationProfile> deviceManipulationProfiles;

uint32_t motionCompensationVelAccMode = 0;

unsigned settingsUpdateCounter = 0;

std::thread identifyThread;
Expand All @@ -85,6 +87,7 @@ class DeviceManipulationTabController : public QObject {
Q_INVOKABLE double getDriverFromHeadTranslationOffset(unsigned index, unsigned axis);
Q_INVOKABLE double getDriverRotationOffset(unsigned index, unsigned axis);
Q_INVOKABLE double getDriverTranslationOffset(unsigned index, unsigned axis);
Q_INVOKABLE unsigned getMotionCompensationVelAccMode();

void reloadDeviceManipulationSettings();
void reloadDeviceManipulationProfiles();
Expand Down Expand Up @@ -116,11 +119,14 @@ public slots:
void applyDeviceManipulationProfile(unsigned index, unsigned deviceIndex);
void deleteDeviceManipulationProfile(unsigned index);

void setMotionCompensationVelAccMode(unsigned mode, bool notify = true);

signals:
void deviceCountChanged(unsigned deviceCount);
void deviceInfoChanged(unsigned index);
void motionCompensationSettingsChanged();
void deviceManipulationProfilesChanged();
void motionCompensationVelAccModeChanged(unsigned mode);
};

} // namespace inputemulator
Binary file modified docs/screenshots/MotionCompensationPage.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions driver_vrinputemulator/src/com/shm/driver_ipc_shm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -812,6 +812,7 @@ void IpcShmCommunicator::_ipcThreadFunc(IpcShmCommunicator* _this, CServerDriver
} else {
auto serverDriver = CServerDriver::getInstance();
if (serverDriver) {
serverDriver->setMotionCompensationVelAccMode(message.msg.dm_MotionCompensationMode.velAccCompensationMode);
info->setMotionCompensationMode();
resp.status = ipc::ReplyStatus::Ok;
} else {
Expand Down Expand Up @@ -897,6 +898,7 @@ void IpcShmCommunicator::_ipcThreadFunc(IpcShmCommunicator* _this, CServerDriver
resp.messageId = message.msg.dm_SetMotionCompensationProperties.messageId;
auto serverDriver = CServerDriver::getInstance();
if (serverDriver) {
serverDriver->setMotionCompensationVelAccMode(message.msg.dm_SetMotionCompensationProperties.velAccCompensationMode);
resp.status = ipc::ReplyStatus::Ok;
} else {
resp.status = ipc::ReplyStatus::UnknownError;
Expand Down
29 changes: 10 additions & 19 deletions driver_vrinputemulator/src/driver_deviceinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,23 +73,7 @@ void OpenvrDeviceManipulationInfo::handleNewDevicePose(vr::IVRServerDriverHost*
}
auto serverDriver = CServerDriver::getInstance();
if (serverDriver) {
if (serverDriver->_applyMotionCompensation(newPose, this)) {
/*auto now = std::chrono::duration_cast <std::chrono:: microseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
if (m_lastDriverPoseValid) {
double tdiff = (double)(now - m_lastDriverPoseTime) / 500000.0;
newPose.vecVelocity[0] = (newPose.vecPosition[0] - m_lastDriverPose.vecPosition[0]) / tdiff;
newPose.vecVelocity[1] = (newPose.vecPosition[1] - m_lastDriverPose.vecPosition[1]) / tdiff;
newPose.vecVelocity[2] = (newPose.vecPosition[2] - m_lastDriverPose.vecPosition[2]) / tdiff;
}
m_lastDriverPose = newPose;
m_lastDriverPoseTime = now;
m_lastDriverPoseValid = true;
newPose.vecAcceleration[0] = 0.0;
newPose.vecAcceleration[1] = 0.0;
newPose.vecAcceleration[2] = 0.0;*/
} else {
m_lastDriverPoseValid = false;
}
serverDriver->_applyMotionCompensation(newPose, this);
}
if (m_deviceMode == 2 && !m_redirectSuspended) { // redirect source
if (!_disconnectedMsgSend) {
Expand Down Expand Up @@ -227,7 +211,7 @@ int OpenvrDeviceManipulationInfo::setMotionCompensationMode() {
auto serverDriver = CServerDriver::getInstance();
if (res == 0 && serverDriver) {
_disconnectedMsgSend = false;
serverDriver->_enableMotionCompensation(true);
serverDriver->enableMotionCompensation(true);
m_deviceMode = 5;
}
return 0;
Expand All @@ -248,11 +232,18 @@ int OpenvrDeviceManipulationInfo::_disableOldMode(int newMode) {
if (m_deviceMode == 5) {
auto serverDriver = CServerDriver::getInstance();
if (serverDriver) {
serverDriver->_enableMotionCompensation(false);
serverDriver->enableMotionCompensation(false);
}
} else if (m_deviceMode == 3 || m_deviceMode == 2 || m_deviceMode == 4) {
m_redirectRef->m_deviceMode = 0;
}
if (newMode == 5) {
auto serverDriver = CServerDriver::getInstance();
if (serverDriver) {
serverDriver->disableMotionCompensationOnAllDevices();
serverDriver->enableMotionCompensation(false);
}
}
}
return 0;
}
Expand Down
Loading

0 comments on commit 1dc083e

Please sign in to comment.