Main Content

本页翻译不是最新的。点击此处可查看最新英文版本。

记录和回放 CAN 报文

以下示例说明如何在 Simulink® 中使用 MathWorks® 虚拟 CAN 通道记录和回放 CAN 报文。您可以更新此模型以连接到您的系统上支持的硬件。

从示例文件夹中的 SourceMsgs.mat 文件加载保存的 CAN 报文。该文件包含 CAN 报文,这些报文表示绕试车道一周 90 秒的驾驶循环。

load SourceMsgs.mat

或者,使用 blfread 函数从 BLF 文件中读取 CAN 报文。请注意,输出是标量元胞,因此需要从该元胞中提取时间表。

canMsgTimetable = blfread("SourceMsgs.blf");
canMsgTimetable = canMsgTimetable{1};

通过 mdfRead 函数,可以使用类似的方法从 MDF 文件中读取。

请注意,所记录报文的初始时间戳不为零:

startTime = seconds(canMsgTimetable.Time(1))
startTime = 88.6176
stopTime = seconds(canMsgTimetable.Time(end))
stopTime = 177.2310

定义 0.01 秒的仿真时间步,并根据该时间步对 startTimestopTime 的值进行舍入。

Ts = 0.01;
startTime = round(startTime, 2);
stopTime = round(stopTime, 2);

将报文转换为与 CAN Replay 模块兼容的格式,并将它们保存到一个单独的文件中。

canMsgs = canMessageReplayBlockStruct(canMsgTimetable);
save DriveReplay.mat canMsgs
whos
  Name                      Size               Bytes  Class        Attributes

  Ts                        1x1                    8  double                 
  canMsgTimetable      100000x8             33510851  timetable              
  canMsgs                   1x1              2401176  struct                 
  startTime                 1x1                    8  double                 
  stopTime                  1x1                    8  double                 

CAN Replay 模型

该模型包含:

  • 一个 CAN Replay 模块,用于向 MathWorks Virtual Channel 1 传输报文。

  • 一个 CAN Receive 模块,用于通过 MathWorks Virtual Channel 2 接收 CAN 网络上的报文。

CAN Receive 模块配置为阻止所有扩展 ID,并且仅允许具有标准 ID 1200WheelSpeed 报文通过。

配置与 CAN 报文时间序列一致的模型参数。点击建模选项卡,然后点击配置参数。在求解器窗格中,在对应的编辑字段中使用 startTimestopTimeTs 变量,如图所示。

点击确定以应用更改并关闭窗口。

Wheel Speeds 子系统

Wheel Speeds 子系统对收到的 CAN 报文中的轮速信息解包,并将它们绘制到示波器中。该子系统还将报文记录到一个文件中。

可视化轮速信息

点击运行以运行仿真。根据您的计算机配置,示波器中显示的输出可能为零。

此结果与预期相符:模型仿真和报文传输在单独的线程中执行,因此它们并不同步。Simulink 会尝试尽可能快地执行仿真,但提供的时间序列很短;因此,在仿真完成之前,很可能第一条报文的传输尚未开始。

要回放记录的信号,更好的方法是使用仿真调速,因为这会减慢模型执行速度,以实现近实时的仿真。要激活仿真调速,请点击运行 -> 仿真调速,然后通过勾选框激活选项。再次运行仿真,然后在试驾期间可视化所有车轮的轮速。

demoVNTSL_CANReplayAndLog_Scope.png

加载包含所记录报文的文件

每次运行模型时,CAN Log 模块都会创建一个唯一文件。在 MATLAB® 命令行窗口中使用 dir 查找最新日志文件。

dir WheelSpeeds*.mat
WheelSpeeds_2023-Jun-20_150142.mat  
load WheelSpeeds_2023-Jun-20_150142.mat
whos
  Name                      Size               Bytes  Class        Attributes

  Ts                        1x1                    8  double                 
  canMsgTimetable      100000x8             33510851  timetable              
  canMsgs                   1x1              2401176  struct                 
  outMsgs                   1x1               240528  struct                 
  startTime                 1x1                    8  double                 
  stopTime                  1x1                    8  double                 

转换记录的报文

使用之前定义的 startTime 变量偏移记录的时间戳。

outMsgs.Timestamp = startTime + outMsgs.Timestamp;

使用 canMessageTimetable 将仿真期间记录的报文转换为可在命令行窗口中使用的时间表。

