mirror of
https://github.com/JulianGro/overte.git
synced 2025-05-04 20:12:37 +02:00
Exploring PID again
This commit is contained in:
parent
a6f7135ad8
commit
63eb57c741
4 changed files with 140 additions and 9 deletions
|
@ -75,9 +75,41 @@ void LODManager::autoAdjustLOD(float realTimeDelta) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto Kp = _pid.x;
|
||||||
|
auto Ki = _pid.y;
|
||||||
|
auto Kd = _pid.z;
|
||||||
|
|
||||||
float oldOctreeSizeScale = _octreeSizeScale;
|
float oldOctreeSizeScale = _octreeSizeScale;
|
||||||
|
float oldSolidAngle = getSolidAngle();
|
||||||
|
|
||||||
|
float targetFPS = getLODDecreaseFPS();
|
||||||
|
float targetPeriod = 1.0f / targetFPS;
|
||||||
|
|
||||||
float currentFPS = (float)MSECS_PER_SECOND / _avgRenderTime;
|
float currentFPS = (float)MSECS_PER_SECOND / _avgRenderTime;
|
||||||
|
static uint64_t lastTime = usecTimestampNow();
|
||||||
uint64_t now = 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 (currentFPS < getLODDecreaseFPS()) {
|
||||||
if (now > _decreaseFPSExpiry) {
|
if (now > _decreaseFPSExpiry) {
|
||||||
_decreaseFPSExpiry = now + LOD_AUTO_ADJUST_PERIOD;
|
_decreaseFPSExpiry = now + LOD_AUTO_ADJUST_PERIOD;
|
||||||
|
@ -123,7 +155,7 @@ void LODManager::autoAdjustLOD(float realTimeDelta) {
|
||||||
_increaseFPSExpiry = now + LOD_AUTO_ADJUST_PERIOD;
|
_increaseFPSExpiry = now + LOD_AUTO_ADJUST_PERIOD;
|
||||||
_decreaseFPSExpiry = _increaseFPSExpiry;
|
_decreaseFPSExpiry = _increaseFPSExpiry;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
if (oldOctreeSizeScale != _octreeSizeScale) {
|
if (oldOctreeSizeScale != _octreeSizeScale) {
|
||||||
auto lodToolsDialog = DependencyManager::get<DialogsManager>()->getLodToolsDialog();
|
auto lodToolsDialog = DependencyManager::get<DialogsManager>()->getLodToolsDialog();
|
||||||
if (lodToolsDialog) {
|
if (lodToolsDialog) {
|
||||||
|
@ -243,7 +275,7 @@ bool LODManager::shouldRender(const RenderArgs* args, const AABox& bounds) {
|
||||||
auto pos = args->getViewFrustum().getPosition() - bounds.calcCenter();
|
auto pos = args->getViewFrustum().getPosition() - bounds.calcCenter();
|
||||||
auto dim = bounds.getDimensions();
|
auto dim = bounds.getDimensions();
|
||||||
auto halfTanSq = 0.25f * glm::dot(dim, dim) / glm::dot(pos, pos);
|
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();
|
bool isHMDMode = qApp->isHMDMode();
|
||||||
|
|
||||||
float maxFPS = isHMDMode ? MAX_HMD_FPS : MAX_DESKTOP_FPS;
|
float maxFPS = isHMDMode ? MAX_HMD_FPS : MAX_DESKTOP_FPS;
|
||||||
float desiredFPS = maxFPS - THRASHING_DIFFERENCE;
|
float desiredFPS = maxFPS /* - THRASHING_DIFFERENCE*/;
|
||||||
|
|
||||||
if (!isLowestValue) {
|
if (!isLowestValue) {
|
||||||
float calculatedFPS = (maxFPS - (maxFPS * quality)) - THRASHING_DIFFERENCE;
|
float calculatedFPS = (maxFPS - (maxFPS * quality))/* - THRASHING_DIFFERENCE*/;
|
||||||
desiredFPS = calculatedFPS < MIN_FPS ? MIN_FPS : calculatedFPS;
|
desiredFPS = calculatedFPS < MIN_FPS ? MIN_FPS : calculatedFPS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,14 +347,15 @@ float LODManager::getWorldDetailQuality() const {
|
||||||
increaseFPS = getDesktopLODDecreaseFPS();
|
increaseFPS = getDesktopLODDecreaseFPS();
|
||||||
}
|
}
|
||||||
float maxFPS = inHMD ? MAX_HMD_FPS : MAX_DESKTOP_FPS;
|
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;
|
return LOW;
|
||||||
}
|
}
|
||||||
else if (percentage >= LOW) {
|
else if (percentage <= MEDIUM) {
|
||||||
return MEDIUM;
|
return MEDIUM;
|
||||||
}
|
}
|
||||||
|
|
||||||
return HIGH;
|
return HIGH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -334,3 +367,29 @@ float LODManager::getSolidAngleHalfTan() const {
|
||||||
float LODManager::getSolidAngle() const {
|
float LODManager::getSolidAngle() const {
|
||||||
return glm::degrees(2.0 * atan(getSolidAngleHalfTan()));
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -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_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_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 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_DESKTOP_FPS = 61.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_HMD_FPS = 91.0f; // this is essentially, V-synch - 1 fps
|
||||||
const float INCREASE_LOD_GAP_FPS = 10.0f; // 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).
|
// 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 solidAngleHalfTan READ getSolidAngleHalfTan)
|
||||||
Q_PROPERTY(float solidAngle READ getSolidAngle)
|
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:
|
public:
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
|
@ -190,6 +196,15 @@ public:
|
||||||
float getSolidAngleHalfTan() const;
|
float getSolidAngleHalfTan() const;
|
||||||
float getSolidAngle() 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:
|
signals:
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
|
@ -222,6 +237,8 @@ private:
|
||||||
float _octreeSizeScale = DEFAULT_OCTREE_SIZE_SCALE;
|
float _octreeSizeScale = DEFAULT_OCTREE_SIZE_SCALE;
|
||||||
int _boundaryLevelAdjust = 0;
|
int _boundaryLevelAdjust = 0;
|
||||||
|
|
||||||
|
glm::vec4 _pid{ 0.1f, 0.0f, 0.0f, 3.0f };
|
||||||
|
|
||||||
uint64_t _decreaseFPSExpiry { 0 };
|
uint64_t _decreaseFPSExpiry { 0 };
|
||||||
uint64_t _increaseFPSExpiry { 0 };
|
uint64_t _increaseFPSExpiry { 0 };
|
||||||
};
|
};
|
||||||
|
|
|
@ -81,6 +81,7 @@ namespace render {
|
||||||
_context(context),
|
_context(context),
|
||||||
_sizeScale(sizeScale),
|
_sizeScale(sizeScale),
|
||||||
_solidAngleHalfTan(solidAngleHalfTan),
|
_solidAngleHalfTan(solidAngleHalfTan),
|
||||||
|
_solidAngleHalfTanSq(solidAngleHalfTan * solidAngleHalfTan),
|
||||||
_boundaryLevelAdjust(boundaryLevelAdjust),
|
_boundaryLevelAdjust(boundaryLevelAdjust),
|
||||||
_renderMode(renderMode),
|
_renderMode(renderMode),
|
||||||
_displayMode(displayMode),
|
_displayMode(displayMode),
|
||||||
|
@ -111,6 +112,7 @@ namespace render {
|
||||||
float _sizeScale { 1.0f };
|
float _sizeScale { 1.0f };
|
||||||
int _boundaryLevelAdjust { 0 };
|
int _boundaryLevelAdjust { 0 };
|
||||||
float _solidAngleHalfTan{ 0.1f };
|
float _solidAngleHalfTan{ 0.1f };
|
||||||
|
float _solidAngleHalfTanSq{ _solidAngleHalfTan * _solidAngleHalfTan };
|
||||||
|
|
||||||
RenderMode _renderMode { DEFAULT_RENDER_MODE };
|
RenderMode _renderMode { DEFAULT_RENDER_MODE };
|
||||||
DisplayMode _displayMode { MONO };
|
DisplayMode _displayMode { MONO };
|
||||||
|
|
|
@ -78,6 +78,59 @@ Item {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
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 {
|
Column {
|
||||||
|
|
Loading…
Reference in a new issue