В этом примере показано, как протестировать внешний код С с помощью модульных тестов MATLAB ® с Coder™ MATLAB ®.
Если вы хотите протестировать код С, можно использовать MATLAB Coder, чтобы перенести код в MATLAB. Затем можно записать модульные тесты с помощью среды тестирования MATLAB. Можно написать более богатые, гибкие тесты, воспользовавшись расширенными возможностями числовых вычислений и визуализации MATLAB.
В этом примере показано, как:
Внесите Код С в MATLAB как MEX-функцию, которую вы генерируете с MATLAB Coder.
Написание модульного теста с помощью среды тестирования MATLAB.
Запустите тест на 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.
Хотя вы хотите протестировать 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 строит графики траектории расчетных и фактических положений объекта. Каждый модульный тест вызывает эту функцию.
Чтобы открыть приложение MATLAB Coder, на вкладке MATLAB Toolstrip Apps, в разделе Генерация кода, щелкните значок приложения MATLAB Coder.
Чтобы подготовиться к генерации кода, пройдите по шагам приложения.
На странице Select Source Files задайте, что функция точки входа callKalmanFilter.
На странице Define Input Types задайте, что входной параметр x является массив типа double 2 на 310.
Модульные тесты загружают переменную position от position.mat и передайте position на callKalmanFilter. Поэтому вход для callKalmanFilter должны иметь свойства, которые position имеет. В рабочем пространстве MATLAB, если вы загружаете position.mat, вы видите это position является массив типа double 2 на 310.
Пропустите шаг Проверка проблем во время выполнения для этого примера.
Настройте приложение для генерации кода MEX. Укажите имена исходных и заголовочных файлов C, поскольку callKalmanFilter интегрирует внешний код С
Для типа сборки задайте MEX.
Щелкните Дополнительные параметры.
На вкладке Пользовательский код:
В разделе Пользовательский код С для сгенерированных файлов выберите Файл заголовка. В поле пользовательского кода введите #include "kalmanfilter.h".
В поле Дополнительные исходные файлы введите kalmanfilter.c.

Чтобы сгенерировать MEX-функцию, нажмите Generate.
Запустите модульные тесты на сгенерированном MEX.
Нажмите «Проверить код».
В поле для тестового файла задайте run_unit_tests_kalman.
Убедитесь, что для параметра «Выполнить с использованием» задано значение «Сгенерированный код».
Щелкните Выполнить сгенерированный код.

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

На графиках можно увидеть, что траектория предполагаемого положения сходится с траекторией фактического положения.

Когда вы изменяете код С, чтобы запустить модульные тесты:
Перегенерируйте MEX-функцию для функции MATLAB, которая вызывает код С
Повторите верификацию шаг.
Для примера измените kalmanfilter.c так, чтобы значение, присвоенное y[r2] умножается на 1.1.
y[r2] += (double)d_a[r2 + (i0 << 1)] * x_est[i0] * 1.1;
Редактирование kalmanfilter.c вне приложения, поскольку вы можете использовать приложение для редактирования только файлов MATLAB, перечисленных на панели Исходный код приложения.
Чтобы сгенерировать MEX-функцию для измененной функции, нажмите Generate.
Чтобы запустить модульные тесты:
Нажмите «Проверить код».
Убедитесь, что вы установили тестовый файл на run_unit_tests и Запуск с использованием в сгенерированный код
Щелкните Выполнить сгенерированный код.
Не удалось выполнить тесты, поскольку ошибка превышает заданный допуск.
Графики показывают ошибку между траекторией для предполагаемого положения и траекторией для фактического положения.

Можно использовать рабочий процесс командной строки, чтобы запустить модульные тесты на внешнем коде С при помощи 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
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.

