2022-2023 大创项目——定制化汽车动力系统
汽车功率需求仿真
模型初步搭建与仿真验证
每个驾驶员有自己的驾驶习惯,不同的驾驶习惯对应不同的驾驶模式,不同的驾驶模式对应不同的功率需求。因此,我们需要对不同的驾驶模式进行仿真。
于是我们使用了MATLAB/Simulink进行仿真,很简单粗暴,其公式依据是:
?
车的质量
?
道路倾角
0.0065
滚动阻力系数1
滚动阻力系数2
?
车的速度
空气密度
车的正前方面积
0.8
气动阻力系数
暂不考虑
传输效率
暂不考虑
发动机效率
暂不考虑
反相器效率
可能有些参数设定的不是很准确(比如 ),再说吧。
模型需要参数输入,我个人采用了一种绕弯的思路:python生成h5数据文件,再用matlab转换成mat读取到simulink中(具体为什么,我也不知道我为啥这么干QAQ)
1. python生成h5数据文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import scipy.io as scio import h5pyimport numpy as npimport json simin_v = list (np.zeros(5 )) + list (range (0 ,20 )) + list (20 * np.ones(20 )) + list (np.arange(20 , 0 , -0.5 )) + list (np.zeros(5 )) simin_mass = list (2000 * np.ones(len (simin_v))) simin_theta = list (np.zeros(len (simin_v))) h5file = h5py.File("./dataset/data_v.h5" , 'w' ) h5file.create_dataset('simin_v' , data=simin_v) h5file = h5py.File("./dataset/data_mass.h5" , 'w' ) h5file.create_dataset('simin_mass' , data=simin_mass) h5file = h5py.File("./dataset/data_theta.h5" , 'w' ) h5file.create_dataset('simin_theta' , data=simin_theta) h5file.close
matlab读取h5数据文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 fileInfo_v = h5info('./dataset/data_v.h5' ); fileInfo_mass = h5info('./dataset/data_mass.h5' ); fileInfo_theta = h5info('./dataset/data_theta.h5' ); h5disp('./dataset/data_v.h5' ); h5disp('./dataset/data_mass.h5' ); h5disp('./dataset/data_theta.h5' ); v = h5read("./dataset/data_v.h5" ,'/simin_v' ); mass = h5read("./dataset/data_mass.h5" ,'/simin_mass' ); theta = h5read("./dataset/data_theta.h5" ,'/simin_theta' ); v_time_table = array2timetable(v,'TimeStep' ,seconds(1 )); mass_time_table = array2timetable(mass,'TimeStep' ,seconds(1 )); theta_time_table = array2timetable(theta,'TimeStep' ,seconds(1 )); save('data_v.mat' ,'v_time_table' ,"-v7.3" ); save('data_mass.mat' ,'mass_time_table' ,"-v7.3" ); save('data_theta.mat' ,'theta_time_table' ,"-v7.3" ); load_system('force_model' ); out = sim('force_model' ); plot (out.P_trac);
准备好所用的数据之后,就可以开始扔进simulink中进行仿真了。仿真模型如下:
仿真结果:(以python中的数据为例)
有负值的功率很正常,这涉及到制动过程中的反向充电等机电专业的知识(承认自己也不是很懂这一块)。
用户API的搭建实现个性化输入数据
如前所示,不同的人驾驶习惯不同,主要体现在加速度和速度的变化、车的质量喜好等等,所以我们需要一个用户API,让用户可以自定义输入数据,这样才能更好的模拟真实的驾驶情况。
由于本人之前从没接触过前端开发,队(WANG)友(LAO)曾经用过C++写过串口调试助手,于是也试一试基于C++开发上位机。所用IDE为Visual
Studio 2022, 环境搭建参见Microsoft官方文档:https://learn.microsoft.com/zh-cn/cpp/windows/desktop-applications-visual-cpp?view=msvc-170 .跑了遍例程,发现报错:
错误
LNK2019
无法解析的外部符号 main,函数 "int __cdecl invoke_main(void)"
(?invoke_main@@YAHXZ )
中引用了该符号
DesktopApp
D:FILES WorkSpace.lib(exe_main.obj)
1
错误
LNK1120
1 个无法解析的外部命令
DesktopApp
D:FILES WorkSpace.exe
1
经过一番搜索,发现是因为项目配置不对。参考下面的博客https://blog.csdn.net/csshuaige/article/details/120313469 修改配置后无错运行,证明环境搭建成功。
跑完了,这个界面是真的丑……
果断放弃,转战Qt! Qt的安装参见官方文档:https://doc.qt.io/qt-5/windows.html#installing-qt-creator ,这里不再赘述。
Qt Creator初体验
打开Qt Creator,创建一个新工程。
至此,一个简单的Qt工程就创建好了。
该工程的目录结构如下:
其中供用户操作的文件包括一个头文件,两个cpp,和一个ui文件。头文件中包含了用户API的声明,cpp文件中包含了用户API的实现,ui文件中包含了用户界面的设计。
源代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QTextEdit> #include <QFile> #include <QDataStream> #include <QMessageBox> QT_BEGIN_NAMESPACE namespace Ui { class Widget ; } QT_END_NAMESPACE class Widget : public QWidget{ Q_OBJECT public: Widget(QWidget *parent = nullptr); ~Widget(); private slots: void on_pushButton_clicked () ; private: QTextEdit *textEdit; Ui::Widget *ui; }; #endif
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #include "widget.h" #include <QApplication> #include <QLocale> #include <QTranslator> int main (int argc, char *argv[]) { QApplication a (argc, argv) ; QTranslator translator; const QStringList uiLanguages = QLocale::system().uiLanguages(); for (const QString &locale : uiLanguages) { const QString baseName = "test01_" + QLocale(locale).name(); if (translator.load(":/i18n/" + baseName)) { a.installTranslator(&translator); break ; } } Widget w; w.show(); return a.exec(); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 #include "widget.h" #include "./ui_widget.h" Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui->setupUi(this); } Widget::~Widget() { delete ui; } void Widget::on_pushButton_clicked () { QTextEdit *textEdit; QString text_simulation_time = ui->textEdit->toPlainText(); QString text_car_mass = ui->textEdit_2->toPlainText(); QString text_velocity = ui->textEdit_3->toPlainText(); QString text_angle = ui->textEdit_4->toPlainText(); QFile file ("D:/PERSONAL FILES/Qt_workspace/test01/testfile.txt" ) ; if (!file.open(QFile::WriteOnly | QFile::Text)) { QMessageBox::information(this, "Error Message" , "Please Select a Text File!" ); return ; } QTextStream out (&file) ; out << text_simulation_time; out << "\n" ; out << text_car_mass; out << "\n" ; out << text_velocity; out << "\n" ; out << text_angle; }
ui文件负责设计界面样式,与源代码交互是通过“槽”来实现。比如,如果想在按钮点击的时候触发某些事件,需要在'.ui'文件中右击按钮,点击“转到槽”,然后在弹出的窗口中选择“on_pushButton_clicked”这个槽,这样就将按钮和槽连接起来了。在源代码中,只需要在槽函数 中实现相应的功能即可。
下面是我用来实现点击按钮保存的槽函数代码部分:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 void Widget::on_pushButton_clicked () { QTextEdit *textEdit; QString text_simulation_time = ui->textEdit->toPlainText(); QString text_car_mass = ui->textEdit_2->toPlainText(); QString text_velocity = ui->textEdit_3->toPlainText(); QString text_angle = ui->textEdit_4->toPlainText(); QFile file ("D:/PERSONAL FILES/Qt_workspace/test01/testfile.txt" ) ; if (!file.open(QFile::WriteOnly | QFile::Text)) { QMessageBox::information(this, "Error Message" , "Please Select a Text File!" ); return ; } QTextStream out (&file) ; out << text_simulation_time; out << "\n" ; out << text_car_mass; out << "\n" ; out << text_velocity; out << "\n" ; out << text_angle; }
下面是初步设计的UI界面
实现效果:
至此,初步完成了数据输入保存的操作。
数据有了,接下来的一部就是与之前的python文件结合了。以下为修改之后的用于读取生成数据的txt文件的python脚本代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 import scipy.io as scioimport h5pyimport numpy as npimport jsonimport os file_path = 'D:/PERSONAL FILES/Qt_workspace/test01/testfile.txt' with open (file_path, encoding='utf-8' ) as file_obj: lines = file_obj.readlines() for line in lines: print (line.rstrip()) simin_time = int (lines[0 ]) list_simin_v = lines[2 ].strip().split(',' ) list_simin_v_0 = list (map (lambda x: int (x), list_simin_v)) list_simin_mass = list (int (lines[1 ]) * np.ones(simin_time)) list_simin_theta = [int (lines[3 ])] list_simin_theta_0 = list (map (lambda x: int (x), list_simin_theta)) print (" simin_time:%s;\n car mass:%s;\n car velocity:%s;\n road angle:%s\n" % (simin_time, int (lines[1 ]), list_simin_v_0, int (lines[3 ])))print (list_simin_v_0)print (list_simin_mass)print (list_simin_theta_0)h5file = h5py.File("./dataset/data_v.h5" , 'w' ) h5file.create_dataset('simin_v' , data=list_simin_v_0) h5file = h5py.File("./dataset/data_mass.h5" , 'w' ) h5file.create_dataset('simin_mass' , data=list_simin_mass) h5file = h5py.File("./dataset/data_theta.h5" , 'w' ) h5file.create_dataset('simin_theta' , data=list_simin_theta_0) h5file.close
路面状态仿真
锂电池参数仿真
氢氧燃料电池参数仿真
优化算法