Калибруйте характеристики XCP

В этом примере показано, как использовать поддержку протокола XCP соединить и калибровать доступные характеристические данные из модели Simulink, развернутой на исполняемом файле Windows. Пример пишет, чтобы изменить параметры модели с помощью TCP и прямого доступа к памяти, и сравнивает измерения до и после калибровки. XCP является высокоуровневым протоколом, используемым для доступа и изменения внутренних параметров и переменных модели, алгоритма или ECU. Для получения дополнительной информации обратитесь к стандартам ASAM.

Обзор алгоритма

Алгоритм, используемый в этом примере, является моделью Simulink, созданной и развернутой как сервер XCP. Модель была уже скомпилирована и доступна, чтобы запустить в файле XCPServerSineWaveGenerator.exe. Кроме того, A2L-файл XCPServerSineWaveGenerator.a2l обеспечивается как выход того процесса сборки. Модель содержит три измерения и две характеристики, доступные через XCP. Поскольку модель уже развертывается, Simulink не требуется запустить этот пример. Следующее изображение иллюстрирует модель.

SineAfterGain сигнала получен при помощи множителя Gain чтобы масштабировать источник сигнализируют о Sine, и SineAfterTable сигнала получен при помощи 1D интерполяционной таблицы, чтобы изменить исходный сигнал Sine. Калибровка параметра Gain и 1D интерполяционная таблица производит различный SineAfterGain и SineAfterTable формы волны, соответственно.

Для получения дополнительной информации о том, как создать модель Simulink, включая сервер XCP и генерацию A2L-файла, смотрите Экспорт Файл ASAP2 для Измерения Данных и Калибровки (Simulink Coder).

Запустите модель сервера XCP

Чтобы связаться с сервером XCP, развернутая модель должна быть запущена. При помощи system функция, можно выполнить XCPServer.exe из MATLAB. Функция требует построения списка аргументов, указывающего на исполняемый файл. Отдельное командное окно открывает и показывает рабочие выходные параметры с сервера.

sysCommand = ['"', fullfile(pwd, 'XCPServerSineWaveGenerator.exe'),'"', ' &'];
system(sysCommand);

Откройте A2L-файл

A2L-файл требуется, чтобы устанавливать связь с сервером XCP. A2L-файл описывает всю функциональность и возможность, которую сервер XCP предусматривает, а также детали того, как связать с сервером. Используйте xcpA2L функционируйте, чтобы открыть A2L-файл, который описывает модель сервера.

a2lInfo = xcpA2L("XCPServerSineWaveGenerator.a2l")
a2lInfo = 
  A2L with properties:

   File Details
                 FileName: 'XCPServerSineWaveGenerator.a2l'
                 FilePath: 'C:\Users\siyingl\OneDrive - MathWorks\Documents\MATLAB\Examples\vnt-ex09112476\XCPServerSineWaveGenerator.a2l'
               ServerName: 'ModuleName'
                 Warnings: [0×0 string]

   Parameter Details
                   Events: {'100 ms'}
                EventInfo: [1×1 xcp.a2l.Event]
             Measurements: {'Sine'  'SineAfterGain'  'SineAfterTable'  'XCPServer_DW.lastCos'  'XCPServer_DW.lastSin'  'XCPServer_DW.systemEnable'}
          MeasurementInfo: [6×1 containers.Map]
          Characteristics: {'Gain'  'ydata'}
       CharacteristicInfo: [2×1 containers.Map]
                 AxisInfo: [1×1 containers.Map]
            RecordLayouts: [4×1 containers.Map]
             CompuMethods: [3×1 containers.Map]
                CompuTabs: [0×1 containers.Map]
               CompuVTabs: [0×1 containers.Map]

   XCP Protocol Details
        ProtocolLayerInfo: [1×1 xcp.a2l.ProtocolLayer]
                  DAQInfo: [1×1 xcp.a2l.DAQ]
    TransportLayerCANInfo: [0×0 xcp.a2l.XCPonCAN]
    TransportLayerUDPInfo: [0×0 xcp.a2l.XCPonIP]
    TransportLayerTCPInfo: [1×1 xcp.a2l.XCPonIP]

TCP является транспортным протоколом, используемым, чтобы связаться с сервером XCP. Детали для соединения по протоколу TCP, такие как IP-адрес и номер порта, содержатся в TransportLayerTCPInfo свойство.

a2lInfo.TransportLayerTCPInfo
ans = 
  XCPonIP with properties:
          CommonParameters: [1×1 xcp.a2l.CommonParameters]
    TransportLayerInstance: ''
                      Port: 17725
                   Address: 2.1307e+09
             AddressString: '127.0.0.1'

