From 63eb57c741c352e86caaa59515e203a3e8f6e13c Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 28 Aug 2018 08:58:25 -0700 Subject: [PATCH] Exploring PID again --- interface/src/LODManager.cpp | 73 +++++++++++++++++++--- interface/src/LODManager.h | 21 ++++++- libraries/render/src/render/Args.h | 2 + scripts/developer/utilities/render/lod.qml | 53 ++++++++++++++++ 4 files changed, 140 insertions(+), 9 deletions(-) diff --git a/interface/src/LODManager.cpp b/interface/src/LODManager.cpp index cd692bccf0..91a547cf31 100644 --- a/interface/src/LODManager.cpp +++ b/interface/src/LODManager.cpp @@ -75,9 +75,41 @@ void LODManager::autoAdjustLOD(float realTimeDelta) { return; } + auto Kp = _pid.x; + auto Ki = _pid.y; + auto Kd = _pid.z; + float oldOctreeSizeScale = _octreeSizeScale; + float oldSolidAngle = getSolidAngle(); + + float targetFPS = getLODDecreaseFPS(); + float targetPeriod = 1.0f / targetFPS; + float currentFPS = (float)MSECS_PER_SECOND / _avgRenderTime; + static uint64_t lastTime = usecTimestampNow(); uint64_t now = usecTimestampNow(); + auto dt = (float) ((now - lastTime) / double(USECS_PER_MSEC)); + if (dt < targetPeriod * _pid.w) return; + + float deltaFPS = currentFPS - getLODDecreaseFPS(); + + lastTime = now; + auto previous_error = 0.f; + auto integral = 0.f; + + auto error = getLODDecreaseFPS() - currentFPS; + integral = integral + error * dt; + auto derivative = (error - previous_error) / dt; + auto output = Kp * error + Ki * integral + Kd * derivative; + previous_error = error; + + auto newSolidAngle = std::max( 0.1f, std::min(output, 45.f)); + + auto halTan = glm::tan(glm::radians(newSolidAngle * 0.5f)); + + auto octreeSizeScale = TREE_SCALE * OCTREE_TO_MESH_RATIO / halTan; + _octreeSizeScale = octreeSizeScale; +/* if (currentFPS < getLODDecreaseFPS()) { if (now > _decreaseFPSExpiry) { _decreaseFPSExpiry = now + LOD_AUTO_ADJUST_PERIOD; @@ -123,7 +155,7 @@ void LODManager::autoAdjustLOD(float realTimeDelta) { _increaseFPSExpiry = now + LOD_AUTO_ADJUST_PERIOD; _decreaseFPSExpiry = _increaseFPSExpiry; } - +*/ if (oldOctreeSizeScale != _octreeSizeScale) { auto lodToolsDialog = DependencyManager::get()->getLodToolsDialog(); if (lodToolsDialog) { @@ -243,7 +275,7 @@ bool LODManager::shouldRender(const RenderArgs* args, const AABox& bounds) { auto pos = args->getViewFrustum().getPosition() - bounds.calcCenter(); auto dim = bounds.getDimensions(); auto halfTanSq = 0.25f * glm::dot(dim, dim) / glm::dot(pos, pos); - return (halfTanSq >= args->_solidAngleHalfTan * args->_solidAngleHalfTan); + return (halfTanSq >= args->_solidAngleHalfTanSq); }; @@ -279,10 +311,10 @@ void LODManager::setWorldDetailQuality(float quality) { bool isHMDMode = qApp->isHMDMode(); float maxFPS = isHMDMode ? MAX_HMD_FPS : MAX_DESKTOP_FPS; - float desiredFPS = maxFPS - THRASHING_DIFFERENCE; + float desiredFPS = maxFPS /* - THRASHING_DIFFERENCE*/; if (!isLowestValue) { - float calculatedFPS = (maxFPS - (maxFPS * quality)) - THRASHING_DIFFERENCE; + float calculatedFPS = (maxFPS - (maxFPS * quality))/* - THRASHING_DIFFERENCE*/; desiredFPS = calculatedFPS < MIN_FPS ? MIN_FPS : calculatedFPS; } @@ -315,14 +347,15 @@ float LODManager::getWorldDetailQuality() const { increaseFPS = getDesktopLODDecreaseFPS(); } float maxFPS = inHMD ? MAX_HMD_FPS : MAX_DESKTOP_FPS; - float percentage = increaseFPS / maxFPS; + float percentage = 1.0 - increaseFPS / maxFPS; - if (percentage >= HIGH) { + if (percentage <= LOW) { return LOW; } - else if (percentage >= LOW) { + else if (percentage <= MEDIUM) { return MEDIUM; } + return HIGH; } @@ -334,3 +367,29 @@ float LODManager::getSolidAngleHalfTan() const { float LODManager::getSolidAngle() const { return glm::degrees(2.0 * atan(getSolidAngleHalfTan())); } + + +float LODManager::getPidKp() const { + return _pid.x; +} +float LODManager::getPidKi() const { + return _pid.y; +} +float LODManager::getPidKd() const { + return _pid.z; +} +float LODManager::getPidT() const { + return _pid.w; +} +void LODManager::setPidKp(float k) { + _pid.x = k; +} +void LODManager::setPidKi(float k) { + _pid.y = k; +} +void LODManager::setPidKd(float k) { + _pid.z = k; +} +void LODManager::setPidT(float t) { + _pid.w = t; +} diff --git a/interface/src/LODManager.h b/interface/src/LODManager.h index 340292c579..2251281ae2 100644 --- a/interface/src/LODManager.h +++ b/interface/src/LODManager.h @@ -23,8 +23,8 @@ const float DEFAULT_DESKTOP_LOD_DOWN_FPS = 30.0f; const float DEFAULT_HMD_LOD_DOWN_FPS = 34.0f; const float DEFAULT_DESKTOP_MAX_RENDER_TIME = (float)MSECS_PER_SECOND / DEFAULT_DESKTOP_LOD_DOWN_FPS; // msec const float DEFAULT_HMD_MAX_RENDER_TIME = (float)MSECS_PER_SECOND / DEFAULT_HMD_LOD_DOWN_FPS; // msec -const float MAX_LIKELY_DESKTOP_FPS = 59.0f; // this is essentially, V-synch - 1 fps -const float MAX_LIKELY_HMD_FPS = 74.0f; // this is essentially, V-synch - 1 fps +const float MAX_LIKELY_DESKTOP_FPS = 61.0f; // this is essentially, V-synch - 1 fps +const float MAX_LIKELY_HMD_FPS = 91.0f; // this is essentially, V-synch - 1 fps const float INCREASE_LOD_GAP_FPS = 10.0f; // fps // The default value DEFAULT_OCTREE_SIZE_SCALE means you can be 400 meters away from a 1 meter object in order to see it (which is ~20:20 vision). @@ -72,6 +72,12 @@ class LODManager : public QObject, public Dependency { Q_PROPERTY(float solidAngleHalfTan READ getSolidAngleHalfTan) Q_PROPERTY(float solidAngle READ getSolidAngle) + Q_PROPERTY(float pidKp READ getPidKp WRITE setPidKp) + Q_PROPERTY(float pidKi READ getPidKi WRITE setPidKi) + Q_PROPERTY(float pidKd READ getPidKd WRITE setPidKd) + Q_PROPERTY(float pidT READ getPidT WRITE setPidT) + + public: /**jsdoc @@ -190,6 +196,15 @@ public: float getSolidAngleHalfTan() const; float getSolidAngle() const; + float getPidKp() const; + float getPidKi() const; + float getPidKd() const; + float getPidT() const; + void setPidKp(float k); + void setPidKi(float k); + void setPidKd(float k); + void setPidT(float t); + signals: /**jsdoc @@ -222,6 +237,8 @@ private: float _octreeSizeScale = DEFAULT_OCTREE_SIZE_SCALE; int _boundaryLevelAdjust = 0; + glm::vec4 _pid{ 0.1f, 0.0f, 0.0f, 3.0f }; + uint64_t _decreaseFPSExpiry { 0 }; uint64_t _increaseFPSExpiry { 0 }; }; diff --git a/libraries/render/src/render/Args.h b/libraries/render/src/render/Args.h index a46b914826..589945e9c7 100644 --- a/libraries/render/src/render/Args.h +++ b/libraries/render/src/render/Args.h @@ -81,6 +81,7 @@ namespace render { _context(context), _sizeScale(sizeScale), _solidAngleHalfTan(solidAngleHalfTan), + _solidAngleHalfTanSq(solidAngleHalfTan * solidAngleHalfTan), _boundaryLevelAdjust(boundaryLevelAdjust), _renderMode(renderMode), _displayMode(displayMode), @@ -111,6 +112,7 @@ namespace render { float _sizeScale { 1.0f }; int _boundaryLevelAdjust { 0 }; float _solidAngleHalfTan{ 0.1f }; + float _solidAngleHalfTanSq{ _solidAngleHalfTan * _solidAngleHalfTan }; RenderMode _renderMode { DEFAULT_RENDER_MODE }; DisplayMode _displayMode { MONO }; diff --git a/scripts/developer/utilities/render/lod.qml b/scripts/developer/utilities/render/lod.qml index c08c089bad..742e8c0dc1 100644 --- a/scripts/developer/utilities/render/lod.qml +++ b/scripts/developer/utilities/render/lod.qml @@ -78,6 +78,59 @@ Item { anchors.left: parent.left anchors.right: parent.right } + + RichSlider { + visible: LODManager.automaticLODAdjust + showLabel: true + label: "LOD PID Kp" + valueVar: LODManager["pidKp"] + valueVarSetter: (function (v) { LODManager["pidKp"] = v }) + max: 1.0 + min: 0.0 + integral: false + + anchors.left: parent.left + anchors.right: parent.right + } + RichSlider { + visible: LODManager.automaticLODAdjust + showLabel: true + label: "LOD PID Ki" + valueVar: LODManager["pidKi"] + valueVarSetter: (function (v) { LODManager["pidKi"] = v }) + max: 1.0 + min: 0.0 + integral: false + + anchors.left: parent.left + anchors.right: parent.right + } + RichSlider { + visible: LODManager.automaticLODAdjust + showLabel: true + label: "LOD PID Kd" + valueVar: LODManager["pidKd"] + valueVarSetter: (function (v) { LODManager["pidKd"] = v }) + max: 1.0 + min: 0.0 + integral: false + + anchors.left: parent.left + anchors.right: parent.right + } + RichSlider { + visible: LODManager.automaticLODAdjust + showLabel: true + label: "LOD PID Num T" + valueVar: LODManager["pidT"] + valueVarSetter: (function (v) { LODManager["pidT"] = v }) + max: 5.0 + min: 0.0 + integral: false + + anchors.left: parent.left + anchors.right: parent.right + } } Column {