要直接访问报文信号,请在转换中使用对应的数据库文件以及 canSignalTimetable

然后使用绘图函数可视化信号,并将它们与仿真输出进行比较。

db = canDatabase('VehicleInfo.dbc');
wheelSpeedMsgTimetable = canMessageTimetable(outMsgs, db);
wheelSpeedMsgTimetable(1:15, :)
ans=15×8 timetable
       Time        ID     Extended         Name                     Data                Length      Signals       Error    Remote
    __________    ____    ________    _______________    ___________________________    ______    ____________    _____    ______

    88.912 sec    1200     false      {'WheelSpeeds'}    {[39 16 39 16 39 16 39 16]}      8       {1x1 struct}    false    false 
    88.92 sec     1200     false      {'WheelSpeeds'}    {[39 16 39 16 39 16 39 16]}      8       {1x1 struct}    false    false 
    88.929 sec    1200     false      {'WheelSpeeds'}    {[39 16 39 16 39 16 39 16]}      8       {1x1 struct}    false    false 
    88.939 sec    1200     false      {'WheelSpeeds'}    {[39 16 39 16 39 16 39 16]}      8       {1x1 struct}    false    false 
    88.947 sec    1200     false      {'WheelSpeeds'}    {[39 16 39 16 39 16 39 16]}      8       {1x1 struct}    false    false 
    88.957 sec    1200     false      {'WheelSpeeds'}    {[39 16 39 16 39 16 39 16]}      8       {1x1 struct}    false    false 
    88.965 sec    1200     false      {'WheelSpeeds'}    {[39 16 39 16 39 16 39 16]}      8       {1x1 struct}    false    false 
    88.974 sec    1200     false      {'WheelSpeeds'}    {[39 16 39 16 39 16 39 16]}      8       {1x1 struct}    false    false 
    88.982 sec    1200     false      {'WheelSpeeds'}    {[39 16 39 16 39 16 39 16]}      8       {1x1 struct}    false    false 
    88.99 sec     1200     false      {'WheelSpeeds'}    {[39 16 39 16 39 16 39 16]}      8       {1x1 struct}    false    false 
    88.999 sec    1200     false      {'WheelSpeeds'}    {[39 16 39 16 39 16 39 16]}      8       {1x1 struct}    false    false 
    89.007 sec    1200     false      {'WheelSpeeds'}    {[39 16 39 16 39 16 39 16]}      8       {1x1 struct}    false    false 
    89.016 sec    1200     false      {'WheelSpeeds'}    {[39 16 39 16 39 16 39 16]}      8       {1x1 struct}    false    false 
    89.024 sec    1200     false      {'WheelSpeeds'}    {[39 16 39 16 39 16 39 16]}      8       {1x1 struct}    false    false 
    89.033 sec    1200     false      {'WheelSpeeds'}    {[39 16 39 16 39 16 39 16]}      8       {1x1 struct}    false    false 

wheelSpeedSignals = canSignalTimetable(wheelSpeedMsgTimetable);
wheelSpeedSignals(end-14:end, :)
ans=15×4 timetable
       Time       LR_WSpeed    RR_WSpeed    RF_WSpeed    LF_WSpeed
    __________    _________    _________    _________    _________

    177.38 sec      56.73        56.73        56.61        56.65  
    177.39 sec      56.76        56.69        56.64        56.66  
    177.4 sec       56.74        56.66        56.62        56.65  
    177.41 sec      56.72        56.73        56.56        56.64  
    177.42 sec      56.76        56.76        56.57        56.66  
    177.43 sec      56.78        56.69        56.66        56.72  
    177.44 sec      56.82        56.74        56.72        56.74  
    177.45 sec      56.85        56.81        56.77        56.72  
    177.45 sec      56.79        56.81        56.79        56.69  
    177.46 sec      56.76        56.83        56.78        56.66  
    177.47 sec      56.74        56.79        56.74        56.66  
    177.48 sec       56.7        56.74        56.68        56.69  
    177.49 sec      56.76        56.77        56.69        56.72  
    177.5 sec       56.76        56.81        56.72        56.77  
    177.51 sec      56.65        56.83        56.68        56.77  

plot(wheelSpeedSignals.Time, wheelSpeedSignals{:,:});

Figure contains an axes object. The axes object contains 4 objects of type line.

此示例中使用了 MathWorks CAN 虚拟通道。但是,您可以将模型连接到其他支持的硬件。

另请参阅

工具

相关示例

详细信息