summaryrefslogtreecommitdiffstats
path: root/Project/ControlElementSolver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Project/ControlElementSolver.cpp')
-rw-r--r--Project/ControlElementSolver.cpp114
1 files changed, 99 insertions, 15 deletions
diff --git a/Project/ControlElementSolver.cpp b/Project/ControlElementSolver.cpp
index 799ca57..d1c9b26 100644
--- a/Project/ControlElementSolver.cpp
+++ b/Project/ControlElementSolver.cpp
@@ -13,12 +13,15 @@
#include "Sum.h"
#include "TransferFunction.h"
-ControlElementSolver::ControlElementSolver(ControlEditor* controlEditor, double timeStep, bool startAllZero, double input)
+ControlElementSolver::ControlElementSolver(ControlEditor* controlEditor,
+ double timeStep,
+ bool startAllZero,
+ double input)
{
m_ctrlContainer = new ControlElementContainer();
m_ctrlContainer->FillContainer(controlEditor);
-
- //Check if the sistem have one input and one output
+
+ // Check if the sistem have one input and one output
bool fail = false;
wxString failMessage = "";
auto ioList = m_ctrlContainer->GetIOControlList();
@@ -33,8 +36,7 @@ ControlElementSolver::ControlElementSolver(ControlEditor* controlEditor, double
if(io->GetType() == Node::NODE_OUT) {
m_inputControl = io;
haveInput = true;
- }
- else if(io->GetType() == Node::NODE_IN) {
+ } else if(io->GetType() == Node::NODE_IN) {
m_outputControl = io;
haveOutput = true;
}
@@ -47,28 +49,110 @@ ControlElementSolver::ControlElementSolver(ControlEditor* controlEditor, double
fail = true;
failMessage = _("There is no output in the control system.");
}
-
+
if(fail) {
wxMessageDialog msgDialog(controlEditor, failMessage, _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
msgDialog.ShowModal();
}
-
+
m_timeStep = timeStep;
if(!startAllZero) InitializeValues(input);
}
-void ControlElementSolver::InitializeValues(double input)
-{
-
-}
-
+void ControlElementSolver::InitializeValues(double input) {}
void ControlElementSolver::SolveNextStep(double input)
{
+ // Set all elements as not solved
+ auto elementList = m_ctrlContainer->GetControlElementsList();
+ for(auto it = elementList.begin(), itEnd = elementList.end(); it != itEnd; ++it) {
+ ControlElement* element = *it;
+ element->SetSolved(false);
+ }
auto connectionLineList = m_ctrlContainer->GetConnectionLineList();
for(auto it = connectionLineList.begin(), itEnd = connectionLineList.end(); it != itEnd; ++it) {
ConnectionLine* cLine = *it;
cLine->SetSolved(false);
}
- // Get first node (connected with input)
- ConnectionLine
-} \ No newline at end of file
+
+ // Get first node and set input value on connected lines
+ ConnectionLine* firstConn = static_cast<ConnectionLine*>(m_inputControl->GetChildList()[0]);
+ m_inputControl->SetSolved();
+ firstConn->SetValue(input);
+ firstConn->SetSolved();
+ FillAllConnectedChildren(firstConn);
+
+ // Set value to the connected lines in constants
+ auto constantList = m_ctrlContainer->GetConstantList();
+ for(auto it = constantList.begin(), itEnd = constantList.end(); it != itEnd; ++it) {
+ Constant* constant = *it;
+ constant->SetSolved();
+ ConnectionLine* child = static_cast<ConnectionLine*>(constant->GetChildList()[0]);
+ child->SetValue(constant->GetValue());
+ child->SetSolved();
+ FillAllConnectedChildren(child);
+ }
+
+ ConnectionLine* currentLine = firstConn;
+ while(currentLine) {
+ wxMessageBox(wxString::Format("%d", currentLine->GetID()));
+ currentLine = SolveNextElement(currentLine);
+ }
+}
+
+void ControlElementSolver::FillAllConnectedChildren(ConnectionLine* parent)
+{
+ auto childList = parent->GetLineChildList();
+ for(auto it = childList.begin(), itEnd = childList.end(); it != itEnd; ++it) {
+ ConnectionLine* child = *it;
+ child->SetValue(parent->GetValue());
+ child->SetSolved();
+ FillAllConnectedChildren(child);
+ }
+}
+
+ConnectionLine* ControlElementSolver::SolveNextElement(ConnectionLine* currentLine)
+{
+ auto parentList = currentLine->GetParentList();
+ for(auto it = parentList.begin(), itEnd = parentList.end(); it != itEnd; ++it) {
+ ControlElement* element = static_cast<ControlElement*>(*it);
+ // Solve the unsolved parent.
+ if(!element->IsSolved()) {
+ if(!element->Solve(currentLine->GetValue())) return NULL;
+ element->SetSolved();
+
+ // Get the output node (must have one or will result NULL).
+ Node* outNode = NULL;
+ auto nodeList = element->GetNodeList();
+ for(auto itN = nodeList.begin(), itNEnd = nodeList.end(); itN != itNEnd; ++itN) {
+ Node* node = *itN;
+ if(node->GetNodeType() == Node::NODE_OUT)
+ outNode = node;
+ }
+ if(!outNode) return NULL;
+
+ // Set connection line value associated with the output node.
+ auto childList = element->GetChildList();
+ for(auto itC = childList.begin(), itCEnd = childList.end(); itC != itCEnd; ++itC) {
+ ConnectionLine* cLine = static_cast<ConnectionLine*>(*itC);
+ if(!cLine->IsSolved()) { // Only check unsolved lines
+ // Check if the connection line have the output node on the list
+ auto lineNodeList = cLine->GetNodeList();
+ for(auto itCN = nodeList.begin(), itCNEnd = nodeList.end(); itCN != itCNEnd; ++itCN) {
+ Node* childNode = *itCN;
+ if(childNode == outNode) {
+ // Check if the line connect two elements, otherwise return NULL
+ if(cLine->GetType() != ConnectionLine::ELEMENT_ELEMENT) return NULL;
+
+ // Set the connection line value and return it.
+ cLine->SetValue(element->GetOutput());
+ cLine->SetSolved();
+ FillAllConnectedChildren(cLine);
+ return cLine;
+ }
+ }
+ }
+ }
+ }
+ }
+ return NULL;
+}