Picking pid values

This commit is contained in:
Sam Gateau 2018-08-28 16:05:57 -07:00
parent 7dfdc79644
commit 0da22db837
5 changed files with 112 additions and 54 deletions

View file

@ -5987,7 +5987,7 @@ void Application::updateRenderArgs(float deltaTime) {
_viewFrustum.calculate(); _viewFrustum.calculate();
} }
appRenderArgs._renderArgs = RenderArgs(_gpuContext, lodManager->getOctreeSizeScale(), appRenderArgs._renderArgs = RenderArgs(_gpuContext, lodManager->getOctreeSizeScale(),
lodManager->getBoundaryLevelAdjust(), lodManager->getSolidAngleHalfTan(), RenderArgs::DEFAULT_RENDER_MODE, lodManager->getBoundaryLevelAdjust(), lodManager->getLODAngleHalfTan(), RenderArgs::DEFAULT_RENDER_MODE,
RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE); RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE);
appRenderArgs._renderArgs._scene = getMain3DScene(); appRenderArgs._renderArgs._scene = getMain3DScene();

View file

@ -75,12 +75,8 @@ 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 oldSolidAngle = getLODAngleDeg();
float targetFPS = getLODDecreaseFPS(); float targetFPS = getLODDecreaseFPS();
float targetPeriod = 1.0f / targetFPS; float targetPeriod = 1.0f / targetFPS;
@ -89,29 +85,44 @@ void LODManager::autoAdjustLOD(float realTimeDelta) {
static uint64_t lastTime = usecTimestampNow(); static uint64_t lastTime = usecTimestampNow();
uint64_t now = usecTimestampNow(); uint64_t now = usecTimestampNow();
auto dt = (float) ((now - lastTime) / double(USECS_PER_MSEC)); auto dt = (float) ((now - lastTime) / double(USECS_PER_MSEC));
if (dt < targetPeriod * _pid.w) return; if (dt < targetPeriod * _pidCoefs.w) return;
float deltaFPS = currentFPS - getLODDecreaseFPS(); float deltaFPS = currentFPS - getLODDecreaseFPS();
lastTime = now; lastTime = now;
auto previous_error = 0.f; auto previous_error = _pidHistory.x;
auto integral = 0.f; auto previous_integral = _pidHistory.y;
auto error = getLODDecreaseFPS() - currentFPS; auto error = getLODDecreaseFPS() - currentFPS;
integral = integral + error * dt; auto integral = previous_integral + error * dt;
auto derivative = (error - previous_error) / dt; auto derivative = (error - previous_error) / dt;
auto output = Kp * error + Ki * integral + Kd * derivative;
previous_error = error;
_pidHistory.x = error;
_pidHistory.y = integral;
_pidHistory.z = derivative;
auto Kp = _pidCoefs.x;
auto Ki = _pidCoefs.y;
auto Kd = _pidCoefs.z;
_pidOutputs.x = Kp * error;
_pidOutputs.y = Ki * integral;
_pidOutputs.z = Kd * derivative;
auto output = _pidOutputs.x + _pidOutputs.y + _pidOutputs.z;
_pidOutputs.w = output;
auto newSolidAngle = oldSolidAngle + output; auto newSolidAngle = oldSolidAngle + output;
newSolidAngle = std::max( 0.5f, std::min(newSolidAngle, 90.f)); setLODAngleDeg(newSolidAngle);
auto halTan = glm::tan(glm::radians(newSolidAngle * 0.5f)); //newSolidAngle = std::max( 0.5f, std::min(newSolidAngle, 90.f));
auto octreeSizeScale = TREE_SCALE * OCTREE_TO_MESH_RATIO / halTan; //auto halTan = glm::tan(glm::radians(newSolidAngle * 0.5f));
_octreeSizeScale = octreeSizeScale;
//auto octreeSizeScale = TREE_SCALE * OCTREE_TO_MESH_RATIO / halTan;
// _octreeSizeScale = octreeSizeScale;
/* /*
if (currentFPS < getLODDecreaseFPS()) { if (currentFPS < getLODDecreaseFPS()) {
if (now > _decreaseFPSExpiry) { if (now > _decreaseFPSExpiry) {
@ -363,36 +374,57 @@ float LODManager::getWorldDetailQuality() const {
} }
float LODManager::getSolidAngleHalfTan() const { float LODManager::getLODAngleHalfTan() const {
return getPerspectiveAccuracyAngleTan(_octreeSizeScale, _boundaryLevelAdjust); return getPerspectiveAccuracyAngleTan(_octreeSizeScale, _boundaryLevelAdjust);
} }
float LODManager::getLODAngle() const {
float LODManager::getSolidAngle() const { return 2.0f * atan(getLODAngleHalfTan());
return glm::degrees(2.0 * atan(getSolidAngleHalfTan())); }
float LODManager::getLODAngleDeg() const {
return glm::degrees(getLODAngle());
} }
void LODManager::setLODAngleDeg(float lodAngle) {
auto newSolidAngle = std::max(0.5f, std::min(lodAngle, 90.f));
auto halTan = glm::tan(glm::radians(newSolidAngle * 0.5f));
auto octreeSizeScale = TREE_SCALE * OCTREE_TO_MESH_RATIO / halTan;
setOctreeSizeScale(octreeSizeScale);
}
float LODManager::getPidKp() const { float LODManager::getPidKp() const {
return _pid.x; return _pidCoefs.x;
} }
float LODManager::getPidKi() const { float LODManager::getPidKi() const {
return _pid.y; return _pidCoefs.y;
} }
float LODManager::getPidKd() const { float LODManager::getPidKd() const {
return _pid.z; return _pidCoefs.z;
} }
float LODManager::getPidT() const { float LODManager::getPidT() const {
return _pid.w; return _pidCoefs.w;
} }
void LODManager::setPidKp(float k) { void LODManager::setPidKp(float k) {
_pid.x = k; _pidCoefs.x = k;
} }
void LODManager::setPidKi(float k) { void LODManager::setPidKi(float k) {
_pid.y = k; _pidCoefs.y = k;
} }
void LODManager::setPidKd(float k) { void LODManager::setPidKd(float k) {
_pid.z = k; _pidCoefs.z = k;
} }
void LODManager::setPidT(float t) { void LODManager::setPidT(float t) {
_pid.w = t; _pidCoefs.w = t;
}
float LODManager::getPidOp() const {
return _pidOutputs.x;
}
float LODManager::getPidOi() const {
return _pidOutputs.y;
}
float LODManager::getPidOd() const {
return _pidOutputs.z;
}
float LODManager::getPidO() const {
return _pidOutputs.w;
} }

View file

@ -69,14 +69,17 @@ class LODManager : public QObject, public Dependency {
Q_PROPERTY(float worldDetailQuality READ getWorldDetailQuality WRITE setWorldDetailQuality NOTIFY worldDetailQualityChanged) Q_PROPERTY(float worldDetailQuality READ getWorldDetailQuality WRITE setWorldDetailQuality NOTIFY worldDetailQualityChanged)
Q_PROPERTY(float solidAngleHalfTan READ getSolidAngleHalfTan) Q_PROPERTY(float lodAngleDeg READ getLODAngleDeg WRITE setLODAngleDeg)
Q_PROPERTY(float solidAngle READ getSolidAngle)
Q_PROPERTY(float pidKp READ getPidKp WRITE setPidKp) Q_PROPERTY(float pidKp READ getPidKp WRITE setPidKp)
Q_PROPERTY(float pidKi READ getPidKi WRITE setPidKi) Q_PROPERTY(float pidKi READ getPidKi WRITE setPidKi)
Q_PROPERTY(float pidKd READ getPidKd WRITE setPidKd) Q_PROPERTY(float pidKd READ getPidKd WRITE setPidKd)
Q_PROPERTY(float pidT READ getPidT WRITE setPidT) Q_PROPERTY(float pidT READ getPidT WRITE setPidT)
Q_PROPERTY(float pidOp READ getPidOp)
Q_PROPERTY(float pidOi READ getPidOi)
Q_PROPERTY(float pidOd READ getPidOd)
Q_PROPERTY(float pidO READ getPidO)
public: public:
@ -187,14 +190,17 @@ public:
float getAverageRenderTime() const { return _avgRenderTime; }; float getAverageRenderTime() const { return _avgRenderTime; };
float getMaxTheoreticalFPS() const { return (float)MSECS_PER_SECOND / _avgRenderTime; }; float getMaxTheoreticalFPS() const { return (float)MSECS_PER_SECOND / _avgRenderTime; };
float getLODLevel() const; float getLODLevel() const;
void setLODLevel(float level); void setLODLevel(float level);
void setWorldDetailQuality(float quality); void setWorldDetailQuality(float quality);
float getWorldDetailQuality() const; float getWorldDetailQuality() const;
float getSolidAngleHalfTan() const; float getLODAngleDeg() const;
float getSolidAngle() const; void setLODAngleDeg(float lodAngle);
float getLODAngleHalfTan() const;
float getLODAngle() const;
float getPidKp() const; float getPidKp() const;
float getPidKi() const; float getPidKi() const;
@ -205,6 +211,11 @@ public:
void setPidKd(float k); void setPidKd(float k);
void setPidT(float t); void setPidT(float t);
float getPidOp() const;
float getPidOi() const;
float getPidOd() const;
float getPidO() const;
signals: signals:
/**jsdoc /**jsdoc
@ -237,7 +248,9 @@ private:
float _octreeSizeScale = DEFAULT_OCTREE_SIZE_SCALE; float _octreeSizeScale = DEFAULT_OCTREE_SIZE_SCALE;
int _boundaryLevelAdjust = 0; int _boundaryLevelAdjust = 0;
glm::vec4 _pid{ 0.06f, 0.005f, 0.01f, 4.0f }; glm::vec4 _pidCoefs{ 0.1526f, 0.00000015f, 15.f, 4.0f };
glm::vec4 _pidHistory{ 0.0f };
glm::vec4 _pidOutputs{ 0.0f };
uint64_t _decreaseFPSExpiry { 0 }; uint64_t _decreaseFPSExpiry { 0 };
uint64_t _increaseFPSExpiry { 0 }; uint64_t _increaseFPSExpiry { 0 };

View file

@ -29,6 +29,7 @@ Item {
property var labelAreaWidthScale: 0.5 property var labelAreaWidthScale: 0.5
property bool integral: false property bool integral: false
property var numDigits: 2
property var valueVarSetter: defaultSet property var valueVarSetter: defaultSet
property alias valueVar : sliderControl.value property alias valueVar : sliderControl.value
@ -71,7 +72,7 @@ Item {
HifiControls.Label { HifiControls.Label {
id: labelValue id: labelValue
enabled: root.showValue enabled: root.showValue
text: sliderControl.value.toFixed(root.integral ? 0 : 2) text: sliderControl.value.toFixed(root.integral ? 0 : root.numDigits)
anchors.right: labelControl.right anchors.right: labelControl.right
anchors.rightMargin: 5 anchors.rightMargin: 5
anchors.verticalCenter: root.verticalCenter anchors.verticalCenter: root.verticalCenter

View file

@ -68,11 +68,11 @@ Item {
RichSlider { RichSlider {
visible: !LODManager.automaticLODAdjust visible: !LODManager.automaticLODAdjust
showLabel: true showLabel: true
label: "LOD Level" label: "LOD Angle [deg]"
valueVar: LODManager["lodLevel"] valueVar: LODManager["lodAngleDeg"]
valueVarSetter: (function (v) { LODManager["lodLevel"] = v }) valueVarSetter: (function (v) { LODManager["lodAngleDeg"] = v })
max: 1.0 max: 90.0
min: 0.0 min: 0.5
integral: false integral: false
anchors.left: parent.left anchors.left: parent.left
@ -85,9 +85,10 @@ Item {
label: "LOD PID Kp" label: "LOD PID Kp"
valueVar: LODManager["pidKp"] valueVar: LODManager["pidKp"]
valueVarSetter: (function (v) { LODManager["pidKp"] = v }) valueVarSetter: (function (v) { LODManager["pidKp"] = v })
max: 1.0 max: 0.2
min: 0.0 min: 0.0
integral: false integral: false
numDigits: 3
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
@ -98,9 +99,10 @@ Item {
label: "LOD PID Ki" label: "LOD PID Ki"
valueVar: LODManager["pidKi"] valueVar: LODManager["pidKi"]
valueVarSetter: (function (v) { LODManager["pidKi"] = v }) valueVarSetter: (function (v) { LODManager["pidKi"] = v })
max: 0.02 max: 0.000005
min: 0.0 min: 0.0
integral: false integral: false
numDigits: 8
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
@ -111,9 +113,10 @@ Item {
label: "LOD PID Kd" label: "LOD PID Kd"
valueVar: LODManager["pidKd"] valueVar: LODManager["pidKd"]
valueVarSetter: (function (v) { LODManager["pidKd"] = v }) valueVarSetter: (function (v) { LODManager["pidKd"] = v })
max: 0.1 max: 10.0
min: 0.0 min: 0.0
integral: false integral: false
numDigits: 3
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
@ -124,9 +127,9 @@ Item {
label: "LOD PID Num T" label: "LOD PID Num T"
valueVar: LODManager["pidT"] valueVar: LODManager["pidT"]
valueVarSetter: (function (v) { LODManager["pidT"] = v }) valueVarSetter: (function (v) { LODManager["pidT"] = v })
max: 5.0 max: 10.0
min: 0.0 min: 0.0
integral: false integral: true
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
@ -199,31 +202,40 @@ Item {
] ]
} }
PlotPerf { PlotPerf {
title: "LOD" title: "LOD Angle"
height: parent.evalEvenHeight() height: parent.evalEvenHeight()
object: LODManager object: LODManager
valueScale: 0.1 valueScale: 1.0
valueUnit: "" valueUnit: "deg"
plots: [ plots: [
{ {
prop: "lodLevel", prop: "lodAngleDeg",
label: "LOD", label: "LOD Angle",
color: "#9999FF" color: "#9999FF"
} }
] ]
} }
PlotPerf { PlotPerf {
title: "Solid Angle" title: "PID Output"
height: parent.evalEvenHeight() height: parent.evalEvenHeight()
object: LODManager object: LODManager
valueScale: 1.0 valueScale: 1.0
valueUnit: "deg" valueUnit: "deg"
//valueNumDigits: 0
plots: [ plots: [
{ {
prop: "solidAngle", prop: "pidOp",
label: "Solid Angle", label: "Op",
color: "#9999FF" color: "#9999FF"
},
{
prop: "pidOi",
label: "Oi",
color: "#FFFFFF"
},
{
prop: "pidOd",
label: "Od",
color: "#FF6666"
} }
] ]
} }