Модульный тест внешний код С с MATLAB Coder

Этот пример показывает, как протестировать внешний код С при помощи модульных тестов MATLAB® с MATLAB® Coder™.

Если вы хотите протестировать код С, можно использовать MATLAB Coder, чтобы принести код в MATLAB. Можно затем записать модульные тесты при помощи среды тестирования MATLAB. Можно записать более богатые, более гибкие тесты путем использования в своих интересах усовершенствованных числовых возможностей вычисления и визуализации MATLAB.

Этот пример показывает как:

  1. Принесите свой код С в MATLAB как MEX-функция, которую вы генерируете с MATLAB Coder.

  2. Запишите модульный тест при помощи среды тестирования MATLAB.

  3. Запустите тест на MEX-функции.

Если у вас есть Embedded Coder®, можно запустить модульные тесты на сгенерированном автономном коде (статическая библиотека или совместно использованная библиотека) при помощи модульных тестов с программным обеспечением в цикле (SIL) выполнение или процессор в цикле (PIL) выполнение.

Исследуйте файлы

Чтобы получить доступ к файлам, которые использует этот пример, нажмите Open Script.

kalmanfilter.c

kalmanfilter.c является функцией C, которую тестирует пример. Это оценивает положение перемещения, основанного на объектах на его прошлых положениях.

kalmanfilter.h

kalmanfilter.h является заголовочным файлом для kalmanfilter.c.

position.mat

position.mat содержит положения объекта.

callKalmanFilter.m

callKalmanFilter вызывает kalmanfilter при помощи coder.ceval.

function [a,b] = callKalmanFilter(position)
% Copyright 2014 - 2016 The MathWorks, Inc.

numPts = size(position,2);

a = zeros(2,numPts,'double');
b = zeros(2,numPts,'double');
y = zeros(2,1,'double');

% Main loop
for idx = 1: numPts
    z = position(:,idx);     % Get the input data
    
    % Call the initialize function
    coder.ceval('kalmanfilter_initialize');
    
    % Call the C function
    coder.ceval('kalmanfilter',z,coder.ref(y));
    
    % Call the terminate function
    coder.ceval('kalmanfilter_terminate');
    
    a(:,idx) = [z(1); z(2)];
    b(:,idx) = [y(1); y(2)];
end
end

TestKalmanFilter.m

TestKalmanFilter тестирует, превышает ли ошибка между предсказанным положением и фактическим положением заданный допуск. Модульные тесты являются модульными тестами, основанными на классах. Для получения дополнительной информации смотрите Создание модульных тестов на основе классов в MATLAB (MATLAB).

Несмотря на то, что вы хотите протестировать MEX-функцию, модульные тесты в TestKalmanFilter вызывают исходную функцию MATLAB, от которой вы сгенерировали MEX-функцию. Когда MATLAB Coder запускает тесты, он заменяет вызовы функции MATLAB с вызовами MEX-функции. Вы не можете запустить эти тесты непосредственно в MATLAB, потому что MATLAB не распознает вызовы coder.ceval в callKalmanFilter.

classdef TestKalmanFilter < matlab.unittest.TestCase
    % Copyright 2014 - 2016 The MathWorks, Inc.
    
    methods ( Test )
        
        function SSE_LessThanTolerance( testCase )
            load position.mat;
            [z,y] = callKalmanFilter( position );
            
            tolerance = 0.001; % tolerance of 0.0001 will break
            A = z-1000*y;
            error = sum(sum(A.^2));
            
            testCase.verifyLessThanOrEqual( error, tolerance);
            
            % For debugging
            plot_kalman_filter_trajectory(z,1000*y);
        end
        
        function SampleErrorLessThanTolerance( testCase )
            load position.mat;
            [z,y] = callKalmanFilter( position );
            
            tolerance = 0.01;   % tolerance of 0.001 will break
            A = z-1000*y;

            testCase.verifyEqual(1000*y, z, 'AbsTol', tolerance);
            % For debugging
            plot_kalman_filter_trajectory(z,1000*y);
            
            [value, location] = max(A(:));
            [R,C] = ind2sub(size(A),location);
            disp(['Max value ' num2str(value) ' is located at [' num2str(R) ',' num2str(C) ']']);
        end
    end
end

run_unit_tests_kalman.m

run_unit_tests_kalman вызывает runtests, чтобы запустить тесты в TestKalmanFilter.m.

% Run unit tests
% Copyright 2014 - 2016 The MathWorks, Inc.

runtests('TestKalmanFilter')

plot_kalman_filter_trajectory.m

plot_kalman_filter_trajectory строит траекторию предполагаемых и фактических положений объекта. Каждый модульный тест вызывает эту функцию.

Сгенерируйте MEX и запущенные модульные тесты в приложении MATLAB Coder

Чтобы открыть приложение MATLAB Coder, на вкладке MATLAB Toolstrip Apps, под Генерацией кода, кликают по значку приложения MATLAB Coder.

