Skip to content

Commit

Permalink
Added support for typed interfaces in composite models.
Browse files Browse the repository at this point in the history
Squashed commit of the following:

commit 79b7362676f8e3f99fa529ba0c18dec130901e4d
Author: Robert Braun <robbr48@liu.se>
Date:   Fri Jan 13 08:28:40 2017 +0100

    Removed accidentally added file

commit 9b0c08004388f41aeca1e46a073595555b4a2e1e
Merge: 4bb4b9a b93871b
Author: Robert Braun <robbr48@liu.se>
Date:   Fri Jan 13 08:00:52 2017 +0100

    Merge remote-tracking branch 'origin/master' into typed_interfaces

commit 4bb4b9a11aec32006a845d1108f919627e8a4888
Author: Robert Braun <robbr48@liu.se>
Date:   Fri Jan 13 07:50:00 2017 +0100

    FIXUP

commit c55aff5ee2f0d5d5c0a584835646e9cc3f36a943
Merge: 4e65f24 3d30078
Author: Robert Braun <robbr48@liu.se>
Date:   Thu Jan 12 18:49:25 2017 +0100

    Merge remote-tracking branch 'origin/master' into typed_interfaces

commit 4e65f24d179a63e38dad918abc608ed044ffdbd9
Merge: abf6d24 a6c5fbc
Author: Robert Braun <robbr48@liu.se>
Date:   Thu Jan 12 15:18:19 2017 +0100

    Merged master into typed_interfaces

commit abf6d24d54a30c53fe1a81654166eb8e00b30fcd
Author: Robert Braun <robbr48@liu.se>
Date:   Thu Jan 12 15:17:58 2017 +0100

    Merge

commit ba6c97ea80d3709ec9a7aacdd028a5e4028ac65a
Author: Robert Braun <robbr48@liu.se>
Date:   Thu Jan 12 14:46:57 2017 +0100

    Fixed alignment check for 1D interfaces in composite models.

commit ef4d3393e279ba84389e9b582163861dee2f3517
Author: Robert Braun <robert.braun@liu.se>
Date:   Wed Jan 11 11:06:46 2017 +0100

    Added dimensions and causality for composite model interfaces

    - Replaced interface type with dimensions and causality.
    - Disabled alignment for non-bidirectional connections.
    - Moved hard-coded strings to string handler.

commit e7336167a3b3a2343e0e34806e5dcd5f2bcd8f43
Author: Robert Braun <robbr48@liu.se>
Date:   Mon Jan 9 08:11:30 2017 +0100

    Added correct loading of signal connector appearance in composite models.

commit f7e0321cea086eaff133400bfa275f6a0cdc8e95
Author: Robert Braun <robbr48@liu.se>
Date:   Thu Jan 5 14:11:02 2017 +0100

    Made signal metamodel connections dashed with arrows.

commit e432fa71b32c1b4c5c12d6ce9f23036b0e4f7855
Author: Robert Braun <robbr48@liu.se>
Date:   Thu Dec 22 11:19:42 2016 +0100

    Added types and domains to co-simulation interface points.

commit 074d60ffbe839b8c334e3d3909659f3fa8e4572e
Author: Robert Braun <robbr48@liu.se>
Date:   Wed Dec 21 14:09:03 2016 +0100

    Added type and domain attributes for interface points.
  • Loading branch information
