diff options
-rw-r--r-- | Project/ChartView.cpp | 2 | ||||
-rw-r--r-- | Project/ChartView.h | 2 | ||||
-rw-r--r-- | Project/ControlEditor.cpp | 71 | ||||
-rw-r--r-- | Project/ControlEditor.h | 2 | ||||
-rw-r--r-- | Project/ControlElement.cpp | 2 | ||||
-rw-r--r-- | Project/ControlElement.h | 2 | ||||
-rw-r--r-- | Project/ControlElementContainer.cpp | 5 | ||||
-rw-r--r-- | Project/ControlElementSolver.cpp | 63 | ||||
-rw-r--r-- | Project/Exponential.cpp | 2 | ||||
-rw-r--r-- | Project/Exponential.h | 2 | ||||
-rw-r--r-- | Project/Gain.cpp | 2 | ||||
-rw-r--r-- | Project/Gain.h | 2 | ||||
-rw-r--r-- | Project/Limiter.cpp | 2 | ||||
-rw-r--r-- | Project/Limiter.h | 2 | ||||
-rw-r--r-- | Project/Multiplier.cpp | 2 | ||||
-rw-r--r-- | Project/Multiplier.h | 2 | ||||
-rw-r--r-- | Project/Project.mk | 2 | ||||
-rw-r--r-- | Project/RateLimiter.cpp | 6 | ||||
-rw-r--r-- | Project/RateLimiter.h | 6 | ||||
-rw-r--r-- | Project/Sum.cpp | 3 | ||||
-rw-r--r-- | Project/Sum.h | 2 | ||||
-rw-r--r-- | Project/TransferFunction.cpp | 11 | ||||
-rw-r--r-- | Project/TransferFunction.h | 6 |
23 files changed, 97 insertions, 104 deletions
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<double> time; std::vector<double> solution; std::vector<double> 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<ElementPlotData> 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<ElementPlotData> 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<double> 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<ElementPlotData> 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 <GL/gl.h> #include <GL/glu.h> +#include <wx/progdlg.h> + #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<ControlElement*> controlElementList, std::vector<ConnectionLine*> connectionLineList) +void ControlElementContainer::FillContainer(std::vector<ControlElement*> controlElementList, + std::vector<ConnectionLine*> 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<double> num = tf->GetNumerator(); - std::vector<double> den = tf->GetDenominator(); - for(unsigned int i = 0; i < num.size(); ++i) { - if(num[i] < timeStep) timeStep = num[i]; - } - for(unsigned int i = 0; i < den.size(); ++i) { - if(den[i] < timeStep) timeStep = den[i]; - } - } - m_timeStep = timeStep;*/ double prevSol = 0.0; double currentSol = 1.0; + double error = 1.0; + double prevError = 1.0; int numIt = 0; - while(std::abs(prevSol - currentSol) > minError || numIt <= minIteration) { + while(error > minError) { prevSol = currentSol; + prevError = error; SolveNextStep(input); currentSol = GetLastSolution(); numIt++; + error = std::abs(prevSol - currentSol); + if(std::abs(error - prevError) < 1e-1) { + if(m_timeStep < maxStep) { + m_timeStep *= 1.5; + } + } else if(std::abs(error - prevError) > 10) { + if(m_timeStep > minStep) { + m_timeStep /= 1.5; + } + } if(numIt >= maxIteration) return false; } - wxMessageBox(wxString::Format("%d\n%e\n%f", numIt, minError,currentSol)); - // m_timeStep = origTimeStep; + m_timeStep = origTimeStep; m_solutions.clear(); } @@ -168,9 +169,7 @@ void ControlElementSolver::SolveNextStep(double input) ConnectionLine* currentLine = firstConn; while(currentLine) { - // ConnectionLine* lastLine = currentLine; currentLine = SolveNextElement(currentLine); - // if(!currentLine) m_solutions.push_back(lastLine->GetValue()); } bool haveUnsolvedElement = true; @@ -224,7 +223,7 @@ ConnectionLine* ControlElementSolver::SolveNextElement(ConnectionLine* currentLi ControlElement* element = static_cast<ControlElement*>(*it); // Solve the unsolved parent. if(!element->IsSolved()) { - if(!element->Solve(currentLine->GetValue())) return NULL; + if(!element->Solve(currentLine->GetValue(), m_timeStep)) return NULL; element->SetSolved(); // Get the output node (must have one or will result NULL). 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<double> 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<double> 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<Signal> GetSignalList() const { return m_signalList; } virtual void SetSignalList(std::vector<Signal> 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<int>(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<int>(m_ss.A.size()); std::vector<double> 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<double> 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<double> m_x; std::vector<double> m_dx; - double m_timeStep = 1e-3; double m_error = 1e-3; + int m_maxIteration = 100; }; #endif // TRANSFERFUNCTION_H |