# 如何快速开发 APP


本文介绍使用 SDK 如何快速开发 APP。

# 质量弹簧阻尼 APP 介绍

本章节将使用 SDK 快速开发完成一个弹簧阻尼模型案例,从模型搭建-工程配置-SDK 功能开发流程开发一个质量弹簧阻尼仿真 APP,最终开发效果如下所示:

该 APP 可满足以下功能点:

  • 底层加载 Modelica3.2.1 标准模型库;

  • 打开已搭建好的质量弹簧阻尼模型;

  • 可对质量、阻尼系数、质量块初始位置、弹簧刚度、施加压力等参数和输入进行设置;

  • 可对仿真设置中的仿真停止时间进行设置;

  • 可对打开的质量弹簧阻尼模型进行仿真;

  • 对仿真后的压力、位移变化、速率变化等数据进行获取;

  • 将获取的数据显示到 SDK 提供的曲线组件上。

# 运行实例:

打开 vs2017.sln,右击项目,将其设置为启动项目。

选择 ReleaseX64,运行代码,首次启动要加载各种库文件,比较慢,可以优先选择 Release 启动。

如果第一次启动调试报错如下:

则需要更新下 QT 版本:

# 模型搭建

本次开发 APP 需依赖模型,打开 Sysplorer 搭建一个质量弹簧阻尼系统,质量-弹簧-阻尼器系统可用简单的数学模型表示,即数轴建模法,建立与系统平行方向的数轴,把弹簧或阻尼器的实际位移值当做有理数标在数轴上对应位置,然后按照有理数比较大小的结果确定相应质量块所受弹簧力或阻尼力的大小和方向,进而求得系统的微分方程。分别以单自由度系统、两自由度振动系统及多自由度系统为例,阐述了数轴法在建立机械振动系统的数学模型中的应用。最终搭建效果如下所示:

记录下搭建该模型的名称,及路径位置,便于后续使用。

# 开发工程构建

基于 VS2017 版本进行开发,请确保已安装 VS2017 Qt 插件,并安装 Qt5.14.2 等相关开发环境。

# 新建工程

基于 VS2017 新建一个 Qt Application 工程,命名为 MassSpringDamperApp:

# 输出目录配置

  • 将输出目录配置到安装的 SDK 路径的 bin 目录$(MWBin)$(Configuration)

  • 将 MWBin 换为实际 SDK 对应路径:SDK安装路径\bin\win_msvc2017x64

  • $(MWBin)$(MoKeyerface)$(MWInclude)需在电脑中的系统环境变量中将 SDK 安装路径配置上:



# 附加包含目录配置

  • 包含目录添加 SDK 的 include 与 interface 目录:

    .\GeneratedFiles
    .
    $(QTDIR)\include
    .\GeneratedFiles\$(ConfigurationName)
    $(QTDIR)\include\QtCore
    $(QTDIR)\include\QtGui
    $(QTDIR)\include\QtWidgets
    $(MWInclude)
    $(MWInclude)\boost161
    $(MoKeyerface)
    $(MoKeyerface)\modelica_services
    $(MoKeyerface)\common_kits
    
  • MWInclude——SDK安装路径/include

  • MoKeyerface——SDK安装路径/interface


# 链接库依赖项配置

  • 依赖库目录添加 SDK 的 bin\lib 与文件输出目录

    $(OutDir)
    $(QTDIR)\lib
    $(MWBin)\lib
    


# 附加依赖项配置

  • Debug 下的附加依赖项设置为:

    qtmaind.lib
    Qt5Cored.lib
    Qt5Guid.lib
    Qt5Widgetsd.lib
    mw_develop_d.lib
    mw_graphics_view_d.lib
    mw_class_manager_d.lib
    mw_global_d.lib
    mw_help_d.lib
    mw_sim_inst_d.lib
    mw_sim_plot_d.lib
    model_var_tree_d.lib
    mw_develop_d.lib
    
  • Release 下的附件依赖项设置为:

    qtmain.lib
    Qt5Core.lib
    Qt5Gui.lib
    Qt5Widgets.lib
    mw_develop.lib
    mw_graphics_view.lib
    mw_class_manager.lib
    mw_global.lib
    mw_help.lib
    mw_sim_inst.lib
    mw_sim_plot.lib
    model_var_tree.lib
    mw_develop.lib
    


# APP 界面及功能详解

# main 函数

main函数中主要做以下功能点:

  • 初始化 QApplication
  • 初始化 MwClassManager 类
  • 加载翻译文件
  • 显示 QMainWindow 主窗口
int main(int argc, char *argv[])
{
    QApplication app(argc,argv);

    //初始化SDK内核管理类接口
    MwClassManager* classMgr = new MwClassManager();
    classMgr->Initialize();

    //加载中文配置文件
    LoadChineseTranslateFile();

    //显示主窗口
    MainWindow main_win(classMgr);
    main_win.show();

    return app.exec();
}