Robert Braun committed Jan 13, 2017
1 parent 89f201c commit a7bf0d7
Show file tree
Hide file tree
Showing 11 changed files with 319 additions and 15 deletions.
Empty file.
14 changes: 12 additions & 2 deletions OMEdit/OMEditGUI/Annotations/ShapeAnnotation.cpp
Expand Up @@ -1589,8 +1589,18 @@ void ShapeAnnotation::contextMenuEvent(QGraphicsSceneContextMenuEvent *pEvent)
QMenu menu(mpGraphicsView);
if (mpGraphicsView->getModelWidget()->getLibraryTreeItem()->getLibraryType()== LibraryTreeItem::MetaModel) {
menu.addAction(mpShapeAttributesAction);
menu.addSeparator();
menu.addAction(mpAlignInterfacesAction);

//Only show align interfaces action for bidirectional connections
LineAnnotation *pConnectionLineAnnotation = dynamic_cast<LineAnnotation*>(this);
QString startName = pConnectionLineAnnotation->getStartComponentName();
QString endName = pConnectionLineAnnotation->getEndComponentName();
MetaModelEditor *pEditor = dynamic_cast<MetaModelEditor*>(mpGraphicsView->getModelWidget()->getEditor());
if(pEditor->getInterfaceCausality(startName) == StringHandler::getTLMCausality(StringHandler::TLMBidirectional) &&
pEditor->getInterfaceCausality(endName) == StringHandler::getTLMCausality(StringHandler::TLMBidirectional)) {
menu.addSeparator();
menu.addAction(mpAlignInterfacesAction);
}

menu.addSeparator();
menu.addAction(mpGraphicsView->getDeleteAction());
} else {
Expand Down
49 changes: 46 additions & 3 deletions OMEdit/OMEditGUI/Component/Component.cpp
Expand Up @@ -623,10 +623,44 @@ Component::Component(ComponentInfo *pComponentInfo, Component *pParentComponent)
mpResizerRectangle = 0;
createNonExistingComponent();
createDefaultComponent();
mpDefaultComponentRectangle->setVisible(true);

if(mpComponentInfo->getTLMCausality() == StringHandler::getTLMCausality(StringHandler::TLMBidirectional)) {
if(mpComponentInfo->getDomain() == StringHandler::getTLMDomain(StringHandler::Mechanical)) {
mpDefaultComponentRectangle->setFillColor(QColor(100, 100, 255)); //Mechanical = blue
}
else if(mpComponentInfo->getDomain() == StringHandler::getTLMDomain(StringHandler::Electric)) {
mpDefaultComponentRectangle->setFillColor(QColor(255, 255, 100)); //Hydraulic = yellow
}
else if(mpComponentInfo->getDomain() == StringHandler::getTLMDomain(StringHandler::Hydraulic)) {
mpDefaultComponentRectangle->setFillColor(QColor(100, 255, 100)); //Hydraulic = green
}
else if(mpComponentInfo->getDomain() == StringHandler::getTLMDomain(StringHandler::Pneumatic)) {
mpDefaultComponentRectangle->setFillColor(QColor(100, 255, 255)); //Pneumatic = turquoise
}
else if(mpComponentInfo->getDomain() == StringHandler::getTLMDomain(StringHandler::Magnetic)) {
mpDefaultComponentRectangle->setFillColor(QColor(255, 100, 255)); //Magnetic = purple
}
mpDefaultComponentText->setTextString(QString::number(mpComponentInfo->getDimensions())+"D");
}
else if((mpComponentInfo->getTLMCausality() == StringHandler::getTLMCausality(StringHandler::TLMInput)) |
(mpComponentInfo->getTLMCausality() == StringHandler::getTLMCausality(StringHandler::TLMOutput))) {
mpDefaultComponentRectangle->setFillColor(QColor(255, 100, 100)); //Signal = red
if(mpComponentInfo->getTLMCausality() == StringHandler::getTLMCausality(StringHandler::TLMInput)) {
mpDefaultComponentText->setTextString("in");
}
else {
mpDefaultComponentText->setTextString("out");
}
}
mpDefaultComponentRectangle->setLineColor(QColor(0, 0, 0));
mpDefaultComponentRectangle->setLineColor(QColor(0, 0, 0));
mpDefaultComponentRectangle->setFillColor(QColor(110, 214, 0));
mpDefaultComponentRectangle->setFillPattern(StringHandler::FillSolid);
mpDefaultComponentRectangle->setFillPattern(StringHandler::FillSolid);
mpDefaultComponentRectangle->setVisible(true);
mpDefaultComponentText->setFontSize(300);
mpDefaultComponentText->setVisible(true);


// transformation
qreal yPosition = 80 - mpParentComponent->getComponentsList().size() * 40;
QString transformation = QString("Placement(true,110.0,%1,-15.0,-15.0,15.0,15.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0)").arg(yPosition);
Expand Down Expand Up @@ -1219,12 +1253,15 @@ void Component::renameComponentInConnections(QString newName)
* Inserts a new interface point.
* \param interfaceName
*/
void Component::insertInterfacePoint(QString interfaceName, QString position, QString angle321)
void Component::insertInterfacePoint(QString interfaceName, QString position, QString angle321, int dimensions, QString causality, QString domain)
{
ComponentInfo *pComponentInfo = new ComponentInfo;
pComponentInfo->setName(interfaceName);
pComponentInfo->setPosition(position);
pComponentInfo->setAngle321(angle321);
pComponentInfo->setDimensions(dimensions);
pComponentInfo->setTLMCausality(causality);
pComponentInfo->setDomain(domain);
mComponentsList.append(new Component(pComponentInfo, this));
}

Expand Down Expand Up @@ -1280,7 +1317,13 @@ void Component::drawInterfacePoints()
pComponentInfo->setName(interfacePoint.attribute("Name"));
pComponentInfo->setPosition(interfacePoint.attribute("Position", "0,0,0"));
pComponentInfo->setAngle321(interfacePoint.attribute("Angle321", "0,0,0"));
pComponentInfo->setDimensions(interfacePoint.attribute("Dimensions", "3").toInt());
pComponentInfo->setTLMCausality(interfacePoint.attribute("Causality",
StringHandler::getTLMCausality(StringHandler::TLMBidirectional)));
pComponentInfo->setDomain(interfacePoint.attribute("Domain",
StringHandler::getTLMDomain(StringHandler::Mechanical)));
mComponentsList.append(new Component(pComponentInfo, this));
mComponentsList.last();
}
}
}
Expand Down
11 changes: 10 additions & 1 deletion OMEdit/OMEditGUI/Component/Component.h
Expand Up @@ -117,6 +117,12 @@ class ComponentInfo : public QObject
QString getPosition() const {return mPosition;}
void setAngle321(QString angle321) {mAngle321 = angle321;}
QString getAngle321() const {return mAngle321;}
void setDimensions(int dimensions) {mDimensions = dimensions;}
int getDimensions() const {return mDimensions;}
void setTLMCausality(QString causality) {mTLMCausality = causality;}
QString getTLMCausality() const {return mTLMCausality;}
void setDomain(QString domain) {mDomain = domain;}
QString getDomain() const {return mDomain;}
// operator overloading
bool operator==(const ComponentInfo &componentInfo) const;
bool operator!=(const ComponentInfo &componentInfo) const;
Expand Down Expand Up @@ -148,6 +154,9 @@ class ComponentInfo : public QObject
QString mGeometryFile;
QString mPosition;
QString mAngle321;
int mDimensions;
QString mTLMCausality;
QString mDomain;

