今天我很高兴欢迎客座博主
艾琳McGarrity
.我很高兴欢迎Erin作为客座博客的主要原因是,他将讨论如何从MATLAB代码和Simulink模型中生成C/ c++代码金宝app
MATLAB编码器
,
金宝app仿真软件编码器
而且
嵌入式编码器
.虽然我以前在这个博客中更多地关注与模拟相关的主题,但我意识到代码生成对这个博客的许多读者来说是一个重要的主题。我们希望在下面的评论中听到您对今天的主题的看法,以及您希望在这个博客中看到其他与代码生成相关的主题。
简介
假设我们有一个奇特的数值例程,我们一直在MATLAB中工作,我们想在外部c++应用程序中使用。在这篇文章中,我们将展示如何从MATLAB代码中生成动态库,我们可以从c++程序中调用它。这将允许我们在外部程序中利用MATLAB的一些功能。
MATLAB代码
为了演示工作流,让我们创建一个执行适合某些数据的行的例程。这个函数有两个输入,
x
而且
y
,它们都是要拟合的数据向量。这些向量的长度应该相等
N
.这个函数的输出是
米
而且
b
为最拟合数据的直线的斜率和截距。我们将通过最小化点到直线垂直距离的平方来进行拟合,其形式是这个方程给出的点斜式
[1]
:
ϕ(m,b)= ∑i=1N(y(i)-(m⋅x(i)+b))2" style="vertical-align:-17px">
的最小值
ϕ(m,b) " style="vertical-align:-5px">
可以用通常的方法求它对的导数吗
米
而且
b
把这些设为0。这样我们就得到了以下两个方程组:
∂∂mϕ(m,b)=0=∑i=1N-2(y(i)-(m⋅x(i)+b))⋅x(i)" style="vertical-align:-17px">
而且
∂∂bϕ (m,b)=0=∑i=1N-2(y(i)-(m⋅x(i)+b))⋅1" style="vertical-align:-17px">
这里我们用到了导数算子和和交换。方程两边都除以-2后,我们可以把这个方程组重新排列成一个矩阵方程
[∑i=1Nx(i)2∑i=1Nx(i)∑i=1Nx(i)N]⋅[mb]=[∑i=1Nx(i)⋅y(i)∑i=1Ny(i)]." style="vertical-align:-45px">
这个方程组可以用紧凑符号表示为
H⋅p=f." style="vertical-align:-5px">
来解
$ p=[m,b]^T $
我们可以两边同时乘以的倒数
H
H-1⋅H⋅p=H-1⋅f," style="vertical-align:-5px">
或者简单地
p=H-1⋅f." style="vertical-align:-5px">
说明:MATLAB代码求解。-
米
而且
b
看起来是这样的:
在MATLAB中测试拟合程序
为了检查我们的代码,让我们加载一些数据,拟合直线并绘制所有内容。
D = readmatrix(“myData.csv”);
为拟合例程生成代码
CFG = code .config(“dll”);
Xarg = code .typeof(1.0, [10000, 1], [1,0]);
Yarg = code .typeof(1.0, [10000, 1], [1,0]);
codegen-config cfg lineFitter。米-args {xarg,yarg} -nargout 2 -report
编译lineFitter函数…------------------------------------------------------------------------ 编译抑制:生成代码。------------------------------------------------------------------------ ### 生成编译报告……代码生成成功:查看报告
MATLAB R2022b中的代码生成报告有一个整洁的功能,称为“
跟踪代码
,它显示了MATLAB代码对应于C代码:
我们稍后需要的相关代码是接口
lineFitter
.关键代码在里面
lineFitter.h
:
输入是常量数组指针,输出是指向double类型的指针。这将指导我们的客户端实现,如下所示。
打包代码
现在我们有了代码,我们可以使用
codebuild
而且
packNgo
生成和打包构建工件,我们可以接管我们的客户端应用程序。在本例中,我们将使用
CMake
而且
SHARED_LIBRARY
选项来进行代码构建,以便我们能够使用
CMake程序
在我们的客户端建立一切。CMake是一个允许我们执行平台独立编译代码的工具。简而言之,我们可以为CMake提供一个要构建的东西的列表,它将为我们执行所有的检查和编译。
codebuild (”。/ codegen / dll / lineFitter”,“BuildMethod”,“CMake”,“BuildVariant”,“SHARED_LIBRARY”);
packNGo (”。/ codegen / dll / lineFitter”,“PackType”,“分层”,“文件名”,“lineFitter”);
这会生成一个存档文件
lineFitter.zip
,我们可以复制到我们的客户端代码库。
创建动态库
现在我们有了代码,就可以构建它并创建一个例程来链接到客户端机器上。之后,我们可以在客户端代码中添加调用行拟合例程所需的代码。假设我们把新生成的
lineFitter.zip
这里,把所有东西都解压。解
lineFitter.zip
会产生两个文件,
mlrFiles.zip
而且
sDirFiles.zip
.解压缩这些文件将创建两个目录,R2022b和codegen。
它们分别包含所需的MATLAB头文件和我们生成的代码。为了构建这些文件,我们将创建一个名为build_lib的目录,然后使用以下命令调用cmake
[2]
(结果也显示出来了):
使用动态库
现在我们已经生成了动态库
lineFitter_win64.dll
时,就可以创建将使用
lineFitter
例行公事。我们的客户端应用程序读取csv文件,并将列放入两个列表中:
为了使这段代码与我们新创建的动态库连接,我们需要分配数组。这些数组是有类型的
emx_Array_real_T
如上所示。我们将编写一个函数来进行分配,但首先我们将包括两个我们需要的头文件:
现在我们准备编写数组分配函数,我们将把它放在主例程之上。此函数接受一个double类型的列表,并将其复制到
emxArray_real_T
它已经被分配到合适的大小。此代码的示例可以在该目录中找到
。\ codegen \ dll \ lineFitter \ \ c例子
.
最后,我们将添加调用来分配我们的向量,并在主例程的读取代码下面,但在最终的return语句之前求解系统:
我们客户端的CMakeLists.txt文件如下所示:
这个过程类似于编译上面的库,这是CMake的吸引力的一部分。命令如下:
现在我们在构建目录中有了可执行文件myFit.exe。测试代码的最后步骤是:
我们可以看到,斜率和截距和我们在MATLAB中得到的是一样的。
笔记
此方法仅用于演示目的。在生产中,您应该使用
polyfit
来解决这个问题。
在这个例子中,我们使用Visual Studio工具来编译代码。为了在命令行中设置,我运行了脚本:
C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\辅助\Build\vcvars64.bat
现在轮到你了
我们希望你喜欢这个例子。很快,我们将在此基础上构建一个更复杂的示例。如果你想在博客上看到其他与Coder相关的话题,请在下面的评论中告诉我们。
댓글
댓글을남기려면링크를클릭하여MathWorks계정에로그하거나계정을새로만드십시오。