Этот пример показывает, как протестировать внешний код С при помощи модульных тестов MATLAB® с MATLAB® Coder™.
Если вы хотите протестировать код С, можно использовать MATLAB CODER, чтобы принести код в MATLAB. Можно затем записать модульные тесты при помощи среды тестирования MATLAB. Можно записать более богатые, более гибкие тесты путем использования в своих интересах усовершенствованных числовых возможностей вычисления и визуализации MATLAB.
Этот пример показывает как:
Принесите свой код С в MATLAB как MEX-функция, которую вы генерируете с MATLAB CODER.
Запишите модульный тест при помощи среды тестирования MATLAB.
Запустите тест на MEX-функции.
Если вы Встроили Coder®, можно запустить модульные тесты на сгенерированном автономном коде (статическая библиотека или совместно использованная библиотека) при помощи модульных тестов с программным обеспечением в цикле (SIL) выполнение или процессор в цикле (PIL) выполнение.
Чтобы получить доступ к файлам, которые использует этот пример, нажмите Open Script.
kalmanfilter. c
kalmanfilter.c
является функцией C, которую тестирует пример. Это оценивает положение перемещения, основанного на объектах на его прошлых положениях.
kalmanfilter. h
kalmanfilter.h
является заголовочным файлом для kalmanfilter.c
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
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 workspace, если вы загружаете position.mat
, вы видите, что position
2 310, массив удваивается.
Пропустите Проверку на шаг Проблем Во время выполнения для этого примера.
Сконфигурируйте приложение для генерации кода MEX. Задайте имена исходных и заголовочных файлов C, потому что callKalmanFilter
интегрирует внешний код С.
Для типа Сборки задайте MEX
.
Нажмите More Settings.
На вкладке Custom Code:
Под Пользовательским кодом С для Сгенерированных Файлов выберите Заголовочный файл. В поле пользовательского кода введите #include "kalmanfilter.h"
h.
В Дополнительном поле исходных файлов введите kalmanfilter.c
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
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.7256 seconds testing time.