bool isModiferClassRecord(QString modifierName, Component *pComponent);
};
Expand Down Expand Up @@ -223,7 +232,7 @@ class Component : public QObject, public QGraphicsItem
void shapeUpdated();
void shapeDeleted();
void renameComponentInConnections(QString newName);
void insertInterfacePoint(QString interfaceName, QString position, QString angle321);
void insertInterfacePoint(QString interfaceName, QString position, QString angle321, int dimensions, QString causality, QString domain);
void removeInterfacePoint(QString interfaceName);

Transformation mTransformation;
Expand Down
163 changes: 161 additions & 2 deletions OMEdit/OMEditGUI/Editors/MetaModelEditor.cpp
Expand Up @@ -385,11 +385,80 @@ bool MetaModelEditor::createConnection(LineAnnotation *pConnectionLineAnnotation
// check if interfaces are aligned
bool aligned = interfacesAligned(pConnectionLineAnnotation->getStartComponentName(), pConnectionLineAnnotation->getEndComponentName());
pConnectionLineAnnotation->setAligned(aligned);

if(this->getInterfaceCausality(pConnectionLineAnnotation->getEndComponentName()) ==
StringHandler::getTLMCausality(StringHandler::TLMInput)) {
pConnectionLineAnnotation->setLinePattern(StringHandler::LineDash);
pConnectionLineAnnotation->setEndArrow(StringHandler::ArrowFilled);
pConnectionLineAnnotation->update();
pConnectionLineAnnotation->handleComponentMoved();
}
else if(this->getInterfaceCausality(pConnectionLineAnnotation->getEndComponentName()) ==
StringHandler::getTLMCausality(StringHandler::TLMOutput)) {
pConnectionLineAnnotation->setLinePattern(StringHandler::LineDash);
pConnectionLineAnnotation->setStartArrow(StringHandler::ArrowFilled);
pConnectionLineAnnotation->update();
pConnectionLineAnnotation->handleComponentMoved();
}

return true;
}
return false;
}

