Generate C++ Classes for MATLAB Classes That Model Simple and Damped Oscillators - MATLAB & Simulink (original) (raw)

MATLAB® classes provide a natural framework for modeling physical systems:

This example shows how to generate C++ code for a MATLAB function that compares the time evolution of a simple oscillator and a damped oscillator with identical parameters and initial conditions. The two oscillator systems are modeled by using the MATLAB classes simpleOscillator and dampedOscillator that are defined inside a MATLAB namespace mySystem. The generated code contains C++ classes for the source MATLAB classes. The example also shows how the MATLAB classes map to the generated C++ classes and how to use the generated code in a custom C++ main function.

Simple and Damped Oscillators as MATLAB Classes

Governing Equations

A simple harmonic oscillator has two parameters, the mass m and the spring constant k. The angular frequency of the oscillator is ω=km. The position of the oscillator x as a function of time t is given by:

x(t)=A sin(ωt+ϕ).

The amplitude A and the phase constant ϕ are determined by the initial position x0 and the initial velocity v0 of the simple oscillator. In this example, the MATLAB class simpleOscillator models this system.

A damped harmonic oscillator has one additional parameter, the damping constant b. This example considers the case where the normalized damping parameter γ=b2m is small compared to the angular frequency ω such that only first-order damping effects are significant. The position of the damped oscillator xd as a function of time t is:

xd(t)=A e-γt sin(ωt+ϕd)

Like before, the amplitude A and the phase constant ϕd are determined by the initial position x0 and the initial velocity v0 of the damped oscillator. The main effect of damping is to cause the amplitude to decay exponentially. In this example, the MATLAB class dampedOscillator which is a subclass of simpleOscillator models the damped system.

MATLAB and C++ Files

This example uses these supporting files that are present in the current working directory:

Run MATLAB Code

Define a structure params that has fields for the three oscillator parameters. Make sure the dampingConstant parameter is small compared to springConstant and mass (in normalized units).

params.springConstant = 1; params.dampingConstant = 0.1; params.mass = 1;

Call the effectOfDamping function to calculate the position vs. time trajectories of the simple and damped oscillators from t=0 to t=100. Specify initial position x0=1and initial velocity v0=0.

[time1,position1,time2,position2] = effectOfDamping(params,1,0,100,0.01);

Plot position vs. time graphs of the simple and damped oscillators. Observe how the amplitude of the damped oscillator decays exponentially with time.

plot(time1,position1) hold on plot(time2,position2)

Figure contains an axes object. The axes object contains 2 objects of type line.

Display the final position of the simple oscillator.

Display the final position of the damped oscillator. Observe that damping causes this final position to be close to the mean position xmean=0.

Generate and Run C++ MEX

To check for run-time issues, generate a C++ MEX function for the effectOfDamping function. Specify the first argument to have the same type and size as params. Specify the other arguments to be scalar doubles.

codegen -lang:c++ effectOfDamping -args {params,0,0,0,0} -report

Code generation successful: To view the report, open('codegen/mex/effectOfDamping/html/report.mldatx')

Call the generated MEX function effectOfDamping_mex to calculate the position vs. time trajectories of the simple and damped oscillators from t=0 to t=100. Specify initial position x0=1and initial velocity v0=0.

[time1,position1,time2,position2] = effectOfDamping_mex(params,1,0,100,0.01);

Plot position vs. time graphs of the simple and damped oscillators. Observe that the plot is identical to the one produced by the original MATLAB function.

plot(time1,position1) hold on plot(time2,position2)

Figure contains an axes object. The axes object contains 4 objects of type line.

Display the final positions of the two oscillators. These values are also identical to those produced by the original MATLAB code.

Clear the MEX file from memory.

clear effectOfDamping_mex

Generate and Inspect Static C++ Library

Create a code configuration object for generating a static C++ library with class interface. Specify the name of the interface class to be 'myOscillators'. For these settings, the code generator produces the entry-point function as a methods of the C++ class 'myOscillators'. The constructor and the destructor of this interface class implement the initialize and terminate functions, respectively.

cfg = coder.config('lib'); cfg.TargetLang = 'C++'; cfg.CppInterfaceStyle = 'Methods'; cfg.CppInterfaceClassName = 'myOscillators';

Adjust the global settings for function inlining to:

cfg.InlineBetweenUserFunctions = 'Readability'; cfg.InlineBetweenUserAndMathWorksFunctions = 'Readability'; cfg.InlineBetweenMathWorksFunctions = 'Speed';

For more information about controlling function inlining behavior of the code generator, see Control Inlining to Fine-Tune Performance and Readability of Generated Code.

Generate a static C++ library by using the codegen command.

codegen -config cfg effectOfDamping -args {params,0,0,0,0} -report

Code generation successful: To view the report, open('codegen/lib/effectOfDamping/html/report.mldatx')

Open the code generation report and inspect the generated C++ source code:

For example, here is the declaration of the generated mySystem::simpleOscillator class contained in the header file simpleOscillator.h.

type codegen/lib/effectOfDamping/simpleOscillator.h

// // File: simpleOscillator.h // // MATLAB Coder version : 24.2 // C/C++ source code generated on : 22-Jan-2025 23:11:39 //

#ifndef SIMPLEOSCILLATOR_H #define SIMPLEOSCILLATOR_H

// Include Files #include "rtwtypes.h" #include "coder_array.h" #include #include

// Type Definitions namespace mySystem { class simpleOscillator { public: void init(double m, double k); void evolution(double initialPosition, double initialVelocity, double timeInterval, double timeStep, coder::array<double, 1U> &b_time, coder::array<double, 1U> &position) const; double dynamics(double initialPosition, double initialVelocity, double timeInterval) const; double amplitude(double initialPosition, double initialVelocity) const; double angularFrequency() const; double phase(double initialPosition, double initialVelocity) const;

protected: double mass; double springConstant; };

} // namespace mySystem

#endif // // File trailer for simpleOscillator.h // // [EOF] //

If you have Embedded Coder®, you can set the VerificationMode property of the configuration object to 'SIL' and generate a SIL MEX function effectOfDamping_sil. This SIL interface allows you to verify the production ready source code inside the MATLAB environment. See Software-in-the-Loop Execution from Command Line (Embedded Coder).

Generate and Run Executable

In the previous part of this example, when you generate library code, the code generator also produces example main files main.h and main.cpp in the examples subfolder of the build folder. The supporting C++ files main_damped_oscillator.h and main_damped_oscillator.cpp are modified versions of these example files.

Create a code configuration object for generating a C++ executable. Use the same settings as in the previous part of this example.

cfg = coder.config('exe'); cfg.TargetLang = 'C++'; cfg.CppInterfaceStyle = 'Methods'; cfg.CppInterfaceClassName = 'myOscillators';

cfg.InlineBetweenUserFunctions = 'Readability'; cfg.InlineBetweenUserAndMathWorksFunctions = 'Readability'; cfg.InlineBetweenMathWorksFunctions = 'Speed';

Specify the custom C++ source file and the custom include folder.

cfg.CustomSource = 'main_damped_oscillator.cpp'; cfg.CustomInclude = {pwd};

Generate an executable by using the codegen command.

codegen -config cfg effectOfDamping -args {params,0,0,0,0} -report

Code generation successful: To view the report, open('codegen/exe/effectOfDamping/html/report.mldatx')

Run the generated executable. Observe that the final positions of the two oscillators that this execution returns match the outputs of the original MATLAB code.

if isunix system('./effectOfDamping') elseif ispc system('effectOfDamping.exe') else disp('Platform is not supported') end

See Also

codegen | coder.config