Создайте канал XCP

Чтобы создать активную связь XCP с сервером, используйте xcpChannel функция. Функция требует, чтобы ссылка на A2L-файл сервера и тип транспортного протокола использовала для обмена сообщениями с сервером.

xcpCh = xcpChannel(a2lInfo, "TCP")
xcpCh = 
  Channel with properties:

              ServerName: 'ModuleName'
             A2LFileName: 'XCPServerSineWaveGenerator.a2l'
          TransportLayer: 'TCP'
    TransportLayerDevice: [1×1 struct]
              SeedKeyDLL: []

Свяжите с сервером

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

connect(xcpCh)

Просмотрите доступные характеристики из A2L-файла

Характеристика в XCP представляет настраиваемый параметр в памяти о модели. Характеристики, доступные для калибровки, заданы в A2L-файле и могут быть найдены в Characteristics свойство. Обратите внимание на то, что параметр Gain множитель и ydata задает точки выходных данных 1D интерполяционной таблицы.

a2lInfo.Characteristics
ans = 1×2 cell
    {'Gain'}    {'ydata'}

a2lInfo.CharacteristicInfo("Gain")
ans = 
  Characteristic with properties:
                   Name: 'Gain'
         LongIdentifier: ''
     CharacteristicType: VALUE
             ECUAddress: 549960
                Deposit: [1×1 xcp.a2l.RecordLayout]
                MaxDiff: 0
             Conversion: [1×1 xcp.a2l.CompuMethod]
             LowerLimit: -5
             UpperLimit: 5
              Dimension: 1
         AxisConversion: {1×0 cell}
                BitMask: []
              ByteOrder: MSB_LAST
               Discrete: []
    ECUAddressExtension: 0
                 Format: ''
                 Number: []
               PhysUnit: ''

a2lInfo.CharacteristicInfo("ydata")
ans = 
  Characteristic with properties:
                   Name: 'ydata'
         LongIdentifier: 'Y data'
     CharacteristicType: CURVE
             ECUAddress: 550024
                Deposit: [1×1 xcp.a2l.RecordLayout]
                MaxDiff: 0
             Conversion: [1×1 xcp.a2l.CompuMethod]
             LowerLimit: -2
             UpperLimit: 2
              Dimension: 7
         AxisConversion: {[1×1 xcp.a2l.CompuMethod]}
                BitMask: []
              ByteOrder: MSB_LAST
               Discrete: []
    ECUAddressExtension: 0
                 Format: ''
                 Number: []
               PhysUnit: ''

Смотрите предварительно загруженные характеристические значения

Считайте текущее значение характеристического Gain. readCharacteristic функция выполняет прямое чтение с сервера для данной характеристики.

initialGain = readCharacteristic(xcpCh, "Gain")
initialGain = 2

Считайте текущую 1D характеристику интерполяционной таблицы использование readAxis и readCharacteristic, затем постройте отображение. Эта таблица эффективно сопоставляет любое положительное входное значение, чтобы обнулить выход.

inputBreakpoints = readAxis(xcpCh, "xdata")
inputBreakpoints = 1×7

   -1.0000   -0.5000   -0.2000         0    0.2000    0.5000    1.0000

outputPoints = readCharacteristic(xcpCh, "ydata")
outputPoints = 1×7

   -1.0000   -0.5000   -0.2000         0         0         0         0

plot(inputBreakpoints, outputPoints);
title("Initial 1-D Look-up Table Map");
xlabel("Input Value");
ylabel("Output Value");

Создайте список измерений

Этот пример исследует значение измерения Sine, немодифицированный и измененный этими двумя характеристиками. Визуализировать постоянно изменяющееся значение Sine пред - и посткалибровка, получите значения данных измерения с помощью списка DAQ. Используйте createMeasurementList функция, чтобы создать список DAQ, содержащий весь Sine- основанные измерения, доступные с сервера.

createMeasurementList(xcpCh, "DAQ", "100 ms", ["Sine", "SineAfterGain", "SineAfterTable"])

Получите измерения перед калибровкой

Используйте startMeasurement функция и stopMeasurement функционируйте, чтобы запустить список DAQ в течение короткого периода времени.

startMeasurement(xcpCh);
pause(3);
stopMeasurement(xcpCh);