/*!
* \brief MetaModelEditor::okToConnect
* Checks if a connection between two interfaces is legal
* \param pConnectionLineAnnotation
* \return
*/
bool MetaModelEditor::okToConnect(LineAnnotation *pConnectionLineAnnotation)
{
QString startComp = pConnectionLineAnnotation->getStartComponentName();
QString endComp = pConnectionLineAnnotation->getEndComponentName();

int dimensions1 = getInterfaceDimensions(startComp);
int dimensions2 = getInterfaceDimensions(endComp);
QString causality1 = getInterfaceCausality(startComp);
QString causality2 = getInterfaceCausality(endComp);
QString domain1 = getInterfaceDomain(startComp);
QString domain2 = getInterfaceDomain(endComp);

MessagesWidget::instance()->addGUIMessage(MessageItem(MessageItem::MetaModel, "", false, 0, 0, 0, 0,
"Checking connection between "+
startComp+" and " +endComp,
Helper::scriptingKind, Helper::notificationLevel));

if(dimensions1 != dimensions2) {
MessagesWidget::instance()->addGUIMessage(MessageItem(MessageItem::MetaModel, "", false, 0, 0, 0, 0,
"Cannot connect interface points of different dimensions ("+
QString::number(dimensions1)+" to "+
QString::number(dimensions2)+")",
Helper::scriptingKind, Helper::errorLevel));
return false;
}
if(!(causality1 == StringHandler::getTLMCausality(StringHandler::TLMBidirectional) &&
causality2 == StringHandler::getTLMCausality(StringHandler::TLMBidirectional)) &&
!(causality1 == StringHandler::getTLMCausality(StringHandler::TLMInput) &&
causality2 != StringHandler::getTLMCausality(StringHandler::TLMOutput)) &&
!(causality1 == StringHandler::getTLMCausality(StringHandler::TLMOutput) &&
causality2 != StringHandler::getTLMCausality(StringHandler::TLMInput))) {
MessagesWidget::instance()->addGUIMessage(MessageItem(MessageItem::MetaModel, "", false, 0, 0, 0, 0,
"Cannot connect interface points of different causality ("+
causality1+" to "+causality2+")",
Helper::scriptingKind, Helper::errorLevel));
return false;
}
if(domain1 != domain2) {
MessagesWidget::instance()->addGUIMessage(MessageItem(MessageItem::MetaModel, "", false, 0, 0, 0, 0,
"Cannot connect interface points of different domains ("+
domain1+" to "+domain2+")",
Helper::scriptingKind, Helper::errorLevel));
return false;
}
return true;
}

