Power System Platform  2026w11a-beta
Loading...
Searching...
No Matches
Limiter.cpp
1/*
2 * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
18#include "Limiter.h"
19#include "../../forms/LimiterForm.h"
20#include <wx/pen.h>
21#include <wx/brush.h>
22
23Limiter::Limiter(int id) : ControlElement(id)
24{
25 m_width = m_height = 36.0;
26 Node* nodeIn = new Node(m_position + wxPoint2DDouble(-18, 0), Node::NodeType::NODE_IN, m_borderSize);
27 nodeIn->StartMove(m_position);
28 Node* nodeOut = new Node(m_position + wxPoint2DDouble(18, 0), Node::NodeType::NODE_OUT, m_borderSize);
29 nodeOut->SetAngle(180.0);
30 nodeOut->StartMove(m_position);
31 m_nodeList.push_back(nodeIn);
32 m_nodeList.push_back(nodeOut);
33}
34
35Limiter::~Limiter()
36{
37 for (auto& node : m_nodeList) if (node) delete node;
38 m_nodeList.clear();
39}
40
41//void Limiter::Draw(wxPoint2DDouble translation, double scale) const
42//{
43// glLineWidth(1.0);
44// if(m_selected) {
45// glColor4dv(m_selectionColour.GetRGBA());
46// double borderSize = (m_borderSize * 2.0 + 1.0) / scale;
47// DrawRectangle(m_position, m_width + borderSize, m_height + borderSize);
48// }
49// glColor4d(1.0, 1.0, 1.0, 1.0);
50// DrawRectangle(m_position, m_width, m_height);
51// glColor4d(0.0, 0.0, 0.0, 1.0);
52// DrawRectangle(m_position, m_width, m_height, GL_LINE_LOOP);
53//
54// // Plot symbol.
55// glLineWidth(2.0);
56// std::vector<wxPoint2DDouble> limSymbol;
57// limSymbol.push_back(m_position + wxPoint2DDouble(10, -10));
58// limSymbol.push_back(m_position + wxPoint2DDouble(2, -10));
59// limSymbol.push_back(m_position + wxPoint2DDouble(-2, 10));
60// limSymbol.push_back(m_position + wxPoint2DDouble(-10, 10));
61// glColor4d(0.0, 0.3, 1.0, 1.0);
62// DrawLine(limSymbol);
63//
64// glColor4d(0.0, 0.0, 0.0, 1.0);
65// DrawNodes();
66//}
67
68void Limiter::DrawDC(wxPoint2DDouble translation, double scale, wxGraphicsContext* gc) const
69{
70 if (m_selected) {
71 gc->SetPen(*wxTRANSPARENT_PEN);
72 gc->SetBrush(wxBrush(m_selectionColour));
73 double borderSize = (m_borderSize * 2.0 + 1.0) / scale;
74 gc->DrawRectangle(m_position.m_x - m_width / 2 - borderSize / 2, m_position.m_y - m_height / 2 - borderSize / 2, m_width + borderSize, m_height + borderSize);
75 }
76 gc->SetPen(wxPen(wxColour(0, 0, 0, 255), 1));
77 gc->SetBrush(wxBrush(wxColour(255, 255, 255, 255)));
78 gc->DrawRectangle(m_position.m_x - m_width / 2, m_position.m_y - m_height / 2, m_width, m_height);
79
80 // Plot symbol.
81 gc->SetPen(wxPen(wxColour(0, 77, 255, 255), 2));
82 gc->SetBrush(*wxTRANSPARENT_BRUSH);
83 wxPoint2DDouble limSymbol[4];
84 limSymbol[0] = m_position + wxPoint2DDouble(10, -10);
85 limSymbol[1] = m_position + wxPoint2DDouble(2, -10);
86 limSymbol[2] = m_position + wxPoint2DDouble(-2, 10);
87 limSymbol[3] = m_position + wxPoint2DDouble(-10, 10);
88 gc->StrokeLines(4, limSymbol);
89
90 gc->SetPen(*wxTRANSPARENT_PEN);
91 gc->SetBrush(*wxBLACK_BRUSH);
92 DrawDCNodes(gc);
93}
94
95bool Limiter::ShowForm(wxWindow* parent, Element* element, wxWindow* workspace)
96{
97 LimiterForm limiter(parent, this);
98 limiter.CenterOnParent();
99 if (limiter.ShowModal() == wxID_OK) {
100 return true;
101 }
102 return false;
103}
104
105void Limiter::Rotate(bool clockwise)
106{
107 if (clockwise)
108 m_angle += 90.0;
109 else
110 m_angle -= 90.0;
111 if (m_angle >= 360.0)
112 m_angle = 0.0;
113 else if (m_angle < 0)
114 m_angle = 270.0;
115
116 UpdatePoints();
117
118 for (auto it = m_nodeList.begin(), itEnd = m_nodeList.end(); it != itEnd; ++it) {
119 Node* node = *it;
120 node->Rotate(clockwise);
121 }
122}
123
124void Limiter::UpdatePoints()
125{
126 if (m_angle == 0.0) {
127 m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(-18, 0));
128 m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(18, 0));
129 }
130 else if (m_angle == 90.0) {
131 m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(0, -18));
132 m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(0, 18));
133 }
134 else if (m_angle == 180.0) {
135 m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(18, 0));
136 m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(-18, 0));
137 }
138 else if (m_angle == 270.0) {
139 m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(0, 18));
140 m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(0, -18));
141 }
142}
143
144bool Limiter::Solve(double* input, double timeStep)
145{
146 if (!input) {
147 m_output = 0.0;
148 return true;
149 }
150 m_output = input[0];
151 if (m_output > m_upLimit)
152 m_output = m_upLimit;
153 else if (m_output < m_lowLimit)
154 m_output = m_lowLimit;
155
156 return true;
157}
158
160{
161 Limiter* copy = new Limiter(*this);
162 return copy;
163}
164
165rapidxml::xml_node<>* Limiter::SaveElement(rapidxml::xml_document<>& doc, rapidxml::xml_node<>* elementListNode)
166{
167 auto elementNode = XMLParser::AppendNode(doc, elementListNode, "Limiter");
168 XMLParser::SetNodeAttribute(doc, elementNode, "ID", m_elementID);
169
170 SaveCADProperties(doc, elementNode);
171 SaveControlNodes(doc, elementNode);
172
173 // Element properties
174 auto upLimit = XMLParser::AppendNode(doc, elementNode, "UpperLimit");
175 XMLParser::SetNodeValue(doc, upLimit, m_upLimit);
176 auto lowLimit = XMLParser::AppendNode(doc, elementNode, "LowerLimit");
177 XMLParser::SetNodeValue(doc, lowLimit, m_lowLimit);
178
179 return elementNode;
180}
181
182bool Limiter::OpenElement(rapidxml::xml_node<>* elementNode)
183{
184 if (!OpenCADProperties(elementNode)) return false;
185 if (!OpenControlNodes(elementNode)) return false;
186
187 // Element properties
188 m_upLimit = XMLParser::GetNodeValueDouble(elementNode, "UpperLimit");
189 m_lowLimit = XMLParser::GetNodeValueDouble(elementNode, "LowerLimit");
190
191 StartMove(m_position);
192 UpdatePoints();
193 return true;
194}
virtual void StartMove(wxPoint2DDouble position)
Update the element attributes related to the movement.
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition Element.h:112
Form to edit the limit control data.
Definition LimiterForm.h:32
Limits the input value by superior and inferior values.
Definition Limiter.h:33
virtual bool ShowForm(wxWindow *parent, Element *element, wxWindow *workspace=nullptr)
Show element data form.
Definition Limiter.cpp:95
virtual Element * GetCopy()
Get a the element copy.
Definition Limiter.cpp:159
virtual void Rotate(bool clockwise=true)
Rotate the element.
Definition Limiter.cpp:105
virtual void DrawDC(wxPoint2DDouble translation, double scale, wxGraphicsContext *gc) const
Draw the element using GDI+.
Definition Limiter.cpp:68
Node of a control element. This class manages the user interaction with the connection and control el...