文章目录
- SIMULINK 建模
- 模型转代码
- 自动生成代码的处理
- 代码编译.so动态链接库文件
- .so路径设置
- 编写程序调用
- 引用动态链接库编译
- 运行查看效果
- 后续
SIMULINK 建模
处于测试需要,建立简单的SIMULINK模型一个,实现加法功能。两个输入,一个输出。之后使用转代码功能将模型转为代码。
如图:两个输入“a1,a2”,一个输出“o”
模型转代码
转代码这一步最容易出问题,一些参数设置的好不好直接决定代码能不能用。
我的设置如下图:
目标文件类型选择ert.tlc代码结构更紧凑。尽管如此,一个简单的加法功能竟然生成了以下几个文件。。。。。
随着模型的复杂度提高,生成文件数也会增加很多,这就是本文研究将代码生成动态链接库的意义,减少文件数量,把所有文件编译成一个.so文件。
到这里你可能有疑问,既然生成一个简单的加法都这么复杂,我为什么还要这样做,为什么还要转代码?
因为模型复杂度提高以后建模的难度比写代码低很多,只要建模能够建成,在ROS中就可以调用正是本文要解决的问题。
自动生成代码的处理
可能是出于用户定制化需求考虑,自动生成的代码如果不在后期进行修改,是没有任何作用的代码。我们只需要改动一下主函数的文件就可以。以下是改动后的结果:
#include <stddef.h>
#include <stdio.h>
#include "addd.h"
#include "rtwtypes.h"
#include <iostream>
using namespace std;
static adddModelClass addd_Obj; // Instance of model class
double adddd(double a1,double a2 ){
addd_Obj.initialize();
addd_Obj.addd_U.a1=a1;
addd_Obj.addd_U.a2=a2;
addd_Obj.step();
addd_Obj.terminate();
return addd_Obj.addd_Y.o;
}
没改之前自动生成的ert_main.cpp如果你们自己实践过的话就很清楚,那个代码多的很,还没用,我保留了功能模块,废话全都删除了。
代码编译.so动态链接库文件
需要编写成动态链接库的代码显然是需要有功能的,那就需要有函数,我们在上面的代码中对自动生成的代码进行了二次封装,得到了一个新的函数“adddd”,这个函数在生成动态链接库并正确设置了以后,就可以在任何地方调用了,甚至可以跨语言。
将得到的代码转移到ubuntu系统计算机中。
在代码文件夹打开终端,输入(以我的举例):
g++ -c -fPIC ert_main.cpp addd.cpp
g++ -shared -fPIC -o libdlladdd.so addd.o ert_main.o
不出意外,现在已经生成了.so文件
.so路径设置
.so文件必须放到系统的/lib或/usr/lib中才能用,否则编译不通或者运行不了,总有一款适合你。
sudo cp libdlladdd.so /usr/lib
这样就把动态链接库放到了库文件索引里了。
编写程序调用
处于测试目的,简单写个小程序,代码如下:
#include <iostream>
using namespace std;
double adddd(double a1,double a2);
int main(){
double a1,a2;
cout<<"Please enter a1:";
cin>>a1;
cout<<"Please enter a2:";
cin>>a2;
cout<<"a1 + a2 = "<<adddd(a1,a2)<<endl;
return 0;
}
简单分析代码就能发现,这段代码中只有addd函数的声明,并没有实现。如果没有调用动态链接库,这个加法功能是不可能实现的。用于测试正好够用。
引用动态链接库编译
g++ test.cpp libdlladdd.so
运行查看效果
如图:加法实现了。
后续
1.本文还有很多不完善的地方以后等了解更深入了再来补。
2.关于SIMULINK转代码的设置部分可以详细的写,因为有的地方的设置很重要。
3.自动生成的代码的结构和功能可以详细的写一写。
4.g++编译还需要深入了解。
5.探究动态链接库文件的路径是否必须是“/lib”或“/usr/lib”。
6.SIMULINK中有ROS模块,探索这些模块具体在ROS里的作用。