/*!
* \brief MetaModelEditor::updateConnection
* Updates the MetaModel connection annotation.
Expand Down Expand Up @@ -498,6 +567,9 @@ void MetaModelEditor::addInterfacesData(QDomElement interfaces)
interfacePoint.setAttribute("Name", interfaceDataElement.attribute("Name"));
interfacePoint.setAttribute("Position", interfaceDataElement.attribute("Position"));
interfacePoint.setAttribute("Angle321", interfaceDataElement.attribute("Angle321"));
interfacePoint.setAttribute("Dimensions", interfaceDataElement.attribute("Dimensions"));
interfacePoint.setAttribute("Domain", interfaceDataElement.attribute("Domain"));
interfacePoint.setAttribute("Causality", interfaceDataElement.attribute("Causality"));
setPlainText(mXmlDocument.toString());
// check if interface is aligned
foreach (LineAnnotation* pConnectionLineAnnotation, mpModelWidget->getDiagramGraphicsView()->getConnectionsList()) {
Expand All @@ -514,11 +586,18 @@ void MetaModelEditor::addInterfacesData(QDomElement interfaces)
interfacePoint.setAttribute("Name", interfaceDataElement.attribute("Name"));
interfacePoint.setAttribute("Position", interfaceDataElement.attribute("Position"));
interfacePoint.setAttribute("Angle321", interfaceDataElement.attribute("Angle321"));
interfacePoint.setAttribute("Dimensions", interfaceDataElement.attribute("Dimensions"));
interfacePoint.setAttribute("Causality", interfaceDataElement.attribute("Causality"));
interfacePoint.setAttribute("Domain", interfaceDataElement.attribute("Domain"));
subModel.appendChild(interfacePoint);
Component *pComponent = mpModelWidget->getDiagramGraphicsView()->getComponentObject(subModel.attribute("Name"));
if (pComponent) {
pComponent->insertInterfacePoint(interfaceDataElement.attribute("Name"), interfaceDataElement.attribute("Position", "0,0,0"),
interfaceDataElement.attribute("Angle321", "0,0,0"));
pComponent->insertInterfacePoint(interfaceDataElement.attribute("Name"),
interfaceDataElement.attribute("Position", "0,0,0"),
interfaceDataElement.attribute("Angle321", "0,0,0"),
interfaceDataElement.attribute("Dimensions", "3").toInt(),
interfaceDataElement.attribute("Causality", StringHandler::getTLMCausality(StringHandler::TLMBidirectional)),
interfaceDataElement.attribute("Domain", StringHandler::getTLMDomain(StringHandler::Mechanical)));
}
}
}
Expand Down Expand Up @@ -601,6 +680,11 @@ void MetaModelEditor::addInterfacesData(QDomElement interfaces)
*/
bool MetaModelEditor::interfacesAligned(QString interface1, QString interface2)
{
if(getInterfaceCausality(interface1) != StringHandler::getTLMCausality(StringHandler::TLMBidirectional)) {
//Assume interface2 has same causality and dimensions, otherwise they could not be connected)
return true; //Alignment is not relevant for non-bidirectional connections
}

//Extract rotation and position vectors to Qt matrices
QGenericMatrix<3,1,double> CG_X1_PHI_CG; //Rotation of X1 relative to CG expressed in CG
QGenericMatrix<3,1,double> X1_C1_PHI_X1; //Rotation of C1 relative to X1 expressed in X1
Expand All @@ -618,6 +702,15 @@ bool MetaModelEditor::interfacesAligned(QString interface1, QString interface2)
return false;
}

else if(getInterfaceCausality(interface1) == StringHandler::getTLMCausality(StringHandler::TLMBidirectional) &&
getInterfaceDimensions(interface1) == 1) {
//Handle 1D- interfaces
//Assume interface2 has same causality and dimensions, otherwise they could not be connected)
//Only compare first element of interface position relative to external model,
//the model orientation should not matter for 1D connections
return fuzzyCompare(X1_C1_R_X1(0,0),X2_C2_R_X2(0,0));
}

QGenericMatrix<3,1,double> CG_C1_R_CG, CG_C1_PHI_CG, CG_C2_R_CG, CG_C2_PHI_CG;
QGenericMatrix<3,3,double> R_X1_C1, R_CG_X1, R_CG_C1, R_X2_C2, R_CG_X2, R_CG_C2;

Expand Down Expand Up @@ -885,6 +978,72 @@ void MetaModelEditor::alignInterfaces(QString fromInterface, QString toInterface
}
}

