diff options
author | Thales Lima Oliveira <thaleslima.ufu@gmail.com> | 2017-05-06 18:28:23 -0300 |
---|---|---|
committer | Thales Lima Oliveira <thaleslima.ufu@gmail.com> | 2017-05-06 18:28:23 -0300 |
commit | 74d795cb074b6ae9aa93bcfacee8995d7e6d5945 (patch) | |
tree | ea56758240928de036e9632dde2fb94bb634ba08 | |
parent | 412ddd0fa4a6e32651619897c8606d4cbaaa1ffa (diff) | |
download | PSP.git-74d795cb074b6ae9aa93bcfacee8995d7e6d5945.tar.gz PSP.git-74d795cb074b6ae9aa93bcfacee8995d7e6d5945.tar.xz PSP.git-74d795cb074b6ae9aa93bcfacee8995d7e6d5945.zip |
Streight control solver implemented
Buggy, running 2x... Why??
-rw-r--r-- | Project/ConnectionLine.h | 4 | ||||
-rw-r--r-- | Project/ControlEditor.cpp | 2 | ||||
-rw-r--r-- | Project/ControlElement.h | 11 | ||||
-rw-r--r-- | Project/ControlElementSolver.cpp | 114 | ||||
-rw-r--r-- | Project/ControlElementSolver.h | 16 | ||||
-rw-r--r-- | Project/Project.mk | 2 |
6 files changed, 117 insertions, 32 deletions
diff --git a/Project/ConnectionLine.h b/Project/ConnectionLine.h index 8000cfa..98e3098 100644 --- a/Project/ConnectionLine.h +++ b/Project/ConnectionLine.h @@ -30,9 +30,6 @@ class ConnectionLine : public ControlElement virtual std::vector<ConnectionLine*> GetLineChildList() const; - virtual bool IsSolved() const { return m_solved; } - virtual SetSolved(bool solved) { m_solved = solved; } - virtual double GetValue() const { return m_value; } virtual void SetValue(double value) { m_value = value; } @@ -46,7 +43,6 @@ class ConnectionLine : public ControlElement ConnectionLine* m_parentLine = NULL; double m_value; - bool m_solved = false; }; #endif // CONNECTIONLINE_H diff --git a/Project/ControlEditor.cpp b/Project/ControlEditor.cpp index 5fbd60e..0780590 100644 --- a/Project/ControlEditor.cpp +++ b/Project/ControlEditor.cpp @@ -622,6 +622,8 @@ void ControlEditor::OnKeyDown(wxKeyEvent& event) if(event.ControlDown() && event.ShiftDown()) { ControlElementSolver solver(this, 1e-3, true, 0.0); + solver.SolveNextStep(1.0); + solver.SolveNextStep(1.12); /* std::vector<double> time, sinC, cosC, tgC; for(int i=0; i<360; ++i) { diff --git a/Project/ControlElement.h b/Project/ControlElement.h index 8e377b2..e2b9a29 100644 --- a/Project/ControlElement.h +++ b/Project/ControlElement.h @@ -63,14 +63,13 @@ class ControlElement : public Element std::vector<Node*> GetNodeList() const { return m_nodeList; } virtual void DrawNodes() const; - void SetInput(double input) { m_input = input; } - double GetInput() const { return m_input; } - double GetOutput() const { return m_output; } - virtual bool Solve() { return false; } + virtual bool IsSolved() const { return m_solved; } + virtual void SetSolved(bool solved = true) { m_solved = solved; } + virtual bool Solve(double input) { return true; } + virtual double GetOutput() const { return m_output; } protected: std::vector<Node*> m_nodeList; - - double m_input = 0.0; + bool m_solved = false; double m_output = 0.0; }; 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; +} diff --git a/Project/ControlElementSolver.h b/Project/ControlElementSolver.h index 47838d7..9ca6e02 100644 --- a/Project/ControlElementSolver.h +++ b/Project/ControlElementSolver.h @@ -1,7 +1,7 @@ #ifndef CONTROLELEMENTSOLVER_H #define CONTROLELEMENTSOLVER_H -#include <stddef.h> // NULL definition +#include <stddef.h> // NULL definition #include <vector> class ControlElementContainer; @@ -21,19 +21,23 @@ class ControlElementSolver { public: ControlElementSolver() {} - ControlElementSolver(ControlEditor* controlEditor, double timeStep = 1e-3, bool startAllZero = false, double input = 0.0); + ControlElementSolver(ControlEditor* controlEditor, + double timeStep = 1e-3, + bool startAllZero = false, + double input = 0.0); ~ControlElementSolver() {} - virtual void InitializeValues(double input); virtual void SolveNextStep(double input); virtual std::vector<double> GetSolutions() { return m_solutions; } - virtual double GetLastSolution() {return m_solutions[m_solutions.size() - 1];} - + virtual double GetLastSolution() { return m_solutions[m_solutions.size() - 1]; } protected: + void FillAllConnectedChildren(ConnectionLine* parent); + ConnectionLine* SolveNextElement(ConnectionLine* currentLine); + ControlElementContainer* m_ctrlContainer = NULL; double m_timeStep; std::vector<double> m_solutions; - + IOControl* m_inputControl = NULL; IOControl* m_outputControl = NULL; }; diff --git a/Project/Project.mk b/Project/Project.mk index 07076f7..8d02db8 100644 --- a/Project/Project.mk +++ b/Project/Project.mk @@ -13,7 +13,7 @@ CurrentFileName := CurrentFilePath := CurrentFileFullPath := User :=NDSE-69 -Date :=04/05/2017 +Date :=06/05/2017 CodeLitePath :="C:/Program Files/CodeLite" LinkerName :=C:/TDM-GCC-64/bin/g++.exe SharedObjectLinkerName :=C:/TDM-GCC-64/bin/g++.exe -shared -fPIC |