%%  Unit Test External C Code with MATLAB Coder
% This example shows how to test external C code by using  
% MATLAB&#0174; unit tests with  MATLAB&#0174; Coder&#8482;.
%
% If you want to test C code, you can use MATLAB Coder to bring the code
% into MATLAB. You can then write unit tests by using the MATLAB testing
% framework. You can write richer, more flexible tests by taking advantage
% of the advanced numerical computing and visualization capabilities of MATLAB.
%
% This example shows how to:
%
% # Bring your C code into MATLAB as a MEX function that you generate with MATLAB Coder. 
% # Write a unit test by using the MATLAB testing framework. 
% # Run the test on the MEX function.
%
% If you have  Embedded Coder&#0174;, you can run unit tests on generated
% standalone code (static library or shared library)
% by using the unit tests with software-in-the-loop (SIL) execution
% or processor-in-the-loop (PIL) execution.
%
%% Examine the Files 
% To access the files that this example uses, click *Open Script*.
%
% *kalmanfilter.c*
%
% |kalmanfilter.c| is the C function that the example tests. It estimates 
% the position of a moving object based on its past positions. 
%
%
% *kalmanfilter.h*
%
% |kalmanfilter.h| is the header file for |kalmanfilter.c|.
%
%
% *position.mat*
%
% |position.mat| contains the positions of the object.
% 
% *callKalmanFilter.m*
%
% |callKalmanFilter| calls |kalmanfilter| by using |coder.ceval|.
%
% <include>callKalmanFilter.m</include>
%
% *TestKalmanFilter.m*
% 
% |TestKalmanFilter| tests whether the
% error between the predicted position and actual position exceeds
% the specified tolerance. The unit tests are class-based unit tests. For
% more information, see
% <docid:matlab_prog.bufaqr6-1 Author Class-Based Unit Tests in MATLAB>.
%
% Although you want to test the MEX function, the unit tests in |TestKalmanFilter|
% call the original MATLAB function from which you generated the MEX
% function. When MATLAB Coder runs the tests, it replaces the calls to the
% MATLAB function with calls to the MEX function. You cannot run
% these tests directly in MATLAB because MATLAB does not recognize the
% |coder.ceval| calls in |callKalmanFilter|.
% 
% <include>TestKalmanFilter.m</include>
%
% *run_unit_tests_kalman.m*
%
% |run_unit_tests_kalman| calls |runtests| to run the tests in |TestKalmanFilter.m|.
%
% <include>run_unit_tests_kalman.m</include>
%
% *plot_kalman_filter_trajectory.m*
%
% |plot_kalman_filter_trajectory| plots the trajectory of the
% estimated and actual positions of the object. Each unit test calls this
% function.
%% Generate MEX and Run Unit Tests in the MATLAB Coder App
%%
% To open the MATLAB Coder app, on the MATLAB Toolstrip *Apps* tab,
% under *Code Generation*, click the MATLAB Coder app icon.
%%
% To prepare for code generation, advance through the app steps.
%
% * On the *Select Source Files* page, specify that the entry-point function is |callKalmanFilter|.
% * On the *Define Input Types* page, specify that the input argument |x| is a 2-by-310 array of doubles.
%
% The unit tests load the variable |position| from |position.mat| and pass
% |position| to |callKalmanFilter|. Therefore, the input to |callKalmanFilter|
% must have the properties that |position| has. In the MATLAB workspace, if you
% load |position.mat|, you see that |position| is a 2-by-310 array of doubles.
%
% * Skip the *Check for Run-Time Issues* step for this example. 
%
%% 
% Configure the app for MEX code generation.  Specify the names of the
% C source and header files because |callKalmanFilter| integrates external C code.
%
% # For *Build type*, specify |MEX|.
% # Click *More Settings*.
% # On the *Custom Code* tab:
%
% * Under *Custom C Code for Generated Files*, select *Header file*. In the custom code field, enter |#include "kalmanfilter.h"|. 
% * In the *Additional source files* field, enter |kalmanfilter.c|.
%
% <<../custom_code_kalman.png>>
%
% To generate the MEX function, click *Generate*.
%
%%
% Run the unit tests on the generated MEX.
% 
% # Click *Verify Code*.
% # In the field for the test file, specify |run_unit_tests_kalman|.
% # Make sure that you set *Run using* to *Generated code*.
% # Click *Run Generated Code*. 
%
% <<../verify_kalman_app.png>>
%
% When the app runs the test file, it replaces calls to   
% |callKalmanFilter| in the unit test with calls to |callKalmanFilter_mex|. 
% The unit tests run on the MEX function instead of the original MATLAB function.
% 
% The app displays the test output on the *Test Output* tab. The unit tests pass.
%
% <<../test_output_kalman_app.png>>
%
% From the plots, you can see that the trajectory of the estimated position
% converges with the trajectory of the actual position.
%
% <<../kalman_error_plot.png>>
%
%% Run Unit Tests After Modifying C Code
% When you modify the C code, to run the unit tests:
%
% # Regenerate the MEX function for the MATLAB function that calls the C code.
% # Repeat the verification step.
%
% For example, modify |kalmanfilter.c| so that the value assigned to |y[r2]| is multiplied by 1.1.
% 
% |y[r2] += (double)d_a[r2 + (i0 << 1)] * x_est[i0] * 1.1;|
%
% Edit |kalmanfilter.c| outside of the app because you can use the app to edit only
% MATLAB files listed in the *Source Code* pane of the app.
%%
% To generate the MEX function for the modified function, click *Generate*.
%%
% To run the unit tests:
%
% # Click *Verify Code*.
% # Make sure that you set the test file to |run_unit_tests| and *Run using* 
% to *Generated code*
% # Click *Run Generated Code*.
% 
% The tests fail because the error exceeds the specified tolerance.
%
% The plots show the error between the trajectory for the estimated position
% and the trajectory for the actual position.
%
% <<../kalman_error_plot_test_fails.png>>
%% Generate MEX and Run Unit Tests by Using the Command-Line Workflow 
%%
% You can use the command-line workflow to run unit tests on 
% external C code by using |coder.runTest|. Specify a test file that runs the
% unit tests on the MATLAB function that calls your C code.
%%
% Generate a MEX function for the MATLAB function that calls your C code. For this
% example, generate MEX for |callKalmanFilter|.
%%
% Create a configuration object for MEX code generation.
cfg = coder.config('mex');
%%
% Specify the external source code and header file.
cfg.CustomSource = 'kalmanfilter.c';
cfg.CustomHeaderCode = '#include "kalmanfilter.h"';
%%
% To determine the type for the input to |callKalmanFilter|, load the position file. 
load position.mat
%%
% To generate the MEX function, run |codegen|. Specify that the input to |callKalmanFilter| has the same type as |position|.
codegen -config cfg callKalmanFilter -args position
%% 
% Run the units tests on the MEX function. Specify that the test file is 
% |run_unit_tests_kalman| and that the function is |callKalmanfilter|. 
% When |coder.runTest|  runs the test file, it replaces calls to   
% |callKalmanFilter| in the unit test with calls to |callKalmanFilter_mex|. 
% The unit tests run on the MEX function instead of the original MATLAB function.
coder.runTest('run_unit_tests_kalman', 'callKalmanFilter')





%% 
% Copyright 2012 The MathWorks, Inc.