/*!
* \brief MetaModelEditor::getInterfaceType
* Returns the type of specified interface (e.g. "3D", "Input"...)
* \param pConnectionLineAnnotation
* \return
*/
int MetaModelEditor::getInterfaceDimensions(QString interfacePoint)
{
//Extract submodel and interface names
QString modelName = interfacePoint.split(".").at(0);
QString interfaceName = interfacePoint.split(".").at(1);

QDomElement subModelElement = getSubModelElement(modelName);
QDomElement interfaceElement = subModelElement.firstChildElement("InterfacePoint");
while (!interfaceElement.isNull()) {
if (interfaceElement.attribute("Name").compare(interfaceName) == 0) {
return interfaceElement.attribute("Dimensions", "3").toInt();
}
interfaceElement = interfaceElement.nextSiblingElement("InterfacePoint");
}
return 3; //Backwards compatibility
}

QString MetaModelEditor::getInterfaceCausality(QString interfacePoint)
{
MessagesWidget::instance()->addGUIMessage(MessageItem(MessageItem::MetaModel, "", false, 0, 0, 0, 0, "Checking causality for: "+interfacePoint,
Helper::scriptingKind, Helper::notificationLevel));
//Extract submodel and interface names
QString modelName = interfacePoint.split(".").at(0);
QString interfaceName = interfacePoint.split(".").at(1);

QDomElement subModelElement = getSubModelElement(modelName);
QDomElement interfaceElement = subModelElement.firstChildElement("InterfacePoint");
while (!interfaceElement.isNull()) {
if (interfaceElement.attribute("Name").compare(interfaceName) == 0) {
return interfaceElement.attribute("Causality", StringHandler::getTLMCausality(StringHandler::TLMBidirectional));
}
interfaceElement = interfaceElement.nextSiblingElement("InterfacePoint");
}
return StringHandler::getTLMCausality(StringHandler::TLMBidirectional); //Backwards compatibility
}

/*!
* \brief MetaModelEditor::getInterfaceDomain
* Returns the physical domain of specified interface (e.g. "Mechanical", "Hydraulic"...)
* \param pConnectionLineAnnotation
* \return
*/
QString MetaModelEditor::getInterfaceDomain(QString interfacePoint)
{
//Extract submodel and interface names
QString modelName = interfacePoint.split(".").at(0);
QString interfaceName = interfacePoint.split(".").at(1);

QDomElement subModelElement = getSubModelElement(modelName);
QDomElement interfaceElement = subModelElement.firstChildElement("InterfacePoint");
while (!interfaceElement.isNull()) {
if (interfaceElement.attribute("Name").compare(interfaceName) == 0) {
//Default to mechanical for backwards compatibility
return interfaceElement.attribute("Domain", StringHandler::getTLMDomain(StringHandler::Mechanical));
}
interfaceElement = interfaceElement.nextSiblingElement("InterfacePoint");
}
return StringHandler::getTLMDomain(StringHandler::Mechanical); //Backwards compatibility
}

/*!
* \brief MetaModelEditor::fuzzyCompare
* Special implementation of fuzzyCompare. Uses much larger tolerance than built-in qFuzzyCompare()
Expand Down
4 changes: 4 additions & 0 deletions OMEdit/OMEditGUI/Editors/MetaModelEditor.h
Expand Up @@ -80,6 +80,7 @@ class MetaModelEditor : public BaseEditor
void updateSubModelParameters(QString name, QString startCommand, QString exactStep, QString geometryFile);
void updateSubModelOrientation(QString name, QGenericMatrix<3,1,double> rot, QGenericMatrix<3,1,double> pos);
bool createConnection(LineAnnotation *pConnectionLineAnnotation);
bool okToConnect(LineAnnotation *pConnectionLineAnnotation);
void updateConnection(LineAnnotation *pConnectionLineAnnotation);
void updateSimulationParams(QString startTime, QString stopTime);
bool isSimulationParams();
Expand Down Expand Up @@ -107,6 +108,9 @@ public slots:
virtual void contentsHasChanged(int position, int charsRemoved, int charsAdded);
virtual void toggleCommentSelection() {}
void alignInterfaces(QString fromSubModel, QString toSubModel, bool showError = true);
int getInterfaceDimensions(QString interfacePoint);
QString getInterfaceCausality(QString interfacePoint);
QString getInterfaceDomain(QString interfacePoint);
};

class MetaModelEditorPage;
Expand Down

0 comments on commit a7bf0d7

Please sign in to comment.