diff options
author | Thales1330 <thaleslima.ufu@gmail.com> | 2017-01-06 20:49:28 -0200 |
---|---|---|
committer | Thales1330 <thaleslima.ufu@gmail.com> | 2017-01-06 20:49:28 -0200 |
commit | 2cd589742c6a4fd289d2f0696d844ccf18b917cb (patch) | |
tree | 42a64542d07a4997be5e216ffd54a27e39f76b56 | |
parent | 6a268dba6da88e0a371ce6358e4f43b0c3d08d7d (diff) | |
download | PSP.git-2cd589742c6a4fd289d2f0696d844ccf18b917cb.tar.gz PSP.git-2cd589742c6a4fd289d2f0696d844ccf18b917cb.tar.xz PSP.git-2cd589742c6a4fd289d2f0696d844ccf18b917cb.zip |
Several bugfixes on power elements
-rw-r--r-- | Buglist.txt | 34 | ||||
-rw-r--r-- | Project/Capacitor.cpp | 4 | ||||
-rw-r--r-- | Project/IndMotor.cpp | 10 | ||||
-rw-r--r-- | Project/Inductor.cpp | 6 | ||||
-rw-r--r-- | Project/Line.cpp | 2 | ||||
-rw-r--r-- | Project/Load.cpp | 4 | ||||
-rw-r--r-- | Project/Machines.cpp | 1 | ||||
-rw-r--r-- | Project/MainFrame.cpp | 10 | ||||
-rw-r--r-- | Project/Project.mk | 2 | ||||
-rw-r--r-- | Project/Project.project | 4 | ||||
-rw-r--r-- | Project/SyncGenerator.cpp | 69 | ||||
-rw-r--r-- | Project/SyncMotor.cpp | 10 | ||||
-rw-r--r-- | Project/Text.cpp | 57 | ||||
-rw-r--r-- | Project/Transformer.cpp | 6 | ||||
-rw-r--r-- | Project/Workspace.cpp | 154 | ||||
-rw-r--r-- | Project/Workspace.h | 4 |
16 files changed, 216 insertions, 161 deletions
diff --git a/Buglist.txt b/Buglist.txt deleted file mode 100644 index 2fb2758..0000000 --- a/Buglist.txt +++ /dev/null @@ -1,34 +0,0 @@ -BUG/TODO LIST [pt-br] - -PRIORIDADE 1: --> Textos exibidos incorretamente quando abertos (raramente). - -PRIORIDADE 2: --> Verificar a performance de c-style casting e c++ casting (static_cast/dynamic_cast); --> Ao arrastar os elementos que estão sendo colados são colocados; --> Ctrl + retângulo de seleção não está mantendo os elementos já selecionados; --> Atualizar a posição dos disjuntores quando um circuito for colado; --> Abrir o formulário do elemento após inserir o mesmo; --> Calcular posição média na opção de mover do menu ribbon considerando os textos; --> Potência reativa não está sendo distribuída apropriadamente em barras de tensão controlada caso tenha mais de uma máquina síncrona (com valores de reativos máximos/mínimos acionados); --> Dados de elementos desconectados/offline não estão sendo zerados/reiniciados; --> É necessário perguntar ao usuário se ele deseja trocar a tensão de todo o trecho conectado por linhas (quando é trocada a tensão de uma barra); --> Setas de fluxo de carga de linhas e transformadores não são atualizadas quando uma barra conectada é removida; --> Setas do fluxo de carga das máquinas elétricas não são atualizadas quando a barra conectada é rotacionada; --> Criar segurança caso um aquivo não possa ser gravado ou aberto; --> Linhas dos transformadores desalinhadas quando movidos. - -PRIORIDADE 3: --> Fluxo de potência dos elementos de ramo na unidade da potência base do sistema; --> Inserir texto com nome da barra juntamente com barra; --> Implementar dados em relação à base de potência do elemento (e não somente do sistema); --> Implementar fluxo de carga pelo método numérico de Newton-Raphson; --> Textos vetorizados ou aumentar/diminuir a resolução das texturas de acordo com o zoom; --> Separar sistemas não conectados e resolvê-los separadamente (criar lista de barras de oscilação prioritárias). - -OBJETIVOS GERAIS: --> Criar uma GUI amigável (wip); --> Cálculo de fluxo de carga (OK); --> Cálculo de faltas (curto simétrico e assimétrico / abertura de linhas); --> Criar GUI para definir controles genéricos; --> Cálculo eletromecânico.
\ No newline at end of file diff --git a/Project/Capacitor.cpp b/Project/Capacitor.cpp index 4f43f05..4bf595b 100644 --- a/Project/Capacitor.cpp +++ b/Project/Capacitor.cpp @@ -177,7 +177,9 @@ wxString Capacitor::GetTipText() const // TODO: Avoid reactive power calculation. double reactivePower = m_electricalData.reactivePower; - if(m_online) { + if(!m_online) + reactivePower = 0.0; + else { std::complex<double> v = static_cast<Bus*>(m_parentList[0])->GetEletricalData().voltage; reactivePower *= std::pow(std::abs(v), 2); } diff --git a/Project/IndMotor.cpp b/Project/IndMotor.cpp index 3a6c0fa..8fab5c4 100644 --- a/Project/IndMotor.cpp +++ b/Project/IndMotor.cpp @@ -91,7 +91,9 @@ wxString IndMotor::GetTipText() const { wxString tipText = m_electricalData.name; tipText += "\n"; - tipText += _("\nP = ") + wxString::FromDouble(m_electricalData.activePower, 5); + double activePower = m_electricalData.activePower; + if(!m_online) activePower = 0.0; + tipText += _("\nP = ") + wxString::FromDouble(activePower, 5); switch(m_electricalData.activePowerUnit) { case UNIT_PU: { tipText += _(" p.u."); @@ -108,7 +110,9 @@ wxString IndMotor::GetTipText() const default: break; } - tipText += _("\nQ = ") + wxString::FromDouble(m_electricalData.reactivePower, 5); + double reactivePower = m_electricalData.reactivePower; + if(!m_online) reactivePower = 0.0; + tipText += _("\nQ = ") + wxString::FromDouble(reactivePower, 5); switch(m_electricalData.reactivePowerUnit) { case UNIT_PU: { tipText += _(" p.u."); @@ -125,6 +129,6 @@ wxString IndMotor::GetTipText() const default: break; } - + return tipText; } diff --git a/Project/Inductor.cpp b/Project/Inductor.cpp index 69279df..b9a3da6 100644 --- a/Project/Inductor.cpp +++ b/Project/Inductor.cpp @@ -171,7 +171,9 @@ wxString Inductor::GetTipText() const // TODO: Avoid reactive power calculation. double reactivePower = m_electricalData.reactivePower; - if(m_online) { + if(!m_online) + reactivePower = 0.0; + else { std::complex<double> v = static_cast<Bus*>(m_parentList[0])->GetEletricalData().voltage; reactivePower *= std::pow(std::abs(v), 2); } @@ -193,6 +195,6 @@ wxString Inductor::GetTipText() const default: break; } - + return tipText; } diff --git a/Project/Line.cpp b/Project/Line.cpp index 7e1755e..66a43c5 100644 --- a/Project/Line.cpp +++ b/Project/Line.cpp @@ -239,7 +239,7 @@ void Line::MoveNode(Element* parent, wxPoint2DDouble position) // If the line is selected, move all the points, except the switches and buses points. if(m_selected) { - for(int i = 2; i < (int)m_pointList.size() - 2; i++) { + for(int i = 2; i < (int)m_pointList.size() - 1; i++) { m_pointList[i] = m_movePts[i] + position - m_moveStartPt; } } diff --git a/Project/Load.cpp b/Project/Load.cpp index 5eda960..3cce7a1 100644 --- a/Project/Load.cpp +++ b/Project/Load.cpp @@ -189,6 +189,10 @@ wxString Load::GetTipText() const // TODO: Avoid power calculation. double activePower = m_electricalData.activePower; double reactivePower = m_electricalData.reactivePower; + if(!m_online) { + activePower = 0.0; + reactivePower = 0.0; + } if(m_online && m_electricalData.loadType == CONST_IMPEDANCE) { std::complex<double> v = static_cast<Bus*>(m_parentList[0])->GetEletricalData().voltage; reactivePower *= std::pow(std::abs(v), 2); diff --git a/Project/Machines.cpp b/Project/Machines.cpp index bde70cb..6016df8 100644 --- a/Project/Machines.cpp +++ b/Project/Machines.cpp @@ -136,6 +136,7 @@ void Machines::RotateNode(Element* parent, bool clockwise) if(parent == m_parentList[0]) { m_pointList[0] = parent->RotateAtPosition(m_pointList[0], rotAngle); UpdateSwitchesPosition(); + UpdatePowerFlowArrowsPosition(); } } diff --git a/Project/MainFrame.cpp b/Project/MainFrame.cpp index 76c7b6f..ef9f327 100644 --- a/Project/MainFrame.cpp +++ b/Project/MainFrame.cpp @@ -170,11 +170,11 @@ void MainFrame::OnMoveClick(wxRibbonButtonBarEvent& event) { Workspace* workspace = static_cast<Workspace*>(m_auiNotebook->GetCurrentPage()); if(workspace) { - auto elementList = workspace->GetElementList(); + auto elementList = workspace->GetAllElements(); // Calculate the average position of selected elements. wxPoint2DDouble averagePos(0, 0); int numSelElements = 0; - for(auto it = elementList.begin(); it != elementList.end(); it++) { + for(auto it = elementList.begin(), itEnd = elementList.end(); it != itEnd; ++it) { Element* element = *it; if(element->IsSelected()) { averagePos += element->GetPosition(); @@ -183,7 +183,7 @@ void MainFrame::OnMoveClick(wxRibbonButtonBarEvent& event) } averagePos = wxPoint2DDouble(averagePos.m_x / double(numSelElements), averagePos.m_y / double(numSelElements)); // Set the move position to the average of selected elements. - for(auto it = elementList.begin(); it != elementList.end(); it++) { + for(auto it = elementList.begin(), itEnd = elementList.end(); it != itEnd; ++it) { Element* element = *it; if(element->IsSelected()) { element->StartMove(averagePos); @@ -218,7 +218,9 @@ void MainFrame::OnOpenClick(wxRibbonButtonBarEvent& event) newWorkspace->SetJustOpened(true); m_projectNumber++; } else { - // TODO: fail message. + wxMessageDialog msgDialog( + this, _("It was not possible to open the selected file."), _("Error"), wxOK | wxCENTRE | wxICON_ERROR); + msgDialog.ShowModal(); delete newWorkspace; } } diff --git a/Project/Project.mk b/Project/Project.mk index 08cc479..ea938a7 100644 --- a/Project/Project.mk +++ b/Project/Project.mk @@ -13,7 +13,7 @@ CurrentFileName := CurrentFilePath := CurrentFileFullPath := User :=Thales -Date :=05/01/2017 +Date :=06/01/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/Project.project b/Project/Project.project index ce1e9dd..9c325b1 100644 --- a/Project/Project.project +++ b/Project/Project.project @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="UTF-8"?> -<CodeLite_Project Name="Project" InternalType="GUI"> +<CodeLite_Project Name="Project" InternalType="GUI" Version="10.0.0"> <Plugins> - <Plugin Name="CppCheck"/> <Plugin Name="qmake"> <![CDATA[00020001N0005Debug0000000000000001N0007Release000000000000]]> </Plugin> + <Plugin Name="CppCheck"/> </Plugins> <Description/> <Dependencies/> diff --git a/Project/SyncGenerator.cpp b/Project/SyncGenerator.cpp index 0fecff5..17a7e91 100644 --- a/Project/SyncGenerator.cpp +++ b/Project/SyncGenerator.cpp @@ -1,41 +1,43 @@ #include "SyncMachineForm.h" #include "SyncGenerator.h" -SyncGenerator::SyncGenerator() : Machines() +SyncGenerator::SyncGenerator() + : Machines() { Init(); } -SyncGenerator::SyncGenerator(wxString name) : Machines() +SyncGenerator::SyncGenerator(wxString name) + : Machines() { - Init(); - m_electricalData.name = name; + Init(); + m_electricalData.name = name; } SyncGenerator::~SyncGenerator() {} void SyncGenerator::Init() { - int numPtsSine = 10; + int numPtsSine = 10; double mx = 15.0; double my = 10.0; double pi = 3.14159265359; for(int i = 0; i <= numPtsSine; i++) { - double x = (2.0 * pi / double(numPtsSine)) * double(i) - pi; - double y = std::sin(x); - m_sinePts.push_back(wxPoint2DDouble((x / pi) * mx, y * my)); - } + double x = (2.0 * pi / double(numPtsSine)) * double(i) - pi; + double y = std::sin(x); + m_sinePts.push_back(wxPoint2DDouble((x / pi) * mx, y * my)); + } } void SyncGenerator::DrawSymbol() const { // Draw sine. - std::vector<wxPoint2DDouble> sinePts; - for(int i = 0; i < (int)m_sinePts.size(); i++) { - sinePts.push_back(m_sinePts[i] + m_position); - } - DrawLine(sinePts); + std::vector<wxPoint2DDouble> sinePts; + for(int i = 0; i < (int)m_sinePts.size(); i++) { + sinePts.push_back(m_sinePts[i] + m_position); + } + DrawLine(sinePts); } bool SyncGenerator::GetContextMenu(wxMenu& menu) { @@ -46,12 +48,12 @@ bool SyncGenerator::GetContextMenu(wxMenu& menu) bool SyncGenerator::ShowForm(wxWindow* parent, Element* element) { - SyncMachineForm* generatorForm = new SyncMachineForm(parent, this); + SyncMachineForm* generatorForm = new SyncMachineForm(parent, this); generatorForm->SetTitle(_("Generator")); if(generatorForm->ShowModal() == wxID_OK) { - generatorForm->Destroy(); - return true; - } + generatorForm->Destroy(); + return true; + } generatorForm->Destroy(); return false; @@ -59,8 +61,8 @@ bool SyncGenerator::ShowForm(wxWindow* parent, Element* element) SyncGeneratorElectricalData SyncGenerator::GetPUElectricalData(double systemPowerBase) { - SyncGeneratorElectricalData data = m_electricalData; - switch(data.activePowerUnit) { + SyncGeneratorElectricalData data = m_electricalData; + switch(data.activePowerUnit) { case UNIT_W: { data.activePower = data.activePower / systemPowerBase; data.activePowerUnit = UNIT_PU; @@ -92,7 +94,7 @@ SyncGeneratorElectricalData SyncGenerator::GetPUElectricalData(double systemPowe default: break; } - switch(data.maxReactiveUnit) { + switch(data.maxReactiveUnit) { case UNIT_VAr: { data.maxReactive = data.maxReactive / systemPowerBase; data.maxReactiveUnit = UNIT_PU; @@ -108,7 +110,7 @@ SyncGeneratorElectricalData SyncGenerator::GetPUElectricalData(double systemPowe default: break; } - switch(data.minReactiveUnit) { + switch(data.minReactiveUnit) { case UNIT_VAr: { data.minReactive = data.minReactive / systemPowerBase; data.minReactiveUnit = UNIT_PU; @@ -124,11 +126,12 @@ SyncGeneratorElectricalData SyncGenerator::GetPUElectricalData(double systemPowe default: break; } - - return data; + + return data; } -void SyncGenerator::SetNominalVoltage(std::vector<double> nominalVoltage, std::vector<ElectricalUnit> nominalVoltageUnit) +void SyncGenerator::SetNominalVoltage(std::vector<double> nominalVoltage, + std::vector<ElectricalUnit> nominalVoltageUnit) { if(nominalVoltage.size() > 0) { m_electricalData.nominalVoltage = nominalVoltage[0]; @@ -138,16 +141,18 @@ void SyncGenerator::SetNominalVoltage(std::vector<double> nominalVoltage, std::v Element* SyncGenerator::GetCopy() { - SyncGenerator* copy = new SyncGenerator(); - *copy = *this; - return copy; + SyncGenerator* copy = new SyncGenerator(); + *copy = *this; + return copy; } wxString SyncGenerator::GetTipText() const { wxString tipText = m_electricalData.name; tipText += "\n"; - tipText += _("\nP = ") + wxString::FromDouble(m_electricalData.activePower, 5); + double activePower = m_electricalData.activePower; + if(!m_online) activePower = 0.0; + tipText += _("\nP = ") + wxString::FromDouble(activePower, 5); switch(m_electricalData.activePowerUnit) { case UNIT_PU: { tipText += _(" p.u."); @@ -164,7 +169,9 @@ wxString SyncGenerator::GetTipText() const default: break; } - tipText += _("\nQ = ") + wxString::FromDouble(m_electricalData.reactivePower, 5); + double reactivePower = m_electricalData.reactivePower; + if(!m_online) reactivePower = 0.0; + tipText += _("\nQ = ") + wxString::FromDouble(reactivePower, 5); switch(m_electricalData.reactivePowerUnit) { case UNIT_PU: { tipText += _(" p.u."); @@ -181,6 +188,6 @@ wxString SyncGenerator::GetTipText() const default: break; } - + return tipText; } diff --git a/Project/SyncMotor.cpp b/Project/SyncMotor.cpp index ba45906..c1e1986 100644 --- a/Project/SyncMotor.cpp +++ b/Project/SyncMotor.cpp @@ -116,7 +116,9 @@ wxString SyncMotor::GetTipText() const { wxString tipText = m_electricalData.name; tipText += "\n"; - tipText += _("\nP = ") + wxString::FromDouble(m_electricalData.activePower, 5); + double activePower = m_electricalData.activePower; + if(!m_online) activePower = 0.0; + tipText += _("\nP = ") + wxString::FromDouble(activePower, 5); switch(m_electricalData.activePowerUnit) { case UNIT_PU: { tipText += _(" p.u."); @@ -133,7 +135,9 @@ wxString SyncMotor::GetTipText() const default: break; } - tipText += _("\nQ = ") + wxString::FromDouble(m_electricalData.reactivePower, 5); + double reactivePower = m_electricalData.reactivePower; + if(!m_online) reactivePower = 0.0; + tipText += _("\nQ = ") + wxString::FromDouble(reactivePower, 5); switch(m_electricalData.reactivePowerUnit) { case UNIT_PU: { tipText += _(" p.u."); @@ -150,6 +154,6 @@ wxString SyncMotor::GetTipText() const default: break; } - + return tipText; } diff --git a/Project/Text.cpp b/Project/Text.cpp index 5168329..8c76956 100644 --- a/Project/Text.cpp +++ b/Project/Text.cpp @@ -302,45 +302,44 @@ void Text::UpdateText(double systemPowerBase) SetText(data.name); } break; case DATA_ACTIVE_POWER: { + double activePower = data.activePower; + if(!syncGenerator->IsOnline()) activePower = 0.0; switch(m_unit) { case UNIT_PU: { - SetText(wxString::FromDouble(data.activePower, m_decimalPlaces) + " p.u."); + SetText(wxString::FromDouble(activePower, m_decimalPlaces) + " p.u."); } break; case UNIT_W: { - SetText( - wxString::FromDouble(data.activePower * systemPowerBase, m_decimalPlaces) + " W"); + SetText(wxString::FromDouble(activePower * systemPowerBase, m_decimalPlaces) + " W"); } break; case UNIT_kW: { SetText( - wxString::FromDouble(data.activePower * systemPowerBase / 1e3, m_decimalPlaces) + - " kW"); + wxString::FromDouble(activePower * systemPowerBase / 1e3, m_decimalPlaces) + " kW"); } break; case UNIT_MW: { SetText( - wxString::FromDouble(data.activePower * systemPowerBase / 1e6, m_decimalPlaces) + - " MW"); + wxString::FromDouble(activePower * systemPowerBase / 1e6, m_decimalPlaces) + " MW"); } break; default: break; } } break; case DATA_REACTIVE_POWER: { + double reactivePower = data.reactivePower; + if(!syncGenerator->IsOnline()) reactivePower = 0.0; switch(m_unit) { case UNIT_PU: { - SetText(wxString::FromDouble(data.reactivePower, m_decimalPlaces) + " p.u."); + SetText(wxString::FromDouble(reactivePower, m_decimalPlaces) + " p.u."); } break; case UNIT_VAr: { - SetText(wxString::FromDouble(data.reactivePower * systemPowerBase, m_decimalPlaces) + - " VAr"); + SetText( + wxString::FromDouble(reactivePower * systemPowerBase, m_decimalPlaces) + " VAr"); } break; case UNIT_kVAr: { - SetText( - wxString::FromDouble(data.reactivePower * systemPowerBase / 1e3, m_decimalPlaces) + + SetText(wxString::FromDouble(reactivePower * systemPowerBase / 1e3, m_decimalPlaces) + " kVAr"); } break; case UNIT_MVAr: { - SetText( - wxString::FromDouble(data.reactivePower * systemPowerBase / 1e6, m_decimalPlaces) + + SetText(wxString::FromDouble(reactivePower * systemPowerBase / 1e6, m_decimalPlaces) + " MVAr"); } break; default: @@ -350,6 +349,7 @@ void Text::UpdateText(double systemPowerBase) case DATA_SC_CURRENT: { double faultCurrent[3] = { std::abs(data.faultCurrent[0]), std::abs(data.faultCurrent[1]), std::abs(data.faultCurrent[2]) }; + if(!syncGenerator->IsOnline()) faultCurrent[0] = faultCurrent[1] = faultCurrent[2] = 0.0; switch(m_unit) { case UNIT_PU: { wxString str = @@ -398,6 +398,7 @@ void Text::UpdateText(double systemPowerBase) } break; case DATA_PF_ACTIVE: { double activePF = std::real(data.powerFlow[m_direction]); + if(!line->IsOnline()) activePF = 0.0; switch(m_unit) { case UNIT_PU: { SetText(wxString::FromDouble(activePF, m_decimalPlaces) + " p.u."); @@ -419,6 +420,7 @@ void Text::UpdateText(double systemPowerBase) } break; case DATA_PF_REACTIVE: { double reactivePF = std::imag(data.powerFlow[m_direction]); + if(!line->IsOnline()) reactivePF = 0.0; switch(m_unit) { case UNIT_PU: { SetText(wxString::FromDouble(reactivePF, m_decimalPlaces) + " p.u."); @@ -440,6 +442,7 @@ void Text::UpdateText(double systemPowerBase) } break; case DATA_PF_LOSSES: { double losses = std::abs(std::real(data.powerFlow[0]) + std::real(data.powerFlow[1])); + if(!line->IsOnline()) losses = 0.0; switch(m_unit) { case UNIT_PU: { SetText(wxString::FromDouble(losses, m_decimalPlaces) + " p.u."); @@ -459,6 +462,7 @@ void Text::UpdateText(double systemPowerBase) } break; case DATA_PF_CURRENT: { double current = std::abs(data.current[m_direction]); + if(!line->IsOnline()) current = 0.0; switch(m_unit) { case UNIT_PU: { SetText(wxString::FromDouble(current, m_decimalPlaces) + " p.u."); @@ -476,6 +480,7 @@ void Text::UpdateText(double systemPowerBase) case DATA_SC_CURRENT: { double faultCurrent[3] = { std::abs(data.faultCurrent[m_direction][0]), std::abs(data.faultCurrent[m_direction][1]), std::abs(data.faultCurrent[m_direction][2]) }; + if(!line->IsOnline()) faultCurrent[0] = faultCurrent[1] = faultCurrent[2] = 0.0; switch(m_unit) { case UNIT_PU: { wxString str = @@ -528,6 +533,7 @@ void Text::UpdateText(double systemPowerBase) } break; case DATA_PF_ACTIVE: { double activePF = std::real(data.powerFlow[m_direction]); + if(!transformer->IsOnline()) activePF = 0.0; switch(m_unit) { case UNIT_PU: { SetText(wxString::FromDouble(activePF, m_decimalPlaces) + " p.u."); @@ -549,6 +555,7 @@ void Text::UpdateText(double systemPowerBase) } break; case DATA_PF_REACTIVE: { double reactivePF = std::imag(data.powerFlow[m_direction]); + if(!transformer->IsOnline()) reactivePF = 0.0; switch(m_unit) { case UNIT_PU: { SetText(wxString::FromDouble(reactivePF, m_decimalPlaces) + " p.u."); @@ -570,6 +577,7 @@ void Text::UpdateText(double systemPowerBase) } break; case DATA_PF_LOSSES: { double losses = std::abs(std::real(data.powerFlow[0]) + std::real(data.powerFlow[1])); + if(!transformer->IsOnline()) losses = 0.0; switch(m_unit) { case UNIT_PU: { SetText(wxString::FromDouble(losses, m_decimalPlaces) + " p.u."); @@ -589,6 +597,7 @@ void Text::UpdateText(double systemPowerBase) } break; case DATA_PF_CURRENT: { double current = std::abs(data.current[m_direction]); + if(!transformer->IsOnline()) current = 0.0; switch(m_unit) { case UNIT_PU: { SetText(wxString::FromDouble(current, m_decimalPlaces) + " p.u."); @@ -609,6 +618,7 @@ void Text::UpdateText(double systemPowerBase) case DATA_SC_CURRENT: { double faultCurrent[3] = { std::abs(data.faultCurrent[m_direction][0]), std::abs(data.faultCurrent[m_direction][1]), std::abs(data.faultCurrent[m_direction][2]) }; + if(!transformer->IsOnline()) faultCurrent[0] = faultCurrent[1] = faultCurrent[2] = 0.0; switch(m_unit) { case UNIT_PU: { wxString str = @@ -662,6 +672,7 @@ void Text::UpdateText(double systemPowerBase) std::complex<double> v = static_cast<Bus*>(load->GetParentList()[0])->GetEletricalData().voltage; sPower = std::pow(std::abs(v), 2) * sPower; } + if(!load->IsOnline()) sPower = std::complex<double>(0.0, 0.0); switch(m_dataType) { case DATA_NAME: { SetText(data.name); @@ -717,6 +728,7 @@ void Text::UpdateText(double systemPowerBase) if(syncMotor) { SyncMotorElectricalData data = syncMotor->GetPUElectricalData(systemPowerBase); std::complex<double> sPower(data.activePower, data.reactivePower); + if(!syncMotor->IsOnline()) sPower = std::complex<double>(0.0, 0.0); switch(m_dataType) { case DATA_NAME: { SetText(data.name); @@ -772,6 +784,7 @@ void Text::UpdateText(double systemPowerBase) if(indMotor) { IndMotorElectricalData data = indMotor->GetPUElectricalData(systemPowerBase); std::complex<double> sPower(data.activePower, data.reactivePower); + if(!indMotor->IsOnline()) sPower = std::complex<double>(0.0, 0.0); switch(m_dataType) { case DATA_NAME: { SetText(data.name); @@ -826,9 +839,12 @@ void Text::UpdateText(double systemPowerBase) Capacitor* capacitor = static_cast<Capacitor*>(m_element); if(capacitor) { CapacitorElectricalData data = capacitor->GetPUElectricalData(systemPowerBase); - double reativePower = -data.reactivePower; - if(capacitor->IsOnline()) { - std::complex<double> v = static_cast<Bus*>(capacitor->GetParentList()[0])->GetEletricalData().voltage; + double reativePower = data.reactivePower; + if(!capacitor->IsOnline()) + reativePower = 0.0; + else { + std::complex<double> v = + static_cast<Bus*>(capacitor->GetParentList()[0])->GetEletricalData().voltage; reativePower *= std::pow(std::abs(v), 2); } switch(m_dataType) { @@ -865,8 +881,11 @@ void Text::UpdateText(double systemPowerBase) if(inductor) { InductorElectricalData data = inductor->GetPUElectricalData(systemPowerBase); double reativePower = data.reactivePower; - if(inductor->IsOnline()) { - std::complex<double> v = static_cast<Bus*>(inductor->GetParentList()[0])->GetEletricalData().voltage; + if(!inductor->IsOnline()) + reativePower = 0.0; + else { + std::complex<double> v = + static_cast<Bus*>(inductor->GetParentList()[0])->GetEletricalData().voltage; reativePower *= std::pow(std::abs(v), 2); } switch(m_dataType) { diff --git a/Project/Transformer.cpp b/Project/Transformer.cpp index 7db7813..3d3156a 100644 --- a/Project/Transformer.cpp +++ b/Project/Transformer.cpp @@ -56,11 +56,11 @@ bool Transformer::AddParent(Element* parent, wxPoint2DDouble position) // Set the transformer rectangle. m_width = 70.0; m_height = 40.0; - m_rect = wxRect2DDouble(m_position.m_x - m_width / 2.0, m_position.m_y - m_height / 2.0, m_width, m_height); + SetPosition(m_position); // This method calculates the rectangle propely. // Set the "side" points. - m_pointList.push_back(wxPoint2DDouble(m_rect.GetPosition() + wxPoint2DDouble(-10, m_height / 2.0))); + m_pointList.push_back(wxPoint2DDouble(m_rect.GetPosition() + wxPoint2DDouble(-10 - m_borderSize, m_height / 2.0))); m_pointList.push_back( - wxPoint2DDouble(m_rect.GetPosition() + wxPoint2DDouble(m_width + 10, m_height / 2.0))); + wxPoint2DDouble(m_rect.GetPosition() + wxPoint2DDouble(m_width + 10 + m_borderSize, m_height / 2.0))); // Set first switch point. wxPoint2DDouble secondPoint = parentPt; diff --git a/Project/Workspace.cpp b/Project/Workspace.cpp index ef0a911..e668bf3 100644 --- a/Project/Workspace.cpp +++ b/Project/Workspace.cpp @@ -163,16 +163,19 @@ void Workspace::SetViewport() void Workspace::OnLeftClickDown(wxMouseEvent& event) { + wxPoint clickPoint = event.GetPosition(); bool foundElement = false; - if(m_mode == MODE_INSERT_TEXT || m_mode == MODE_PASTE) { + Element* newElement = NULL; + bool showNewElementForm = false; + if(m_mode == MODE_INSERT_TEXT || m_mode == MODE_PASTE || m_mode == MODE_DRAG_PASTE) { m_mode = MODE_EDIT; } else if(m_mode == MODE_INSERT || m_mode == MODE_DRAG_INSERT || m_mode == MODE_DRAG_INSERT_TEXT) { // Get the last element inserted on the list. - Element* newElement = *(m_elementList.end() - 1); - for(auto it = m_elementList.begin(); it != m_elementList.end(); ++it) { + newElement = *(m_elementList.end() - 1); + for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) { Element* element = *it; // Clicked in any element. - if(element->Contains(m_camera->ScreenToWorld(event.GetPosition()))) { + if(element->Contains(m_camera->ScreenToWorld(clickPoint))) { // Click at a bus. if(typeid(*element) == typeid(Bus)) { // Select the bus. @@ -180,8 +183,10 @@ void Workspace::OnLeftClickDown(wxMouseEvent& event) foundElement = true; // Element found. // Add the new element's parent. If the element being inserted returns true, back to // edit mode. - if(newElement->AddParent(element, m_camera->ScreenToWorld(event.GetPosition()))) { + if(newElement->AddParent(element, m_camera->ScreenToWorld(clickPoint))) { ValidateElementsVoltages(); + m_timer->Stop(); + showNewElementForm = true; m_mode = MODE_EDIT; } } @@ -190,27 +195,27 @@ void Workspace::OnLeftClickDown(wxMouseEvent& event) // The line element can have an indefined number of points. if(!foundElement) { if(typeid(*newElement) == typeid(Line)) { - newElement->AddPoint(m_camera->ScreenToWorld(event.GetPosition())); + newElement->AddPoint(m_camera->ScreenToWorld(clickPoint)); } } foundElement = true; } else { bool clickPickbox = false; - for(auto it = m_elementList.begin(); it != m_elementList.end(); ++it) { + for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) { Element* element = *it; element->ResetPickboxes(); // Reset pickbox state. // Set movement initial position (not necessarily will be moved). - element->StartMove(m_camera->ScreenToWorld(event.GetPosition())); + element->StartMove(m_camera->ScreenToWorld(clickPoint)); // Click in selected element node. - if(element->NodeContains(m_camera->ScreenToWorld(event.GetPosition())) != 0 && element->IsSelected()) { + if(element->NodeContains(m_camera->ScreenToWorld(clickPoint)) != 0 && element->IsSelected()) { m_mode = MODE_MOVE_NODE; foundElement = true; } // Click in an element. - else if(element->Contains(m_camera->ScreenToWorld(event.GetPosition()))) { + else if(element->Contains(m_camera->ScreenToWorld(clickPoint))) { if(!foundElement) { // Select and show pickbox. element->SetSelected(); @@ -218,7 +223,7 @@ void Workspace::OnLeftClickDown(wxMouseEvent& event) foundElement = true; } // If pickbox contains the click, move the pickbox - if(element->PickboxContains(m_camera->ScreenToWorld(event.GetPosition()))) { + if(element->PickboxContains(m_camera->ScreenToWorld(clickPoint))) { m_mode = MODE_MOVE_PICKBOX; clickPickbox = true; } @@ -229,18 +234,18 @@ void Workspace::OnLeftClickDown(wxMouseEvent& event) } // Click in a switch. - else if(element->SwitchesContains(m_camera->ScreenToWorld(event.GetPosition()))) { + else if(element->SwitchesContains(m_camera->ScreenToWorld(clickPoint))) { element->SetOnline(element->IsOnline() ? false : true); } } // Text element - for(auto it = m_textList.begin(); it != m_textList.end(); it++) { + for(auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; ++it) { Text* text = *it; - text->StartMove(m_camera->ScreenToWorld(event.GetPosition())); + text->StartMove(m_camera->ScreenToWorld(clickPoint)); - if(text->Contains(m_camera->ScreenToWorld(event.GetPosition()))) { + if(text->Contains(m_camera->ScreenToWorld(clickPoint))) { if(!foundElement) { text->SetSelected(); m_mode = MODE_MOVE_ELEMENT; @@ -252,11 +257,16 @@ void Workspace::OnLeftClickDown(wxMouseEvent& event) if(!foundElement) { m_mode = MODE_SELECTION_RECT; - m_startSelRect = m_camera->ScreenToWorld(event.GetPosition()); + m_startSelRect = m_camera->ScreenToWorld(clickPoint); } Redraw(); UpdateStatusBar(); + + if(showNewElementForm) { + if(newElement) newElement->ShowForm(this, newElement); + } + event.Skip(); } @@ -272,9 +282,10 @@ void Workspace::OnLeftDoubleClick(wxMouseEvent& event) if(element->Contains(m_camera->ScreenToWorld(event.GetPosition()))) { bool elementIsBus = false; Bus oldBus; - if(Bus* bus = dynamic_cast<Bus*>(element)) { + Bus* currentBus = NULL; + if((currentBus = dynamic_cast<Bus*>(element))) { elementIsBus = true; - oldBus = *bus; + oldBus = *currentBus; } m_timer->Stop(); element->ShowForm(this, element); @@ -285,27 +296,25 @@ void Workspace::OnLeftDoubleClick(wxMouseEvent& event) // propagated through the lines if(elementIsBus) { // The voltage was changed - if(oldBus.GetEletricalData().nominalVoltage != - static_cast<Bus*>(element)->GetEletricalData().nominalVoltage || - oldBus.GetEletricalData().nominalVoltageUnit != - static_cast<Bus*>(element)->GetEletricalData().nominalVoltageUnit) { - // Check if the lines has this bus as parent - for(auto it = m_elementList.begin(); it != m_elementList.end(); it++) { - Element* child = *it; - - bool elementIsParent = false; + if(oldBus.GetEletricalData().nominalVoltage != currentBus->GetEletricalData().nominalVoltage || + oldBus.GetEletricalData().nominalVoltageUnit != currentBus->GetEletricalData().nominalVoltageUnit) { + // Check if the bus has line as child. + std::vector<Element*> childList = element->GetChildList(); + for(auto itc = childList.begin(), itcEnd = childList.end(); itc != itcEnd; ++itc) { + Element* child = *itc; if(typeid(*child) == typeid(Line)) { - for(int i = 0; i < (int)child->GetParentList().size(); i++) { - Element* parent = child->GetParentList()[i]; - if(parent == element) { - // TODO: Ask the user if he wants to change all - // voltages - ValidateBusesVoltages(element); - elementIsParent = true; - } + wxMessageDialog msgDialog(this, _("Do you want to change the rated voltage of the path?"), + _("Warning"), wxYES_NO | wxCENTRE | wxICON_WARNING); + if(msgDialog.ShowModal() == wxID_YES) + ValidateBusesVoltages(element); + else { + auto data = currentBus->GetEletricalData(); + data.nominalVoltage = oldBus.GetEletricalData().nominalVoltage; + data.nominalVoltageUnit = oldBus.GetEletricalData().nominalVoltageUnit; + currentBus->SetElectricalData(data); } + break; } - if(elementIsParent) break; } } ValidateElementsVoltages(); @@ -353,11 +362,6 @@ void Workspace::OnRightClickDown(wxMouseEvent& event) if(!menu.GetClientData()) break; } element->ResetPickboxes(); - - /*if(redraw) { - Redraw(); - redraw = false; - }*/ } } } @@ -402,7 +406,7 @@ void Workspace::OnLeftClickUp(wxMouseEvent& event) if(m_mode == MODE_SELECTION_RECT) { if(element->Intersects(m_selectionRect)) { element->SetSelected(); - } else { + } else if(!event.ControlDown()) { element->SetSelected(false); } } else if(m_mode == MODE_MOVE_NODE) { @@ -444,7 +448,7 @@ void Workspace::OnLeftClickUp(wxMouseEvent& event) if(m_mode == MODE_SELECTION_RECT) { if(text->Intersects(m_selectionRect)) { text->SetSelected(); - } else { + } else if(!event.ControlDown()) { text->SetSelected(false); } } else if(!event.ControlDown()) { @@ -492,7 +496,8 @@ void Workspace::OnMouseMotion(wxMouseEvent& event) case MODE_DRAG: case MODE_DRAG_INSERT: - case MODE_DRAG_INSERT_TEXT: { + case MODE_DRAG_INSERT_TEXT: + case MODE_DRAG_PASTE: { m_camera->SetTranslation(event.GetPosition()); redraw = true; } break; @@ -603,28 +608,54 @@ void Workspace::OnMouseMotion(wxMouseEvent& event) void Workspace::OnMiddleDown(wxMouseEvent& event) { // Set to drag mode. - if(m_mode != MODE_INSERT && m_mode != MODE_INSERT_TEXT && m_mode != MODE_DRAG_INSERT && - m_mode != MODE_DRAG_INSERT_TEXT) { + switch(m_mode) { + case MODE_INSERT: { + m_mode = MODE_DRAG_INSERT; + } break; + case MODE_INSERT_TEXT: { + m_mode = MODE_DRAG_INSERT_TEXT; + } break; + case MODE_PASTE: { + m_mode = MODE_DRAG_PASTE; + } break; + default: { + m_mode = MODE_DRAG; + } break; + } + /*if(m_mode != MODE_INSERT && m_mode != MODE_INSERT_TEXT && m_mode == MODE_PASTE && m_mode != MODE_DRAG_INSERT && + m_mode != MODE_DRAG_INSERT_TEXT && m_mode != MODE_DRAG_PASTE) { m_mode = MODE_DRAG; } else if(m_mode == MODE_INSERT_TEXT) { m_mode = MODE_DRAG_INSERT_TEXT; + }else if(m_mode == MODE_PASTE) { + m_mode = MODE_DRAG_PASTE; } else { m_mode = MODE_DRAG_INSERT; - } + }*/ m_camera->StartTranslation(m_camera->ScreenToWorld(event.GetPosition())); UpdateStatusBar(); } void Workspace::OnMiddleUp(wxMouseEvent& event) { - if(m_mode != MODE_INSERT && m_mode != MODE_INSERT_TEXT && m_mode != MODE_DRAG_INSERT && - m_mode != MODE_DRAG_INSERT_TEXT) { - // Set to edit mode back. - m_mode = MODE_EDIT; - } else if(m_mode == MODE_DRAG_INSERT_TEXT) { - m_mode = MODE_INSERT_TEXT; - } else if(m_mode == MODE_DRAG_INSERT) { - m_mode = MODE_INSERT; + switch(m_mode) { + case MODE_DRAG_INSERT: { + m_mode = MODE_INSERT; + } break; + case MODE_DRAG_INSERT_TEXT: { + m_mode = MODE_INSERT_TEXT; + } break; + case MODE_DRAG_PASTE: { + m_mode = MODE_PASTE; + } break; + case MODE_INSERT: + case MODE_INSERT_TEXT: + case MODE_PASTE: { + // Does nothing. + } break; + default: { + m_mode = MODE_EDIT; + } break; } UpdateStatusBar(); } @@ -822,7 +853,8 @@ void Workspace::UpdateStatusBar() m_statusBar->SetStatusText(_("MODE: DRAG"), 1); } break; - case MODE_PASTE: { + case MODE_PASTE: + case MODE_DRAG_PASTE: { m_statusBar->SetStatusText(_("MODE: PASTE"), 1); } @@ -1371,3 +1403,13 @@ void Workspace::OnIdle(wxIdleEvent& event) Redraw(); } } + +std::vector<Element*> Workspace::GetAllElements() const +{ + std::vector<Element*> allElements; + + for(auto it = m_elementList.begin(), itEnd = m_elementList.end(); it != itEnd; ++it) allElements.push_back(*it); + for(auto it = m_textList.begin(), itEnd = m_textList.end(); it != itEnd; ++it) allElements.push_back(*it); + + return allElements; +} diff --git a/Project/Workspace.h b/Project/Workspace.h index 4ac469c..e4e0a37 100644 --- a/Project/Workspace.h +++ b/Project/Workspace.h @@ -40,7 +40,8 @@ enum WorkspaceMode { MODE_INSERT, MODE_INSERT_TEXT, MODE_SELECTION_RECT, - MODE_PASTE + MODE_PASTE, + MODE_DRAG_PASTE }; enum ElementID { @@ -68,6 +69,7 @@ public: wxString GetName() const { return m_name; } std::vector<Element*> GetElementList() const { return m_elementList; } std::vector<Text*> GetTextList() const { return m_textList; } + std::vector<Element*> GetAllElements() const; WorkspaceMode GetWorkspaceMode() const { return m_mode; } Camera* GetCamera() const { return m_camera; } |