summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThales Lima Oliveira <thaleslima.ufu@gmail.com>2017-12-20 20:45:35 -0200
committerThales Lima Oliveira <thaleslima.ufu@gmail.com>2017-12-20 20:45:35 -0200
commitc6d815b6b11504be68d7a97df63cfef749624418 (patch)
tree750161c22282c781ab9c62fec84c8de50dfb230f
parent54bb80251432ff49c967115f8401e7dafc5c57d6 (diff)
downloadPSP.git-c6d815b6b11504be68d7a97df63cfef749624418.tar.gz
PSP.git-c6d815b6b11504be68d7a97df63cfef749624418.tar.xz
PSP.git-c6d815b6b11504be68d7a97df63cfef749624418.zip
Math expr GUI implemented
-rw-r--r--Project/ControlEditor.cpp2
-rw-r--r--Project/ControlElement.cpp2
-rw-r--r--Project/ControlElement.h3
-rw-r--r--Project/ControlElementSolver.cpp36
-rw-r--r--Project/ControlElementSolver.h2
-rw-r--r--Project/Divider.cpp2
-rw-r--r--Project/Divider.h2
-rw-r--r--Project/Exponential.cpp2
-rw-r--r--Project/Exponential.h2
-rw-r--r--Project/Gain.cpp2
-rw-r--r--Project/Gain.h2
-rw-r--r--Project/Limiter.cpp2
-rw-r--r--Project/Limiter.h2
-rw-r--r--Project/MathExpression.cpp75
-rw-r--r--Project/MathExpression.h14
-rw-r--r--Project/MathExpressionForm.cpp105
-rw-r--r--Project/MathExpressionForm.h6
-rw-r--r--Project/Multiplier.cpp2
-rw-r--r--Project/Multiplier.h2
-rw-r--r--Project/Project.mk2
-rw-r--r--Project/RateLimiter.cpp2
-rw-r--r--Project/RateLimiter.h2
-rw-r--r--Project/Sum.cpp2
-rw-r--r--Project/Sum.h2
-rw-r--r--Project/TransferFunction.cpp2
-rw-r--r--Project/TransferFunction.h2
-rw-r--r--Project/data/lang/pt_BR/pt_BR.mobin48550 -> 48756 bytes
-rw-r--r--Project/data/lang/pt_BR/pt_BR.po136
28 files changed, 278 insertions, 137 deletions
diff --git a/Project/ControlEditor.cpp b/Project/ControlEditor.cpp
index becfa43..4e426fe 100644
--- a/Project/ControlEditor.cpp
+++ b/Project/ControlEditor.cpp
@@ -764,6 +764,8 @@ void ControlEditor::CheckConnections()
ConnectionLine* cLine = *it;
if(cLine->GetType() == ConnectionLine::ELEMENT_ELEMENT) {
if(cLine->GetParentList().size() < 2) { it = DeleteLineFromList(it); }
+ } else if(cLine->GetParentList().size() < 1) {
+ it = DeleteLineFromList(it);
}
}
}
diff --git a/Project/ControlElement.cpp b/Project/ControlElement.cpp
index 0a37803..d709af2 100644
--- a/Project/ControlElement.cpp
+++ b/Project/ControlElement.cpp
@@ -131,7 +131,7 @@ void ControlElement::Move(wxPoint2DDouble position)
}
}
-bool ControlElement::Solve(double input, double timeStep)
+bool ControlElement::Solve(double input, double timeStep, double currentTime)
{
m_output = input;
return true;
diff --git a/Project/ControlElement.h b/Project/ControlElement.h
index 434e535..39e2dcf 100644
--- a/Project/ControlElement.h
+++ b/Project/ControlElement.h
@@ -102,7 +102,8 @@ class ControlElement : public Element
virtual bool UpdateText() { return true; }
virtual bool IsSolved() const { return m_solved; }
virtual void SetSolved(bool solved = true) { m_solved = solved; }
- virtual bool Solve(double input, double timeStep);
+ virtual bool Solve(double input, double timeStep, double currentTime);
+ virtual bool Initialize() { return true; }
virtual double GetOutput() const { return m_output; }
virtual void SetOutput(double output) { m_output = output; }
protected:
diff --git a/Project/ControlElementSolver.cpp b/Project/ControlElementSolver.cpp
index 3534023..c14dd54 100644
--- a/Project/ControlElementSolver.cpp
+++ b/Project/ControlElementSolver.cpp
@@ -17,10 +17,10 @@
#include "ControlElementSolver.h"
-#include "ControlElementContainer.h"
-#include "ControlEditor.h"
#include "ConnectionLine.h"
#include "Constant.h"
+#include "ControlEditor.h"
+#include "ControlElementContainer.h"
#include "Exponential.h"
#include "Gain.h"
#include "IOControl.h"
@@ -119,6 +119,11 @@ bool ControlElementSolver::InitializeValues(bool startAllZero)
cLine->SetSolved(false);
cLine->SetValue(0.0);
}
+ auto mathExprList = m_ctrlContainer->GetMathExprList();
+ for(auto it = mathExprList.begin(), itEnd = mathExprList.end(); it != itEnd; ++it) {
+ MathExpression* mathExpr = *it;
+ if(!mathExpr->Initialize()) return false;
+ }
if(!startAllZero) {
double origTimeStep = m_timeStep;
@@ -141,13 +146,9 @@ bool ControlElementSolver::InitializeValues(bool startAllZero)
numIt++;
error = std::abs(prevSol - currentSol);
if(std::abs(error - prevError) < 1e-1) {
- if(m_timeStep < maxStep) {
- m_timeStep *= 1.5;
- }
+ if(m_timeStep < maxStep) { m_timeStep *= 1.5; }
} else if(std::abs(error - prevError) > 10) {
- if(m_timeStep > minStep) {
- m_timeStep /= 1.5;
- }
+ if(m_timeStep > minStep) { m_timeStep /= 1.5; }
}
if(numIt >= maxIteration) {
m_failMessage = _("It was not possible to initialize the control system.");
@@ -177,10 +178,6 @@ void ControlElementSolver::SolveNextStep()
// Get first node connection
ConnectionLine* firstConn = static_cast<ConnectionLine*>(m_inputControl->GetChildList()[0]);
- /*m_inputControl->SetSolved();
- firstConn->SetValue(1);
- firstConn->SetSolved();
- FillAllConnectedChildren(firstConn);*/
// Set value to the connected lines in constants
auto constantList = m_ctrlContainer->GetConstantList();
@@ -246,9 +243,7 @@ void ControlElementSolver::SolveNextStep()
}
ConnectionLine* currentLine = firstConn;
- while(currentLine) {
- currentLine = SolveNextElement(currentLine);
- }
+ while(currentLine) { currentLine = SolveNextElement(currentLine); }
bool haveUnsolvedElement = true;
while(haveUnsolvedElement) {
@@ -264,9 +259,7 @@ void ControlElementSolver::SolveNextStep()
haveUnsolvedElement = true;
// Solve secondary branch.
currentLine = cLine;
- while(currentLine) {
- currentLine = SolveNextElement(currentLine);
- }
+ while(currentLine) { currentLine = SolveNextElement(currentLine); }
break;
}
}
@@ -276,11 +269,6 @@ void ControlElementSolver::SolveNextStep()
}
// Set the control system output.
- /*if(m_outputControl->GetChildList().size() == 1) {
- ConnectionLine* cLine = static_cast<ConnectionLine*>(m_outputControl->GetChildList()[0]);
- m_solutions.push_back(cLine->GetValue());
- } else
- m_solutions.push_back(0.0);*/
for(auto it = ioList.begin(), itEnd = ioList.end(); it != itEnd; ++it) {
IOControl* io = *it;
if(io->GetChildList().size() == 1) {
@@ -320,7 +308,7 @@ ConnectionLine* ControlElementSolver::SolveNextElement(ConnectionLine* currentLi
ControlElement* element = static_cast<ControlElement*>(*it);
// Solve the unsolved parent.
if(!element->IsSolved()) {
- if(!element->Solve(currentLine->GetValue(), m_timeStep)) return NULL;
+ if(!element->Solve(currentLine->GetValue(), m_timeStep, m_currentTime)) return NULL;
element->SetSolved();
// Get the output node (must have one or will result NULL).
diff --git a/Project/ControlElementSolver.h b/Project/ControlElementSolver.h
index 9bc54f7..5717b08 100644
--- a/Project/ControlElementSolver.h
+++ b/Project/ControlElementSolver.h
@@ -58,6 +58,7 @@ class ControlElementSolver
virtual double GetLastSolution() { return m_solutions[m_solutions.size() - 1]; }
virtual bool IsOK() const { return m_isOK; }
virtual wxString GetErrorMessage() { return m_failMessage; }
+ void SetCurrentTime(double value) { m_currentTime = value; }
void SetTerminalVoltage(double value) { m_terminalVoltage = value; }
void SetVelocity(double value) { m_velocity = value; }
void SetActivePower(double value) { m_activePower = value; }
@@ -86,6 +87,7 @@ class ControlElementSolver
IOControl* m_inputControl = NULL; /**< First input control to be solved */
IOControl* m_outputControl = NULL;
// Inputs
+ double m_currentTime = 0.0;
double m_terminalVoltage = 0.0;
double m_velocity = 0.0;
double m_activePower = 0.0;
diff --git a/Project/Divider.cpp b/Project/Divider.cpp
index 2bd8251..c458002 100644
--- a/Project/Divider.cpp
+++ b/Project/Divider.cpp
@@ -33,7 +33,7 @@ void Divider::DrawSymbol() const
DrawCircle(m_position + wxPoint2DDouble(0, 3), 2, 10, GL_POLYGON);
}
-bool Divider::Solve(double input, double timeStep)
+bool Divider::Solve(double input, double timeStep, double currentTime)
{
std::vector<double> inputVector;
for(auto itN = m_nodeList.begin(), itNEnd = m_nodeList.end(); itN != itNEnd; ++itN) {
diff --git a/Project/Divider.h b/Project/Divider.h
index 59b7309..6697bf8 100644
--- a/Project/Divider.h
+++ b/Project/Divider.h
@@ -36,7 +36,7 @@ class Divider : public MathOperation
~Divider();
virtual void DrawSymbol() const;
- virtual bool Solve(double input, double timeStep);
+ virtual bool Solve(double input, double timeStep, double currentTime);
virtual Element* GetCopy();
};
diff --git a/Project/Exponential.cpp b/Project/Exponential.cpp
index 64af421..e07525b 100644
--- a/Project/Exponential.cpp
+++ b/Project/Exponential.cpp
@@ -129,7 +129,7 @@ void Exponential::SetValues(double aValue, double bValue)
m_bValue = bValue;
}
-bool Exponential::Solve(double input, double timeStep)
+bool Exponential::Solve(double input, double timeStep, double currentTime)
{
m_output = m_aValue * std::exp(m_bValue * input);
return true;
diff --git a/Project/Exponential.h b/Project/Exponential.h
index accdd48..cb97724 100644
--- a/Project/Exponential.h
+++ b/Project/Exponential.h
@@ -54,7 +54,7 @@ class Exponential : public ControlElement
* @param timeStep Time step.
* @return Aways true.
*/
- virtual bool Solve(double input, double timeStep);
+ virtual bool Solve(double input, double timeStep, double currentTime);
virtual Element* GetCopy();
diff --git a/Project/Gain.cpp b/Project/Gain.cpp
index 8851863..701b470 100644
--- a/Project/Gain.cpp
+++ b/Project/Gain.cpp
@@ -175,7 +175,7 @@ void Gain::Move(wxPoint2DDouble position)
UpdatePoints();
}
-bool Gain::Solve(double input, double timeStep)
+bool Gain::Solve(double input, double timeStep, double currentTime)
{
m_output = input * m_value;
return true;
diff --git a/Project/Gain.h b/Project/Gain.h
index 8570672..2f6a027 100644
--- a/Project/Gain.h
+++ b/Project/Gain.h
@@ -56,7 +56,7 @@ class Gain : public ControlElement
* @param timeStep Time step.
* @return Always true.
*/
- virtual bool Solve(double input, double timeStep);
+ virtual bool Solve(double input, double timeStep, double currentTime);
virtual Element* GetCopy();
diff --git a/Project/Limiter.cpp b/Project/Limiter.cpp
index 830ef6a..a394874 100644
--- a/Project/Limiter.cpp
+++ b/Project/Limiter.cpp
@@ -105,7 +105,7 @@ void Limiter::UpdatePoints()
}
}
-bool Limiter::Solve(double input, double timeStep)
+bool Limiter::Solve(double input, double timeStep, double currentTime)
{
m_output = input;
if(m_output > m_upLimit)
diff --git a/Project/Limiter.h b/Project/Limiter.h
index 396ae16..c9f160b 100644
--- a/Project/Limiter.h
+++ b/Project/Limiter.h
@@ -40,7 +40,7 @@ class Limiter : public ControlElement
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, double timeStep);
+ virtual bool Solve(double input, double timeStep, double currentTime);
virtual void UpdatePoints();
diff --git a/Project/MathExpression.cpp b/Project/MathExpression.cpp
index 1cb6aba..5bb69d6 100644
--- a/Project/MathExpression.cpp
+++ b/Project/MathExpression.cpp
@@ -15,13 +15,14 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
+#include "ConnectionLine.h"
#include "MathExpression.h"
#include "MathExpressionForm.h"
MathExpression::MathExpression(int id) : ControlElement(id)
{
m_variablesVector.push_back("x");
- // m_variablesVector.push_back("y");
+ m_variablesVector.push_back("y");
for(unsigned int i = 0; i < m_variablesVector.size(); ++i) {
m_glTextInputVector.push_back(new OpenGLText(m_variablesVector[i]));
@@ -151,8 +152,32 @@ void MathExpression::Rotate(bool clockwise)
}
}
-bool MathExpression::Solve(double input, double timeStep)
+bool MathExpression::Solve(double input, double timeStep, double currentTime)
{
+ // Get the input vector from connection lines (can't use default (one) input argument)
+ std::vector<double> 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); // Node not connected means zero value as input.
+ } else {
+ for(auto itC = m_childList.begin(), itCEnd = m_childList.end(); itC != itCEnd; ++itC) {
+ ConnectionLine* cLine = static_cast<ConnectionLine*>(*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_variablesVector.size() != inputVector.size()) return false;
+
// Solve the math expression using fparser
return true;
}
@@ -250,3 +275,49 @@ void MathExpression::CalculateBlockSize(double numInNodes)
m_height = m_maxSringSize + m_symbolSize.GetHeight() + 18;
}
}
+
+bool MathExpression::UpdateText()
+{
+ bool isTextureOK = true;
+ m_symbol.SetText(m_symbol.GetText());
+ if(!m_symbol.IsTextureOK()) isTextureOK = false;
+ for(auto it = m_glTextInputVector.begin(), itEnd = m_glTextInputVector.end(); it != itEnd; ++it) {
+ (*it)->SetText((*it)->GetText());
+ if(!(*it)->IsTextureOK()) isTextureOK = false;
+ }
+ return isTextureOK;
+}
+
+void MathExpression::SetVariables(std::vector<wxString> variablesVector)
+{
+ m_variablesVector = variablesVector;
+ // Clear old glTextVector
+ for(auto it = m_glTextInputVector.begin(), itEnd = m_glTextInputVector.end(); it != itEnd; ++it) { delete *it; }
+ m_glTextInputVector.clear();
+
+ for(auto it = m_variablesVector.begin(), itEnd = m_variablesVector.end(); it != itEnd; ++it)
+ m_glTextInputVector.push_back(new OpenGLText(*(it)));
+}
+
+bool MathExpression::Initialize()
+{
+ m_variables = "time,step,";
+ for(auto it = m_variablesVector.begin(), itEnd = m_variablesVector.end(); it != itEnd; ++it)
+ m_variables += *(it) + ",";
+ m_variables.RemoveLast();
+
+ // Set locale to ENGLISH_US to avoid parser error in numbers (eg. comma).
+ int currentLang = wxLocale::GetSystemLanguage();
+ wxLocale newLocale(wxLANGUAGE_ENGLISH_US);
+ int parserRes = m_fparser.Parse(static_cast<std::string>(m_mathExpression), static_cast<std::string>(m_variables));
+ if(parserRes != -1) return false; // Parse error.
+ wxLocale oldLocale(currentLang); // Return to current language.
+
+ if(m_inputValues) delete m_inputValues;
+ m_inputValues = new double[m_variablesVector.size() + 2]; // Custom variables + time + step
+
+ // Optimize only once to gain performance.
+ m_fparser.Optimize();
+
+ return true;
+}
diff --git a/Project/MathExpression.h b/Project/MathExpression.h
index ce39aca..92b3796 100644
--- a/Project/MathExpression.h
+++ b/Project/MathExpression.h
@@ -22,6 +22,8 @@
#include "MathExprParser.h"
#include "OpenGLText.h"
+class ConnectionLine;
+
class MathExpressionForm;
/**
@@ -43,11 +45,18 @@ class MathExpression : public ControlElement
virtual bool ShowForm(wxWindow* parent, Element* element);
virtual void Rotate(bool clockwise = true);
- virtual bool Solve(double input, double timeStep);
+ virtual bool Solve(double input, double timeStep, double currentTime);
+ virtual bool Initialize();
+ virtual wxString GetMathExpression() { return m_mathExpression; }
+ virtual void SetMathExpression(wxString mathExpression) { m_mathExpression = mathExpression; }
+ virtual std::vector<wxString> GetVariables() { return m_variablesVector; }
+ virtual void SetVariables(std::vector<wxString> variablesVector);
+ virtual MathExprParser GetParser() { return m_fparser; }
virtual void UpdatePoints();
void AddInNode();
void RemoveInNode();
+ virtual bool UpdateText();
virtual Element* GetCopy();
@@ -56,8 +65,9 @@ class MathExpression : public ControlElement
MathExprParser m_fparser;
wxString m_mathExpression = "sqrt(x^2 + y^2)";
- wxString m_variables = "x,y";
+ wxString m_variables = "time,step,x,y";
std::vector<wxString> m_variablesVector;
+ double* m_inputValues = NULL;
std::vector<OpenGLText*> m_glTextInputVector;
OpenGLText m_symbol;
wxSize m_symbolSize;
diff --git a/Project/MathExpressionForm.cpp b/Project/MathExpressionForm.cpp
index f4214c6..33ea50d 100644
--- a/Project/MathExpressionForm.cpp
+++ b/Project/MathExpressionForm.cpp
@@ -15,26 +15,45 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
+#include "MathExpression.h"
#include "MathExpressionForm.h"
#define ERROR_INDICATOR 10
-MathExpressionForm::MathExpressionForm(wxWindow* parent, MathExpression* mathEpr) : MathExpressionFormBase(parent)
+MathExpressionForm::MathExpressionForm(wxWindow* parent, MathExpression* mathExpr) : MathExpressionFormBase(parent)
{
m_parent = parent;
- m_mathEpr = mathEpr;
-
+ m_mathExpr = mathExpr;
+
+ // Variables string.
+ wxString variables = "";
+ for(unsigned int i = 0; i < m_mathExpr->GetVariables().size(); ++i) {
+ variables += m_mathExpr->GetVariables()[i] + " ";
+ }
+ variables.RemoveLast();
+
+ // Variables text ctrl.
+ wxFont variablesFont = m_textCtrlVariables->GetFont();
+ variablesFont.SetWeight(wxFONTWEIGHT_BOLD);
+ m_textCtrlVariables->SetFont(variablesFont);
+ m_textCtrlVariables->SetForegroundColour(wxColour(160, 0, 0));
+ m_textCtrlVariables->SetValue(variables);
+
+ m_stcMathExpr->SetText(m_mathExpr->GetMathExpression());
+
m_staticTextCheckStatus->SetLabel(_("No checks performed."));
SetSintaxHighlights();
m_stcMathExpr->SetTabWidth(3);
+
+ // Error indicator
m_stcMathExpr->IndicatorSetUnder(ERROR_INDICATOR, true);
m_stcMathExpr->IndicatorSetStyle(ERROR_INDICATOR, wxSTC_INDIC_ROUNDBOX);
m_stcMathExpr->IndicatorSetAlpha(ERROR_INDICATOR, 200);
m_stcMathExpr->IndicatorSetUnder(ERROR_INDICATOR, true);
m_stcMathExpr->IndicatorSetForeground(ERROR_INDICATOR, wxColor(255, 85, 0));
m_stcMathExpr->SetIndicatorCurrent(ERROR_INDICATOR);
- m_stcMathExpr->SetText("a := 0.98 * x;\nb := int(a) + e^y;\nsqrt(1 - sin(2.2 * a) + cos(pi / b) / 3.3)");
+ // Parser error messages to translation.
m_translatedErrorMsg.clear();
m_translatedErrorMsg.push_back(_("Syntax error"));
m_translatedErrorMsg.push_back(_("Mismatched parenthesis"));
@@ -45,6 +64,7 @@ MathExpressionForm::MathExpressionForm(wxWindow* parent, MathExpression* mathEpr
m_translatedErrorMsg.push_back(_("An unexpected error occurred"));
m_translatedErrorMsg.push_back(_("Syntax error in input variables"));
m_translatedErrorMsg.push_back(_("Illegal number of parameters to function"));
+ m_translatedErrorMsg.push_back(_("Syntax error: Premature end of string"));
m_translatedErrorMsg.push_back(_("Syntax error: Expecting ( after function"));
m_translatedErrorMsg.push_back(_("Syntax error: Unknown identifier"));
m_translatedErrorMsg.push_back(_("No function has been parsed yet"));
@@ -52,31 +72,48 @@ MathExpressionForm::MathExpressionForm(wxWindow* parent, MathExpression* mathEpr
MathExpressionForm::~MathExpressionForm() {}
-void MathExpressionForm::OnCheckButtonClick(wxCommandEvent& event)
-{
- m_stcMathExpr->IndicatorClearRange(0, m_stcMathExpr->GetValue().length());
- int currentLang = wxLocale::GetSystemLanguage();
- wxLocale newLocale(wxLANGUAGE_ENGLISH_US);
- MathExprParser parser;
- int parserRes = parser.Parse(static_cast<std::string>(m_stcMathExpr->GetValue()), GetVariablesToParse());
- if(parserRes != -1) {
- m_staticTextCheckStatus->SetLabel(m_translatedErrorMsg[parser.GetParseErrorType()]);
- m_staticTextCheckStatus->SetForegroundColour(wxColor(255, 0, 0));
- m_stcMathExpr->IndicatorFillRange(parserRes, 1);
- } else {
- m_staticTextCheckStatus->SetLabel(_("OK!"));
- m_staticTextCheckStatus->SetForegroundColour(wxColor(0, 128, 0));
- }
- Layout();
- wxLocale oldLocale(currentLang);
-}
+void MathExpressionForm::OnCheckButtonClick(wxCommandEvent& event) { CheckMathExpression(); }
void MathExpressionForm::OnOKButtonClick(wxCommandEvent& event)
{
if(ValidateData()) EndModal(wxID_OK);
}
-bool MathExpressionForm::ValidateData() { return true; }
+bool MathExpressionForm::ValidateData()
+{
+ if(!CheckMathExpression()) {
+ wxMessageDialog msg(this, _("There is an error on math expression."), _("Error"), wxOK | wxCENTRE | wxICON_ERROR);
+ msg.ShowModal();
+ return false;
+ }
+ wxString rawVariables = m_textCtrlVariables->GetValue();
+ wxString var = "";
+ std::vector<wxString> variables;
+ for(unsigned int i = 0; i < rawVariables.length(); ++i) {
+ if(rawVariables[i] == ' ') {
+ variables.push_back(var);
+ var = "";
+ } else if((i + 1) == static_cast<unsigned int>(rawVariables.length())) {
+ var += rawVariables[i];
+ variables.push_back(var);
+ } else {
+ var += rawVariables[i];
+ }
+ }
+
+ int diff = static_cast<int>(variables.size()) - static_cast<int>(m_mathExpr->GetVariables().size());
+
+ if(diff < 0) {
+ diff = std::abs(diff);
+ for(int i = 0; i < diff; ++i) { m_mathExpr->RemoveInNode(); }
+ } else if(diff > 0) {
+ for(int i = 0; i < diff; ++i) { m_mathExpr->AddInNode(); }
+ }
+ m_mathExpr->SetVariables(variables);
+ m_mathExpr->SetMathExpression(m_stcMathExpr->GetValue());
+ m_mathExpr->UpdatePoints();
+ return true;
+}
void MathExpressionForm::SetSintaxHighlights()
{
@@ -117,3 +154,25 @@ void MathExpressionForm::OnLeftClickDown(wxMouseEvent& event)
m_stcMathExpr->IndicatorClearRange(0, m_stcMathExpr->GetValue().length());
event.Skip();
}
+
+bool MathExpressionForm::CheckMathExpression()
+{
+ bool success = true;
+ m_stcMathExpr->IndicatorClearRange(0, m_stcMathExpr->GetValue().length());
+ int currentLang = wxLocale::GetSystemLanguage();
+ wxLocale newLocale(wxLANGUAGE_ENGLISH_US);
+ MathExprParser parser = m_mathExpr->GetParser();
+ int parserRes = parser.Parse(static_cast<std::string>(m_stcMathExpr->GetValue()), GetVariablesToParse());
+ if(parserRes != -1) {
+ m_staticTextCheckStatus->SetLabel(m_translatedErrorMsg[parser.GetParseErrorType()]);
+ m_staticTextCheckStatus->SetForegroundColour(wxColor(255, 0, 0));
+ m_stcMathExpr->IndicatorFillRange(parserRes, 1);
+ success = false;
+ } else {
+ m_staticTextCheckStatus->SetLabel(_("The math expression is correct."));
+ m_staticTextCheckStatus->SetForegroundColour(wxColor(0, 128, 0));
+ }
+ wxLocale oldLocale(currentLang);
+ Layout();
+ return success;
+}
diff --git a/Project/MathExpressionForm.h b/Project/MathExpressionForm.h
index 03fb134..c0ff4b9 100644
--- a/Project/MathExpressionForm.h
+++ b/Project/MathExpressionForm.h
@@ -19,7 +19,6 @@
#define MATHEXPRESSIONFORM_H
#include "base/ElementFormBase.h"
-#include "MathExprParser.h"
#include <wx/msgdlg.h>
class MathExpression;
@@ -27,11 +26,12 @@ class MathExpression;
class MathExpressionForm : public MathExpressionFormBase
{
public:
- MathExpressionForm(wxWindow* parent, MathExpression* mathEpr);
+ MathExpressionForm(wxWindow* parent, MathExpression* mathExpr);
virtual ~MathExpressionForm();
protected:
bool ValidateData();
void SetSintaxHighlights();
+ bool CheckMathExpression();
std::string GetVariablesToParse();
virtual void OnCancelButtonClick(wxCommandEvent& event) { EndModal(wxID_CANCEL); }
virtual void OnCheckButtonClick(wxCommandEvent& event);
@@ -43,6 +43,6 @@ protected:
std::vector<wxString> m_translatedErrorMsg;
wxWindow* m_parent;
- MathExpression* m_mathEpr;
+ MathExpression* m_mathExpr;
};
#endif // MATHEXPRESSIONFORM_H
diff --git a/Project/Multiplier.cpp b/Project/Multiplier.cpp
index 14dd182..87324a4 100644
--- a/Project/Multiplier.cpp
+++ b/Project/Multiplier.cpp
@@ -33,7 +33,7 @@ void Multiplier::DrawSymbol() const
DrawLine(xSymbol, GL_LINES);
}
-bool Multiplier::Solve(double input, double timeStep)
+bool Multiplier::Solve(double input, double timeStep, double currentTime)
{
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 2bc0be9..13b6259 100644
--- a/Project/Multiplier.h
+++ b/Project/Multiplier.h
@@ -36,7 +36,7 @@ class Multiplier : public MathOperation
~Multiplier();
virtual void DrawSymbol() const;
- virtual bool Solve(double input, double timeStep);
+ virtual bool Solve(double input, double timeStep, double currentTime);
virtual Element* GetCopy();
};
diff --git a/Project/Project.mk b/Project/Project.mk
index f1c4b64..56cd195 100644
--- a/Project/Project.mk
+++ b/Project/Project.mk
@@ -13,7 +13,7 @@ CurrentFileName :=
CurrentFilePath :=
CurrentFileFullPath :=
User :=NDSE-69
-Date :=19/12/2017
+Date :=20/12/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 afba0ee..b9235a7 100644
--- a/Project/RateLimiter.cpp
+++ b/Project/RateLimiter.cpp
@@ -110,7 +110,7 @@ void RateLimiter::UpdatePoints()
}
}
-bool RateLimiter::Solve(double input, double timeStep)
+bool RateLimiter::Solve(double input, double timeStep, double currentTime)
{
double rate = (input - m_output) / timeStep;
diff --git a/Project/RateLimiter.h b/Project/RateLimiter.h
index 3d57498..5523b86 100644
--- a/Project/RateLimiter.h
+++ b/Project/RateLimiter.h
@@ -63,7 +63,7 @@ class RateLimiter : public ControlElement
* @param timeStep Time step.
* @return Always true.
*/
- virtual bool Solve(double input, double timeStep);
+ virtual bool Solve(double input, double timeStep, double currentTime);
virtual Element* GetCopy();
diff --git a/Project/Sum.cpp b/Project/Sum.cpp
index 37d10f9..749a056 100644
--- a/Project/Sum.cpp
+++ b/Project/Sum.cpp
@@ -199,7 +199,7 @@ void Sum::Rotate(bool clockwise)
}
}
-bool Sum::Solve(double input, double timeStep)
+bool Sum::Solve(double input, double timeStep, double currentTime)
{
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 e91e139..6c22b1e 100644
--- a/Project/Sum.h
+++ b/Project/Sum.h
@@ -45,7 +45,7 @@ class Sum : public ControlElement
virtual std::vector<Signal> GetSignalList() const { return m_signalList; }
virtual void SetSignalList(std::vector<Signal> signalList) { m_signalList = signalList; }
- virtual bool Solve(double input, double timeStep);
+ virtual bool Solve(double input, double timeStep, double currentTime);
virtual void UpdatePoints();
void AddInNode();
diff --git a/Project/TransferFunction.cpp b/Project/TransferFunction.cpp
index e4c8a4e..2233764 100644
--- a/Project/TransferFunction.cpp
+++ b/Project/TransferFunction.cpp
@@ -308,7 +308,7 @@ void TransferFunction::CalculateSpaceState(int maxIteration, double error)
}
}
-bool TransferFunction::Solve(double input, double timeStep)
+bool TransferFunction::Solve(double input, double timeStep, double currentTime)
{
int order = static_cast<int>(m_ss.A.size());
diff --git a/Project/TransferFunction.h b/Project/TransferFunction.h
index 776ecb7..c87fd60 100644
--- a/Project/TransferFunction.h
+++ b/Project/TransferFunction.h
@@ -73,7 +73,7 @@ class TransferFunction : public ControlElement
* @param timeStep Time step.
* @return true if the calculation converges, false otherwise.
*/
- virtual bool Solve(double input, double timeStep);
+ virtual bool Solve(double input, double timeStep, double currentTime);
virtual Element* GetCopy();
diff --git a/Project/data/lang/pt_BR/pt_BR.mo b/Project/data/lang/pt_BR/pt_BR.mo
index 6bc34f7..bb5feb8 100644
--- a/Project/data/lang/pt_BR/pt_BR.mo
+++ b/Project/data/lang/pt_BR/pt_BR.mo
Binary files differ
diff --git a/Project/data/lang/pt_BR/pt_BR.po b/Project/data/lang/pt_BR/pt_BR.po
index 937c958..89bb982 100644
--- a/Project/data/lang/pt_BR/pt_BR.po
+++ b/Project/data/lang/pt_BR/pt_BR.po
@@ -1,15 +1,15 @@
msgid ""
msgstr ""
"Project-Id-Version: PSP-UFU pt_BR 0.0.1\n"
-"POT-Creation-Date: 2017-12-19 10:56-0200\n"
-"PO-Revision-Date: 2017-12-19 10:57-0200\n"
+"POT-Creation-Date: 2017-12-20 11:07-0200\n"
+"PO-Revision-Date: 2017-12-20 11:08-0200\n"
"Last-Translator: \n"
"Language-Team: Thales Lima Oliveira <thaleslima.ufu@gmail.com>\n"
"Language: pt_BR\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Poedit 2.0.4\n"
+"X-Generator: Poedit 2.0.5\n"
"X-Poedit-Basepath: ../../..\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
"X-Poedit-KeywordsList: _\n"
@@ -323,7 +323,7 @@ msgstr "Gerador síncrono"
msgid "Transformer"
msgstr "Transformador"
-#: ChartView.cpp:116 ControlEditor.cpp:806
+#: ChartView.cpp:116 ControlEditor.cpp:809
msgid "Test"
msgstr "Teste"
@@ -369,15 +369,15 @@ msgstr "Informação"
msgid "It was not possible to send to clipboard"
msgstr "Não foi possível enviar para a área de transferência"
-#: ChartView.cpp:264 ChartView.cpp:483 ControlEditor.cpp:791
-#: ControlEditor.cpp:885 ControlElementSolver.cpp:95 ControlSystemTest.cpp:53
+#: ChartView.cpp:264 ChartView.cpp:483 ControlEditor.cpp:794
+#: ControlEditor.cpp:888 ControlElementSolver.cpp:95 ControlSystemTest.cpp:53
#: ControlSystemTest.cpp:60 ControlSystemTest.cpp:67 ControlSystemTest.cpp:74
#: Element.cpp:297 Element.cpp:311 GeneralPropertiesForm.cpp:74 Line.cpp:168
#: Line.cpp:397 LoadForm.cpp:189 LoadForm.cpp:196 MainFrame.cpp:311
#: SimulationsSettingsForm.cpp:188 SimulationsSettingsForm.cpp:195
-#: SumForm.cpp:58 SumForm.cpp:74 TextForm.cpp:1225 Workspace.cpp:1147
-#: Workspace.cpp:1212 Workspace.cpp:1320 Workspace.cpp:1424 Workspace.cpp:1446
-#: Workspace.cpp:1464
+#: SumForm.cpp:58 SumForm.cpp:74 TextForm.cpp:1225 Workspace.cpp:1143
+#: Workspace.cpp:1208 Workspace.cpp:1316 Workspace.cpp:1420 Workspace.cpp:1442
+#: Workspace.cpp:1460
msgid "Error"
msgstr "Erro"
@@ -393,75 +393,79 @@ msgstr "Não foi possível criar ou abrir o arquivo selecionado."
msgid "Value entered incorrectly in the field \"Constant value\"."
msgstr "Valor inserido incorretamente no campo \"Valor da constante\"."
-#: ControlEditor.cpp:158
+#: ControlEditor.cpp:159
msgid "In/Out"
msgstr "Entrada/Saída"
-#: ControlEditor.cpp:164
+#: ControlEditor.cpp:165
msgid "Transfer fcn"
msgstr "Func Transferência"
-#: ControlEditor.cpp:171 base/ElementFormBase.h:870
+#: ControlEditor.cpp:172 base/ElementFormBase.h:870
msgid "Sum"
msgstr "Somador"
-#: ControlEditor.cpp:177 base/ElementFormBase.h:988
+#: ControlEditor.cpp:178 base/ElementFormBase.h:988
msgid "Constant"
msgstr "Constante"
-#: ControlEditor.cpp:184 base/ElementFormBase.h:1014
+#: ControlEditor.cpp:185 base/ElementFormBase.h:1014
msgid "Gain"
msgstr "Ganho"
-#: ControlEditor.cpp:190 base/ElementFormBase.h:900
+#: ControlEditor.cpp:191 base/ElementFormBase.h:900
msgid "Limiter"
msgstr "Limitador"
-#: ControlEditor.cpp:197 base/ElementFormBase.h:930
+#: ControlEditor.cpp:198 base/ElementFormBase.h:930
msgid "Rate limiter"
msgstr "Limitador de taxa"
-#: ControlEditor.cpp:204
+#: ControlEditor.cpp:205
msgid "Multiplier"
msgstr "Multiplicador"
-#: ControlEditor.cpp:210
+#: ControlEditor.cpp:211
msgid "Divider"
msgstr "Divisor"
-#: ControlEditor.cpp:217 base/ElementFormBase.h:962
+#: ControlEditor.cpp:218
+msgid "Math Expression"
+msgstr "Expressão matemática"
+
+#: ControlEditor.cpp:225 base/ElementFormBase.h:962
msgid "Exponential"
msgstr "Exponencial"
-#: ControlEditor.cpp:772
+#: ControlEditor.cpp:775
msgid "Save CTL file"
msgstr "Salvar arquivo CTL"
-#: ControlEditor.cpp:783
+#: ControlEditor.cpp:786
msgid "Open CTL file"
msgstr "Abrir arquivo CTL"
-#: ControlEditor.cpp:791 MainFrame.cpp:311
+#: ControlEditor.cpp:794 MainFrame.cpp:311
msgid "It was not possible to open the selected file."
msgstr "Não foi possível abrir o arquivo selecionado."
-#: ControlEditor.cpp:806 Electromechanical.cpp:70
+#: ControlEditor.cpp:809 Electromechanical.cpp:70
msgid "Initializing..."
msgstr "Inicializando..."
-#: ControlEditor.cpp:869
+#: ControlEditor.cpp:872
msgid "I/O"
msgstr "I/O"
-#: ControlEditor.cpp:870 base/ElementFormBase.cpp:3656
+#: ControlEditor.cpp:873 base/ElementFormBase.cpp:3656
msgid "Input"
msgstr "Entrada"
-#: ControlEditor.cpp:871 base/ElementFormBase.cpp:3666
+#: ControlEditor.cpp:874 base/ElementFormBase.cpp:3666
msgid "Output"
msgstr "Saída"
-#: ControlEditor.cpp:885
+#: ControlEditor.cpp:888
msgid "It was not possible to solve the control system"
msgstr "Não foi possível resolver o sistema de controle"
@@ -1245,21 +1249,21 @@ msgstr "Linha %d"
msgid "Insert Line: Click on two buses, ESC to cancel."
msgstr "Inserir Linha: Clique em duas barras, ESC para cancelar."
-#: MainFrame.cpp:416 Workspace.cpp:755
+#: MainFrame.cpp:416 Workspace.cpp:751
#, c-format
msgid "Transformer %d"
msgstr "Transformador %d"
-#: MainFrame.cpp:419 Workspace.cpp:759
+#: MainFrame.cpp:419 Workspace.cpp:755
msgid "Insert Transformer: Click on two buses, ESC to cancel."
msgstr "Inserir Transformador: Clique em duas barras, ESC para cancelar."
-#: MainFrame.cpp:424 Workspace.cpp:767
+#: MainFrame.cpp:424 Workspace.cpp:763
#, c-format
msgid "Generator %d"
msgstr "Gerador %d"
-#: MainFrame.cpp:427 Workspace.cpp:771
+#: MainFrame.cpp:427 Workspace.cpp:767
msgid "Insert Generator: Click on a buses, ESC to cancel."
msgstr "Inserir Gerador: Clique em uma barra, ESC para cancelar."
@@ -1272,99 +1276,103 @@ msgstr "Carga %d"
msgid "Insert Load: Click on a buses, ESC to cancel."
msgstr "Inserir Carga: Clique em uma barra, ESC para cancelar."
-#: MainFrame.cpp:439 Workspace.cpp:812
+#: MainFrame.cpp:439 Workspace.cpp:808
#, c-format
msgid "Capacitor %d"
msgstr "Capacitor %d"
-#: MainFrame.cpp:442 Workspace.cpp:816
+#: MainFrame.cpp:442 Workspace.cpp:812
msgid "Insert Capacitor: Click on a buses, ESC to cancel."
msgstr "Inserir Capacitor: Clique em uma barra, ESC para cancelar."
-#: MainFrame.cpp:447 Workspace.cpp:779
+#: MainFrame.cpp:447 Workspace.cpp:775
#, c-format
msgid "Inductor %d"
msgstr "Indutor %d"
-#: MainFrame.cpp:450 Workspace.cpp:783
+#: MainFrame.cpp:450 Workspace.cpp:779
msgid "Insert Inductor: Click on a buses, ESC to cancel."
msgstr "Inserir Indutor: Clique em uma barra, ESC para cancelar."
-#: MainFrame.cpp:455 Workspace.cpp:787
+#: MainFrame.cpp:455 Workspace.cpp:783
#, c-format
msgid "Induction motor %d"
msgstr "Motor de indução %d"
-#: MainFrame.cpp:458 Workspace.cpp:791
+#: MainFrame.cpp:458 Workspace.cpp:787
msgid "Insert Induction Motor: Click on a buses, ESC to cancel."
msgstr "Inserir Motor de indução: Clique em uma barra, ESC para cancelar."
-#: MainFrame.cpp:463 Workspace.cpp:800
+#: MainFrame.cpp:463 Workspace.cpp:796
#, c-format
msgid "Synchronous condenser %d"
msgstr "Compensador síncrono %d"
-#: MainFrame.cpp:466 Workspace.cpp:804
+#: MainFrame.cpp:466 Workspace.cpp:800
msgid "Insert Synchronous Condenser: Click on a buses, ESC to cancel."
msgstr "Inserir Compensador síncrono: Clique em uma barra, ESC para cancelar."
-#: MathExpressionForm.cpp:7
+#: MathExpressionForm.cpp:44
msgid "No checks performed."
msgstr "Nenhuma verificação realizada."
-#: MathExpressionForm.cpp:19
+#: MathExpressionForm.cpp:57
msgid "Syntax error"
msgstr "Erro de sintaxe"
-#: MathExpressionForm.cpp:20
+#: MathExpressionForm.cpp:58
msgid "Mismatched parenthesis"
msgstr "Parênteses sem correspondência"
-#: MathExpressionForm.cpp:21
+#: MathExpressionForm.cpp:59
msgid "Missing ')'"
msgstr "Faltando ')'"
-#: MathExpressionForm.cpp:22
+#: MathExpressionForm.cpp:60
msgid "Empty parentheses"
msgstr "Parênteses vazios"
-#: MathExpressionForm.cpp:23
+#: MathExpressionForm.cpp:61
msgid "Syntax error: Operator expected"
msgstr "Erro de sintaxe: Operador esperado"
-#: MathExpressionForm.cpp:24
+#: MathExpressionForm.cpp:62
msgid "Not enough memory"
msgstr "Não possui memória"
-#: MathExpressionForm.cpp:25
+#: MathExpressionForm.cpp:63
msgid "An unexpected error occurred"
msgstr "Um erro inesperado ocorreu"
-#: MathExpressionForm.cpp:26
+#: MathExpressionForm.cpp:64
msgid "Syntax error in input variables"
msgstr "Erro de sintaxe nas variáveis de entrada"
-#: MathExpressionForm.cpp:27
+#: MathExpressionForm.cpp:65
msgid "Illegal number of parameters to function"
msgstr "Número ilegal de parâmetros para a função"
-#: MathExpressionForm.cpp:28
+#: MathExpressionForm.cpp:66
+msgid "Syntax error: Premature end of string"
+msgstr "Erro de sintaxe: Fim prematuro da string"
+
+#: MathExpressionForm.cpp:67
msgid "Syntax error: Expecting ( after function"
msgstr "Erro de sintaxe: '(' esperado após a função"
-#: MathExpressionForm.cpp:29
+#: MathExpressionForm.cpp:68
msgid "Syntax error: Unknown identifier"
-msgstr "Erro de sintaxe: identificador desconhecida"
+msgstr "Erro de sintaxe: Identificador desconhecido"
-#: MathExpressionForm.cpp:30
+#: MathExpressionForm.cpp:69
msgid "No function has been parsed yet"
msgstr "Nenhuma função foi analisada ainda"
-#: MathExpressionForm.cpp:47
+#: MathExpressionForm.cpp:86
msgid "OK!"
msgstr "OK!"
-#: OpenGLText.h:52 Text.h:109 base/ElementFormBase.h:814
+#: OpenGLText.h:57 Text.h:109 base/ElementFormBase.h:814
msgid "Text"
msgstr "Texto"
@@ -1786,40 +1794,40 @@ msgstr "Atenção"
msgid "Insert Text: Click to insert, ESC to cancel."
msgstr "Inserir Texto: Clique para inserir, ESC para cancelar."
-#: Workspace.cpp:843
+#: Workspace.cpp:839
msgid "MODE: DRAG"
msgstr "MODO: ARRASTAR"
-#: Workspace.cpp:848
+#: Workspace.cpp:844
msgid "MODE: PASTE"
msgstr "MODO: COLAR"
-#: Workspace.cpp:855
+#: Workspace.cpp:851
msgid "MODE: INSERT"
msgstr "MODO: INSERÇÃO"
-#: Workspace.cpp:864
+#: Workspace.cpp:860
msgid "MODE: EDIT"
msgstr "MODO: EDIÇÃO"
-#: Workspace.cpp:868
+#: Workspace.cpp:864
#, c-format
msgid "ZOOM: %d%%"
msgstr "ZOOM: %d%%"
-#: Workspace.cpp:1212 Workspace.cpp:1320
+#: Workspace.cpp:1208 Workspace.cpp:1316
msgid "It was not possible to paste from clipboard."
msgstr "Não foi possível colar da área de transferência."
-#: Workspace.cpp:1328
+#: Workspace.cpp:1324
msgid "Click to paste."
msgstr "Clique para colar."
-#: Workspace.cpp:1473
+#: Workspace.cpp:1469
msgid "Do you wish to open the stability graphics?"
msgstr "Você deseja abrir os gráficos do estudo de estabilidade?"
-#: Workspace.cpp:1473
+#: Workspace.cpp:1469
msgid "Question"
msgstr "Pergunta"