diff options
Diffstat (limited to 'Project')
-rw-r--r-- | Project/ControlEditor.cpp | 10 | ||||
-rw-r--r-- | Project/ControlElementSolver.cpp | 91 | ||||
-rw-r--r-- | Project/ControlElementSolver.h | 38 | ||||
-rw-r--r-- | Project/Electromechanical.cpp | 37 | ||||
-rw-r--r-- | Project/GeneratorStabForm.cpp | 8 | ||||
-rw-r--r-- | Project/IOControl.cpp | 8 | ||||
-rw-r--r-- | Project/IOControl.h | 5 | ||||
-rw-r--r-- | Project/IOControlForm.cpp | 19 | ||||
-rw-r--r-- | Project/Project.mk | 2 |
9 files changed, 164 insertions, 54 deletions
diff --git a/Project/ControlEditor.cpp b/Project/ControlEditor.cpp index 75fe6c3..d127a63 100644 --- a/Project/ControlEditor.cpp +++ b/Project/ControlEditor.cpp @@ -801,7 +801,15 @@ void ControlEditor::OnTestClick(wxCommandEvent& event) } } - solver.SolveNextStep(input); + // solver.SolveNextStep(input); + solver.SetInitialTerminalVoltage(input); + solver.SetActivePower(input); + solver.SetInitialMecPower(input); + solver.SetInitialVelocity(input); + solver.SetReactivePower(input); + solver.SetTerminalVoltage(input); + solver.SetVelocity(input); + solver.SolveNextStep(); if(printTime >= printStep) { time.push_back(currentTime); diff --git a/Project/ControlElementSolver.cpp b/Project/ControlElementSolver.cpp index 175a329..42fb2d3 100644 --- a/Project/ControlElementSolver.cpp +++ b/Project/ControlElementSolver.cpp @@ -30,47 +30,36 @@ #include "Sum.h" #include "TransferFunction.h" -ControlElementSolver::ControlElementSolver(ControlEditor* controlEditor, - double timeStep, - double integrationError, - bool startAllZero, - double input) +ControlElementSolver::ControlElementSolver(ControlEditor* controlEditor, double timeStep, double integrationError) { m_ctrlContainer = new ControlElementContainer(); m_ctrlContainer->FillContainer(controlEditor); - Initialize(controlEditor, timeStep, integrationError, startAllZero, input); + Initialize(controlEditor, timeStep, integrationError); } ControlElementSolver::ControlElementSolver(ControlElementContainer* ctrlContainer, double timeStep, double integrationError, - bool startAllZero, - double input, wxWindow* parent) { m_ctrlContainer = ctrlContainer; - Initialize(parent, timeStep, integrationError, startAllZero, input); + Initialize(parent, timeStep, integrationError); } -void ControlElementSolver::Initialize(wxWindow* parent, - double timeStep, - double integrationError, - bool startAllZero, - double input) +void ControlElementSolver::Initialize(wxWindow* parent, double timeStep, double integrationError) { // Check if the sistem have one input and one output bool fail = false; - wxString failMessage = ""; auto ioList = m_ctrlContainer->GetIOControlList(); - if(ioList.size() != 2) { + if(ioList.size() < 2) { fail = true; - failMessage = _("The control system must have one input and one output."); + m_failMessage = _("The control system must have at least 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) { + if(io->GetType() == Node::NODE_OUT && !haveInput) { m_inputControl = io; haveInput = true; } else if(io->GetType() == Node::NODE_IN) { @@ -80,37 +69,37 @@ void ControlElementSolver::Initialize(wxWindow* parent, } if(!fail && !haveInput) { fail = true; - failMessage = _("There is no input in the control system."); + m_failMessage = _("There is no input in the control system."); } if(!fail && !haveOutput) { fail = true; - failMessage = _("There is no output in the control system."); + m_failMessage = _("There is no output in the control system."); } if(!fail) { if(m_inputControl->GetChildList().size() == 0) { fail = true; - failMessage = _("Input not connected."); + m_failMessage = _("Input not connected."); } } m_timeStep = timeStep; m_integrationError = integrationError; if(!fail) { - if(!InitializeValues(input, startAllZero)) { + if(!InitializeValues(false)) { fail = true; - failMessage = _("It was not possible to initialize the control system."); + m_failMessage = _("It was not possible to initialize the control system."); } } if(fail) { - wxMessageDialog msgDialog(parent, failMessage, _("Error"), wxOK | wxCENTRE | wxICON_ERROR); + wxMessageDialog msgDialog(parent, m_failMessage, _("Error"), wxOK | wxCENTRE | wxICON_ERROR); msgDialog.ShowModal(); } else { m_isOK = true; } } -bool ControlElementSolver::InitializeValues(double input, bool startAllZero) +bool ControlElementSolver::InitializeValues(bool startAllZero) { // Reset Elements values auto elementList = m_ctrlContainer->GetControlElementsList(); @@ -147,7 +136,7 @@ bool ControlElementSolver::InitializeValues(double input, bool startAllZero) while(error > minError) { prevSol = currentSol; prevError = error; - SolveNextStep(input); + SolveNextStep(); currentSol = GetLastSolution(); numIt++; error = std::abs(prevSol - currentSol); @@ -160,7 +149,10 @@ bool ControlElementSolver::InitializeValues(double input, bool startAllZero) m_timeStep /= 1.5; } } - if(numIt >= maxIteration) return false; + if(numIt >= maxIteration) { + m_failMessage = _("It was not possible to initialize the control system."); + return false; + } } m_timeStep = origTimeStep; m_solutions.clear(); @@ -169,7 +161,7 @@ bool ControlElementSolver::InitializeValues(double input, bool startAllZero) return true; } -void ControlElementSolver::SolveNextStep(double input) +void ControlElementSolver::SolveNextStep() { // Set all elements as not solved auto elementList = m_ctrlContainer->GetControlElementsList(); @@ -183,12 +175,12 @@ void ControlElementSolver::SolveNextStep(double input) cLine->SetSolved(false); } - // Get first node and set input value on connected lines + // Get first node connection ConnectionLine* firstConn = static_cast<ConnectionLine*>(m_inputControl->GetChildList()[0]); - m_inputControl->SetSolved(); + /*m_inputControl->SetSolved(); firstConn->SetValue(input); firstConn->SetSolved(); - FillAllConnectedChildren(firstConn); + FillAllConnectedChildren(firstConn);*/ // Set value to the connected lines in constants auto constantList = m_ctrlContainer->GetConstantList(); @@ -203,6 +195,43 @@ void ControlElementSolver::SolveNextStep(double input) } } + // Set value to the connected lines in inputs + auto ioList = m_ctrlContainer->GetIOControlList(); + for(auto it = ioList.begin(), itEnd = ioList.end(); it != itEnd; ++it) { + IOControl* io = *it; + if(io->GetChildList().size() == 1) { + io->SetSolved(); + ConnectionLine* child = static_cast<ConnectionLine*>(io->GetChildList()[0]); + switch(io->GetValue()) { + case IOControl::IN_TERMINAL_VOLTAGE: { + child->SetValue(m_terminalVoltage); + } break; + case IOControl::IN_VELOCITY: { + child->SetValue(m_velocity); + } break; + case IOControl::IN_ACTIVE_POWER: { + child->SetValue(m_activePower); + } break; + case IOControl::IN_REACTIVE_POWER: { + child->SetValue(m_reactivePower); + } break; + case IOControl::IN_INITIAL_TERMINAL_VOLTAGE: { + child->SetValue(m_initTerminalVoltage); + } break; + case IOControl::IN_INITIAL_MEC_POWER: { + child->SetValue(m_initMecPower); + } break; + case IOControl::IN_INITIAL_VELOCITY: { + child->SetValue(m_initVelocity); + } break; + default: + break; + } + child->SetSolved(); + FillAllConnectedChildren(child); + } + } + ConnectionLine* currentLine = firstConn; while(currentLine) { currentLine = SolveNextElement(currentLine); diff --git a/Project/ControlElementSolver.h b/Project/ControlElementSolver.h index 44925f5..786ae78 100644 --- a/Project/ControlElementSolver.h +++ b/Project/ControlElementSolver.h @@ -46,25 +46,29 @@ class ControlElementSolver { public: ControlElementSolver() {} - ControlElementSolver(ControlEditor* controlEditor, - double timeStep = 1e-3, - double integrationError = 1e-3, - bool startAllZero = true, - double input = 0.0); + ControlElementSolver(ControlEditor* controlEditor, double timeStep = 1e-3, double integrationError = 1e-3); ControlElementSolver(ControlElementContainer* ctrlContainer, double timeStep = 1e-3, double integrationError = 1e-3, - bool startAllZero = true, - double input = 0.0, wxWindow* parent = NULL); virtual ~ControlElementSolver() {} - virtual bool InitializeValues(double input, bool startAllZero); - virtual void SolveNextStep(double input); + virtual bool InitializeValues(bool startAllZero); + virtual void SolveNextStep(); virtual std::vector<double> GetSolutions() { return m_solutions; } virtual double GetLastSolution() { return m_solutions[m_solutions.size() - 1]; } virtual bool IsOK() const { return m_isOK; } + virtual wxString GetErrorMessage() { return m_failMessage; } + void SetTerminalVoltage(double value) { m_terminalVoltage = value; } + void SetVelocity(double value) { m_velocity = value; } + void SetActivePower(double value) { m_activePower = value; } + void SetReactivePower(double value) { m_reactivePower = value; } + void SetInitialTerminalVoltage(double value) { m_initTerminalVoltage = value; } + void SetInitialMecPower(double value) { m_initMecPower = value; } + void SetInitialVelocity(double value) { m_initVelocity = value; } + double GetFieldVoltage() { return m_fieldVoltage; } + double GetMechanicalPower() { return m_mecPower; } protected: - void Initialize(wxWindow* parent, double timeStep, double integrationError, bool startAllZero, double input); + void Initialize(wxWindow* parent, double timeStep, double integrationError); void FillAllConnectedChildren(ConnectionLine* parent); ConnectionLine* SolveNextElement(ConnectionLine* currentLine); @@ -73,9 +77,21 @@ class ControlElementSolver double m_integrationError; std::vector<double> m_solutions; bool m_isOK = false; + wxString m_failMessage = _("Unknown error."); - IOControl* m_inputControl = NULL; + IOControl* m_inputControl = NULL; /**< First input control to be solved */ IOControl* m_outputControl = NULL; + // Inputs + double m_terminalVoltage = 0.0; + double m_velocity = 0.0; + double m_activePower = 0.0; + double m_reactivePower = 0.0; + double m_initTerminalVoltage = 0.0; + double m_initMecPower = 0.0; + double m_initVelocity = 0.0; + // Outputs + double m_fieldVoltage = 0.0; + double m_mecPower = 0.0; }; #endif // CONTROLELEMENTSOLVER_H diff --git a/Project/Electromechanical.cpp b/Project/Electromechanical.cpp index 4b8a711..b925234 100644 --- a/Project/Electromechanical.cpp +++ b/Project/Electromechanical.cpp @@ -606,10 +606,16 @@ bool Electromechanical::InitializeDynamicElements() // Initialize controllers if(data.useAVR) { if(data.avrSolver) delete data.avrSolver; - data.avrSolver = new ControlElementSolver(data.avr, m_timeStep * m_ctrlTimeStepMultiplier, m_tolerance, - false, std::abs(data.terminalVoltage), m_parent); + data.avrSolver = + new ControlElementSolver(data.avr, m_timeStep * m_ctrlTimeStepMultiplier, m_tolerance, m_parent); + data.avrSolver->SetTerminalVoltage(std::abs(data.terminalVoltage)); + data.avrSolver->SetInitialTerminalVoltage(std::abs(data.terminalVoltage)); + data.avrSolver->SetActivePower(dataPU.activePower); + data.avrSolver->SetReactivePower(dataPU.reactivePower); + data.avrSolver->InitializeValues(false); if(!data.avrSolver->IsOK()) { - m_errorMsg = _("Error on initializate the AVR of \"") + data.name + _("\"."); + m_errorMsg = _("Error on initializate the AVR of \"") + data.name + wxT("\".\n") + + data.avrSolver->GetErrorMessage(); syncGenerator->SetElectricalData(data); return false; } @@ -617,9 +623,16 @@ bool Electromechanical::InitializeDynamicElements() if(data.useSpeedGovernor) { if(data.speedGovSolver) delete data.speedGovSolver; data.speedGovSolver = new ControlElementSolver(data.speedGov, m_timeStep * m_ctrlTimeStepMultiplier, - m_tolerance, false, data.speed, m_parent); + m_tolerance, m_parent); + data.speedGovSolver->SetActivePower(dataPU.activePower); + data.speedGovSolver->SetReactivePower(dataPU.reactivePower); + data.speedGovSolver->SetVelocity(data.speed); + data.speedGovSolver->SetInitialVelocity(data.speed); + data.speedGovSolver->SetInitialMecPower(data.pm); + data.speedGovSolver->InitializeValues(false); if(!data.speedGovSolver->IsOK()) { - m_errorMsg = _("Error on initializate the speed governor of \"") + data.name + _("\"."); + m_errorMsg = _("Error on initializate the speed governor of \"") + data.name + wxT("\".\n") + + data.speedGovSolver->GetErrorMessage(); syncGenerator->SetElectricalData(data); return false; } @@ -901,12 +914,22 @@ bool Electromechanical::SolveSynchronousMachines() SyncGenerator* syncGenerator = *it; auto data = syncGenerator->GetElectricalData(); if(data.useAVR && data.avrSolver) { - for(int i = 0; i < ctrlRatio; ++i) data.avrSolver->SolveNextStep(std::abs(data.terminalVoltage)); + data.avrSolver->SetTerminalVoltage(std::abs(data.terminalVoltage)); + data.avrSolver->SetActivePower(data.electricalPower.real()); + data.avrSolver->SetReactivePower(data.electricalPower.imag()); + + for(int i = 0; i < ctrlRatio; ++i) data.avrSolver->SolveNextStep(); + data.fieldVoltage = data.initialFieldVoltage + data.avrSolver->GetLastSolution(); } if(data.useSpeedGovernor && data.speedGovSolver) { - for(int i = 0; i < ctrlRatio; ++i) data.speedGovSolver->SolveNextStep(data.speed); + data.speedGovSolver->SetVelocity(data.speed); + data.speedGovSolver->SetActivePower(data.electricalPower.real()); + data.speedGovSolver->SetReactivePower(data.electricalPower.imag()); + + for(int i = 0; i < ctrlRatio; ++i) data.speedGovSolver->SolveNextStep(); + data.pm = data.speedGovSolver->GetLastSolution(); } syncGenerator->SetElectricalData(data); diff --git a/Project/GeneratorStabForm.cpp b/Project/GeneratorStabForm.cpp index 7a68391..34f8027 100644 --- a/Project/GeneratorStabForm.cpp +++ b/Project/GeneratorStabForm.cpp @@ -67,7 +67,9 @@ void GeneratorStabForm::OnEditAVRButtonClick(wxCommandEvent& event) data.avr = new ControlElementContainer(); m_syncGenerator->SetElectricalData(data); } - ControlEditor* cEditor = new ControlEditor(m_parent, IOControl::IN_TERMINAL_VOLTAGE | IOControl::OUT_FIELD_VOLTAGE); + ControlEditor* cEditor = new ControlEditor( + m_parent, IOControl::IN_TERMINAL_VOLTAGE | IOControl::IN_ACTIVE_POWER | IOControl::IN_REACTIVE_POWER | + IOControl::IN_INITIAL_TERMINAL_VOLTAGE | IOControl::OUT_FIELD_VOLTAGE); cEditor->SetElementsList(data.avr->GetControlElementsList()); cEditor->SetConnectionsList(data.avr->GetConnectionLineList()); cEditor->SetControlContainer(data.avr); @@ -86,7 +88,9 @@ void GeneratorStabForm::OnSpeedGovernorButtonClick(wxCommandEvent& event) data.speedGov = new ControlElementContainer(); m_syncGenerator->SetElectricalData(data); } - ControlEditor* cEditor = new ControlEditor(m_parent, IOControl::IN_VELOCITY | IOControl::OUT_MEC_POWER); + ControlEditor* cEditor = + new ControlEditor(m_parent, IOControl::IN_VELOCITY | IOControl::IN_ACTIVE_POWER | IOControl::IN_REACTIVE_POWER | + IOControl::IN_INITIAL_VELOCITY | IOControl::OUT_MEC_POWER); cEditor->SetElementsList(data.speedGov->GetControlElementsList()); cEditor->SetConnectionsList(data.speedGov->GetConnectionLineList()); cEditor->SetControlContainer(data.speedGov); diff --git a/Project/IOControl.cpp b/Project/IOControl.cpp index bf40200..da3ef03 100644 --- a/Project/IOControl.cpp +++ b/Project/IOControl.cpp @@ -178,6 +178,14 @@ wxString IOControl::GenerateText() m_ioNodeType = Node::NODE_IN; return _("Pm"); } break; + case IN_INITIAL_TERMINAL_VOLTAGE: { + m_ioNodeType = Node::NODE_IN; + return _("Vt0"); + } break; + case IN_INITIAL_MEC_POWER: { + m_ioNodeType = Node::NODE_IN; + return _("Pm0"); + } break; } return ""; } diff --git a/Project/IOControl.h b/Project/IOControl.h index 307cc1a..eb0b763 100644 --- a/Project/IOControl.h +++ b/Project/IOControl.h @@ -41,7 +41,10 @@ class IOControl : public ControlElement IN_ACTIVE_POWER = 1 << 2, IN_REACTIVE_POWER = 1 << 3, OUT_FIELD_VOLTAGE = 1 << 4, - OUT_MEC_POWER = 1 << 5 + OUT_MEC_POWER = 1 << 5, + IN_INITIAL_TERMINAL_VOLTAGE = 1 << 6, + IN_INITIAL_MEC_POWER = 1 << 7, + IN_INITIAL_VELOCITY = 1 << 8, }; IOControl(int ioFlags, int id); diff --git a/Project/IOControlForm.cpp b/Project/IOControlForm.cpp index 583e534..592c5be 100644 --- a/Project/IOControlForm.cpp +++ b/Project/IOControlForm.cpp @@ -59,6 +59,25 @@ IOControlForm::IOControlForm(wxWindow* parent, IOControl* ioControl) : IOControl if(m_ioControl->GetValue() == IOControl::OUT_MEC_POWER) outChoiceNumber = (int)m_outputFlags.size() - 1; } + if(ioFlags & IOControl::IN_INITIAL_MEC_POWER) { + m_choiceOutput->Append(_("Initial mechanical power")); + m_outputFlags.push_back(IOControl::IN_INITIAL_MEC_POWER); + if(m_ioControl->GetValue() == IOControl::IN_INITIAL_MEC_POWER) outChoiceNumber = (int)m_outputFlags.size() - 1; + } + + if(ioFlags & IOControl::IN_INITIAL_TERMINAL_VOLTAGE) { + m_choiceOutput->Append(_("Initial terminal voltage")); + m_outputFlags.push_back(IOControl::IN_INITIAL_TERMINAL_VOLTAGE); + if(m_ioControl->GetValue() == IOControl::IN_INITIAL_TERMINAL_VOLTAGE) + outChoiceNumber = (int)m_outputFlags.size() - 1; + } + + if(ioFlags & IOControl::IN_INITIAL_VELOCITY) { + m_choiceOutput->Append(_("Initial velocity")); + m_outputFlags.push_back(IOControl::IN_INITIAL_VELOCITY); + if(m_ioControl->GetValue() == IOControl::IN_INITIAL_VELOCITY) outChoiceNumber = (int)m_outputFlags.size() - 1; + } + if(inChoiceNumber != -1) { m_choiceInput->SetSelection(inChoiceNumber); m_checkBoxInput->SetValue(true); diff --git a/Project/Project.mk b/Project/Project.mk index d74ffe2..6bb12a0 100644 --- a/Project/Project.mk +++ b/Project/Project.mk @@ -13,7 +13,7 @@ CurrentFileName := CurrentFilePath := CurrentFileFullPath := User :=NDSE-69 -Date :=05/10/2017 +Date :=06/10/2017 CodeLitePath :="C:/Program Files/CodeLite" LinkerName :=C:/TDM-GCC-64/bin/g++.exe SharedObjectLinkerName :=C:/TDM-GCC-64/bin/g++.exe -shared -fPIC |