Generating corresponding C++ interface class function signature inline behaviour for MATLAB classes not as expected?
6 次查看(过去 30 天)
显示 更早的评论
Descriptions:
I would like to generate C++ classes for the MATLAB built-in object function poseGraph and its object functions, so that it is as easy to use poseGraph these object functions as in the stand-alone C++ environment. I have simply written a custom class slamPoseGraph to wrap poseGraph, and the entry parameters are all designed to be supported basic data types, the reference code is as follows:
classdef slamPoseGraph<handle
properties (SetAccess = private, GetAccess = public)
NumNodes
NumEdges
NumLoopClosureEdges
LoopClosureEdgeIDs
LandmarkNodeIDs
end
properties (Access=private)
graph
end
methods
function obj = slamPoseGraph(MaxNumEdges,MaxNumNodes)
obj.graph = poseGraph('MaxNumEdges',MaxNumEdges,'MaxNumNodes',MaxNumNodes);
obj.NumNodes = obj.graph.NumNodes;
obj.NumEdges = obj.graph.NumEdges;
obj.NumLoopClosureEdges = obj.graph.NumLoopClosureEdges;
obj.LoopClosureEdgeIDs = obj.graph.LoopClosureEdgeIDs;
obj.LandmarkNodeIDs = obj.graph.LandmarkNodeIDs;
end
function addRelativePose2D(obj,measurement,fromNodeID,toNodeID)
infoMat = [1 0 0 1 0 1];
addRelativePose(obj.graph,measurement,infoMat,fromNodeID,toNodeID);
end
function optimizePoseGraph2D(obj)
obj.graph = optimizePoseGraph(obj.graph);
obj.NumNodes = obj.graph.NumNodes;
obj.NumEdges = obj.graph.NumEdges;
obj.NumLoopClosureEdges = obj.graph.NumLoopClosureEdges;
obj.LoopClosureEdgeIDs = obj.graph.LoopClosureEdgeIDs;
obj.LandmarkNodeIDs = obj.graph.LandmarkNodeIDs;
end
function measurements = nodeEstimates2D(obj)
measurements = nodeEstimates(obj.graph);
end
end
end
I then wrote the entry-point function used to generate the C++:
function poses1= slamMapGraph2D(poseParams,measurement,fromID,toID)%#codegen
%% pose graph
pg = SlamGraph2D.slamPoseGraph(poseParams.MaxNumEdges,poseParams.MaxNumNodes);
pg.addRelativePose2D(measurement,fromID,toID);
pg.optimizePoseGraph2D();
poses1 = pg.nodeEstimates2D();
end
C++ was successfully generated using the following command:
cfg = coder.config("lib","ecoder",true);
cfg.FilePartitionMethod = "MapMFileToCFile"; % It looks like you must set it up this way to ensure that the generated C++ interface(slamFactorGraph.h,slamFactorGraph.cpp) is not inlined.
cfg.GenCodeOnly = true;
cfg.CppNamespace = "SlamGraph2D"; % or use package folder name
cfg.CppInterfaceStyle ="Methods";
cfg.TargetLang = 'C++';
cfg.CppInterfaceClassName = 'myGraph';
cfg.InlineBetweenUserFunctions = 'Readability';
cfg.InlineBetweenUserAndMathWorksFunctions = 'Readability';
cfg.InlineBetweenMathWorksFunctions = 'Speed';
poseParams.MaxNumEdges = 10000;
poseParams.MaxNumNodes = 5000;
measurement = [1,2,3];
fromID = 1;
toID= 2;
codegen -config cfg slamMapGraph2D -args {poseParams,measurement,fromID,toID} -report
However the corresponding C++ interface class signature was generated as follows:
class slamPoseGraph {
public:
slamPoseGraph *init(double MaxNumEdges, double MaxNumNodes);
void addRelativePose2D(const double measurement[3], double fromNodeID,
double toNodeID);
void optimizePoseGraph2D(myGraph *aInstancePtr,
coder::robotics::core::internal::BlockMatrix &iobj_0,
coder::poseGraph &iobj_1);
void nodeEstimates2D(::coder::array<double, 2U> &measurements) const;
coder::poseGraph _pobj0;
private:
coder::poseGraph *graph;
};
It is clear that inline behaviour occurs with the input parameters of the member function optimizePoseGraph2D (even when I add coder.inline("never") to the entry-point function slamMapGraph2D), which carries over into the Mathworks internal code and is not user-friendly!
Expectations:
1. A C++ member function signature similar to the following should be generated:
void optimizePoseGraph2D();
I.e. consistent with MATLAB class member function optimizePoseGraph2D(), no input parameter inline behaviour introduced.
2. The slamPoseGraph.h,slamPoseGraph.cpp interface classes should be separate files when configured to generate a single file for all functions.
cfg.FilePartitionMethod = "singleFile";
Environment:
ubuntu 20.04
Matlab R2023a
0 个评论
采纳的回答
Denis Gurchenkov
2023-9-18
Hi cui,
I understand what you want to achieve. You want to generate C++ code for this MATLAB class, and get a reusable, stable interface for all the methods. This is not currently possilbe using MATLAB Coder. See, coder takes an entry point function (or a number of functions) and generates C/C++ code for those functions. It gives you no guarantees about the internals of those functions. In particular, if an entry-point function calls some other (non-entry-point) function, creates an instance of a class, etc - those details may not be fully preserved in the generated code. The functions can be specialized, their inputs can be dropped etc, for the sake of optimization.
And that preservation of prototypes is exactly what you want.
In other words, you need a feature that we have not shipped yet.
MATLAB Coder dev team is aware of this need and is working on a feature to translate a MATLAB class to a C++ class, exactly what you want. I passed your example to the dev team, so that they can take it as a use case.
If you are interested and you would want to offer your feedback, please reach out via the technical support channel, we'd be happy to chat more!
Thanks
Denis
更多回答(0 个)
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!