# QMainWindow 界面

  • Qt Designer 设计界面

    利用 Qt 控件搭建 MainWindow 界面如下,使用 Qt 搭建界面详细材料可查看专题说明部分 Qt 界面开发教程。

  • 界面加载模型图片

    将模型图增加到界面中的 label:

    代码如下:

    //初始化原理图
    QString app_path = QApplication::applicationDirPath();
    QString mo_path = app_path + "/../../../examples/MassSpringDamperApp/Resource/springDamper.png";
    QPixmap pixmap(mo_path);
    pixmap.scaled(ui.label->size(), Qt::IgnoreAspectRatio);
    ui.label->setScaledContents(true);
    ui.label->setPixmap(pixmap);
    
    //初始化模型图
    QString mo_path1 = app_path + "/../../../examples/MassSpringDamperApp/Resource/springDamper_model.png";
    QPixmap pixmap1(mo_path1);
    pixmap1.scaled(ui.label_8->size(), Qt::IgnoreAspectRatio);
    ui.label_8->setScaledContents(true);
    ui.label_8->setPixmap(pixmap1);
    
  • 界面中加载曲线窗口组件

    使用 SDK 中的 MwSimPlotWindow 类创建曲线视图嵌入 QMainWindow 中:

    代码如下:

    //增加曲线界面
    delete ui.widget;
    forcePlotWin = new MwSimPlotWindow(1, true, classMgr, this, false);
    ui.gridLayout_3->addWidget(forcePlotWin, 0, 0, 1, 1);
    forcePlotWin->show();
    
    delete ui.widget_2;
    sPlotWin = new MwSimPlotWindow(1, true, classMgr, this, false);
    ui.gridLayout_4->addWidget(sPlotWin, 0, 0, 1, 1);
    sPlotWin->show();
    
    delete ui.widget_3;
    vPlotWin = new MwSimPlotWindow(1, true, classMgr, this, false);
    ui.gridLayout_5->addWidget(vPlotWin, 0, 0, 1, 1);
    vPlotWin->show();
    
    forcePlotWin->menuBar()->hide();
    sPlotWin->menuBar()->hide();
    vPlotWin->menuBar()->hide();
    
    forcePlotWin->statusBar()->hide();
    sPlotWin->statusBar()->hide();
    vPlotWin->statusBar()->hide();
    

# 主要功能详解

主要开发流程如下,提前加载底层模型及数据、开始仿真、仿真完成后等操作。

# 提前加载底层模型及数据

MainWindow 中的构造函数中主要加载如下几点功能:底层加载标准模型库、打开搭建好的质量-弹簧-阻尼模型文件、提前获取参数值显示在面板中。

  1. 加载标准模型库

    获取 Modelica 标准模型库 3.2.1 版本保证,需 bin 目录下的 Library 路径下存在改模型库,代码如下:

    bool is_success = classMgr->GetMoHandler()->LoadMoLibrary("Modelica", "3.2.1",,nullptr);
    
  2. 加载模型文件

    将搭建的模型在底层打开,代码如下:

    QString app_path = QApplication::applicationDirPath();
     QString mo_path = app_path + "/../../../examples/MassSpringDamperApp/Resource/MassSpringDamper.mo";
    
     bool is_success = classMgr->GetMoHandler()->OpenFile(mo_path.toStdWString(),nullptr);
    
  3. 获取参数数据

    为保证打开软件前,界面能够显示如下数据,需对模型中的相关参数进行获取:

    获取参数数据代码如下:

    //获取模型数据
     MoKey key =  classMgr->GetMoHandler()->DirectLookupType("MassSpringDamper.Demo");
     if (key != 0)
     {
         QString value_force = QString::fromStdString(classMgr->GetMoHandler()->GetParamValue(key, GetMwStrList("const.k")));
         QString value_m = QString::fromStdString(classMgr->GetMoHandler()->GetParamValue(key, GetMwStrList("massSpringDamperModel.m")));
         QString value_k = QString::fromStdString(classMgr->GetMoHandler()->GetParamValue(key, GetMwStrList("massSpringDamperModel.k")));
         QString value_d = QString::fromStdString(classMgr->GetMoHandler()->GetParamValue(key, GetMwStrList("massSpringDamperModel.d")));
         QString value_s0 = QString::fromStdString(classMgr->GetMoHandler()->GetParamValue(key, GetMwStrList("massSpringDamperModel.s0")));
    
         ui.lineEdit_force->setText(value_force);
         ui.lineEdit_m->setText(value_m);
         ui.lineEdit_k->setText(value_k);
         ui.lineEdit_d->setText(value_d);
         ui.lineEdit_s0->setText(value_s0);
     }
    

