summaryrefslogtreecommitdiffstats
path: root/Project/ControlElementSolver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Project/ControlElementSolver.cpp')
-rw-r--r--Project/ControlElementSolver.cpp63
1 files changed, 31 insertions, 32 deletions
diff --git a/Project/ControlElementSolver.cpp b/Project/ControlElementSolver.cpp
index d48e39f..e67cb9a 100644
--- a/Project/ControlElementSolver.cpp
+++ b/Project/ControlElementSolver.cpp
@@ -50,12 +50,20 @@ ControlElementSolver::ControlElementSolver(ControlEditor* controlEditor,
fail = true;
failMessage = _("There is no output in the control system.");
}
+ if(!fail) {
+ if(m_inputControl->GetChildList().size() == 0) {
+ fail = true;
+ failMessage = _("Input not connected.");
+ }
+ }
m_timeStep = timeStep;
m_integrationError = integrationError;
- if(!InitializeValues(input, startAllZero)) {
- fail = true;
- failMessage = _("It was not possible to initialize the control system.");
+ if(!fail) {
+ if(!InitializeValues(input, startAllZero)) {
+ fail = true;
+ failMessage = _("It was not possible to initialize the control system.");
+ }
}
if(fail) {
@@ -78,12 +86,7 @@ bool ControlElementSolver::InitializeValues(double input, bool startAllZero)
auto tfList = m_ctrlContainer->GetTFList();
for(auto it = tfList.begin(), itEnd = tfList.end(); it != itEnd; ++it) {
TransferFunction* tf = *it;
- tf->CalculateSpaceState(m_timeStep, m_integrationError);
- }
- auto rateLimiterList = m_ctrlContainer->GetRateLimiterList();
- for(auto it = rateLimiterList.begin(), itEnd = rateLimiterList.end(); it != itEnd; ++it) {
- RateLimiter* rl = *it;
- rl->SetTimeStep(m_timeStep);
+ tf->CalculateSpaceState(100, m_integrationError);
}
auto connectionLineList = m_ctrlContainer->GetConnectionLineList();
for(auto it = connectionLineList.begin(), itEnd = connectionLineList.end(); it != itEnd; ++it) {
@@ -93,39 +96,37 @@ bool ControlElementSolver::InitializeValues(double input, bool startAllZero)
}
if(!startAllZero) {
- // double origTimeStep = m_timeStep;
+ double origTimeStep = m_timeStep;
+ double minStep = m_timeStep / 10;
+ double maxStep = m_timeStep * 10;
// Calculate the steady-state results according to the input.
double minError = 1e-7 * m_timeStep;
- int minIteration = 20;
int maxIteration = 100 / m_timeStep;
- //double timeStep = 0.1; // Initial value is the maximum step value.
- /*
- // Get the minimum time step
- for(auto it = tfList.begin(), itEnd = tfList.end(); it != itEnd; ++it) {
- TransferFunction* tf = *it;
- std::vector<double> num = tf->GetNumerator();
- std::vector<double> den = tf->GetDenominator();
- for(unsigned int i = 0; i < num.size(); ++i) {
- if(num[i] < timeStep) timeStep = num[i];
- }
- for(unsigned int i = 0; i < den.size(); ++i) {
- if(den[i] < timeStep) timeStep = den[i];
- }
- }
- m_timeStep = timeStep;*/
double prevSol = 0.0;
double currentSol = 1.0;
+ double error = 1.0;
+ double prevError = 1.0;
int numIt = 0;
- while(std::abs(prevSol - currentSol) > minError || numIt <= minIteration) {
+ while(error > minError) {
prevSol = currentSol;
+ prevError = error;
SolveNextStep(input);
currentSol = GetLastSolution();
numIt++;
+ error = std::abs(prevSol - currentSol);
+ if(std::abs(error - prevError) < 1e-1) {
+ if(m_timeStep < maxStep) {
+ m_timeStep *= 1.5;
+ }
+ } else if(std::abs(error - prevError) > 10) {
+ if(m_timeStep > minStep) {
+ m_timeStep /= 1.5;
+ }
+ }
if(numIt >= maxIteration) return false;
}
- wxMessageBox(wxString::Format("%d\n%e\n%f", numIt, minError,currentSol));
- // m_timeStep = origTimeStep;
+ m_timeStep = origTimeStep;
m_solutions.clear();
}
@@ -168,9 +169,7 @@ void ControlElementSolver::SolveNextStep(double input)
ConnectionLine* currentLine = firstConn;
while(currentLine) {
- // ConnectionLine* lastLine = currentLine;
currentLine = SolveNextElement(currentLine);
- // if(!currentLine) m_solutions.push_back(lastLine->GetValue());
}
bool haveUnsolvedElement = true;
@@ -224,7 +223,7 @@ ConnectionLine* ControlElementSolver::SolveNextElement(ConnectionLine* currentLi
ControlElement* element = static_cast<ControlElement*>(*it);
// Solve the unsolved parent.
if(!element->IsSolved()) {
- if(!element->Solve(currentLine->GetValue())) return NULL;
+ if(!element->Solve(currentLine->GetValue(), m_timeStep)) return NULL;
element->SetSolved();
// Get the output node (must have one or will result NULL).