Skip to content

Commit

Permalink
Allow re-simulation of interactive simulation
Browse files Browse the repository at this point in the history
Fixes #8303
  • Loading branch information
adeas31 committed Dec 1, 2023
1 parent ef6b0b1 commit 0933e87
Show file tree
Hide file tree
Showing 13 changed files with 254 additions and 303 deletions.
10 changes: 6 additions & 4 deletions OMEdit/OMEditLIB/Modeling/MessagesWidget.cpp
Expand Up @@ -563,15 +563,17 @@ SimulationOutputWidget* MessagesWidget::getSimulationOutputWidget(const QString
*/
bool MessagesWidget::closeTab(int index)
{
// Close SimulationOutputWidget
SimulationOutputWidget *pSimulationOutputWidget = qobject_cast<SimulationOutputWidget*>(mpMessagesTabWidget->widget(index));
if (pSimulationOutputWidget && !pSimulationOutputWidget->isCompilationProcessRunning() && !pSimulationOutputWidget->isSimulationProcessRunning()) {
if (pSimulationOutputWidget
&& !pSimulationOutputWidget->isCompilationProcessRunning()
&& !pSimulationOutputWidget->isPostCompilationProcessRunning()
&& !pSimulationOutputWidget->isSimulationProcessRunning()) {
mpMessagesTabWidget->removeTab(index);
if (pSimulationOutputWidget->getSimulationOptions().isInteractiveSimulation()) {
MainWindow::instance()->getSimulationDialog()->removeSimulationOutputWidget(pSimulationOutputWidget);
}
emit messageTabClosed(index);
return true;
}
// Close OMSSimulationOutputWidget
OMSSimulationOutputWidget *pOMSSimulationOutputWidget = qobject_cast<OMSSimulationOutputWidget*>(mpMessagesTabWidget->widget(index));
if (pOMSSimulationOutputWidget && !pOMSSimulationOutputWidget->isSimulationProcessRunning()) {
mpMessagesTabWidget->removeTab(index);
Expand Down
26 changes: 18 additions & 8 deletions OMEdit/OMEditLIB/Plotting/PlotWindowContainer.cpp
Expand Up @@ -275,6 +275,22 @@ bool PlotWindowContainer::eventFilter(QObject *pObject, QEvent *pEvent)
return QMdiArea::eventFilter(pObject, pEvent);
}

/*!
* \brief PlotWindowContainer::removePlotCurves
* Removes all the plot curves from PlotWindow
* \param pPlotWindow
*/
void PlotWindowContainer::removePlotCurves(PlotWindow *pPlotWindow)
{
int i = 0;
while(i != pPlotWindow->getPlot()->getPlotCurvesList().size()) {
PlotCurve *pPlotCurve = pPlotWindow->getPlot()->getPlotCurvesList()[i];
pPlotWindow->getPlot()->removeCurve(pPlotCurve);
pPlotCurve->detach();
i = 0; //Restart iteration
}
}

/*!
* \brief PlotWindowContainer::addPlotWindow
* Adds a new Plot Window.
Expand Down Expand Up @@ -521,7 +537,7 @@ void PlotWindowContainer::removeInteractivePlotWindow()
{
PlotWindow *pPlotWindow = qobject_cast<PlotWindow*>(sender());
QString owner = pPlotWindow->getInteractiveOwner();
MainWindow::instance()->getVariablesWidget()->getVariablesTreeModel()->removeVariableTreeItem(owner);
MainWindow::instance()->getVariablesWidget()->getVariablesTreeModel()->removeVariableTreeItem(owner, false);
}

/*!
Expand Down Expand Up @@ -561,13 +577,7 @@ void PlotWindowContainer::clearPlotWindow()
tr("No plot window is active for clearing curves."), Helper::ok);
return;
}
int i = 0;
while(i != pPlotWindow->getPlot()->getPlotCurvesList().size()) {
PlotCurve *pPlotCurve = pPlotWindow->getPlot()->getPlotCurvesList()[i];
pPlotWindow->getPlot()->removeCurve(pPlotCurve);
pPlotCurve->detach();
i = 0; //Restart iteration
}
removePlotCurves(pPlotWindow);
pPlotWindow->fitInView();
MainWindow::instance()->getVariablesWidget()->updateVariablesTreeHelper(subWindowList(QMdiArea::ActivationHistoryOrder).last());
}
Expand Down
1 change: 1 addition & 0 deletions OMEdit/OMEditLIB/Plotting/PlotWindowContainer.h
Expand Up @@ -67,6 +67,7 @@ class PlotWindowContainer : public QMdiArea
bool isDiagramWindow(QObject *pObject);
bool isUniqueName(QString name);
bool eventFilter(QObject *pObject, QEvent *pEvent);
void removePlotCurves(OMPlot::PlotWindow *pPlotWindow);
private:
void addRenameTabToSubWindowSystemMenu(QMdiSubWindow *pMdiSubWindow);
DiagramWindow *mpDiagramWindow;
Expand Down
75 changes: 22 additions & 53 deletions OMEdit/OMEditLIB/Plotting/VariablesWidget.cpp
Expand Up @@ -630,9 +630,10 @@ void VariablesTreeModel::parseInitXml(QXmlStreamReader &xmlReader, SimulationOpt
* \brief VariablesTreeModel::removeVariableTreeItem
* Removes the VariablesTreeItem.
* \param variable
* \param closeInteractivePlotWindow
* \return
*/
bool VariablesTreeModel::removeVariableTreeItem(QString variable)
bool VariablesTreeModel::removeVariableTreeItem(QString variable, bool closeInteractivePlotWindow)
{
VariablesTreeItem *pVariablesTreeItem = findVariablesTreeItem(variable, mpRootVariablesTreeItem);
if (pVariablesTreeItem) {
Expand All @@ -647,14 +648,8 @@ bool VariablesTreeModel::removeVariableTreeItem(QString variable)
pVariablesTreeItem->removeChildren();
VariablesTreeItem *pParentVariablesTreeItem = pVariablesTreeItem->parent();
pParentVariablesTreeItem->removeChild(pVariablesTreeItem);

if (pVariablesTreeItem->getSimulationOptions().isInteractiveSimulation()) {
// remove the right interactive simulation output widget
SimulationOutputWidget *pSimulationOutputWidget = MessagesWidget::instance()->getSimulationOutputWidget(pVariablesTreeItem->getFileName());
if (pSimulationOutputWidget) {
MainWindow::instance()->getSimulationDialog()->removeSimulationOutputWidget(pSimulationOutputWidget);
}
}
MainWindow::instance()->getSimulationDialog()->removeInteractiveSimulation(pVariablesTreeItem->getSimulationOptions().isInteractiveSimulation(),
pVariablesTreeItem->getFileName(), closeInteractivePlotWindow);
if (pVariablesTreeItem) {
delete pVariablesTreeItem;
}
Expand Down Expand Up @@ -795,7 +790,7 @@ bool VariablesTreeModel::insertVariablesItems(QString fileName, QString filePath
* But don't make them checkable so user can't plot them.
*/
QStringList variableListFromResultFile;
if (readingVariablesFromInitFile) {
if (readingVariablesFromInitFile && !simulationOptions.isInteractiveSimulation()) {
variableListFromResultFile = MainWindow::instance()->getOMCProxy()->readSimulationResultVars(QString("%1%2%3").arg(filePath, QDir::separator(), fileName));
}
QStringList variables;
Expand Down Expand Up @@ -1231,7 +1226,7 @@ void VariablesTreeModel::removeVariableTreeItem()
{
QAction *pAction = qobject_cast<QAction*>(sender());
if (pAction) {
removeVariableTreeItem(pAction->data().toString());
removeVariableTreeItem(pAction->data().toString(), true);
emit variableTreeItemRemoved(pAction->data().toString());
}
}
Expand Down Expand Up @@ -1409,7 +1404,7 @@ void VariablesTreeView::keyPressEvent(QKeyEvent *event)
index = mpVariablesWidget->getVariableTreeProxyModel()->mapToSource(index);
VariablesTreeItem *pVariablesTreeItem = static_cast<VariablesTreeItem*>(index.internalPointer());
if (event->key() == Qt::Key_Delete && pVariablesTreeItem->isRootItem()) {
mpVariablesWidget->getVariablesTreeModel()->removeVariableTreeItem(pVariablesTreeItem->getVariableName());
mpVariablesWidget->getVariablesTreeModel()->removeVariableTreeItem(pVariablesTreeItem->getVariableName(), true);
return;
}
}
Expand Down Expand Up @@ -1565,10 +1560,6 @@ void VariablesWidget::insertVariablesItemsToTree(QString fileName, QString fileP
mpVariableTreeProxyModel->setFilterRegExp(QRegExp(""));
// insert the plot variables
bool updateVariables = mpVariablesTreeModel->insertVariablesItems(fileName, filePath, variablesList, simulationOptions);
// handle interactive re-simulation
if (simulationOptions.isInteractiveSimulation() && simulationOptions.isReSimulate()) {
interactiveReSimulation(simulationOptions.getClassName());
}
// update the plot variables tree
if (updateVariables) {
variablesUpdated();
Expand Down Expand Up @@ -1704,24 +1695,6 @@ void VariablesWidget::updateVariablesTreeHelper(QMdiSubWindow *pSubWindow)
mpVariableTreeProxyModel->invalidate();
}

void VariablesWidget::interactiveReSimulation(QString modelName)
{
QList<QString> selectedVariables = mSelectedInteractiveVariables.value(modelName);

foreach (QString variable, selectedVariables) {
QString curveNameStructure = modelName + "." + variable;
VariablesTreeItem *pVariableTreeItem;
pVariableTreeItem = mpVariablesTreeModel->findVariablesTreeItem(curveNameStructure, mpVariablesTreeModel->getRootVariablesTreeItem());
if (pVariableTreeItem) {
bool state = mpVariablesTreeModel->blockSignals(true);
QModelIndex index = mpVariablesTreeModel->variablesTreeItemIndex(pVariableTreeItem);
mpVariablesTreeModel->setData(index, Qt::Checked, Qt::CheckStateRole);
plotVariables(index, 1, 1, false);
mpVariablesTreeModel->blockSignals(state);
}
}
}

/*!
* \brief VariablesWidget::readVariablesAndUpdateXML
* Reads the updated values
Expand Down Expand Up @@ -1800,24 +1773,27 @@ void VariablesWidget::reSimulate(bool showSetup)
pVariablesTreeItem = pVariablesTreeItem->rootParent();
SimulationOptions simulationOptions = pVariablesTreeItem->getSimulationOptions();
if (simulationOptions.isValid()) {
if (simulationOptions.isInteractiveSimulation()) {
QMessageBox::information(this, QString("%1 - %2").arg(Helper::applicationName, Helper::information), tr("You cannot re-simulate an interactive simulation."), Helper::ok);
MainWindow::instance()->getSimulationDialog()->removeInteractiveSimulation(simulationOptions.isInteractiveSimulation(), pVariablesTreeItem->getFileName(), false);
simulationOptions.setReSimulate(true);
updateInitXmlFile(pVariablesTreeItem, simulationOptions);
if (showSetup) {
MainWindow::instance()->getSimulationDialog()->show(0, true, simulationOptions);
} else {
simulationOptions.setReSimulate(true);
updateInitXmlFile(simulationOptions);
if (showSetup) {
MainWindow::instance()->getSimulationDialog()->show(0, true, simulationOptions);
} else {
MainWindow::instance()->getSimulationDialog()->reSimulate(simulationOptions);
}
MainWindow::instance()->getSimulationDialog()->reSimulate(simulationOptions);
}
} else {
QMessageBox::information(this, QString("%1 - %2").arg(Helper::applicationName, Helper::information),
tr("You cannot re-simulate this class.<br />This is just a result file loaded via menu <b>File->Open Result File(s)</b>."), Helper::ok);
}
}

void VariablesWidget::updateInitXmlFile(SimulationOptions simulationOptions)
/*!
* \brief VariablesWidget::updateInitXmlFile
* Updates the model_init.xml file
* \param pVariablesTreeItem
* \param simulationOptions
*/
void VariablesWidget::updateInitXmlFile(VariablesTreeItem *pVariablesTreeItem, SimulationOptions simulationOptions)
{
/* Update the _init.xml file with new values. */
/* open the model_init.xml file for writing */
Expand All @@ -1826,11 +1802,9 @@ void VariablesWidget::updateInitXmlFile(SimulationOptions simulationOptions)
QDomDocument initXmlDocument;
if (initFile.open(QIODevice::ReadOnly)) {
if (initXmlDocument.setContent(&initFile)) {
VariablesTreeItem *pTopVariableTreeItem;
pTopVariableTreeItem = mpVariablesTreeModel->findVariablesTreeItem(simulationOptions.getFullResultFileName(), mpVariablesTreeModel->getRootVariablesTreeItem());
if (pTopVariableTreeItem) {
if (pVariablesTreeItem) {
QHash<QString, QHash<QString, QString> > variables;
readVariablesAndUpdateXML(pTopVariableTreeItem, simulationOptions.getFullResultFileName(), &variables);
readVariablesAndUpdateXML(pVariablesTreeItem, simulationOptions.getFullResultFileName(), &variables);
findVariableAndUpdateValue(initXmlDocument, variables);
}
} else {
Expand Down Expand Up @@ -2303,11 +2277,6 @@ void VariablesWidget::plotVariables(const QModelIndex &index, qreal curveThickne
}
}

void VariablesWidget::addSelectedInteractiveVariables(const QString &modelName, const QList<QString> &selectedVariables)
{
mSelectedInteractiveVariables.insert(modelName, selectedVariables);
}

/*!
* \brief VariablesWidget::unitChanged
* Handles the case when display unit is changed in VariablesTreeView.\n
Expand Down
7 changes: 2 additions & 5 deletions OMEdit/OMEditLIB/Plotting/VariablesWidget.h
Expand Up @@ -161,7 +161,7 @@ class VariablesTreeModel : public QAbstractItemModel
QModelIndex variablesTreeItemIndex(const VariablesTreeItem *pVariablesTreeItem) const;
bool insertVariablesItems(QString fileName, QString filePath, QStringList variablesList, SimulationOptions simulationOptions);
void parseInitXml(QXmlStreamReader &xmlReader, SimulationOptions simulationOptions, QStringList *variablesList);
bool removeVariableTreeItem(QString variable);
bool removeVariableTreeItem(QString variable, bool closeInteractivePlotWindow);
void unCheckVariables(VariablesTreeItem *pVariablesTreeItem);
void plotAllVariables(VariablesTreeItem *pVariablesTreeItem, OMPlot::PlotWindow *pPlotWindow);
private:
Expand Down Expand Up @@ -226,15 +226,13 @@ class VariablesWidget : public QWidget
VariablesTreeView* getVariablesTreeView() {return mpVariablesTreeView;}
void enableVisualizationControls(bool enable);
void insertVariablesItemsToTree(QString fileName, QString filePath, QStringList variablesList, SimulationOptions simulationOptions);
void addSelectedInteractiveVariables(const QString &modelName, const QList<QString> &selectedVariables);
void variablesUpdated();
void updateVariablesTreeHelper(QMdiSubWindow *pSubWindow);
void readVariablesAndUpdateXML(VariablesTreeItem *pVariablesTreeItem, QString outputFileName,
QHash<QString, QHash<QString, QString> > *variables);
void findVariableAndUpdateValue(QDomDocument xmlDocument, QHash<QString, QHash<QString, QString> > variables);
void reSimulate(bool showSetup);
void interactiveReSimulation(QString modelName);
void updateInitXmlFile(SimulationOptions simulationOptions);
void updateInitXmlFile(VariablesTreeItem *pVariablesTreeItem, SimulationOptions simulationOptions);
void initializeVisualization();
void updateVisualization();
void updatePlotWindows();
Expand All @@ -260,7 +258,6 @@ class VariablesWidget : public QWidget
VariablesTreeModel *mpVariablesTreeModel;
VariablesTreeView *mpVariablesTreeView;
QVector<PlotParametricCurve> mPlotParametricCurves;
QHash<QString, QList<QString>> mSelectedInteractiveVariables;
QMdiSubWindow *mpLastActiveSubWindow;
ModelicaMatReader mModelicaMatReader;
csv_data *mpCSVData;
Expand Down
20 changes: 15 additions & 5 deletions OMEdit/OMEditLIB/Simulation/OpcUaClient.cpp
Expand Up @@ -83,18 +83,28 @@ OpcUaClient::~OpcUaClient()
/*!
Connect to an OPC UA server.
*/
bool OpcUaClient::connectToServer()
bool OpcUaClient::connectToServer(QString *pErrorString)
{
std::string endPoint = "opc.tcp://localhost:" + std::to_string(mSimulationOptions.getInteractiveSimulationPortNumber());
mpClient = UA_Client_new(UA_ClientConfig_standard);
UA_StatusCode returnValue;
int tries = 0;
do {
Sleep::msleep(100);
// QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
returnValue = UA_Client_connect(mpClient, endPoint.c_str());
++tries;
if (tries > 50) { // Do not go in infinte loop. Try 50 times i.e., 5 secs max and then give up.
break;
}
} while (returnValue != UA_STATUSCODE_GOOD);
// qDebug() << "Connected to OPC-UA server " << endPoint;
return true;
if (returnValue != UA_STATUSCODE_GOOD) {
*pErrorString = tr("Could not connect to the embedded server. Status code %1.").arg(QString(UA_StatusCode_name(returnValue)));
return false;
} else {
*pErrorString = QString(UA_StatusCode_name(returnValue));
return true;
}
}

/*!
Expand Down Expand Up @@ -454,10 +464,10 @@ void OpcUaWorker::checkMinMaxValues(const double& value)
{
if (value < mMinMaxValues.first) {
mMinMaxValues.first = value;
emit sendUpdateYAxis(mMinMaxValues.first, mMinMaxValues.second);
emit sendUpdateYAxis(qMakePair(mMinMaxValues.first, mMinMaxValues.second));
} else if ( value > mMinMaxValues.second ) {
mMinMaxValues.second = value;
emit sendUpdateYAxis(mMinMaxValues.first, mMinMaxValues.second);
emit sendUpdateYAxis(qMakePair(mMinMaxValues.first, mMinMaxValues.second));
}
}

Expand Down
4 changes: 2 additions & 2 deletions OMEdit/OMEditLIB/Simulation/OpcUaClient.h
Expand Up @@ -16,7 +16,7 @@ class OpcUaClient : public QObject
OpcUaClient(SimulationOptions simulationOptions);
~OpcUaClient();

bool connectToServer();
bool connectToServer(QString *pErrorString);
QStringList fetchVariableNamesFromServer();
QMap<QString, Variable*> *getVariables() {return &mVariables;}
UA_Client* getClient() {return mpClient;}
Expand Down Expand Up @@ -96,7 +96,7 @@ private slots:
UA_UInt32 mSubscriptionId;
signals:
void sendUpdateCurves();
void sendUpdateYAxis(double, double);
void sendUpdateYAxis(QPair<double, double> minMaxValues);
void sendAddMonitoredItem(int, QString);
void sendRemoveMonitoredItem(QString);
};
Expand Down

0 comments on commit 0933e87

Please sign in to comment.