Main Content

覆盖 MDF 文件中的通道组数据

此示例说明如何处理在 MDF 文件的通道组中记录的数据,并将更新后的数据写回同一通道组。此示例 VehicleData.mf4 中使用的 MDF 文件包含从两个通道组中的两个仿真记录的数据,但该示例仅处理通道组 1 中的数据。

您首先需要将通道组 1 中的数据读入一个时间表,然后对该数据副本执行校正和约简,最后用更新后的数据覆盖同一通道组。

查看文件和通道组详细信息

通过指定文件名,使用 mdfInfo 查看 MDF 文件的元数据。

mdfInfo("VehicleData.mf4")
ans = 
  MDFInfo with properties:

   File Details
                  Name: "VehicleData.mf4"
                  Path: "/tmp/Bdoc24a_2511836_3070643/tp8879c7f7/vnt-ex75859393/VehicleData.mf4"
                Author: ""
            Department: ""
               Project: ""
               Subject: ""
               Comment: "Example file demonstrating workflows of writing to MDF files."
               Version: "4.10"
      InitialTimestamp: 2022-01-20 01:22:34.000000000

   Creator Details
     ProgramIdentifier: "MATLAB"
     CreatorVendorName: "The MathWorks, Inc."
       CreatorToolName: "MATLAB"
    CreatorToolVersion: "9.12.0.1846952 (R2022a) Prerelease Update 1"
       CreatorUserName: ""
        CreatorComment: ""

   File Contents
            Attachment: [1x7 table]
     ChannelGroupCount: 2

使用 mdfChannelGroupInfo 检查有关两个通道组的详细信息。

mdfChannelGroupInfo("VehicleData.mf4")
ans=2×13 table
    GroupNumber    AcquisitionName                                      Comment                                      NumSamples    DataSize    Sorted    SourceName     SourcePath     SourceComment    SourceType     SourceBusType    SourceBusChannelNumber    SourceSimulated
    ___________    _______________    ___________________________________________________________________________    __________    ________    ______    ___________    ___________    _____________    ___________    _____________    ______________________    _______________

         1           <undefined>      Simulation of an automatic transmission controller during passing maneuver.        751         43558     true      <undefined>    <undefined>     <undefined>     Unspecified     Unspecified               0                    false     
         2           <undefined>      Simulation of engine gas dynamics.                                               92033       2208792     true      <undefined>    <undefined>     <undefined>     Unspecified     Unspecified               0                    false     

读取包含元数据的通道组数据

使用可选参量 IncludeMetadata 设置为 truemdfRead 函数从通道组 1 读取数据。输出时间表 chanGrp1TT 是通道组 1 中所有通道的数据的副本。

chanGrp1Data = mdfRead("VehicleData.mf4", GroupNumber=1, IncludeMetadata=true)
chanGrp1Data = 1x1 cell array
    {751x8 timetable}

chanGrp1TT = chanGrp1Data{1}
chanGrp1TT=751×8 timetable
      time      EngineRPM    Brake    Throttle    Gear    ImpellerTorque    OutputTorque    TransmissionRPM    VehicleSpeed
    ________    _________    _____    ________    ____    ______________    ____________    _______________    ____________

    0 sec          1000        0           60      1          52.919           282.65                0              0      
    0.04 sec     1383.3        0       59.946      1           101.4           532.63           13.593              0      
    0.08 sec     1685.4        0       59.893      1          150.76           776.41           35.847              0      
    0.12 sec     1907.2        0       59.839      1          193.42           973.15           65.768              0      
    0.16 sec       2062        0       59.785      1          227.02           1117.6           101.53              0      
    0.2 sec      2161.2        0       59.732      1          251.11           1212.8           141.45              0      
    0.24 sec     2221.4        0       59.678      1          267.24           1264.3           183.86              0      
    0.28 sec     2257.2        0       59.624      1          276.35           1271.2           227.25              0      
    0.32 sec     2278.7        0        59.57      1          281.99           1259.5           270.52              0      
    0.36 sec     2292.4        0       59.517      1          283.39             1229           313.08              0      
    0.4 sec      2305.1        0       59.463      1          283.29           1193.4           354.43              0      
    0.44 sec     2317.4        0       59.409      1          282.91           1156.6           394.58              0      
    0.48 sec     2330.5        0       59.356      1          281.84           1112.8           433.27              0      
    0.52 sec     2344.5        0       59.302      1          281.19           1073.1           470.53              0      
    0.56 sec     2359.1        0       59.248      1          279.77           1032.9           506.43              0      
    0.6 sec      2376.4        0       59.195      1          277.89           993.97           540.92              0      
      ⋮

由于在 mdfRead 函数调用期间 IncludeMetadata 设置为 true,因此输出时间表还包含通道组 1 和此组中所有通道的元数据。一个通道组的元数据存储为整个表的时间表自定义属性,属性名称以“ChannelGroup”为前缀。各个通道的元数据存储为各变量的时间表自定义属性,属性名称以“Channel”为前缀。

查看通道组 1 和此组中所有通道的元数据。

