Этот пример показывает, как протестировать внешний код С при помощи модульных тестов MATLAB® с MATLAB® Coder™.
Если вы хотите протестировать код С, можно использовать 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 (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
2 310 массив, удваивается.
Модульные тесты загружают переменную position
из position.mat
и передают position
callKalmanFilter
. Поэтому вход к callKalmanFilter
должен иметь свойства, которые имеет position
. В рабочем пространстве MATLAB, если вы загружаете position.mat
, вы видите, что position
2 310, массив удваивается.
Пропустите Проверку на шаг Проблем Во время выполнения для этого примера.
Сконфигурируйте приложение для генерации кода MEX. Задайте имена исходных и заголовочных файлов C, потому что callKalmanFilter
интегрирует внешний код С.
Для типа Сборки задайте MEX
.
Нажмите More Settings.
На вкладке Custom Code:
Под Пользовательским кодом С для Сгенерированных Файлов выберите Заголовочный файл. В поле пользовательского кода введите #include "kalmanfilter.h"
.
В Дополнительном поле исходных файлов введите kalmanfilter.c
.
Чтобы сгенерировать MEX-функцию, нажмите Generate.
Запустите модульные тесты на сгенерированном MEX.
Нажмите Verify Code.
В поле для тестового файла задайте run_unit_tests_kalman
.
Убедитесь, что вы устанавливаете использование Выполнения на Сгенерированный код.
Нажмите Run Generated Code.
Когда выполнение приложения тестовый файл, это заменяет вызовы 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.
Запускать модульные тесты:
Нажмите Verify Code.
Убедитесь, что вы устанавливаете тестовый файл на run_unit_tests
и использование Выполнения к Сгенерированному коду
Нажмите Run Generated Code.
Тесты перестали работать, потому что ошибка превышает заданный допуск.
Графики показывают ошибку между траекторией для предполагаемого положения и траекторией для фактического положения.
Можно использовать рабочий процесс командной строки, чтобы запустить модульные тесты на внешнем коде С при помощи 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.