Чтобы подготовиться к генерации кода, совершенствуйтесь через шаги приложения.

  • На странице Select Source Files укажите, что функцией точки входа является callKalmanFilter.

  • На странице Define Input Types укажите, что входной параметр, из которого x 2 310 массив, удваивается.

Модульные тесты загружают переменную position из position.mat и передают position callKalmanFilter. Поэтому вход к callKalmanFilter должен иметь свойства, которые имеет position. В рабочем пространстве MATLAB, если вы загружаете position.mat, вы видите, что position 2 310, массив удваивается.

  • Пропустите Проверку на шаг Проблем Во время выполнения для этого примера.

Сконфигурируйте приложение для генерации кода MEX. Задайте имена исходных и заголовочных файлов C, потому что callKalmanFilter интегрирует внешний код С.

  1. Для типа Сборки задайте MEX.

  2. Нажмите More Settings.

  3. На вкладке Custom Code:

  • Под Пользовательским кодом С для Сгенерированных Файлов выберите Заголовочный файл. В поле пользовательского кода введите #include "kalmanfilter.h".

  • В Дополнительном поле исходных файлов введите kalmanfilter.c.

Чтобы сгенерировать MEX-функцию, нажмите Generate.

Запустите модульные тесты на сгенерированном MEX.

  1. Нажмите Verify Code.

  2. В поле для тестового файла задайте run_unit_tests_kalman.

  3. Убедитесь, что вы устанавливаете использование Выполнения на Сгенерированный код.

  4. Нажмите Run Generated Code.

Когда выполнение приложения тестовый файл, это заменяет вызовы callKalmanFilter в модульном тесте с вызовами callKalmanFilter_mex. Модульные тесты работают на MEX-функции вместо исходной функции MATLAB.

Отображения приложения тест выводятся на вкладке Test Output. Передача модульных тестов.

Из графиков вы видите, что траектория предполагаемого положения сходится с траекторией фактического положения.

Запустите модульные тесты после изменения кода С

Когда вы изменяете код С, чтобы запустить модульные тесты:

  1. Регенерируйте MEX-функцию для функции MATLAB, которая вызывает код С.

  2. Повторите шаг верификации.

Например, измените kalmanfilter.c так, чтобы значение, присвоенное y[r2], было умножено на 1,1.

y[r2] += (double)d_a[r2 + (i0 << 1)] * x_est[i0] * 1.1;

Отредактируйте kalmanfilter.c за пределами приложения, потому что можно использовать приложение, чтобы отредактировать только файлы MATLAB, перечисленные в панели Исходного кода приложения.

Чтобы сгенерировать MEX-функцию для измененной функции, нажмите Generate.

Запускать модульные тесты:

  1. Нажмите Verify Code.

  2. Убедитесь, что вы устанавливаете тестовый файл на run_unit_tests и использование Выполнения к Сгенерированному коду

  3. Нажмите Run Generated Code.

Тесты перестали работать, потому что ошибка превышает заданный допуск.

Графики показывают ошибку между траекторией для предполагаемого положения и траекторией для фактического положения.

Сгенерируйте MEX и запущенные модульные тесты при помощи рабочего процесса командной строки

Можно использовать рабочий процесс командной строки, чтобы запустить модульные тесты на внешнем коде С при помощи coder.runTest. Задайте тестовый файл, который запускает модульные тесты на функции MATLAB, которая вызывает ваш код С.

Сгенерируйте MEX-функцию для функции MATLAB, которая вызывает ваш код С. В данном примере сгенерируйте MEX для callKalmanFilter.

Создайте объект настройки для генерации кода MEX.

cfg = coder.config('mex');

Задайте внешний исходный код и заголовочный файл.

cfg.CustomSource = 'kalmanfilter.c';
cfg.CustomHeaderCode = '#include "kalmanfilter.h"';

Чтобы определить тип для входа к callKalmanFilter, загрузите файл положения.

load position.mat

Чтобы сгенерировать MEX-функцию, запустите codegen. Укажите, что вход к callKalmanFilter имеет тот же тип как position.

codegen -config cfg callKalmanFilter -args position

Запустите модульные тесты на MEX-функции. Укажите, что тестовым файлом является run_unit_tests_kalman и что функцией является callKalmanfilter. Когда coder.runTest запускает тестовый файл, он заменяет вызовы callKalmanFilter в модульном тесте с вызовами callKalmanFilter_mex. Модульные тесты работают на MEX-функции вместо исходной функции MATLAB.

coder.runTest('run_unit_tests_kalman', 'callKalmanFilter')
Running TestKalmanFilter
Current plot held
.Current plot held
Max value 0.0010113 is located at [2,273]
.
Done TestKalmanFilter
__________


ans = 

  1x2 TestResult array with properties:

    Name
    Passed
    Failed
    Incomplete
    Duration
    Details

Totals:
   2 Passed, 0 Failed, 0 Incomplete.
   29.591 seconds testing time.

Смотрите также

Похожие темы