exponenta event banner

Тест блока Внешний код C с кодером MATLAB

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

При необходимости тестирования кода C для ввода кода в MATLAB можно использовать кодер MATLAB. Затем можно записать модульные тесты с помощью платформы тестирования MATLAB. Вы можете создавать более насыщенные и гибкие тесты, используя расширенные возможности численных вычислений и визуализации MATLAB.

В этом примере показано, как:

  1. Введите код C в MATLAB как функцию MEX, создаваемую с помощью кодера MATLAB.

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

  3. Запустите тест для функции MEX.

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

Проверка файлов

Чтобы получить доступ к файлам, используемым в этом примере, щелкните Открыть сценарий.

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.

Несмотря на необходимость тестирования функции MEX, модуль тестирует в TestKalmanFilter вызовите исходную функцию MATLAB, из которой была создана функция MEX. Когда кодер MATLAB выполняет тесты, он заменяет вызовы функции 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

Чтобы открыть приложение MATLAB Coder, на вкладке MATLAB Toolstrip Apps в разделе Code Generation щелкните значок приложения MATLAB Coder.

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

  • На странице «Выбор исходных файлов» укажите, что функцией точки входа является callKalmanFilter.

  • На странице «Определение типов ввода» укажите, что входной аргумент x представляет собой массив двойников 2 на 310.

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

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

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

  1. Для параметра «Тип построения» укажите MEX.

  2. Щелкните Дополнительные параметры.

  3. На вкладке Пользовательский код:

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

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

Для создания функции MEX нажмите кнопку Generate.

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

  1. Щелкните Проверить код.

  2. В поле для тестового файла укажите run_unit_tests_kalman.

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

  4. Щелкните Выполнить сгенерированный код.

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

Выходные данные теста отображаются на вкладке «Выходные данные теста». Единичные тесты проходят.

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

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

При изменении кода C для выполнения модульных тестов:

  1. Повторно создайте функцию MEX для функции MATLAB, вызывающей код C.

  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. Щелкните Проверить код.

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

  3. Щелкните Выполнить сгенерированный код.

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

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

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

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

Создайте функцию MEX для функции MATLAB, вызывающей код C. Для этого примера создайте 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
Code generation successful.

Выполните тесты блоков для функции 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.
   20.4016 seconds testing time.

См. также

Связанные темы