# 单击仿真按钮

模型库及模型文件加载完成后,可在界面中输入参数数据和仿真设置,完成后,可单击开始仿真按钮。

单击开始仿真后,会将参数设置到模型中、设置仿真停止时间、编译和仿真等过程。

  1. 设置参数到模型

    获取输入框中对应的值,将其设置到模型中,代码如下:

     //修改参数值
     MoKey key = classMgr->GetMoHandler()->DirectLookupType("MassSpringDamper.Demo");
     std::string value_force = ui.lineEdit_force->text().toStdString();
     classMgr->GetMoHandler()->SetParamValue(key, GetMwStrList("const.k"), value_force);
     std::string value_m = ui.lineEdit_m->text().toStdString();
     classMgr->GetMoHandler()->SetParamValue(key, GetMwStrList("massSpringDamperModel.m"),value_m);
     std::string value_k = ui.lineEdit_k->text().toStdString();
     classMgr->GetMoHandler()->SetParamValue(key, GetMwStrList("massSpringDamperModel.k"),value_k);
     std::string value_d = ui.lineEdit_d->text().toStdString();
     classMgr->GetMoHandler()->SetParamValue(key, GetMwStrList("massSpringDamperModel.d"),value_d);
     std::string value_s0 = ui.lineEdit_s0->text().toStdString();
     classMgr->GetMoHandler()->SetParamValue(key, GetMwStrList("massSpringDamperModel.s0"),value_s0);
    
  2. 设置仿真停止时间

    获取输入框中的仿真停止时间,将其设置到仿真数据中,仿真数据需提前初始化好,代码如下:

     /应用仿真设置数据
     MwSimData *sim_data = new MwSimData(L"MassSpringDamper",data_path.toStdWString(), path.toStdWString());
     bool flag = sim_data->InitializeSimInst();
    
     MwExperimentData experiment_data;
     experiment_data.stopTime = ui.lineEdit_stopTime->text().toDouble();
     sim_data->SetExperimentData(experiment_data);
    
  3. 编译和仿真

    在仿真前需要提前翻译模型,在构造函数中提前 new 出用于仿真 MwSimControl 类,并将该类与用于仿真的数据进行绑定,即可开始进行仿真,代码如下:

     /仿真前翻译模型
     classMgr->GetMoHandler()->CompileModel("MassSpringDamper.Demo",path.toStdWString(),,nullptr);
    
     //仿真模型
     simCtrl->RebindSimData(sim_data);
     bool is_success = simCtrl->StartSimulate(MwSimControl::Sim_ContinueMode);
    
    

# 仿真完成

使用 SigSimStopped 信号用于接收仿真完成,代码如下:

connect(simCtrl, &MwSimControl::SigSimStopped, this, &MainWindow::SlotSimFinshed);

仿真完成后,主要功能为获取仿真结果数据,并将其显示到曲线窗口中,仿真效果如下:

主要代码如下:

MwSimData* sim_data =  simCtrl->GetSimData();
    forcePlotWin->AddCurveToCurrentView("massSpringDamperModel.f", sim_data);
    sPlotWin->AddCurveToCurrentView("massSpringDamperModel.s", sim_data);
    vPlotWin->AddCurveToCurrentView("massSpringDamperModel.v", sim_data);

# APP 运行及打包

将生成的 exe 及依赖的 dll 放入SDK安装目录/bin/win_msvc2017x64/Release目录下:

双击 MassSpringDamperApp.exe 即可启动软件。放入 exe 后可对软件实现打包,打包步骤如下:

  1. 将 Release 改为 bin 名称;

  2. 保存bin\\win_msvc2017x64目录下的以下目录:

    • external
    • initial_files
    • Library
    • bin(原 Release 文件)
    • setting
    • simulator
    • tools
  3. 最终打包目录如下所示:

# 案例所用类和接口汇总

该质量-弹簧-阻尼模型 APP 案例中使用到的 SDK 相关类和接口如下:

接口 注释
MwClassManager Initialize() MwClassManager 初始化
GetMoHandler() 获取 MwMoHandler 类
MwMoHandler LoadMoLibrary() 加载模型库
OpenFile() 打开模型文件
GetParamValue() 获取参数值
DirectLookupType() 根据模型名获取模型 key
SetParamValue() 设置参数值
CompileModel() 编译模型
MwSimControl SigSimStopped() 发送仿真停止信号
RebindSimData() 绑定仿真数据
StartSimulate() 开始仿真
GetSimData() 获取仿真结果数据
MwSimData InitializeSimInst() 初始化仿真数据
SetExperimentData() 应用仿真设置
MwSimPlotWindow AddCurveToCurrentView() 增加曲线数据到曲线窗口
MwExperimentData / 仿真设置结构体