c++11 STL和simulink自动生成代码--Apple的
c++11 STL和simulink自动生成代码--Apple的学习笔记
目的:
为了学习c++11 STL和simulink自动生成代码
c++11集成后的vscode工程及matlab 2015b的工程都上传到了我的github。
https://github.com/AppleCai/myprinter
立项:
我需要设计一个练手的小项目。私人定制播放器
需求:
能将txt每行的内容按控制命令输出。
一个开关按钮(control[0]):1代表开,0代表关
一个暂停按钮(control[1]):1代表暂停,0代表继续
一个向上按钮(control[2]):1代表向上,0代表不变
一个向下按钮(control[3]):1代表向下,0代表不变
总共包括4个状态(open:printState=1;close:printState=0;run:printState=2;suspend:printState=3)
设计:
思路是这样的,从txt中读取需要打印的内容。从doc窗口读取4个控制指令,来控制当前打印第几项内容。而控制功能使用stateflow状态机实现,通过simulink自动生成的代码集成到主函数中,实现将结果输出到doc窗口。
simulink设计:
simulink stateflow.png
c++11主函数:
/*
* @Descripttion: my printer
* @version: V1.0
* @Author: AppleCai
* @Date: 2019-11-02 13:38:13
* @LastEditors: AppleCai
* @LastEditTime: 2019-11-02 17:13:29
*/
#include <iostream> // For standard streams
#include <fstream> // For file streams
#include <iterator> // For iterators and begin() and end()
#include <string> // For string class
#include <vector> // For vector containers
#include "myprinter.h" // Model's header file
#include "rtwtypes.h"
static myprinterModelClass rtObj; // create simulink object
int main()
{
// simulink initialization
rtObj.initialize();
// read txt file
std::string file_in{"D:/ws/readcfg/mylist.txt"};
std::ifstream in{file_in};
if (!in)
{
std::cerr << file_in << " not open." << std::endl;
exit(1);
}
std::vector<std::string> words{std::istream_iterator<std::string>(in), std::istream_iterator<std::string>()};
// print all the lines in txt
std::copy(std::begin(words), std::end(words), std::ostream_iterator<std::string>{std::cout, ","});
std::cout << std::endl;
// close txt file
in.close(); // Close the file
std::vector<std::string> controls;
std::string control;
std::int8_t myindex = 0;
// call simulink function, let it into initial state
rtObj.step();
// main function, use ctrl+C for end
while(true)
{
// get control value, if empty then beark
while (true)
{
myindex++;
std::cout << "Enter control value " << std::to_string(myindex) << ",empty line to end:";
std::getline(std::cin, control, '\n');
if (control.empty())
break;
controls.emplace_back(control);
}
std::cout<<std::endl;
myindex = 0;
// bind the control value to the input of simulink
g_bl_BtnOpen = std::stoi(controls[0]);
g_bl_BtnSuspend =std::stoi(controls[1]);
g_bl_BtnPrevious =std::stoi(controls[2]);
g_bl_BtnNext =std::stoi(controls[3]);
// run stateflow
rtObj.step();
// clear the control command
controls.clear();
// print out the result
if (g_u8_printState == 0)
{
std::cout <<"print out:close"<<std::endl;
}
else if(g_u8_printState == 3)
{
std::cout <<"print out:suspend"<<std::endl;
}
else
{
std::cout <<"print out:"<<words[g_u8_n]<<std::endl;
}
}
}
遇到的问题:
-
simulink中全局变量的设置。我设置完变量后生成代码放入了一个结构体中?
解决方法:通过修改信号线属性中Code Generation中Storage class:选择ExportedGlobal
-
输入控制命令1001期望输出1-cd,但是结果输出close。
解决方法:原因是matlab的step()函数需要先调用一次,因为matlab有状态机的初始化状态。【由于我open状态里面有run和suspend,所以又存在这样的初始化状态问题,这类问题我暂时想到的就是将open状态删除,不要有子状态。将来再看看有没有其他解决方法】
初始状态的问题.png -
输入控制命令在变,但是输出不符合预期,看上去保持了第一次的输入命令。
解决方法:用完一次指令后,需要添加controls.clear(); 来清空控制命令,重新使用下一次的指令。
代码运行结果:
1-a,2-cd,3-ef,4-g,5-h,6-ijk,7-lm,8-op,9-q,10-rs,
Enter control value 1,empty line to end:1
Enter control value 2,empty line to end:0
Enter control value 3,empty line to end:0
Enter control value 4,empty line to end:1
Enter control value 5,empty line to end:
print out:1-a
Enter control value 1,empty line to end:1
Enter control value 2,empty line to end:0
Enter control value 3,empty line to end:0
Enter control value 4,empty line to end:1
Enter control value 5,empty line to end:
print out:2-cd
Enter control value 1,empty line to end:1
Enter control value 2,empty line to end:0
Enter control value 3,empty line to end:1
Enter control value 4,empty line to end:0
Enter control value 5,empty line to end:
print out:1-a
Enter control value 1,empty line to end:1
Enter control value 2,empty line to end:1
Enter control value 3,empty line to end:0
Enter control value 4,empty line to end:0
Enter control value 5,empty line to end:
print out:suspend
Enter control value 1,empty line to end:1
Enter control value 2,empty line to end:0
Enter control value 3,empty line to end:0
Enter control value 4,empty line to end:0
Enter control value 5,empty line to end:
print out:1-a
Enter control value 1,empty line to end:1
Enter control value 2,empty line to end:0
Enter control value 3,empty line to end:0
Enter control value 4,empty line to end:1
Enter control value 5,empty line to end:
print out:2-cd
Enter control value 1,empty line to end:1
Enter control value 2,empty line to end:0
Enter control value 3,empty line to end:0
Enter control value 4,empty line to end:1
Enter control value 5,empty line to end:
print out:3-ef
Enter control value 1,empty line to end:0
Enter control value 2,empty line to end:0
Enter control value 3,empty line to end:0
Enter control value 4,empty line to end:0
Enter control value 5,empty line to end:
print out:close
Enter control value 1,empty line to end:^C