Labview export doesnt support subsystems
Exporting to labview/sit doesnt include the subsystem components in the generated code, and hopsanrt-wrapper.h has no support for adding components in subsystems, connecting components in subsystems, setting parameters in subsystems and adding system ports..
I have made some changes to hopsanrt-wrapper.h and the generated file that seems to be working, at least for level 1 subsystems. I believe it could be easily modified to support nested subsystems.
added functions to hopsanrt-wrapper.h:
void addComponentToSubSystem(string systemName, string name, string type)
{
hopsan::ComponentSystem* system = spCoreComponentSystem->getSubComponentSystem(systemName.c_str());
hopsan::Component* pCoreComponent;
pCoreComponent = gHopsanCore.createComponent(type.c_str());
system->addComponent(pCoreComponent);
pCoreComponent->setName(name.c_str());
sComponentNames.push_back(name);
}
void addSubSystemPort(string systemName, string portName) {
hopsan::ComponentSystem* system = spCoreComponentSystem->getSubComponentSystem(systemName.c_str());
system->addSystemPort(portName.c_str());
//spCoreComponentSystem->
}
bool connectInSubSystem(string systemName, string comp1, string port1, string comp2, string port2)
{
hopsan::ComponentSystem* system = spCoreComponentSystem->getSubComponentSystem(systemName.c_str());
return system->connect(comp1.c_str(), port1.c_str(), comp2.c_str(), port2.c_str());
}
void setParameterInSubSystem(string subSystemName, string compname, string parname, double value)
{
std::stringstream ss;
ss << value;
hopsan::ComponentSystem* system = spCoreComponentSystem->getSubComponentSystem(subSystemName.c_str());
system->getSubComponentOrThisIfSysPort(compname.c_str())->setParameterValue(parname.c_str(), ss.str().c_str());
}
A modified USER_Initialize function with a single subsystem that works with the wrapper above:
long USER_Initialize()
{
createSystem(1e-3);
addComponent("C_type_Voltage_Source", "ElectricUsource");
addComponent("Input_Interface_Component", "SignalInputInterface");
addComponent("Output_Interface_Component", "SignalOutputInterface");
addComponent("Q_type_Ground", "ElectricGround");
addComponent("Subsystem", "Subsystem");
addComponentToSubSystem("Subsystem", "Current_Sensor", "ElectricIsensor");
addComponentToSubSystem("Subsystem", "Q_Type_Inductance", "ElectricInductance");
addSubSystemPort("Subsystem", "SystemPort");
addSubSystemPort("Subsystem", "SystemPort_1");
addSubSystemPort("Subsystem", "SystemPort_2");
connectInSubSystem("Subsystem", "Current_Sensor", "Pel1", "Q_Type_Inductance", "Pel2");
connectInSubSystem("Subsystem", "Current_Sensor", "Piout", "SystemPort_1", "SystemPort_1");
connectInSubSystem("Subsystem", "Q_Type_Inductance", "Pel1", "SystemPort", "SystemPort");
connectInSubSystem("Subsystem", "Q_Type_Inductance", "Pel2", "SystemPort_2", "SystemPort_2");
connect("C_type_Voltage_Source", "Pel1", "Subsystem", "SystemPort");
connect("Output_Interface_Component", "in", "Subsystem", "SystemPort_1");
connect("Q_type_Ground", "Pel1", "Subsystem", "SystemPort_2");
setParameter("C_type_Voltage_Source", "Pel1#Voltage", 0);
setParameter("C_type_Voltage_Source", "Pel1#Current", 0);
setParameter("C_type_Voltage_Source", "Pel1#WaveVariable", 0);
setParameter("C_type_Voltage_Source", "Pel1#CharImpedance", 0);
setParameter("C_type_Voltage_Source", "uin#Value", 1200);
setParameter("Output_Interface_Component", "in#Value", 0);
setParameter("Q_type_Ground", "Pel1#Voltage", 0);
setParameter("Q_type_Ground", "Pel1#Current", 0);
setParameter("Q_type_Ground", "Pel1#WaveVariable", 0);
setParameter("Q_type_Ground", "Pel1#CharImpedance", 0);
setParameterInSubSystem("Subsystem", "Current_Sensor", "Pel1#Voltage", 0);
setParameterInSubSystem("Subsystem", "Current_Sensor", "Pel1#Current", 0);
setParameterInSubSystem("Subsystem", "Current_Sensor", "Pel1#WaveVariable", 0);
setParameterInSubSystem("Subsystem", "Current_Sensor", "Pel1#CharImpedance", 0);
setParameterInSubSystem("Subsystem", "Q_Type_Inductance", "Induct#Value", 0.1);
initSystem();
rtSignal.Time = 0;
return NI_OK;
}
Confirmed. I like your suggestions, but I think we should keep the number of functions to a minimum. The best solution is probably to add an optional subsystem argument at the end in addComponent():
addComponent("C_type_Voltage_Source", "ElectricUsource");
addComponent("Input_Interface_Component", "SignalInputInterface");
addComponent("Output_Interface_Component", "SignalOutputInterface");
addComponent("Q_type_Ground", "ElectricGround");
addComponent("Subsystem", "Subsystem");
addComponent("Subsystem", "Current_Sensor", "ElectricIsensor", "Subsystem");
addComponentToSubSystem("Subsystem", "Q_Type_Inductance", "ElectricInductance", "Subsystem");
The last argument could then support multiple level of subsystems with a separator character, e.g. "Subsystem1|Subsystem2|Subsystem3". The same principle should work for connect() and setParameter(). We still also need to add the addSubSystemPort() I think.
@robbr48 Do you still have access to Labview to test and implement this?
Not on my computer, but I believe it is still installed in some computer in the lab. A better solution might be to harmonize this code with the one used for FMI or S-functions. It still requires testing for all targets though.