From 412ddd0fa4a6e32651619897c8606d4cbaaa1ffa Mon Sep 17 00:00:00 2001 From: Thales Lima Oliveira Date: Thu, 4 May 2017 17:03:19 -0300 Subject: Control solver class created Just the basics methods implemented --- Project/ConnectionLine.h | 9 +++++ Project/ControlEditor.cpp | 7 +++- Project/ControlEditor.h | 2 ++ Project/ControlElement.h | 32 ++++++++--------- Project/ControlElementSolver.cpp | 74 ++++++++++++++++++++++++++++++++++++++++ Project/ControlElementSolver.h | 41 ++++++++++++++++++++++ Project/IOControl.h | 1 + Project/Project.mk | 16 ++++++--- Project/Project.project | 2 ++ Project/Project.txt | 2 +- 10 files changed, 164 insertions(+), 22 deletions(-) create mode 100644 Project/ControlElementSolver.cpp create mode 100644 Project/ControlElementSolver.h (limited to 'Project') diff --git a/Project/ConnectionLine.h b/Project/ConnectionLine.h index e9d238a..8000cfa 100644 --- a/Project/ConnectionLine.h +++ b/Project/ConnectionLine.h @@ -29,6 +29,12 @@ class ConnectionLine : public ControlElement virtual bool SetParentLine(ConnectionLine* parent); virtual std::vector 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; } protected: double m_lineOffset = 0.0; @@ -38,6 +44,9 @@ class ConnectionLine : public ControlElement ConnectionLineType m_type = ELEMENT_ELEMENT; 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 a9d0213..5fbd60e 100644 --- a/Project/ControlEditor.cpp +++ b/Project/ControlEditor.cpp @@ -13,6 +13,8 @@ #include "Constant.h" #include "Gain.h" +#include "ControlElementSolver.h" + #include "ChartView.h" #include "ElementPlotData.h" @@ -618,6 +620,9 @@ void ControlEditor::OnKeyDown(wxKeyEvent& event) { //tests if(event.ControlDown() && event.ShiftDown()) { + + ControlElementSolver solver(this, 1e-3, true, 0.0); + /* std::vector time, sinC, cosC, tgC; for(int i=0; i<360; ++i) { time.push_back(i); @@ -642,7 +647,7 @@ void ControlEditor::OnKeyDown(wxKeyEvent& event) epdList.push_back(curve3Data); ChartView* cView = new ChartView(this, epdList, time); - cView->Show(); + cView->Show();*/ } } } diff --git a/Project/ControlEditor.h b/Project/ControlEditor.h index 232ebd8..9dd4e38 100644 --- a/Project/ControlEditor.h +++ b/Project/ControlEditor.h @@ -25,6 +25,8 @@ class Exponential; class Constant; class Gain; +class ControlElementSolver; + class ChartView; class ElementDataObject; diff --git a/Project/ControlElement.h b/Project/ControlElement.h index 1cf4e0b..8e377b2 100644 --- a/Project/ControlElement.h +++ b/Project/ControlElement.h @@ -5,7 +5,7 @@ class Node { -public: + public: enum NodeType { NODE_IN = 0, NODE_OUT }; Node(wxPoint2DDouble position = wxPoint2DDouble(0, 0), NodeType nodeType = NODE_IN, double borderSize = 0.0); @@ -13,39 +13,33 @@ public: wxRect2DDouble GetRect() const { return m_rect; } void SetRect(wxRect2DDouble rect) { m_rect = rect; } - wxPoint2DDouble GetPosition() const; void SetPosition(wxPoint2DDouble position); NodeType GetNodeType() const { return m_nodeType; } void SetNodeType(NodeType nodeType) { m_nodeType = nodeType; } - double GetRadius() const { return m_radius; } std::vector GetInTrianglePts() const { return m_triPts; } - double GetAngle() const { return m_angle; } void SetAngle(double angle) { m_angle = angle; } - void Rotate(bool clockwise = true); - + void RotateTriPt(double angle); void StartMove(wxPoint2DDouble position); void Move(wxPoint2DDouble position); bool Contains(wxPoint2DDouble position) const; - + bool IsConnected() const { return m_connected; } void SetConnected(bool connected = true) { m_connected = connected; } - int GetID() const { return m_id; } void SetID(int id) { m_id = id; } - -protected: + protected: int m_id = -1; - + wxRect2DDouble m_rect; NodeType m_nodeType; - + bool m_connected = false; wxPoint2DDouble m_moveStartPt; @@ -58,7 +52,7 @@ protected: class ControlElement : public Element { -public: + public: ControlElement(int id); ~ControlElement(); @@ -67,11 +61,17 @@ public: void SetNodeList(std::vector nodeList) { m_nodeList = nodeList; } std::vector GetNodeList() const { return m_nodeList; } - virtual void DrawNodes() const; -protected: + void SetInput(double input) { m_input = input; } + double GetInput() const { return m_input; } + double GetOutput() const { return m_output; } + virtual bool Solve() { return false; } + protected: std::vector m_nodeList; + + double m_input = 0.0; + double m_output = 0.0; }; -#endif // CONTROLELEMENT_H +#endif // CONTROLELEMENT_H diff --git a/Project/ControlElementSolver.cpp b/Project/ControlElementSolver.cpp new file mode 100644 index 0000000..799ca57 --- /dev/null +++ b/Project/ControlElementSolver.cpp @@ -0,0 +1,74 @@ +#include "ControlElementSolver.h" + +#include "ControlElementContainer.h" +#include "ControlEditor.h" +#include "ConnectionLine.h" +#include "Constant.h" +#include "Exponential.h" +#include "Gain.h" +#include "IOControl.h" +#include "Limiter.h" +#include "Multiplier.h" +#include "RateLimiter.h" +#include "Sum.h" +#include "TransferFunction.h" + +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 + bool fail = false; + wxString failMessage = ""; + auto ioList = m_ctrlContainer->GetIOControlList(); + if(ioList.size() != 2) { + fail = true; + failMessage = _("The control system must have one input and one output."); + } + bool haveInput, haveOutput; + haveInput = haveOutput = false; + for(auto it = ioList.begin(), itEnd = ioList.end(); it != itEnd; ++it) { + IOControl* io = *it; + if(io->GetType() == Node::NODE_OUT) { + m_inputControl = io; + haveInput = true; + } + else if(io->GetType() == Node::NODE_IN) { + m_outputControl = io; + haveOutput = true; + } + } + if(!fail && !haveInput) { + fail = true; + failMessage = _("There is no input in the control system."); + } + if(!fail && !haveOutput) { + 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::SolveNextStep(double input) +{ + 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 diff --git a/Project/ControlElementSolver.h b/Project/ControlElementSolver.h new file mode 100644 index 0000000..47838d7 --- /dev/null +++ b/Project/ControlElementSolver.h @@ -0,0 +1,41 @@ +#ifndef CONTROLELEMENTSOLVER_H +#define CONTROLELEMENTSOLVER_H + +#include // NULL definition +#include + +class ControlElementContainer; +class ControlEditor; +class ConnectionLine; +class Constant; +class Exponential; +class Gain; +class IOControl; +class Limiter; +class Multiplier; +class RateLimiter; +class Sum; +class TransferFunction; + +class ControlElementSolver +{ + public: + ControlElementSolver() {} + 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 GetSolutions() { return m_solutions; } + virtual double GetLastSolution() {return m_solutions[m_solutions.size() - 1];} + + protected: + ControlElementContainer* m_ctrlContainer = NULL; + double m_timeStep; + std::vector m_solutions; + + IOControl* m_inputControl = NULL; + IOControl* m_outputControl = NULL; +}; + +#endif // CONTROLELEMENTSOLVER_H diff --git a/Project/IOControl.h b/Project/IOControl.h index 7b3f4d0..8a7666f 100644 --- a/Project/IOControl.h +++ b/Project/IOControl.h @@ -35,6 +35,7 @@ class IOControl : public ControlElement virtual IOFlags GetValue() const { return m_value; } virtual void SetValue(IOFlags value); virtual int GetIOFlags() const { return m_ioFlags; } + virtual Node::NodeType GetType() { return m_ioNodeType; } protected: IOFlags m_value; diff --git a/Project/Project.mk b/Project/Project.mk index c43d7d9..07076f7 100644 --- a/Project/Project.mk +++ b/Project/Project.mk @@ -13,7 +13,7 @@ CurrentFileName := CurrentFilePath := CurrentFileFullPath := User :=NDSE-69 -Date :=03/05/2017 +Date :=04/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 @@ -69,9 +69,9 @@ Objects0=$(IntermediateDirectory)/main.cpp$(ObjectSuffix) $(IntermediateDirector $(IntermediateDirectory)/WorkspaceBase.cpp$(ObjectSuffix) $(IntermediateDirectory)/ElementForm.cpp$(ObjectSuffix) $(IntermediateDirectory)/ControlEditorBase.cpp$(ObjectSuffix) $(IntermediateDirectory)/ChartViewBase.cpp$(ObjectSuffix) $(IntermediateDirectory)/Bus.cpp$(ObjectSuffix) $(IntermediateDirectory)/Line.cpp$(ObjectSuffix) $(IntermediateDirectory)/Transformer.cpp$(ObjectSuffix) $(IntermediateDirectory)/Machines.cpp$(ObjectSuffix) $(IntermediateDirectory)/SyncGenerator.cpp$(ObjectSuffix) $(IntermediateDirectory)/IndMotor.cpp$(ObjectSuffix) \ $(IntermediateDirectory)/Branch.cpp$(ObjectSuffix) $(IntermediateDirectory)/SyncMotor.cpp$(ObjectSuffix) $(IntermediateDirectory)/Shunt.cpp$(ObjectSuffix) $(IntermediateDirectory)/Load.cpp$(ObjectSuffix) $(IntermediateDirectory)/Inductor.cpp$(ObjectSuffix) $(IntermediateDirectory)/Capacitor.cpp$(ObjectSuffix) $(IntermediateDirectory)/PowerElement.cpp$(ObjectSuffix) $(IntermediateDirectory)/ElectricCalculation.cpp$(ObjectSuffix) $(IntermediateDirectory)/PowerFlow.cpp$(ObjectSuffix) $(IntermediateDirectory)/Fault.cpp$(ObjectSuffix) \ $(IntermediateDirectory)/Text.cpp$(ObjectSuffix) $(IntermediateDirectory)/GraphicalElement.cpp$(ObjectSuffix) $(IntermediateDirectory)/ControlElement.cpp$(ObjectSuffix) $(IntermediateDirectory)/TransferFunction.cpp$(ObjectSuffix) $(IntermediateDirectory)/ConnectionLine.cpp$(ObjectSuffix) $(IntermediateDirectory)/Sum.cpp$(ObjectSuffix) $(IntermediateDirectory)/Multiplier.cpp$(ObjectSuffix) $(IntermediateDirectory)/Limiter.cpp$(ObjectSuffix) $(IntermediateDirectory)/RateLimiter.cpp$(ObjectSuffix) $(IntermediateDirectory)/Exponential.cpp$(ObjectSuffix) \ - $(IntermediateDirectory)/Constant.cpp$(ObjectSuffix) $(IntermediateDirectory)/Gain.cpp$(ObjectSuffix) $(IntermediateDirectory)/IOControl.cpp$(ObjectSuffix) $(IntermediateDirectory)/ControlElementContainer.cpp$(ObjectSuffix) $(IntermediateDirectory)/wxMathPlot_mathplot.cpp$(ObjectSuffix) $(IntermediateDirectory)/BusForm.cpp$(ObjectSuffix) $(IntermediateDirectory)/GeneratorStabForm.cpp$(ObjectSuffix) $(IntermediateDirectory)/LineForm.cpp$(ObjectSuffix) $(IntermediateDirectory)/SwitchingForm.cpp$(ObjectSuffix) $(IntermediateDirectory)/TransformerForm.cpp$(ObjectSuffix) \ - $(IntermediateDirectory)/LoadForm.cpp$(ObjectSuffix) $(IntermediateDirectory)/ReactiveShuntElementForm.cpp$(ObjectSuffix) $(IntermediateDirectory)/IndMotorForm.cpp$(ObjectSuffix) $(IntermediateDirectory)/SyncMachineForm.cpp$(ObjectSuffix) $(IntermediateDirectory)/TextForm.cpp$(ObjectSuffix) $(IntermediateDirectory)/TransferFunctionForm.cpp$(ObjectSuffix) $(IntermediateDirectory)/SumForm.cpp$(ObjectSuffix) $(IntermediateDirectory)/LimiterForm.cpp$(ObjectSuffix) $(IntermediateDirectory)/RateLimiterForm.cpp$(ObjectSuffix) $(IntermediateDirectory)/ExponentialForm.cpp$(ObjectSuffix) \ - $(IntermediateDirectory)/ConstantForm.cpp$(ObjectSuffix) $(IntermediateDirectory)/GainForm.cpp$(ObjectSuffix) $(IntermediateDirectory)/IOControlForm.cpp$(ObjectSuffix) + $(IntermediateDirectory)/Constant.cpp$(ObjectSuffix) $(IntermediateDirectory)/Gain.cpp$(ObjectSuffix) $(IntermediateDirectory)/IOControl.cpp$(ObjectSuffix) $(IntermediateDirectory)/ControlElementContainer.cpp$(ObjectSuffix) $(IntermediateDirectory)/ControlElementSolver.cpp$(ObjectSuffix) $(IntermediateDirectory)/wxMathPlot_mathplot.cpp$(ObjectSuffix) $(IntermediateDirectory)/BusForm.cpp$(ObjectSuffix) $(IntermediateDirectory)/GeneratorStabForm.cpp$(ObjectSuffix) $(IntermediateDirectory)/LineForm.cpp$(ObjectSuffix) $(IntermediateDirectory)/SwitchingForm.cpp$(ObjectSuffix) \ + $(IntermediateDirectory)/TransformerForm.cpp$(ObjectSuffix) $(IntermediateDirectory)/LoadForm.cpp$(ObjectSuffix) $(IntermediateDirectory)/ReactiveShuntElementForm.cpp$(ObjectSuffix) $(IntermediateDirectory)/IndMotorForm.cpp$(ObjectSuffix) $(IntermediateDirectory)/SyncMachineForm.cpp$(ObjectSuffix) $(IntermediateDirectory)/TextForm.cpp$(ObjectSuffix) $(IntermediateDirectory)/TransferFunctionForm.cpp$(ObjectSuffix) $(IntermediateDirectory)/SumForm.cpp$(ObjectSuffix) $(IntermediateDirectory)/LimiterForm.cpp$(ObjectSuffix) $(IntermediateDirectory)/RateLimiterForm.cpp$(ObjectSuffix) \ + $(IntermediateDirectory)/ExponentialForm.cpp$(ObjectSuffix) $(IntermediateDirectory)/ConstantForm.cpp$(ObjectSuffix) $(IntermediateDirectory)/GainForm.cpp$(ObjectSuffix) $(IntermediateDirectory)/IOControlForm.cpp$(ObjectSuffix) @@ -528,6 +528,14 @@ $(IntermediateDirectory)/ControlElementContainer.cpp$(DependSuffix): ControlElem $(IntermediateDirectory)/ControlElementContainer.cpp$(PreprocessSuffix): ControlElementContainer.cpp $(CXX) $(CXXFLAGS) $(IncludePCH) $(IncludePath) $(PreprocessOnlySwitch) $(OutputSwitch) $(IntermediateDirectory)/ControlElementContainer.cpp$(PreprocessSuffix) ControlElementContainer.cpp +$(IntermediateDirectory)/ControlElementSolver.cpp$(ObjectSuffix): ControlElementSolver.cpp $(IntermediateDirectory)/ControlElementSolver.cpp$(DependSuffix) + $(CXX) $(IncludePCH) $(SourceSwitch) "C:/Users/NDSE-69/Documents/GitHub/PSP/Project/ControlElementSolver.cpp" $(CXXFLAGS) $(ObjectSwitch)$(IntermediateDirectory)/ControlElementSolver.cpp$(ObjectSuffix) $(IncludePath) +$(IntermediateDirectory)/ControlElementSolver.cpp$(DependSuffix): ControlElementSolver.cpp + @$(CXX) $(CXXFLAGS) $(IncludePCH) $(IncludePath) -MG -MP -MT$(IntermediateDirectory)/ControlElementSolver.cpp$(ObjectSuffix) -MF$(IntermediateDirectory)/ControlElementSolver.cpp$(DependSuffix) -MM ControlElementSolver.cpp + +$(IntermediateDirectory)/ControlElementSolver.cpp$(PreprocessSuffix): ControlElementSolver.cpp + $(CXX) $(CXXFLAGS) $(IncludePCH) $(IncludePath) $(PreprocessOnlySwitch) $(OutputSwitch) $(IntermediateDirectory)/ControlElementSolver.cpp$(PreprocessSuffix) ControlElementSolver.cpp + $(IntermediateDirectory)/wxMathPlot_mathplot.cpp$(ObjectSuffix): wxMathPlot/mathplot.cpp $(IntermediateDirectory)/wxMathPlot_mathplot.cpp$(DependSuffix) $(CXX) $(IncludePCH) $(SourceSwitch) "C:/Users/NDSE-69/Documents/GitHub/PSP/Project/wxMathPlot/mathplot.cpp" $(CXXFLAGS) $(ObjectSwitch)$(IntermediateDirectory)/wxMathPlot_mathplot.cpp$(ObjectSuffix) $(IncludePath) $(IntermediateDirectory)/wxMathPlot_mathplot.cpp$(DependSuffix): wxMathPlot/mathplot.cpp diff --git a/Project/Project.project b/Project/Project.project index 6671989..752ee00 100644 --- a/Project/Project.project +++ b/Project/Project.project @@ -49,6 +49,7 @@ + @@ -140,6 +141,7 @@ + diff --git a/Project/Project.txt b/Project/Project.txt index fbf464d..65a2851 100644 --- a/Project/Project.txt +++ b/Project/Project.txt @@ -1 +1 @@ -./Release/main.cpp.o ./Release/win_resources.rc.o ./Release/ElementDataObject.cpp.o ./Release/Element.cpp.o ./Release/ElementPlotData.cpp.o ./Release/ArtMetro.cpp.o ./Release/wxGLString.cpp.o ./Release/MainFrame.cpp.o ./Release/Workspace.cpp.o ./Release/FileHanding.cpp.o ./Release/ControlEditor.cpp.o ./Release/Camera.cpp.o ./Release/ChartView.cpp.o ./Release/MainFrameBitmaps.cpp.o ./Release/WorkspaceBitmaps.cpp.o ./Release/BusFormBitmaps.cpp.o ./Release/ElementFormBitmaps.cpp.o ./Release/ControlEditorBitmaps.cpp.o ./Release/ChartViewBitmaps.cpp.o ./Release/MainFrameBase.cpp.o ./Release/WorkspaceBase.cpp.o ./Release/ElementForm.cpp.o ./Release/ControlEditorBase.cpp.o ./Release/ChartViewBase.cpp.o ./Release/Bus.cpp.o ./Release/Line.cpp.o ./Release/Transformer.cpp.o ./Release/Machines.cpp.o ./Release/SyncGenerator.cpp.o ./Release/IndMotor.cpp.o ./Release/Branch.cpp.o ./Release/SyncMotor.cpp.o ./Release/Shunt.cpp.o ./Release/Load.cpp.o ./Release/Inductor.cpp.o ./Release/Capacitor.cpp.o ./Release/PowerElement.cpp.o ./Release/ElectricCalculation.cpp.o ./Release/PowerFlow.cpp.o ./Release/Fault.cpp.o ./Release/Text.cpp.o ./Release/GraphicalElement.cpp.o ./Release/ControlElement.cpp.o ./Release/TransferFunction.cpp.o ./Release/ConnectionLine.cpp.o ./Release/Sum.cpp.o ./Release/Multiplier.cpp.o ./Release/Limiter.cpp.o ./Release/RateLimiter.cpp.o ./Release/Exponential.cpp.o ./Release/Constant.cpp.o ./Release/Gain.cpp.o ./Release/IOControl.cpp.o ./Release/ControlElementContainer.cpp.o ./Release/wxMathPlot_mathplot.cpp.o ./Release/BusForm.cpp.o ./Release/GeneratorStabForm.cpp.o ./Release/LineForm.cpp.o ./Release/SwitchingForm.cpp.o ./Release/TransformerForm.cpp.o ./Release/LoadForm.cpp.o ./Release/ReactiveShuntElementForm.cpp.o ./Release/IndMotorForm.cpp.o ./Release/SyncMachineForm.cpp.o ./Release/TextForm.cpp.o ./Release/TransferFunctionForm.cpp.o ./Release/SumForm.cpp.o ./Release/LimiterForm.cpp.o ./Release/RateLimiterForm.cpp.o ./Release/ExponentialForm.cpp.o ./Release/ConstantForm.cpp.o ./Release/GainForm.cpp.o ./Release/IOControlForm.cpp.o +./Release/main.cpp.o ./Release/win_resources.rc.o ./Release/ElementDataObject.cpp.o ./Release/Element.cpp.o ./Release/ElementPlotData.cpp.o ./Release/ArtMetro.cpp.o ./Release/wxGLString.cpp.o ./Release/MainFrame.cpp.o ./Release/Workspace.cpp.o ./Release/FileHanding.cpp.o ./Release/ControlEditor.cpp.o ./Release/Camera.cpp.o ./Release/ChartView.cpp.o ./Release/MainFrameBitmaps.cpp.o ./Release/WorkspaceBitmaps.cpp.o ./Release/BusFormBitmaps.cpp.o ./Release/ElementFormBitmaps.cpp.o ./Release/ControlEditorBitmaps.cpp.o ./Release/ChartViewBitmaps.cpp.o ./Release/MainFrameBase.cpp.o ./Release/WorkspaceBase.cpp.o ./Release/ElementForm.cpp.o ./Release/ControlEditorBase.cpp.o ./Release/ChartViewBase.cpp.o ./Release/Bus.cpp.o ./Release/Line.cpp.o ./Release/Transformer.cpp.o ./Release/Machines.cpp.o ./Release/SyncGenerator.cpp.o ./Release/IndMotor.cpp.o ./Release/Branch.cpp.o ./Release/SyncMotor.cpp.o ./Release/Shunt.cpp.o ./Release/Load.cpp.o ./Release/Inductor.cpp.o ./Release/Capacitor.cpp.o ./Release/PowerElement.cpp.o ./Release/ElectricCalculation.cpp.o ./Release/PowerFlow.cpp.o ./Release/Fault.cpp.o ./Release/Text.cpp.o ./Release/GraphicalElement.cpp.o ./Release/ControlElement.cpp.o ./Release/TransferFunction.cpp.o ./Release/ConnectionLine.cpp.o ./Release/Sum.cpp.o ./Release/Multiplier.cpp.o ./Release/Limiter.cpp.o ./Release/RateLimiter.cpp.o ./Release/Exponential.cpp.o ./Release/Constant.cpp.o ./Release/Gain.cpp.o ./Release/IOControl.cpp.o ./Release/ControlElementContainer.cpp.o ./Release/ControlElementSolver.cpp.o ./Release/wxMathPlot_mathplot.cpp.o ./Release/BusForm.cpp.o ./Release/GeneratorStabForm.cpp.o ./Release/LineForm.cpp.o ./Release/SwitchingForm.cpp.o ./Release/TransformerForm.cpp.o ./Release/LoadForm.cpp.o ./Release/ReactiveShuntElementForm.cpp.o ./Release/IndMotorForm.cpp.o ./Release/SyncMachineForm.cpp.o ./Release/TextForm.cpp.o ./Release/TransferFunctionForm.cpp.o ./Release/SumForm.cpp.o ./Release/LimiterForm.cpp.o ./Release/RateLimiterForm.cpp.o ./Release/ExponentialForm.cpp.o ./Release/ConstantForm.cpp.o ./Release/GainForm.cpp.o ./Release/IOControlForm.cpp.o -- cgit From 74d795cb074b6ae9aa93bcfacee8995d7e6d5945 Mon Sep 17 00:00:00 2001 From: Thales Lima Oliveira Date: Sat, 6 May 2017 18:28:23 -0300 Subject: Streight control solver implemented Buggy, running 2x... Why?? --- Project/ConnectionLine.h | 4 -- Project/ControlEditor.cpp | 2 + Project/ControlElement.h | 11 ++-- Project/ControlElementSolver.cpp | 114 +++++++++++++++++++++++++++++++++------ Project/ControlElementSolver.h | 16 +++--- Project/Project.mk | 2 +- 6 files changed, 117 insertions(+), 32 deletions(-) (limited to 'Project') 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 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 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 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 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(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(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(*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(*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 // NULL definition +#include // NULL definition #include 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 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 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 -- cgit From 9fb33a91aa22fbce6d0b74529e07af9f7781b916 Mon Sep 17 00:00:00 2001 From: Thales Lima Oliveira Date: Mon, 8 May 2017 21:43:17 -0300 Subject: Secondary branch, TF and limiter solution much work, such results --- Project/ControlEditor.cpp | 61 ++++++++++++++------- Project/ControlElement.h | 7 ++- Project/ControlElementSolver.cpp | 86 ++++++++++++++++++++++++------ Project/ControlElementSolver.h | 4 +- Project/Limiter.cpp | 9 ++++ Project/Limiter.h | 1 + Project/Project.mk | 2 +- Project/Sum.cpp | 43 +++++++++++++-- Project/Sum.h | 3 ++ Project/TransferFunction.cpp | 112 ++++++++++++++++++++++++++++++++++++++- Project/TransferFunction.h | 31 ++++++++--- 11 files changed, 309 insertions(+), 50 deletions(-) (limited to 'Project') diff --git a/Project/ControlEditor.cpp b/Project/ControlEditor.cpp index 0780590..b4976ad 100644 --- a/Project/ControlEditor.cpp +++ b/Project/ControlEditor.cpp @@ -616,14 +616,41 @@ void ControlEditor::OnKeyDown(wxKeyEvent& event) { RotateSelectedElements(event.GetModifiers() != wxMOD_SHIFT); } break; - case 'L': - { - //tests + case 'L': { + // tests if(event.ControlDown() && event.ShiftDown()) { - - ControlElementSolver solver(this, 1e-3, true, 0.0); - solver.SolveNextStep(1.0); - solver.SolveNextStep(1.12); + double timeStep = 1e-3; + double integrationError = 1e-5; + double simTime = 10.0; + double printStep = 1e-2; + + ControlElementSolver solver(this, timeStep, integrationError, true, 0.0); + + double currentTime = 0.0; + double printTime = 0.0; + std::vector time; + std::vector solution; + while(currentTime <= simTime) { + double input = 0.0; + if(currentTime >= 1.0) input = 1.0; + + solver.SolveNextStep(input); + if(printTime >= printStep) { + time.push_back(currentTime); + solution.push_back(solver.GetLastSolution()); + printTime = 0.0; + } + printTime += timeStep; + currentTime += timeStep; + } + std::vector epdList; + ElementPlotData curve1Data(_("TESTES"), ElementPlotData::CT_BUS); + curve1Data.AddData(solution, _("teste 1")); + epdList.push_back(curve1Data); + + ChartView* cView = new ChartView(this, epdList, time); + cView->Show(); + /* std::vector time, sinC, cosC, tgC; for(int i=0; i<360; ++i) { @@ -633,21 +660,21 @@ void ControlEditor::OnKeyDown(wxKeyEvent& event) tgC.push_back(std::tan(wxDegToRad(i))); } std::vector epdList; - + ElementPlotData curve1Data(_("Func. polinomiais 1"), ElementPlotData::CT_BUS); curve1Data.AddData(sinC, _("seno")); epdList.push_back(curve1Data); - + ElementPlotData curve2Data(_("Func. polinomiais 2"), ElementPlotData::CT_BUS); curve2Data.AddData(tgC, _("tangente")); epdList.push_back(curve2Data); - + ElementPlotData curve3Data(_("Func. polinomiais 3"), ElementPlotData::CT_SYNC_GENERATOR); curve3Data.AddData(sinC, _("seno")); curve3Data.AddData(cosC, _("cosseno")); curve3Data.AddData(tgC, _("tangente")); epdList.push_back(curve3Data); - + ChartView* cView = new ChartView(this, epdList, time); cView->Show();*/ } @@ -775,21 +802,19 @@ void ControlEditor::OnImportClick(wxCommandEvent& event) wxOK | wxCENTRE | wxICON_ERROR); msgDialog.ShowModal(); } - - //Get the highest id number + + // Get the highest id number int majorElementID = 0; for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) { ControlElement* element = *it; - if(element->GetID() > majorElementID) - majorElementID = element->GetID(); + if(element->GetID() > majorElementID) majorElementID = element->GetID(); } for(auto it = m_connectionList.begin(), itEnd = m_connectionList.end(); it != itEnd; ++it) { ConnectionLine* line = *it; - if(line->GetID() > majorElementID) - majorElementID = line->GetID(); + if(line->GetID() > majorElementID) majorElementID = line->GetID(); } m_lastElementID = ++majorElementID; - + Redraw(); event.Skip(); } diff --git a/Project/ControlElement.h b/Project/ControlElement.h index e2b9a29..3744c6f 100644 --- a/Project/ControlElement.h +++ b/Project/ControlElement.h @@ -65,8 +65,13 @@ class ControlElement : public Element virtual bool IsSolved() const { return m_solved; } virtual void SetSolved(bool solved = true) { m_solved = solved; } - virtual bool Solve(double input) { return true; } + virtual bool Solve(double input) + { + m_output = input * 2.0; + return true; + } virtual double GetOutput() const { return m_output; } + virtual void SetOutput(double output) { m_output = output; } protected: std::vector m_nodeList; bool m_solved = false; diff --git a/Project/ControlElementSolver.cpp b/Project/ControlElementSolver.cpp index d1c9b26..42445f4 100644 --- a/Project/ControlElementSolver.cpp +++ b/Project/ControlElementSolver.cpp @@ -15,6 +15,7 @@ ControlElementSolver::ControlElementSolver(ControlEditor* controlEditor, double timeStep, + double integrationError, bool startAllZero, double input) { @@ -56,10 +57,36 @@ ControlElementSolver::ControlElementSolver(ControlEditor* controlEditor, } m_timeStep = timeStep; - if(!startAllZero) InitializeValues(input); + m_integrationError = integrationError; + InitializeValues(input, startAllZero); +} + +void ControlElementSolver::InitializeValues(double input, bool startAllZero) +{ + // Reset Elements values + auto elementList = m_ctrlContainer->GetControlElementsList(); + for(auto it = elementList.begin(), itEnd = elementList.end(); it != itEnd; ++it) { + ControlElement* element = *it; + element->SetSolved(false); + element->SetOutput(0.0); + } + 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 connectionLineList = m_ctrlContainer->GetConnectionLineList(); + for(auto it = connectionLineList.begin(), itEnd = connectionLineList.end(); it != itEnd; ++it) { + ConnectionLine* cLine = *it; + cLine->SetSolved(false); + cLine->SetValue(0.0); + } + + if(!startAllZero) { + // Calculate the steady-state results according to the input. + } } -void ControlElementSolver::InitializeValues(double input) {} void ControlElementSolver::SolveNextStep(double input) { // Set all elements as not solved @@ -73,7 +100,7 @@ void ControlElementSolver::SolveNextStep(double input) ConnectionLine* cLine = *it; cLine->SetSolved(false); } - + // Get first node and set input value on connected lines ConnectionLine* firstConn = static_cast(m_inputControl->GetChildList()[0]); m_inputControl->SetSolved(); @@ -85,17 +112,45 @@ void ControlElementSolver::SolveNextStep(double input) 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(constant->GetChildList()[0]); - child->SetValue(constant->GetValue()); - child->SetSolved(); - FillAllConnectedChildren(child); + if(constant->GetChildList().size() == 1) { + constant->SetSolved(); + ConnectionLine* child = static_cast(constant->GetChildList()[0]); + child->SetValue(constant->GetValue()); + child->SetSolved(); + FillAllConnectedChildren(child); + } } - + ConnectionLine* currentLine = firstConn; while(currentLine) { - wxMessageBox(wxString::Format("%d", currentLine->GetID())); + ConnectionLine* lastLine = currentLine; currentLine = SolveNextElement(currentLine); + if(!currentLine) m_solutions.push_back(lastLine->GetValue()); + } + + bool haveUnsolvedElement = true; + while(haveUnsolvedElement) { + haveUnsolvedElement = false; + // Get the solved line connected with unsolved element (elements not connected in the main branch). + for(auto it = connectionLineList.begin(), itEnd = connectionLineList.end(); it != itEnd; ++it) { + ConnectionLine* cLine = *it; + if(cLine->IsSolved()) { + auto parentList = cLine->GetParentList(); + for(auto itP = parentList.begin(), itPEnd = parentList.end(); itP != itPEnd; ++itP) { + ControlElement* parent = static_cast(*itP); + if(!parent->IsSolved()) { + haveUnsolvedElement = true; + // Solve secondary branch. + currentLine = cLine; + while(currentLine) { + currentLine = SolveNextElement(currentLine); + } + break; + } + } + } + if(haveUnsolvedElement) break; + } } } @@ -119,22 +174,21 @@ ConnectionLine* ControlElementSolver::SolveNextElement(ConnectionLine* currentLi 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(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(*itC); - if(!cLine->IsSolved()) { // Only check unsolved lines + 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) { @@ -142,7 +196,7 @@ ConnectionLine* ControlElementSolver::SolveNextElement(ConnectionLine* currentLi 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(); diff --git a/Project/ControlElementSolver.h b/Project/ControlElementSolver.h index 9ca6e02..e51c40d 100644 --- a/Project/ControlElementSolver.h +++ b/Project/ControlElementSolver.h @@ -23,10 +23,11 @@ class ControlElementSolver ControlElementSolver() {} ControlElementSolver(ControlEditor* controlEditor, double timeStep = 1e-3, + double integrationError = 1e-3, bool startAllZero = false, double input = 0.0); ~ControlElementSolver() {} - virtual void InitializeValues(double input); + virtual void InitializeValues(double input, bool startAllZero); virtual void SolveNextStep(double input); virtual std::vector GetSolutions() { return m_solutions; } virtual double GetLastSolution() { return m_solutions[m_solutions.size() - 1]; } @@ -36,6 +37,7 @@ class ControlElementSolver ControlElementContainer* m_ctrlContainer = NULL; double m_timeStep; + double m_integrationError; std::vector m_solutions; IOControl* m_inputControl = NULL; diff --git a/Project/Limiter.cpp b/Project/Limiter.cpp index 2a0b707..de2b669 100644 --- a/Project/Limiter.cpp +++ b/Project/Limiter.cpp @@ -87,3 +87,12 @@ void Limiter::UpdatePoints() m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(0, -18)); } } + +bool Limiter::Solve(double input) +{ + m_output = input; + if(m_output > m_upLimit) m_output = m_upLimit; + else if(m_output < m_lowLimit) m_output = m_lowLimit; + + return true; +} diff --git a/Project/Limiter.h b/Project/Limiter.h index 5f4e55b..b51d8cb 100644 --- a/Project/Limiter.h +++ b/Project/Limiter.h @@ -16,6 +16,7 @@ public: virtual bool Intersects(wxRect2DDouble rect) const { return m_rect.Intersects(rect); } virtual bool ShowForm(wxWindow* parent, Element* element); virtual void Rotate(bool clockwise = true); + virtual bool Solve(double input); virtual void UpdatePoints(); diff --git a/Project/Project.mk b/Project/Project.mk index 8d02db8..215c533 100644 --- a/Project/Project.mk +++ b/Project/Project.mk @@ -13,7 +13,7 @@ CurrentFileName := CurrentFilePath := CurrentFileFullPath := User :=NDSE-69 -Date :=06/05/2017 +Date :=08/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 diff --git a/Project/Sum.cpp b/Project/Sum.cpp index 606b367..bd35966 100644 --- a/Project/Sum.cpp +++ b/Project/Sum.cpp @@ -1,8 +1,8 @@ #include "Sum.h" #include "SumForm.h" +#include "ConnectionLine.h" -Sum::Sum(int id) - : ControlElement(id) +Sum::Sum(int id) : ControlElement(id) { m_width = m_height = 36.0; Node* nodeIn1 = new Node(m_position + wxPoint2DDouble(-m_width / 2, 9 - m_height / 2), Node::NODE_IN, m_borderSize); @@ -23,7 +23,6 @@ Sum::Sum(int id) } Sum::~Sum() {} - void Sum::Draw(wxPoint2DDouble translation, double scale) const { glLineWidth(1.0); @@ -133,7 +132,7 @@ void Sum::UpdatePoints() else if(m_angle == 270.0) m_nodeList[m_nodeList.size() - 1]->SetPosition(m_position + wxPoint2DDouble(0, -m_height / 2)); - SetPosition(m_position); // Update rect. + SetPosition(m_position); // Update rect. } void Sum::AddInNode() @@ -181,3 +180,39 @@ void Sum::Rotate(bool clockwise) node->Rotate(clockwise); } } + +bool Sum::Solve(double input) +{ + std::vector inputVector; + for(auto itN = m_nodeList.begin(), itNEnd = m_nodeList.end(); itN != itNEnd; ++itN) { + Node* node = *itN; + if(node->GetNodeType() != Node::NODE_OUT) { + if(!node->IsConnected()) { + inputVector.push_back(0.0); + } else { + for(auto itC = m_childList.begin(), itCEnd = m_childList.end(); itC != itCEnd; ++itC) { + ConnectionLine* cLine = static_cast(*itC); + auto nodeList = cLine->GetNodeList(); + for(auto itCN = nodeList.begin(), itCNEnd = nodeList.end(); itCN != itCNEnd; ++itCN) { + Node* childNode = *itCN; + if(childNode == node) { + inputVector.push_back(cLine->GetValue()); + break; + } + } + } + } + } + } + + if(m_signalList.size() != inputVector.size()) return false; + + m_output = 0.0; + for(unsigned int i = 0; i < m_signalList.size(); ++i) { + if(m_signalList[i] == SIGNAL_POSITIVE) + m_output += inputVector[i]; + else if(m_signalList[i] == SIGNAL_NEGATIVE) + m_output -= inputVector[i]; + } + return true; +} diff --git a/Project/Sum.h b/Project/Sum.h index a99067e..49059f0 100644 --- a/Project/Sum.h +++ b/Project/Sum.h @@ -4,6 +4,7 @@ #include "ControlElement.h" class SumForm; +class ConnectionLine; class Sum : public ControlElement { @@ -21,6 +22,8 @@ public: virtual std::vector GetSignalList() const { return m_signalList; } virtual void SetSignalList(std::vector signalList) { m_signalList = signalList; } + virtual bool Solve(double input); + virtual void UpdatePoints(); void AddInNode(); void RemoveInNode(); diff --git a/Project/TransferFunction.cpp b/Project/TransferFunction.cpp index 9c8ffea..2b023ea 100644 --- a/Project/TransferFunction.cpp +++ b/Project/TransferFunction.cpp @@ -32,7 +32,6 @@ TransferFunction::TransferFunction(int id) : ControlElement(id) } TransferFunction::~TransferFunction() {} - void TransferFunction::Draw(wxPoint2DDouble translation, double scale) const { glLineWidth(1.0); @@ -88,7 +87,7 @@ void TransferFunction::SetText(wxString numerator, wxString denominator) m_width = nWidth > dWidth ? nWidth : dWidth; m_height = m_glStringNum->getheight() + m_glStringDen->getheight() + 2 * m_borderSize; - SetPosition(m_position); // Update rect properly. + SetPosition(m_position); // Update rect properly. } wxString TransferFunction::GetSuperscriptNumber(int number) @@ -248,3 +247,112 @@ void TransferFunction::Rotate(bool clockwise) node->Rotate(clockwise); } } + +void TransferFunction::CalculateSpaceState(double timeStep, double error) +{ + m_timeStep = timeStep; + m_error = error; + + int order = static_cast(m_denominator.size()); + std::vector denominator = m_denominator; + std::vector numerator; + + int k = order; + for(int i = 0; i < order; i++) { + int numIndex = i - (order - static_cast(m_numerator.size())); + if(numIndex < 0) + numerator.push_back(0.0); + else + numerator.push_back(m_numerator[numIndex]); + k--; + } + + SpaceState ss; + for(int i = 0; i < (order - 1); i++) { + std::vector lineA; + for(int j = 0; j < (order - 1); j++) { + if(j == i + 1) + lineA.push_back(1.0); + else + lineA.push_back(0.0); + } + ss.A.push_back(lineA); + ss.B.push_back(0.0); + ss.C.push_back(0.0); + } + for(int i = 0; i < order - 1; i++) { + ss.A[order - 2][i] = -(denominator[order - 1 - i] / denominator[0]); + ss.C[i] = (numerator[order - 1 - i] - denominator[order - 1 - i] * numerator[0]) / denominator[0]; + } + ss.B[order - 2] = 1.0; + ss.D = numerator[0]; + + m_ss = ss; + + // Reset state + m_x.clear(); + m_dx.clear(); + + for(unsigned int i = 0; i < m_denominator.size(); ++i) { + m_x.push_back(0.0); + m_dx.push_back(0.0); + } +} + +bool TransferFunction::Solve(double input) +{ + int maxIter = 100; + int order = static_cast(m_ss.A.size()); + + std::vector x; + std::vector oldx; + std::vector dx; + std::vector olddx; + for(int i = 0; i < order; i++) { + x.push_back(m_x[i]); + oldx.push_back(m_x[i]); + + dx.push_back(m_dx[i]); + olddx.push_back(m_dx[i]); + } + + bool exit = false; + int iter = 0; + while(!exit) { + double xError = 0.0; + double dxError = 0.0; + for(int i = 0; i < order; i++) { + // Trapezoidal method + x[i] = m_x[i] + 0.5 * m_timeStep * (m_dx[i] + dx[i]); + + if(std::abs(x[i] - oldx[i]) > xError) xError = std::abs(x[i] - oldx[i]); + + oldx[i] = x[i]; + } + for(int i = 0; i < order; i++) { + // x' = Ax + Bu + dx[i] = 0.0; + for(int j = 0; j < order; j++) dx[i] += m_ss.A[i][j] * x[j]; + dx[i] += m_ss.B[i] * input; + + if(std::abs(dx[i] - olddx[i]) > dxError) dxError = std::abs(dx[i] - olddx[i]); + + olddx[i] = dx[i]; + } + if(std::max(xError, dxError) < m_error) exit = true; + + iter++; + if(iter >= maxIter) return false; + } + + m_output = 0.0; + for(int i = 0; i < order; i++) { + m_output += m_ss.C[i] * x[i]; + m_x[i] = x[i]; + m_dx[i] = dx[i]; + } + + m_output += m_ss.D * input; + + return true; +} diff --git a/Project/TransferFunction.h b/Project/TransferFunction.h index 45681ce..38e31bb 100644 --- a/Project/TransferFunction.h +++ b/Project/TransferFunction.h @@ -10,7 +10,14 @@ class TransferFunctionForm; class TransferFunction : public ControlElement { -public: + public: + struct SpaceState { + std::vector > A; + std::vector B; + std::vector C; + double D; + }; + TransferFunction(int id); ~TransferFunction(); @@ -19,25 +26,35 @@ public: virtual bool Intersects(wxRect2DDouble rect) const { return m_rect.Intersects(rect); } virtual bool ShowForm(wxWindow* parent, Element* element); virtual void Rotate(bool clockwise = true); - + virtual std::vector GetNumerator() const { return m_numerator; } virtual std::vector GetDenominator() const { return m_denominator; } virtual void SetNumerator(std::vector numerator) { m_numerator = numerator; } virtual void SetDenominator(std::vector denominator) { m_denominator = denominator; } virtual void UpdateTFText(); - -protected: + virtual SpaceState GetSpaceState() { return m_ss; } + virtual void CalculateSpaceState(double timeStep = 1e-3, double error = 1e-3); + virtual bool Solve(double input); + + protected: virtual void SetText(wxString numerator, wxString denominator); virtual wxString GetSuperscriptNumber(int number); virtual void GetTFString(wxString& numerator, wxString& denominator); - + wchar_t m_supNumber[10]; - + wxGLString* m_glStringNum = NULL; wxGLString* m_glStringDen = NULL; int m_fontSize = 10; + std::vector m_numerator; std::vector m_denominator; + SpaceState m_ss; + + std::vector m_x; + std::vector m_dx; + double m_timeStep = 1e-3; + double m_error = 1e-3; }; -#endif // TRANSFERFUNCTION_H +#endif // TRANSFERFUNCTION_H -- cgit From 2ef7d2bdf1ca4a6b9ee207e4a43f3116f55c0274 Mon Sep 17 00:00:00 2001 From: Thales Lima Oliveira Date: Tue, 9 May 2017 19:23:52 -0300 Subject: Several solutions implemented --- Project/ControlEditor.cpp | 12 ++++++++++-- Project/ControlElement.cpp | 6 ++++++ Project/ControlElement.h | 6 +----- Project/Exponential.cpp | 6 ++++++ Project/Exponential.h | 2 ++ Project/Gain.cpp | 6 ++++++ Project/Gain.h | 2 ++ Project/Multiplier.cpp | 39 +++++++++++++++++++++++++++++++++++---- Project/Multiplier.h | 4 ++++ Project/Project.mk | 2 +- 10 files changed, 73 insertions(+), 12 deletions(-) (limited to 'Project') diff --git a/Project/ControlEditor.cpp b/Project/ControlEditor.cpp index b4976ad..ad2db78 100644 --- a/Project/ControlEditor.cpp +++ b/Project/ControlEditor.cpp @@ -623,29 +623,37 @@ void ControlEditor::OnKeyDown(wxKeyEvent& event) double integrationError = 1e-5; double simTime = 10.0; double printStep = 1e-2; + + double pulsePer = 1.0; ControlElementSolver solver(this, timeStep, integrationError, true, 0.0); double currentTime = 0.0; double printTime = 0.0; + double pulseTime = 0.0; std::vector time; std::vector solution; + std::vector inputV; while(currentTime <= simTime) { double input = 0.0; - if(currentTime >= 1.0) input = 1.0; + if(pulseTime >= pulsePer * 2.0) pulseTime = 0.0; + if(pulseTime >= pulsePer) input = 1.0; solver.SolveNextStep(input); if(printTime >= printStep) { time.push_back(currentTime); solution.push_back(solver.GetLastSolution()); + inputV.push_back(input); printTime = 0.0; } printTime += timeStep; currentTime += timeStep; + pulseTime += timeStep; } std::vector epdList; ElementPlotData curve1Data(_("TESTES"), ElementPlotData::CT_BUS); - curve1Data.AddData(solution, _("teste 1")); + curve1Data.AddData(inputV, _("Entrada")); + curve1Data.AddData(solution, _("Saida")); epdList.push_back(curve1Data); ChartView* cView = new ChartView(this, epdList, time); diff --git a/Project/ControlElement.cpp b/Project/ControlElement.cpp index d75c606..e5c7a23 100644 --- a/Project/ControlElement.cpp +++ b/Project/ControlElement.cpp @@ -118,3 +118,9 @@ void ControlElement::Move(wxPoint2DDouble position) m_nodeList[i]->Move(position); } } + +bool ControlElement::Solve(double input) +{ + m_output = input; + return true; +} diff --git a/Project/ControlElement.h b/Project/ControlElement.h index 3744c6f..cce739a 100644 --- a/Project/ControlElement.h +++ b/Project/ControlElement.h @@ -65,11 +65,7 @@ class ControlElement : public Element virtual bool IsSolved() const { return m_solved; } virtual void SetSolved(bool solved = true) { m_solved = solved; } - virtual bool Solve(double input) - { - m_output = input * 2.0; - return true; - } + virtual bool Solve(double input); virtual double GetOutput() const { return m_output; } virtual void SetOutput(double output) { m_output = output; } protected: diff --git a/Project/Exponential.cpp b/Project/Exponential.cpp index 7c4f1fe..a197b93 100644 --- a/Project/Exponential.cpp +++ b/Project/Exponential.cpp @@ -111,3 +111,9 @@ void Exponential::SetValues(double aValue, double bValue) m_aValue = aValue; m_bValue = bValue; } + +bool Exponential::Solve(double input) +{ + m_output = m_aValue * std::exp(m_bValue * input); + return true; +} diff --git a/Project/Exponential.h b/Project/Exponential.h index 8260d66..deb5772 100644 --- a/Project/Exponential.h +++ b/Project/Exponential.h @@ -22,6 +22,8 @@ public: virtual void GetValues(double& aValue, double &bValue); virtual void SetValues(double aValue, double bValue); + virtual bool Solve(double input); + protected: double m_aValue = 0.001; double m_bValue = 5.0; diff --git a/Project/Gain.cpp b/Project/Gain.cpp index faea89c..5f65c0c 100644 --- a/Project/Gain.cpp +++ b/Project/Gain.cpp @@ -167,3 +167,9 @@ void Gain::Move(wxPoint2DDouble position) SetPosition(m_movePos + position - m_moveStartPt); UpdatePoints(); } + +bool Gain::Solve(double input) +{ + m_output = input * m_value; + return true; +} diff --git a/Project/Gain.h b/Project/Gain.h index 8844372..b2552fc 100644 --- a/Project/Gain.h +++ b/Project/Gain.h @@ -24,6 +24,8 @@ class Gain : public ControlElement virtual void SetValue(double value); virtual double GetValue() const { return m_value; } virtual void UpdatePoints(); + + virtual bool Solve(double input); protected: double m_value = 1.0; diff --git a/Project/Multiplier.cpp b/Project/Multiplier.cpp index ee644ed..14efa8c 100644 --- a/Project/Multiplier.cpp +++ b/Project/Multiplier.cpp @@ -1,12 +1,12 @@ #include "Multiplier.h" +#include "ConnectionLine.h" Multiplier::Multiplier(int id) : ControlElement(id) { m_width = m_height = 36.0; Node* nodeIn1 = new Node(m_position + wxPoint2DDouble(-18, -9), Node::NODE_IN, m_borderSize); nodeIn1->StartMove(m_position); - Node* nodeIn2 = - new Node(m_position + wxPoint2DDouble(-18, 9), Node::NODE_IN, m_borderSize); + Node* nodeIn2 = new Node(m_position + wxPoint2DDouble(-18, 9), Node::NODE_IN, m_borderSize); nodeIn2->StartMove(m_position); Node* nodeOut = new Node(m_position + wxPoint2DDouble(18, 0), Node::NODE_OUT, m_borderSize); nodeOut->SetAngle(180.0); @@ -17,7 +17,6 @@ Multiplier::Multiplier(int id) : ControlElement(id) } Multiplier::~Multiplier() {} - void Multiplier::Draw(wxPoint2DDouble translation, double scale) const { glLineWidth(1.0); @@ -30,7 +29,7 @@ void Multiplier::Draw(wxPoint2DDouble translation, double scale) const DrawRectangle(m_position, m_width, m_height); glColor4d(0.0, 0.0, 0.0, 1.0); DrawRectangle(m_position, m_width, m_height, GL_LINE_LOOP); - + // Plot x. glLineWidth(2.0); std::vector xSymbol; @@ -84,3 +83,35 @@ void Multiplier::UpdatePoints() m_nodeList[2]->SetPosition(m_position + wxPoint2DDouble(0, -18)); } } + +bool Multiplier::Solve(double input) +{ + std::vector inputVector; + for(auto itN = m_nodeList.begin(), itNEnd = m_nodeList.end(); itN != itNEnd; ++itN) { + Node* node = *itN; + if(node->GetNodeType() != Node::NODE_OUT) { + if(!node->IsConnected()) { + inputVector.push_back(1.0); + } else { + for(auto itC = m_childList.begin(), itCEnd = m_childList.end(); itC != itCEnd; ++itC) { + ConnectionLine* cLine = static_cast(*itC); + auto nodeList = cLine->GetNodeList(); + for(auto itCN = nodeList.begin(), itCNEnd = nodeList.end(); itCN != itCNEnd; ++itCN) { + Node* childNode = *itCN; + if(childNode == node) { + inputVector.push_back(cLine->GetValue()); + break; + } + } + } + } + } + } + + m_output = 1.0; + for(unsigned int i = 0; i < inputVector.size(); ++i) { + m_output *= inputVector[i]; + } + + return true; +} diff --git a/Project/Multiplier.h b/Project/Multiplier.h index 8a25b23..57efe39 100644 --- a/Project/Multiplier.h +++ b/Project/Multiplier.h @@ -3,6 +3,8 @@ #include "ControlElement.h" +class ConnectionLine; + class Multiplier : public ControlElement { public: @@ -16,6 +18,8 @@ class Multiplier : public ControlElement virtual void Rotate(bool clockwise = true); virtual void UpdatePoints(); + + virtual bool Solve(double input); }; #endif // MULTIPLIER_H diff --git a/Project/Project.mk b/Project/Project.mk index 215c533..caab0f7 100644 --- a/Project/Project.mk +++ b/Project/Project.mk @@ -13,7 +13,7 @@ CurrentFileName := CurrentFilePath := CurrentFileFullPath := User :=NDSE-69 -Date :=08/05/2017 +Date :=09/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 -- cgit From 4269e9370873ac31fe671c710536958ca4374aad Mon Sep 17 00:00:00 2001 From: Thales Lima Oliveira Date: Wed, 10 May 2017 18:27:30 -0300 Subject: All element's solutions implemented Initialization is missing --- Project/ControlElementSolver.cpp | 18 ++++++++++++++++-- Project/Project.mk | 2 +- Project/RateLimiter.cpp | 27 ++++++++++++++++++++++----- Project/RateLimiter.h | 6 ++++++ 4 files changed, 45 insertions(+), 8 deletions(-) (limited to 'Project') diff --git a/Project/ControlElementSolver.cpp b/Project/ControlElementSolver.cpp index 42445f4..a1aee27 100644 --- a/Project/ControlElementSolver.cpp +++ b/Project/ControlElementSolver.cpp @@ -75,6 +75,11 @@ void ControlElementSolver::InitializeValues(double input, bool startAllZero) 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); + } auto connectionLineList = m_ctrlContainer->GetConnectionLineList(); for(auto it = connectionLineList.begin(), itEnd = connectionLineList.end(); it != itEnd; ++it) { ConnectionLine* cLine = *it; @@ -84,6 +89,8 @@ void ControlElementSolver::InitializeValues(double input, bool startAllZero) if(!startAllZero) { // Calculate the steady-state results according to the input. + double minError = 1e-6; + } } @@ -123,9 +130,9 @@ void ControlElementSolver::SolveNextStep(double input) ConnectionLine* currentLine = firstConn; while(currentLine) { - ConnectionLine* lastLine = currentLine; + //ConnectionLine* lastLine = currentLine; currentLine = SolveNextElement(currentLine); - if(!currentLine) m_solutions.push_back(lastLine->GetValue()); + //if(!currentLine) m_solutions.push_back(lastLine->GetValue()); } bool haveUnsolvedElement = true; @@ -152,6 +159,13 @@ void ControlElementSolver::SolveNextStep(double input) if(haveUnsolvedElement) break; } } + + // Set the control system step output. + if(m_outputControl->GetChildList().size() == 1) { + ConnectionLine* cLine = static_cast(m_outputControl->GetChildList()[0]); + m_solutions.push_back(cLine->GetValue()); + } + else m_solutions.push_back(0.0); } void ControlElementSolver::FillAllConnectedChildren(ConnectionLine* parent) diff --git a/Project/Project.mk b/Project/Project.mk index caab0f7..cbf6e8f 100644 --- a/Project/Project.mk +++ b/Project/Project.mk @@ -13,7 +13,7 @@ CurrentFileName := CurrentFilePath := CurrentFileFullPath := User :=NDSE-69 -Date :=09/05/2017 +Date :=10/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 diff --git a/Project/RateLimiter.cpp b/Project/RateLimiter.cpp index 5da0578..3a1b25a 100644 --- a/Project/RateLimiter.cpp +++ b/Project/RateLimiter.cpp @@ -13,10 +13,7 @@ RateLimiter::RateLimiter(int id) : ControlElement(id) m_nodeList.push_back(nodeOut); } -RateLimiter::~RateLimiter() -{ -} - +RateLimiter::~RateLimiter() {} void RateLimiter::Draw(wxPoint2DDouble translation, double scale) const { glLineWidth(1.0); @@ -37,7 +34,7 @@ void RateLimiter::Draw(wxPoint2DDouble translation, double scale) const axis.push_back(m_position + wxPoint2DDouble(0, -13)); axis.push_back(m_position + wxPoint2DDouble(0, 13)); DrawLine(axis, GL_LINES); - + glLineWidth(2.0); std::vector limSymbol; limSymbol.push_back(m_position + wxPoint2DDouble(10, -10)); @@ -95,3 +92,23 @@ void RateLimiter::UpdatePoints() m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(0, -18)); } } + +bool RateLimiter::Solve(double input) +{ + double rate = (input - m_output) / m_timeStep; + + bool reachLimit = false; + if(rate > m_upLimit) { + rate = m_upLimit; + reachLimit = true; + } else if(rate < m_lowLimit) { + rate = m_lowLimit; + reachLimit = true; + } + + if(reachLimit) + m_output += rate * m_timeStep; + else + m_output = input; + return true; +} diff --git a/Project/RateLimiter.h b/Project/RateLimiter.h index d17642b..13125e1 100644 --- a/Project/RateLimiter.h +++ b/Project/RateLimiter.h @@ -24,9 +24,15 @@ class RateLimiter : public ControlElement void SetUpLimit(double upLimit) { m_upLimit = upLimit; } void SetLowLimit(double lowLimit) { m_lowLimit = lowLimit; } + virtual void SetTimeStep(double timeStep) { m_timeStep = timeStep; } + + virtual bool Solve(double input); + protected: double m_upLimit = 5.0; double m_lowLimit = -5.0; + + double m_timeStep = 1e-3; }; #endif // RATELIMITER_H -- cgit From 6cf253651521f0cdaf3a80f8ae58e9917fe2ec57 Mon Sep 17 00:00:00 2001 From: Thales Lima Oliveira Date: Thu, 11 May 2017 17:07:11 -0300 Subject: Initialization implemented --- Project/ControlEditor.cpp | 67 +++++++++++++++++++++------------------- Project/ControlElementSolver.cpp | 62 ++++++++++++++++++++++++++++++------- Project/ControlElementSolver.h | 4 ++- Project/Project.mk | 2 +- 4 files changed, 90 insertions(+), 45 deletions(-) (limited to 'Project') diff --git a/Project/ControlEditor.cpp b/Project/ControlEditor.cpp index ad2db78..ac778de 100644 --- a/Project/ControlEditor.cpp +++ b/Project/ControlEditor.cpp @@ -623,41 +623,46 @@ void ControlEditor::OnKeyDown(wxKeyEvent& event) double integrationError = 1e-5; double simTime = 10.0; double printStep = 1e-2; - + double pulsePer = 1.0; - ControlElementSolver solver(this, timeStep, integrationError, true, 0.0); - - double currentTime = 0.0; - double printTime = 0.0; - double pulseTime = 0.0; - std::vector time; - std::vector solution; - std::vector inputV; - while(currentTime <= simTime) { - double input = 0.0; - if(pulseTime >= pulsePer * 2.0) pulseTime = 0.0; - if(pulseTime >= pulsePer) input = 1.0; - - solver.SolveNextStep(input); - if(printTime >= printStep) { - time.push_back(currentTime); - solution.push_back(solver.GetLastSolution()); - inputV.push_back(input); - printTime = 0.0; + ControlElementSolver solver(this, timeStep, integrationError, false, 0.0); + if(solver.IsOK()) { + double currentTime = 0.0; + double printTime = 0.0; + double pulseTime = 0.0; + std::vector time; + std::vector solution; + std::vector inputV; + while(currentTime <= simTime) { + double input = 0.0; + if(pulseTime >= pulsePer * 2.0) pulseTime = 0.0; + if(pulseTime >= pulsePer) input = 1.0; + + solver.SolveNextStep(input); + if(printTime >= printStep) { + time.push_back(currentTime); + solution.push_back(solver.GetLastSolution()); + inputV.push_back(input); + printTime = 0.0; + } + printTime += timeStep; + currentTime += timeStep; + pulseTime += timeStep; } - printTime += timeStep; - currentTime += timeStep; - pulseTime += timeStep; + std::vector epdList; + ElementPlotData curve1Data(_("TESTES"), ElementPlotData::CT_BUS); + curve1Data.AddData(inputV, _("Entrada")); + curve1Data.AddData(solution, _("Saida")); + epdList.push_back(curve1Data); + + ChartView* cView = new ChartView(this, epdList, time); + cView->Show(); + } else { + wxMessageDialog msgDialog(this, _("it was not possible to solve the control system"), + _("Error"), wxOK | wxCENTRE | wxICON_ERROR); + msgDialog.ShowModal(); } - std::vector epdList; - ElementPlotData curve1Data(_("TESTES"), ElementPlotData::CT_BUS); - curve1Data.AddData(inputV, _("Entrada")); - curve1Data.AddData(solution, _("Saida")); - epdList.push_back(curve1Data); - - ChartView* cView = new ChartView(this, epdList, time); - cView->Show(); /* std::vector time, sinC, cosC, tgC; diff --git a/Project/ControlElementSolver.cpp b/Project/ControlElementSolver.cpp index a1aee27..d48e39f 100644 --- a/Project/ControlElementSolver.cpp +++ b/Project/ControlElementSolver.cpp @@ -51,17 +51,22 @@ ControlElementSolver::ControlElementSolver(ControlEditor* controlEditor, failMessage = _("There is no output in the control system."); } + m_timeStep = timeStep; + m_integrationError = integrationError; + if(!InitializeValues(input, startAllZero)) { + fail = true; + failMessage = _("It was not possible to initialize the control system."); + } + if(fail) { wxMessageDialog msgDialog(controlEditor, failMessage, _("Error"), wxOK | wxCENTRE | wxICON_ERROR); msgDialog.ShowModal(); + } else { + m_isOK = true; } - - m_timeStep = timeStep; - m_integrationError = integrationError; - InitializeValues(input, startAllZero); } -void ControlElementSolver::InitializeValues(double input, bool startAllZero) +bool ControlElementSolver::InitializeValues(double input, bool startAllZero) { // Reset Elements values auto elementList = m_ctrlContainer->GetControlElementsList(); @@ -88,10 +93,43 @@ void ControlElementSolver::InitializeValues(double input, bool startAllZero) } if(!startAllZero) { + // double origTimeStep = m_timeStep; // Calculate the steady-state results according to the input. - double minError = 1e-6; - + 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 num = tf->GetNumerator(); + std::vector 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; + int numIt = 0; + while(std::abs(prevSol - currentSol) > minError || numIt <= minIteration) { + prevSol = currentSol; + SolveNextStep(input); + currentSol = GetLastSolution(); + numIt++; + if(numIt >= maxIteration) return false; + } + wxMessageBox(wxString::Format("%d\n%e\n%f", numIt, minError,currentSol)); + // m_timeStep = origTimeStep; + m_solutions.clear(); } + + return true; } void ControlElementSolver::SolveNextStep(double input) @@ -130,9 +168,9 @@ void ControlElementSolver::SolveNextStep(double input) ConnectionLine* currentLine = firstConn; while(currentLine) { - //ConnectionLine* lastLine = currentLine; + // ConnectionLine* lastLine = currentLine; currentLine = SolveNextElement(currentLine); - //if(!currentLine) m_solutions.push_back(lastLine->GetValue()); + // if(!currentLine) m_solutions.push_back(lastLine->GetValue()); } bool haveUnsolvedElement = true; @@ -159,13 +197,13 @@ void ControlElementSolver::SolveNextStep(double input) if(haveUnsolvedElement) break; } } - + // Set the control system step output. if(m_outputControl->GetChildList().size() == 1) { ConnectionLine* cLine = static_cast(m_outputControl->GetChildList()[0]); m_solutions.push_back(cLine->GetValue()); - } - else m_solutions.push_back(0.0); + } else + m_solutions.push_back(0.0); } void ControlElementSolver::FillAllConnectedChildren(ConnectionLine* parent) diff --git a/Project/ControlElementSolver.h b/Project/ControlElementSolver.h index e51c40d..6d0ad3f 100644 --- a/Project/ControlElementSolver.h +++ b/Project/ControlElementSolver.h @@ -27,10 +27,11 @@ class ControlElementSolver bool startAllZero = false, double input = 0.0); ~ControlElementSolver() {} - virtual void InitializeValues(double input, bool startAllZero); + virtual bool InitializeValues(double input, bool startAllZero); virtual void SolveNextStep(double input); virtual std::vector GetSolutions() { return m_solutions; } virtual double GetLastSolution() { return m_solutions[m_solutions.size() - 1]; } + virtual bool IsOK() const { return m_isOK; } protected: void FillAllConnectedChildren(ConnectionLine* parent); ConnectionLine* SolveNextElement(ConnectionLine* currentLine); @@ -39,6 +40,7 @@ class ControlElementSolver double m_timeStep; double m_integrationError; std::vector m_solutions; + bool m_isOK = false; IOControl* m_inputControl = NULL; IOControl* m_outputControl = NULL; diff --git a/Project/Project.mk b/Project/Project.mk index cbf6e8f..e472ddd 100644 --- a/Project/Project.mk +++ b/Project/Project.mk @@ -13,7 +13,7 @@ CurrentFileName := CurrentFilePath := CurrentFileFullPath := User :=NDSE-69 -Date :=10/05/2017 +Date :=11/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 -- cgit From d44c3a76943c90cfcbf336961d9ba3516a1c80dc Mon Sep 17 00:00:00 2001 From: Thales Lima Oliveira Date: Sat, 13 May 2017 16:13:12 -0300 Subject: Several bugs fixed, ready to pull --- Project/ChartView.cpp | 2 ++ Project/ChartView.h | 2 +- Project/ControlEditor.cpp | 71 +++++++++++++++++-------------------- Project/ControlEditor.h | 2 ++ Project/ControlElement.cpp | 2 +- Project/ControlElement.h | 2 +- Project/ControlElementContainer.cpp | 5 +-- Project/ControlElementSolver.cpp | 63 ++++++++++++++++---------------- Project/Exponential.cpp | 2 +- Project/Exponential.h | 2 +- Project/Gain.cpp | 2 +- Project/Gain.h | 2 +- Project/Limiter.cpp | 2 +- Project/Limiter.h | 2 +- Project/Multiplier.cpp | 2 +- Project/Multiplier.h | 2 +- Project/Project.mk | 2 +- Project/RateLimiter.cpp | 6 ++-- Project/RateLimiter.h | 6 +--- Project/Sum.cpp | 3 +- Project/Sum.h | 2 +- Project/TransferFunction.cpp | 11 +++--- Project/TransferFunction.h | 6 ++-- 23 files changed, 97 insertions(+), 104 deletions(-) (limited to 'Project') diff --git a/Project/ChartView.cpp b/Project/ChartView.cpp index 199060a..2f3f70d 100644 --- a/Project/ChartView.cpp +++ b/Project/ChartView.cpp @@ -45,6 +45,8 @@ ChartView::~ChartView() {} void ChartView::SetMPWindow() { m_mpWindow = new mpWindow(this, wxID_ANY); + + m_mpWindow->SetDoubleBuffered(true); m_mpWindow->SetMargins(20, 10, 40, 60); m_xaxis = new mpScaleX("", mpALIGN_BOTTOM, true); diff --git a/Project/ChartView.h b/Project/ChartView.h index b40a63d..741ffe2 100644 --- a/Project/ChartView.h +++ b/Project/ChartView.h @@ -54,7 +54,7 @@ class ChartView : public ChartViewBase mpInfoCoords* m_coords = NULL; mpInfoLegend* m_leg = NULL; - bool m_hideGrid = false; + bool m_hideGrid = true; bool m_showLeg = false; bool m_showCoords = false; bool m_darkTheme = false; diff --git a/Project/ControlEditor.cpp b/Project/ControlEditor.cpp index ac778de..cb4f816 100644 --- a/Project/ControlEditor.cpp +++ b/Project/ControlEditor.cpp @@ -619,18 +619,24 @@ void ControlEditor::OnKeyDown(wxKeyEvent& event) case 'L': { // tests if(event.ControlDown() && event.ShiftDown()) { - double timeStep = 1e-3; + double timeStep = 1e-4; double integrationError = 1e-5; double simTime = 10.0; - double printStep = 1e-2; + double printStep = 1e-3; + double pdbStep = 1e-1; - double pulsePer = 1.0; + double pulsePer = 5.0; + wxProgressDialog pbd(_("Test"), _("Initializing..."), 100, this, + wxPD_APP_MODAL | wxPD_AUTO_HIDE | wxPD_CAN_ABORT | wxPD_SMOOTH); + pbd.SetDoubleBuffered(true); ControlElementSolver solver(this, timeStep, integrationError, false, 0.0); if(solver.IsOK()) { + bool simStopped = false; double currentTime = 0.0; double printTime = 0.0; double pulseTime = 0.0; + double pdbTime = 0.0; std::vector time; std::vector solution; std::vector inputV; @@ -646,50 +652,37 @@ void ControlEditor::OnKeyDown(wxKeyEvent& event) inputV.push_back(input); printTime = 0.0; } + if((pdbTime > pdbStep)) { + if(!pbd.Update((currentTime / simTime) * 100, + wxString::Format("Time = %.2fs", currentTime))) { + pbd.Update(100); + simStopped = true; + currentTime = simTime; + } + pbd.Refresh(); + pbd.Update(); + pdbTime = 0.0; + } printTime += timeStep; currentTime += timeStep; pulseTime += timeStep; + pdbTime += timeStep; + } + if(!simStopped) { + std::vector epdList; + ElementPlotData curve1Data(_("TESTES"), ElementPlotData::CT_BUS); + curve1Data.AddData(inputV, _("Entrada")); + curve1Data.AddData(solution, _("Saida")); + epdList.push_back(curve1Data); + + ChartView* cView = new ChartView(this, epdList, time); + cView->Show(); } - std::vector epdList; - ElementPlotData curve1Data(_("TESTES"), ElementPlotData::CT_BUS); - curve1Data.AddData(inputV, _("Entrada")); - curve1Data.AddData(solution, _("Saida")); - epdList.push_back(curve1Data); - - ChartView* cView = new ChartView(this, epdList, time); - cView->Show(); } else { - wxMessageDialog msgDialog(this, _("it was not possible to solve the control system"), + wxMessageDialog msgDialog(this, _("It was not possible to solve the control system"), _("Error"), wxOK | wxCENTRE | wxICON_ERROR); msgDialog.ShowModal(); } - - /* - std::vector time, sinC, cosC, tgC; - for(int i=0; i<360; ++i) { - time.push_back(i); - sinC.push_back(std::sin(wxDegToRad(i))); - cosC.push_back(std::cos(wxDegToRad(i))); - tgC.push_back(std::tan(wxDegToRad(i))); - } - std::vector epdList; - - ElementPlotData curve1Data(_("Func. polinomiais 1"), ElementPlotData::CT_BUS); - curve1Data.AddData(sinC, _("seno")); - epdList.push_back(curve1Data); - - ElementPlotData curve2Data(_("Func. polinomiais 2"), ElementPlotData::CT_BUS); - curve2Data.AddData(tgC, _("tangente")); - epdList.push_back(curve2Data); - - ElementPlotData curve3Data(_("Func. polinomiais 3"), ElementPlotData::CT_SYNC_GENERATOR); - curve3Data.AddData(sinC, _("seno")); - curve3Data.AddData(cosC, _("cosseno")); - curve3Data.AddData(tgC, _("tangente")); - epdList.push_back(curve3Data); - - ChartView* cView = new ChartView(this, epdList, time); - cView->Show();*/ } } } diff --git a/Project/ControlEditor.h b/Project/ControlEditor.h index 9dd4e38..9de5a1f 100644 --- a/Project/ControlEditor.h +++ b/Project/ControlEditor.h @@ -9,6 +9,8 @@ #include #include +#include + #include "IOControl.h" class FileHanding; diff --git a/Project/ControlElement.cpp b/Project/ControlElement.cpp index e5c7a23..b928784 100644 --- a/Project/ControlElement.cpp +++ b/Project/ControlElement.cpp @@ -119,7 +119,7 @@ void ControlElement::Move(wxPoint2DDouble position) } } -bool ControlElement::Solve(double input) +bool ControlElement::Solve(double input, double timeStep) { m_output = input; return true; diff --git a/Project/ControlElement.h b/Project/ControlElement.h index cce739a..1e60f97 100644 --- a/Project/ControlElement.h +++ b/Project/ControlElement.h @@ -65,7 +65,7 @@ class ControlElement : public Element virtual bool IsSolved() const { return m_solved; } virtual void SetSolved(bool solved = true) { m_solved = solved; } - virtual bool Solve(double input); + virtual bool Solve(double input, double timeStep); virtual double GetOutput() const { return m_output; } virtual void SetOutput(double output) { m_output = output; } protected: diff --git a/Project/ControlElementContainer.cpp b/Project/ControlElementContainer.cpp index f5372a8..e461529 100644 --- a/Project/ControlElementContainer.cpp +++ b/Project/ControlElementContainer.cpp @@ -2,7 +2,7 @@ #include "ControlEditor.h" #include "ControlElement.h" -ControlElementContainer::ControlElementContainer() {} +ControlElementContainer::ControlElementContainer() { ClearContainer(); } ControlElementContainer::~ControlElementContainer() {} void ControlElementContainer::FillContainer(ControlEditor* editor) { @@ -47,7 +47,8 @@ void ControlElementContainer::ClearContainer() m_tfList.clear(); } -void ControlElementContainer::FillContainer(std::vector controlElementList, std::vector connectionLineList) +void ControlElementContainer::FillContainer(std::vector controlElementList, + std::vector connectionLineList) { m_ctrlElementsList = controlElementList; m_cLineList = connectionLineList; 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 num = tf->GetNumerator(); - std::vector 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(*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). diff --git a/Project/Exponential.cpp b/Project/Exponential.cpp index a197b93..e0daeef 100644 --- a/Project/Exponential.cpp +++ b/Project/Exponential.cpp @@ -112,7 +112,7 @@ void Exponential::SetValues(double aValue, double bValue) m_bValue = bValue; } -bool Exponential::Solve(double input) +bool Exponential::Solve(double input, double timeStep) { m_output = m_aValue * std::exp(m_bValue * input); return true; diff --git a/Project/Exponential.h b/Project/Exponential.h index deb5772..e9e9511 100644 --- a/Project/Exponential.h +++ b/Project/Exponential.h @@ -22,7 +22,7 @@ public: virtual void GetValues(double& aValue, double &bValue); virtual void SetValues(double aValue, double bValue); - virtual bool Solve(double input); + virtual bool Solve(double input, double timeStep); protected: double m_aValue = 0.001; diff --git a/Project/Gain.cpp b/Project/Gain.cpp index 5f65c0c..d2106d7 100644 --- a/Project/Gain.cpp +++ b/Project/Gain.cpp @@ -168,7 +168,7 @@ void Gain::Move(wxPoint2DDouble position) UpdatePoints(); } -bool Gain::Solve(double input) +bool Gain::Solve(double input, double timeStep) { m_output = input * m_value; return true; diff --git a/Project/Gain.h b/Project/Gain.h index b2552fc..bb9c3ce 100644 --- a/Project/Gain.h +++ b/Project/Gain.h @@ -25,7 +25,7 @@ class Gain : public ControlElement virtual double GetValue() const { return m_value; } virtual void UpdatePoints(); - virtual bool Solve(double input); + virtual bool Solve(double input, double timeStep); protected: double m_value = 1.0; diff --git a/Project/Limiter.cpp b/Project/Limiter.cpp index de2b669..cd76fba 100644 --- a/Project/Limiter.cpp +++ b/Project/Limiter.cpp @@ -88,7 +88,7 @@ void Limiter::UpdatePoints() } } -bool Limiter::Solve(double input) +bool Limiter::Solve(double input, double timeStep) { m_output = input; if(m_output > m_upLimit) m_output = m_upLimit; diff --git a/Project/Limiter.h b/Project/Limiter.h index b51d8cb..1585a3c 100644 --- a/Project/Limiter.h +++ b/Project/Limiter.h @@ -16,7 +16,7 @@ public: virtual bool Intersects(wxRect2DDouble rect) const { return m_rect.Intersects(rect); } virtual bool ShowForm(wxWindow* parent, Element* element); virtual void Rotate(bool clockwise = true); - virtual bool Solve(double input); + virtual bool Solve(double input, double timeStep); virtual void UpdatePoints(); diff --git a/Project/Multiplier.cpp b/Project/Multiplier.cpp index 14efa8c..e8708c9 100644 --- a/Project/Multiplier.cpp +++ b/Project/Multiplier.cpp @@ -84,7 +84,7 @@ void Multiplier::UpdatePoints() } } -bool Multiplier::Solve(double input) +bool Multiplier::Solve(double input, double timeStep) { std::vector inputVector; for(auto itN = m_nodeList.begin(), itNEnd = m_nodeList.end(); itN != itNEnd; ++itN) { diff --git a/Project/Multiplier.h b/Project/Multiplier.h index 57efe39..19fca71 100644 --- a/Project/Multiplier.h +++ b/Project/Multiplier.h @@ -19,7 +19,7 @@ class Multiplier : public ControlElement virtual void UpdatePoints(); - virtual bool Solve(double input); + virtual bool Solve(double input, double timeStep); }; #endif // MULTIPLIER_H diff --git a/Project/Project.mk b/Project/Project.mk index e472ddd..b9d2fb9 100644 --- a/Project/Project.mk +++ b/Project/Project.mk @@ -13,7 +13,7 @@ CurrentFileName := CurrentFilePath := CurrentFileFullPath := User :=NDSE-69 -Date :=11/05/2017 +Date :=13/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 diff --git a/Project/RateLimiter.cpp b/Project/RateLimiter.cpp index 3a1b25a..42bede1 100644 --- a/Project/RateLimiter.cpp +++ b/Project/RateLimiter.cpp @@ -93,9 +93,9 @@ void RateLimiter::UpdatePoints() } } -bool RateLimiter::Solve(double input) +bool RateLimiter::Solve(double input, double timeStep) { - double rate = (input - m_output) / m_timeStep; + double rate = (input - m_output) / timeStep; bool reachLimit = false; if(rate > m_upLimit) { @@ -107,7 +107,7 @@ bool RateLimiter::Solve(double input) } if(reachLimit) - m_output += rate * m_timeStep; + m_output += rate * timeStep; else m_output = input; return true; diff --git a/Project/RateLimiter.h b/Project/RateLimiter.h index 13125e1..b1e669c 100644 --- a/Project/RateLimiter.h +++ b/Project/RateLimiter.h @@ -24,15 +24,11 @@ class RateLimiter : public ControlElement void SetUpLimit(double upLimit) { m_upLimit = upLimit; } void SetLowLimit(double lowLimit) { m_lowLimit = lowLimit; } - virtual void SetTimeStep(double timeStep) { m_timeStep = timeStep; } - - virtual bool Solve(double input); + virtual bool Solve(double input, double timeStep); protected: double m_upLimit = 5.0; double m_lowLimit = -5.0; - - double m_timeStep = 1e-3; }; #endif // RATELIMITER_H diff --git a/Project/Sum.cpp b/Project/Sum.cpp index bd35966..b7a4f8a 100644 --- a/Project/Sum.cpp +++ b/Project/Sum.cpp @@ -138,6 +138,7 @@ void Sum::UpdatePoints() void Sum::AddInNode() { Node* newNode = new Node(wxPoint2DDouble(0, 0), Node::NODE_IN, m_borderSize); + newNode->SetAngle(m_angle); m_nodeList.insert(m_nodeList.end() - 1, newNode); } @@ -181,7 +182,7 @@ void Sum::Rotate(bool clockwise) } } -bool Sum::Solve(double input) +bool Sum::Solve(double input, double timeStep) { std::vector inputVector; for(auto itN = m_nodeList.begin(), itNEnd = m_nodeList.end(); itN != itNEnd; ++itN) { diff --git a/Project/Sum.h b/Project/Sum.h index 49059f0..f3ab4c6 100644 --- a/Project/Sum.h +++ b/Project/Sum.h @@ -22,7 +22,7 @@ public: virtual std::vector GetSignalList() const { return m_signalList; } virtual void SetSignalList(std::vector signalList) { m_signalList = signalList; } - virtual bool Solve(double input); + virtual bool Solve(double input, double timeStep); virtual void UpdatePoints(); void AddInNode(); diff --git a/Project/TransferFunction.cpp b/Project/TransferFunction.cpp index 2b023ea..ebb59fb 100644 --- a/Project/TransferFunction.cpp +++ b/Project/TransferFunction.cpp @@ -248,9 +248,9 @@ void TransferFunction::Rotate(bool clockwise) } } -void TransferFunction::CalculateSpaceState(double timeStep, double error) +void TransferFunction::CalculateSpaceState(int maxIteration, double error) { - m_timeStep = timeStep; + m_maxIteration = maxIteration; m_error = error; int order = static_cast(m_denominator.size()); @@ -299,9 +299,8 @@ void TransferFunction::CalculateSpaceState(double timeStep, double error) } } -bool TransferFunction::Solve(double input) +bool TransferFunction::Solve(double input, double timeStep) { - int maxIter = 100; int order = static_cast(m_ss.A.size()); std::vector x; @@ -323,7 +322,7 @@ bool TransferFunction::Solve(double input) double dxError = 0.0; for(int i = 0; i < order; i++) { // Trapezoidal method - x[i] = m_x[i] + 0.5 * m_timeStep * (m_dx[i] + dx[i]); + x[i] = m_x[i] + 0.5 * timeStep * (m_dx[i] + dx[i]); if(std::abs(x[i] - oldx[i]) > xError) xError = std::abs(x[i] - oldx[i]); @@ -342,7 +341,7 @@ bool TransferFunction::Solve(double input) if(std::max(xError, dxError) < m_error) exit = true; iter++; - if(iter >= maxIter) return false; + if(iter >= m_maxIteration) return false; } m_output = 0.0; diff --git a/Project/TransferFunction.h b/Project/TransferFunction.h index 38e31bb..19bd04e 100644 --- a/Project/TransferFunction.h +++ b/Project/TransferFunction.h @@ -33,8 +33,8 @@ class TransferFunction : public ControlElement virtual void SetDenominator(std::vector denominator) { m_denominator = denominator; } virtual void UpdateTFText(); virtual SpaceState GetSpaceState() { return m_ss; } - virtual void CalculateSpaceState(double timeStep = 1e-3, double error = 1e-3); - virtual bool Solve(double input); + virtual void CalculateSpaceState(int maxIteration = 100, double error = 1e-3); + virtual bool Solve(double input, double timeStep); protected: virtual void SetText(wxString numerator, wxString denominator); @@ -53,8 +53,8 @@ class TransferFunction : public ControlElement std::vector m_x; std::vector m_dx; - double m_timeStep = 1e-3; double m_error = 1e-3; + int m_maxIteration = 100; }; #endif // TRANSFERFUNCTION_H -- cgit