Чтобы получить данные, полученные списком DAQ за все Основанные на синусе измерения, используйте readDAQ функция. Количество полученных выборок в течение 3 секунд в событии на 100 мс, как ожидают, будет 30, но потому что сервер XCP работает на Windows, который не является операционной системой реального времени, фактическое количество полученных выборок может быть меньше 30, в зависимости от того, насколько занятый операционная система.

sine = readDAQ(xcpCh, "Sine");
sineAfterGain = readDAQ(xcpCh, "SineAfterGain");
sineAfterTable = readDAQ(xcpCh, "SineAfterTable");

Смотрите измерения перед калибровкой

Постройте SineAfterGain измерение против основного Sine измерение. Значение после Gain повышен на коэффициент 2, на основе исходного измерения, потому что предварительно загруженное значение характеристического Gain 2, как показано ранее.

plot(sine, "o-"); hold on;
plot(sineAfterGain, "*-"); hold off;
title("Before Calibration: Sine Signal vs Sine Signal after Gain");
legend("Original", "After Gain");
xlabel("Data Point");
ylabel("Data Value");

Постройте SineAfterTable измерение против основного Sine измерение. Любое положительное значение исходного измерения сопоставлено, чтобы обнулить согласно предварительно загруженной 1D интерполяционной таблице, поэтому модифицированный сигнал выглядит усеченным и не имеет никаких положительных значений.

plot(sine, "o-"); hold on;
plot(sineAfterTable, "*-"); hold off;
title("Before Calibration: Sine Signal vs Sine Signal after Table");
legend("Original", "After Table");
xlabel("Data Point");
ylabel("Data Value");

Калибруйте усиление и 1D интерполяционную таблицу

Запишите новое значение в характеристический Gain использование writeCharacteristic, и выполните чтение, чтобы проверить изменение с помощью readCharacteristic.

writeCharacteristic(xcpCh, "Gain", 0.5);
newGain = readCharacteristic(xcpCh, "Gain")
newGain = 0.5000

Запишите новые точки данных в выход 1D интерполяционной таблицы с помощью writeCharacteristic.

writeCharacteristic(xcpCh, "ydata", [0 0 0 0 0.2 0.5 1]);

Считайте новые 1D данные интерполяционной таблицы с помощью readAxis и readCharacteristic, затем постройте отображение. Теперь таблица эффективно сопоставляет любое отрицательное входное значение, чтобы обнулить выход.

inputBreakpoints = readAxis(xcpCh, "xdata")
inputBreakpoints = 1×7

   -1.0000   -0.5000   -0.2000         0    0.2000    0.5000    1.0000

newOutputPoints = readCharacteristic(xcpCh, "ydata")
newOutputPoints = 1×7

         0         0         0         0    0.2000    0.5000    1.0000

plot(inputBreakpoints, newOutputPoints);
title("New 1-D Look-up Table Map");
xlabel("Input Value");
ylabel("Output Value");

Получите Измерения после Калибровки

Используйте startMeasurement функция и stopMeasurement функционируйте, чтобы запустить список DAQ в течение короткого периода времени.

startMeasurement(xcpCh);
pause(3);
stopMeasurement(xcpCh);

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

sine = readDAQ(xcpCh, "Sine");
sineAfterGain = readDAQ(xcpCh, "SineAfterGain");
sineAfterTable = readDAQ(xcpCh, "SineAfterTable");

Смотрите измерения после калибровки

Постройте SineAfterGain измерение против основного Sine измерение. Теперь значение после Gain уменьшен на коэффициент 2, на основе исходного измерения, потому что значение характеристического Gain установлен в 0,5 после калибровки.

plot(sine, "o-"); hold on;
plot(sineAfterGain, "*-"); hold off;
title("After Calibration: Sine Signal vs Sine Signal after Gain");
legend("Original", "After Gain");
xlabel("Data Point");
ylabel("Data Value");

Постройте SineAfterTable измерение против основного Sine измерение. Любая отрицательная величина исходного измерения сопоставлена, чтобы обнулить согласно новой 1D интерполяционной таблице, поэтому модифицированный сигнал выглядит усеченным по-другому и не имеет никаких отрицательных величин.

plot(sine, "o-"); hold on;
plot(sineAfterTable, "*-"); hold off;
title("After Calibration: Sine Signal vs Sine Signal after Table");
legend("Original", "After Table");
xlabel("Data Point");
ylabel("Data Value");

Отключитесь от сервера

Чтобы деактивировать связь с сервером, используйте disconnect функция. Сервер XCP может быть безопасно закрыт после разъединения.

disconnect(xcpCh)

Очистка

clear a2lInfo