chanGrp1TT.Properties.CustomProperties
ans = 
CustomProperties with properties:

           ChannelGroupAcquisitionName: ""
                   ChannelGroupComment: "Simulation of an automatic transmission controller during passing maneuver."
                ChannelGroupSourceName: ""
                ChannelGroupSourcePath: ""
             ChannelGroupSourceComment: ""
                ChannelGroupSourceType: Unspecified
             ChannelGroupSourceBusType: Unspecified
    ChannelGroupSourceBusChannelNumber: 0
                    ChannelDisplayName: [""    ""    ""    ""    ""    ""    ""    ""]
                        ChannelComment: [""    ""    ""    ""    ""    ""    ""    ""]
                           ChannelUnit: ["rpm"    "ft*lbf"    "%"    ""    "ft*lbf"    "ft*lbf"    "rpm"    "mph"]
                           ChannelType: [FixedLength    FixedLength    FixedLength    FixedLength    FixedLength    FixedLength    FixedLength    FixedLength]
                       ChannelDataType: [RealLittleEndian    IntegerUnsignedLittleEndian    RealLittleEndian    IntegerUnsignedLittleEndian    RealLittleEndian    RealLittleEndian    RealLittleEndian    RealLittleEndian]
                        ChannelNumBits: [64 8 64 8 64 64 64 64]
                  ChannelComponentType: [None    None    None    None    None    None    None    None]
                ChannelCompositionType: [None    None    None    None    None    None    None    None]
                     ChannelSourceName: [""    ""    ""    ""    ""    ""    ""    ""]
                     ChannelSourcePath: [""    ""    ""    ""    ""    ""    ""    ""]
                  ChannelSourceComment: [""    ""    ""    ""    ""    ""    ""    ""]
                     ChannelSourceType: [Unspecified    Unspecified    Unspecified    Unspecified    Unspecified    Unspecified    Unspecified    Unspecified]
                  ChannelSourceBusType: [Unspecified    Unspecified    Unspecified    Unspecified    Unspecified    Unspecified    Unspecified    Unspecified]
         ChannelSourceBusChannelNumber: [0 0 0 0 0 0 0 0]
                     ChannelReadOption: [All    All    All    All    All    All    All    All]

请注意,当调用 mdfRead 函数时,默认情况下 IncludeMetadata 设置为 false。因此,如果读取通道组数据的最终目标是覆盖从中读取数据的同一通道组,则 IncludeMetadata 必须设置为 true

校正数据副本中的选定采样

对于此特定应用,只有 4 个挡位,因此 Gear 的有效值应为 [1,4] 范围内的一个整数。然而,在每次换挡时,Gear 的值都会因可能的错误而被重置为零。

使用 stackedplot 创建一个堆叠图,以查看 Gear 中的值突然下降到零与 ImpellerTorqueOutputTorque 中的值突然变化是如何同步发生的。

stackedplot(chanGrp1TT, ["ImpellerTorque", "OutputTorque", "Gear"])

Figure contains an object of type stackedplot.

查找 Gear 的值等于零的行索引。

zeroIdx = find(chanGrp1TT.Gear == 0)
zeroIdx =

  0x1 empty double column vector

在找到的索引处校正采样,以获取紧跟在零后面的值。

chanGrp1TT.Gear(zeroIdx) = chanGrp1TT.Gear(zeroIdx + 1)
chanGrp1TT=751×8 timetable
      time      EngineRPM    Brake    Throttle    Gear    ImpellerTorque    OutputTorque    TransmissionRPM    VehicleSpeed
    ________    _________    _____    ________    ____    ______________    ____________    _______________    ____________

    0 sec          1000        0           60      1          52.919           282.65                0              0      
    0.04 sec     1383.3        0       59.946      1           101.4           532.63           13.593              0      
    0.08 sec     1685.4        0       59.893      1          150.76           776.41           35.847              0      
    0.12 sec     1907.2        0       59.839      1          193.42           973.15           65.768              0      
    0.16 sec       2062        0       59.785      1          227.02           1117.6           101.53              0      
    0.2 sec      2161.2        0       59.732      1          251.11           1212.8           141.45              0      
    0.24 sec     2221.4        0       59.678      1          267.24           1264.3           183.86              0      
    0.28 sec     2257.2        0       59.624      1          276.35           1271.2           227.25              0      
    0.32 sec     2278.7        0        59.57      1          281.99           1259.5           270.52              0      
    0.36 sec     2292.4        0       59.517      1          283.39             1229           313.08              0      
    0.4 sec      2305.1        0       59.463      1          283.29           1193.4           354.43              0      
    0.44 sec     2317.4        0       59.409      1          282.91           1156.6           394.58              0      
    0.48 sec     2330.5        0       59.356      1          281.84           1112.8           433.27              0      
    0.52 sec     2344.5        0       59.302      1          281.19           1073.1           470.53              0      
    0.56 sec     2359.1        0       59.248      1          279.77           1032.9           506.43              0      
    0.6 sec      2376.4        0       59.195      1          277.89           993.97           540.92              0      
      ⋮

从数据副本中删除通道

对于此特定应用,假设分析时不再需要 BrakeVehicleSpeed。使用 removevars 从时间表中删除这两个变量。

chanGrp1TT = removevars(chanGrp1TT, ["Brake", "VehicleSpeed"])
chanGrp1TT=751×6 timetable
      time      EngineRPM    Throttle    Gear    ImpellerTorque    OutputTorque    TransmissionRPM
    ________    _________    ________    ____    ______________    ____________    _______________

    0 sec          1000           60      1          52.919           282.65                0     
    0.04 sec     1383.3       59.946      1           101.4           532.63           13.593     
    0.08 sec     1685.4       59.893      1          150.76           776.41           35.847     
    0.12 sec     1907.2       59.839      1          193.42           973.15           65.768     
    0.16 sec       2062       59.785      1          227.02           1117.6           101.53     
    0.2 sec      2161.2       59.732      1          251.11           1212.8           141.45     
    0.24 sec     2221.4       59.678      1          267.24           1264.3           183.86     
    0.28 sec     2257.2       59.624      1          276.35           1271.2           227.25     
    0.32 sec     2278.7        59.57      1          281.99           1259.5           270.52     
    0.36 sec     2292.4       59.517      1          283.39             1229           313.08     
    0.4 sec      2305.1       59.463      1          283.29           1193.4           354.43     
    0.44 sec     2317.4       59.409      1          282.91           1156.6           394.58     
    0.48 sec     2330.5       59.356      1          281.84           1112.8           433.27     
    0.52 sec     2344.5       59.302      1          281.19           1073.1           470.53     
    0.56 sec     2359.1       59.248      1          279.77           1032.9           506.43     
    0.6 sec      2376.4       59.195      1          277.89           993.97           540.92     
      ⋮

将更新后的数据写回同一通道组

将更新后的数据写入 VehicleData.mf4 的通道组 1,这需要 MDF 文件的修改权限。检查您是否拥有 MDF 文件的写入访问权限。如果没有,请使 MDF 文件可写。

[~, values] = fileattrib("VehicleData.mf4");
if ~values.UserWrite
    fileattrib("VehicleData.mf4", "+w")
end

调用函数 mdfWrite,将可选参量 GroupNumber 设置为 1,用 chanGrp1TT 中更新后的数据覆盖通道组 1。

mdfWrite("VehicleData.mf4", chanGrp1TT, GroupNumber=1)
Warning: Channel "Brake" removed while overwriting an existing channel group. Data of the corresponding channel will be erased but the channel will still exist.
Warning: Channel "VehicleSpeed" removed while overwriting an existing channel group. Data of the corresponding channel will be erased but the channel will still exist.

在前一步骤中,从时间表 chanGrp1TT 中删除了 BrakeVehicleSpeed 这两个变量。但是,由于 MDF 是二进制文件格式,更改通道组结构体会导致文件损坏。因此,无法真正从现有通道组中删除通道。删除的通道的数据被擦除,但这些通道仍存在于通道组中。

检查数据

要验证数据是否已成功写入文件,请使用 mdfRead 只读取通道组 1 中不带元数据的数据。检查变量 Gear 中更新后的值。另请注意,对于已删除的变量 BrakeVehicleSpeed,值已擦除并重置为零。

chanGrp1DataNew = mdfRead("VehicleData.mf4", GroupNumber=1)
chanGrp1DataNew = 1x1 cell array
    {751x8 timetable}

chanGrp1TTNew = chanGrp1DataNew{1}
chanGrp1TTNew=751×8 timetable
      time      EngineRPM    Brake    Throttle    Gear    ImpellerTorque    OutputTorque    TransmissionRPM    VehicleSpeed
    ________    _________    _____    ________    ____    ______________    ____________    _______________    ____________

    0 sec          1000        0           60      1          52.919           282.65                0              0      
    0.04 sec     1383.3        0       59.946      1           101.4           532.63           13.593              0      
    0.08 sec     1685.4        0       59.893      1          150.76           776.41           35.847              0      
    0.12 sec     1907.2        0       59.839      1          193.42           973.15           65.768              0      
    0.16 sec       2062        0       59.785      1          227.02           1117.6           101.53              0      
    0.2 sec      2161.2        0       59.732      1          251.11           1212.8           141.45              0      
    0.24 sec     2221.4        0       59.678      1          267.24           1264.3           183.86              0      
    0.28 sec     2257.2        0       59.624      1          276.35           1271.2           227.25              0      
    0.32 sec     2278.7        0        59.57      1          281.99           1259.5           270.52              0      
    0.36 sec     2292.4        0       59.517      1          283.39             1229           313.08              0      
    0.4 sec      2305.1        0       59.463      1          283.29           1193.4           354.43              0      
    0.44 sec     2317.4        0       59.409      1          282.91           1156.6           394.58              0      
    0.48 sec     2330.5        0       59.356      1          281.84           1112.8           433.27              0      
    0.52 sec     2344.5        0       59.302      1          281.19           1073.1           470.53              0      
    0.56 sec     2359.1        0       59.248      1          279.77           1032.9           506.43              0      
    0.6 sec      2376.4        0       59.195      1          277.89           993.97           540.92              0      
      ⋮