CANoe仿真工程开发

news2024/9/28 23:38:33

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
    • 一、网络拓扑图
    • 二、数据库文件设计
    • 四、Panel设计
    • 五、CAPL代码实现
    • 六、Automation Sequences
    • 七、分析窗口设置
    • 八、Trace窗口与Logging
    • 九、Desktop布局
    • 十、工程运行测试


前言

继续学习《CANoe开发从入门到精通》,实现第二个例程。

由于篇幅原因,且在《一步一步动手实现CANoe例程》中有详细的步骤,本例程中数据库文件设计、系统变量及Panel设计就不再面面俱到的展开。

例程主要实现的功能如下:
(1)控制面板:通过调节钥匙锁车/开锁按钮、引擎钥匙旋钮、离合器档位切换、刹车模拟开关、危险警示灯按钮、左转右转按钮、引擎速度滑动条和车速滑动条等控件,模拟IPC需要的测试条件。
(2)显示面板:接收来自总线的报文,显示引擎信息、车速信息、离合器档位信息和车灯的状态等。
(3)添 加 Automation Sequences 功 能 实 现 Signal 和 System Variable的自动变化。
(4)添加Graphic窗口和State Tracker追踪窗口等,便于分析和检测等相关活动。

一、网络拓扑图

网络由仪表单元(IPC)、网关(Gateway)、车身控制器(BCM)三部分组成;
网络拓扑如下图所示:
在这里插入图片描述

二、数据库文件设计

1、以Vector_IL_Basic Template为模板创建一个名称为VehicleSystem的CAN数据库。将它的Protocol设置为CAN。

2、右击Network Nodes,新建BCM、IPC、Gateway三个网络节点。如下图所示:
在这里插入图片描述

3、右击Message,新建报文,参数设置如下所示:
在这里插入图片描述

4、右击Signal,新建信号,参数设置如下所示:
在这里插入图片描述
5、在CANdb++工具栏上,单击Value Tables图标,进入Value Tables界面,在空白处右击,创建Value Table如下:
在这里插入图片描述

在Value Descriptions中参数设置如下所示:
在这里插入图片描述
至此,例程需要的DBC文件已经完成,将其导入仿真工程后如下所示:
在这里插入图片描述
三、设置系统变量
1、在CANoe主界面中选择Environment→System Variables,在左上侧空白窗口中单击鼠标右键系统变量,需要定义的系统变量列表及属性设置如下:
在这里插入图片描述
2、部分变量需要自己实现Value Table,
在这里插入图片描述

以Gear_Status为例,Value Table实现方法如下:
2.1、Values Table下拉选择Custom,如下图所示:
在这里插入图片描述
2.2、点击Value Table Items右侧的图标,进入Value Table编辑界面,如下图所示:
在这里插入图片描述
修改Value和Description为需要设置的值,如下所示:
在这里插入图片描述
完成后如下所示:
在这里插入图片描述

四、Panel设计

需要设计两个面板,用于模拟相关操作和数据的显示。
注意,以下列出的控件属性均为重要属性,未提及的属性将采用默认设置。

1、control面板主要用于模拟来自实际中BCM和Gateway的相关操作,面板的设计效果如下图所示:
在这里插入图片描述
控件列表及重要属性按照《CANoe开发从入门到精通》第292页来设定。

2、IPC面板主要用于模拟实际的仪表盘显示功能,设计效果如下图所示:
在这里插入图片描述
控件列表及重要属性按照《CANoe开发从入门到精通》第297页来设定。
设计时的图片素材在CANoe提供的Sample Configurations 16.4.4文件夹下搜索而来,部分素材和书上例程素材不同,稍作修改即可。
比如,引擎温度显示,书上例程左侧还有个温度刻度表,设计时选择Meter 1。我搜的图片没有,就加个简单的Input/Output Box 1来显示。

五、CAPL代码实现

1、IPC.can
IPC.can主要实现了报文的发送机制。当车在锁车状态时,报文不能通过IL层发送,解锁后周期性报文便可以通过IL层发送出去。

/*@!Encoding:936*/
includes
{
  
}

variables
{
  int busflag = 0;
}

on preStart
{
  ILControlInit();
  ILControlStop();
}

on signal_update LockStatus
{
  if(this!=busflag)
  {
    if(this==1)
    {
      ILControlStart();
    }
    else if(this==0)
    {
      ILControlStop();
    }
    busflag = this;
  }
}

on signal_update Gear
{
  @Cluster::Gear_Status = this;
}

2、BCM.can
在BCM.can中主要实现了转向灯的动态闪烁;

/*@!Encoding:936*/
includes
{
  
}

variables
{
  msTimer msTcrank;
  msTimer msTIL;
  int flashPeriod=500;
  
  int turnLightStatus;
  
  msTimer msTleftflash,msTrightflash;
  message Driver_Info Msgdriver;
}

on preStart
{
  ILControlInit();
  ILControlStop();
}

on sysvar_update Vehicle_Key::Key_State
{
  $Ignition_Info::KeyState=@this;
  if(@this==3)
  {
    @Vehicle_Control::Speed_Up=0;
    setTimer(msTcrank, 800);
  }
}

on timer msTcrank
{
  $KeyState=2;
  @sysvar::Vehicle_Key::Key_State=2;
}

on sysvar_update Vehicle_Key::Car_Driver
{
  if(@this==1)
  {
    Msgdriver.byte(0)=0;
  }
  else if(@this==2)
  {
    Msgdriver.byte(0)=0x1;
  }
  output(Msgdriver);
}

on sysvar_update Vehicle_Key::Unlock_Car
{
  if(@this==1)
  {
    ILControlStart();
    $LockStatus=1;
    @Vehicle_Key::Car_Driver=2;
  }
}
on sysvar_update Vehicle_Key::Lock_Car
{
  if(@this==1)
  {
    $LockStatus=0;
    setTimer(msTIL,1500);
  }
}

on timer msTIL
{
  ILControlStop();
}

void LightOFF(void)
{
  $VehicleLight=0;
  turnLightStatus=0;
  $LightStatus=0;
}

on sysvar Vehicle_Control::Left_Turn_Enable
{
  if(@this==1)
  {
    @sysvar::Vehicle_Control::Right_Turn_Enable=0;
    $VehicleLight=1;
    turnLightStatus=1;
    settimer(msTleftflash,flashPeriod);
  }
  else
  {
    if(@Vehicle_Control::Right_Turn_Enable==0 && @Vehicle_Control::Hazards_Enable==0)
    {
      LightOFF();
    }
    cancelTimer(msTleftflash);
    @Cluster::Left_Turn_Indicator=0;
  }
}

on timer msTleftflash
{
  $LightStatus=!$LightStatus;
  @Cluster::Left_Turn_Indicator=!@Cluster::Left_Turn_Indicator;
  setTimer(msTleftflash,flashPeriod);
}

on sysvar Vehicle_Control::Right_Turn_Enable
{
  if(@this==1)
  {
    @sysvar::Vehicle_Control::Left_Turn_Enable=0;
    $VehicleLight=2;
    turnLightStatus=2;
    setTimer(msTrightflash,flashPeriod);
  }
  else
  {
    if(@Vehicle_Control::Left_Turn_Enable==0 && @Vehicle_Control::Hazards_Enable==0)
    {
      LightOFF();
    }
    
    cancelTimer(msTrightflash);
    @Cluster::Right_Turn_indicator=0;
  }
}

on timer msTrightflash
{
  $LightStatus=!$LightStatus;
  @Cluster::Right_Turn_indicator=!@Cluster::Right_Turn_indicator;
  settimer(msTrightflash,flashPeriod);
}

on sysvar Vehicle_Control::Hazards_Enable
{
  if(@this==1)
  {
    $VehicleLight=3;
    @Cluster::Left_Turn_Indicator=1;
    @Cluster::Right_Turn_indicator=1;
    setTimer(msTleftflash,flashPeriod);
    setTimer(msTrightflash,flashPeriod);
  }
  else
  {
    $VehicleLight=turnLightStatus;
    switch(turnLightStatus)
    {
      case 1:
        cancelTimer(msTrightflash);
        @Cluster::Right_Turn_indicator=0;
        break;
      case 2:
        cancelTimer(msTleftflash);
        @Cluster::Left_Turn_Indicator=0;
        break;
      case 0:
        cancelTimer(msTrightflash);
        cancelTimer(msTleftflash);
        $LightStatus=0;
        @Cluster::Right_Turn_indicator=0;
        @Cluster::Left_Turn_Indicator=0;
        break;
    }
  }
}

3、Gateway.can
Gateway.can 中 , 根 据 Automation Sequences 中 System variable的变化,动态改变车速、引擎转速、油温和油量的值。该程序中车速、引擎转速、油温、油量变化因子只是为了配合Panel面板中可变化范围或可视化效果而增加的。

/*@!Encoding:936*/
includes
{
  
}

variables
{
  msTimer msTVehSpeedDown;
  msTimer msTEngSpeedDown;
  dword WritePage;
  int busflag=0;
}

on preStart
{
  ILControlInit();
  ILControlStop();
  writeLineEx(WritePage,1,"--------This demo demonstrated the CAN bus suimulation!!--------");
  writeLineEx(0,1,"Press <1> to start/stop CAN_logging");
}

on key '1'
{
  int flag;
  if(flag==0)
  {
    flag=1;
    write("CAN logging starts");
    startlogging("CAN_Logging",500);
  }
  else
  {
    flag=0;
    write("CAN logging ends");
    stopLogging("CAN_Logging",1000);
  }
}

on signal_update LockStatus
{
  if(this!=busflag)
  {
    if(this==1)
    {
      ILControlStart();
    }
    else if(this==0)
    {
      ILControlStop();
    }
    busflag=this;
  }
}

on sysvar Vehicle_Control::Gear
{
  $Gear=@this;
}

void EngineData_Init(void)
{
  $VehicleSpeed=0;
  $EngSpeed=0;
  $EngTemp=0;
  $PetrolLevel=0;
}

on signal_update KeyState
{
  if(this==0)
  {
    EngineData_Init();
  }
  if(this>0)
  {
    $PetrolLevel=255;
  }
}

on sysvar_update Vehicle_Control::Eng_Speed
{
  if(@Vehicle_Key::Key_State==2)
  {
    $EngineData::EngSpeed=@this;
  }
  else
    $EngineData::EngSpeed=0;
}

on sysvar_update Vehicle_Control::Veh_Speed
{
  if((@Vehicle_Control::Gear==3)&&(@Vehicle_Key::Key_State==2))
  {
    $VehicleData::VehicleSpeed=@this;
  }
  else
  {
    $VehicleData::VehicleSpeed=0;
  }
}

on sysvar_update Vehicle_Control::Speed_Up
{
  if(@this<50)
  {
    $EngTemp=@this*1.5;
  }
  else
  {
    $EngTemp=75;
  }
  if(@this<30)
  {
    $PetrolLevel=@this*8.5;
  }
  else
  {
    $PetrolLevel=255;
  }
  $VehicleSpeed=@this;
  $EngSpeed=@this*40;
  if(@this>120)
  {
    @this=60;
  }
}

on sysvar Vehicle_Control::Brake
{
  int i;
  if(@this==1)
  {
    $GearLock=0;
    setTimer(msTVehSpeedDown,20);
    setTimer(msTEngSpeedDown,2);
  }
  else
  {
    $GearLock=1;
    cancelTimer(msTVehSpeedDown);
    cancelTimer(msTEngSpeedDown);
  }
}

on timer msTVehSpeedDown
{
  @Vehicle_Control::Veh_Speed=@Vehicle_Control::Veh_Speed-1;
  setTimer(this,50);
  if(@Vehicle_Control::Veh_Speed<=0)
  {
    cancelTimer(msTVehSpeedDown);
    @Vehicle_Control::Veh_Speed=0;
  }
}

on timer msTEngSpeedDown
{
  @Vehicle_Control::Eng_Speed=@Vehicle_Control::Eng_Speed-40;
  setTimer(this,50);
  if(@Vehicle_Control::Eng_Speed<=0)
  {
    cancelTimer(msTEngSpeedDown);
    @Vehicle_Control::Eng_Speed=0;
  }
}

书上的程序,下图红框的判断觉得有点问题,做了修改
在这里插入图片描述

六、Automation Sequences

利用Automation Sequences,可以方便地实现system variables、environment variables或者signals的变化事件序列,同时也可以检查、判断当前变量或信号的值。在本实例中,创建一个名为Vehicle的Automation Sequences,其主要功能是改变变量的值来触发特定的功能。

在CANoe主界面,选择Simulation→Automation,在弹出的菜单Visual Sequences下空白处单击鼠标右键并在菜单中选择New,输入该Sequences的名称为Vehicle。单击工具栏中的Edit图标,开始编辑该Sequence。按照下表参数来设定:
在这里插入图片描述
在工具栏中单击RepeatSequence periodically图标在这里插入图片描述和Start Sequence on measurement start图标在这里插入图片描述使Vehicle自动序列能够在开始测量后自动循环运行。

七、分析窗口设置

1.Graphics窗口
在 CANoe 主界面选择 Analysis→Graphics→New GraphicWindow,输入名称为Signal Observe。该窗口左边信号列表栏中单
击选择Add Signals,在弹出的窗口中选择信号KeyState,同样地加入信号VehicleLight和VehicleSpeed。在Signal Observe窗口工具栏中单击Select y-axis view图标在这里插入图片描述 ,在下拉表中选中Show All Y-Axis,这样上面添加的三个Signal就将显示在同一窗口中,如下图所示:
在这里插入图片描述
鼠标滚轮可以放大缩小坐标刻度,调整好坐标,方便后续观察。

2、State Tracker窗口

在 CANoe 菜 单 栏 中 选 择 Analysis→State Tracker→New State Tracker Window,输入名称为Signal State。在该窗口左边信号列表栏中单击鼠标右键并在菜单中选择Add Variables,添加系统变量Vehicle_Control中的Gear和Brake。在该窗口左边信号列表栏中单击鼠标右键并在菜单中选择Add Database Objects→Signals,添加信号VehicleLight ,如下图所示:
在这里插入图片描述
3、Data窗口
Data窗口中可以添加信号和系统变量,此例添加了Driver、EngSpeed、EngTemp、KeyState和VehicleSpeed五个信号,以及Left_Turn_Enable、
Right_Turn_Enable、Key_State和Gear_Status四个系统变量,如下图所示:
在这里插入图片描述

八、Trace窗口与Logging

Trace窗口帮助用户实时查看和分析总线上的数据。Logging记录下了整个仿真过程中的数据,在大数据量或长时间的测试情况下,使得用户可以在离线状态下查看总线的活动情况,同时,Logging功能记录的数据可以在CANoe中进行回放,对于总线上问题的复现起到了十分重要的作用。

在CANoe主界面下,进入Analysis选项卡,在Measurement Setup窗口中设置Trace窗口、Logging窗口。

1、右键Logging,选择Name,更名为CAN_Logging。设置Configuration,设置参数如下:
在这里插入图片描述
Logging右侧箭头指向一个Logging文件加,可以设置Logging文件保存位置。

2、创建CAN_Trace的Trace模块。

九、Desktop布局

点击下图红箭头所指,可以新增Desktop。
在这里插入图片描述
1、添加一个名为CAN的Desktop布局,将Control和IPC两个面板加进去,并设定为MDI Windows模式。同时添加Write窗口和Test Automation Sequences窗口,都设定为MDI Windows模式。布局好后效果图如下:
在这里插入图片描述

2、在Analysis的Desktop布局中添加Data、CAN Statistics、Signal State Tracker和Signal Observe等窗口
在这里插入图片描述
3、在Configuration的Desktop布局视图中保留Simulation Setup和Measurement Setup窗口,如下图所示:
在这里插入图片描述
4、在Trace的Desktop布局视图中保留Write、CAN Trace和Trace窗口,如下图所示:
在这里插入图片描述

十、工程运行测试

回到CANoe的Home界面,设置为仿真环境,点击Start开始仿真测试,结果如下:

CANoe仿真工程开发演示

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/349322.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【算法 | 例题简答】相关例题讲解

目录 简答题 计算题 时间复杂度的计算 递归算法计算 背包问题&#xff08;0-1背包问题&#xff09; 回溯法 动态规划法 编程题 用回溯法解方程 动态规划法解决蜘蛛吃蚊子 用分治法解决抛硬币问题 用二分法分两边求最大值 简答题 1、什么是算法&#xff1f;算法有哪…

Revit问题:Navisworks中导入的rvt模型角度不正确调整

一、Navisworks中导入的rvt模型角度不正确调整方法 通常情况下&#xff0c;我们做好一个Revit模型&#xff0c;有时候出于成果保护或者鉴于Revit自带的碰撞检测效果不够直观、Revit模型体量太大&#xff0c;需要一个轻量化的模型展示&#xff0c;我们通常情况下会使用Autodesk公…

【python】基于Socket的聊天室Python开发

基于Socket的聊天室Python开发一、Socket简述二、创建服务端Server2.1 创建服务端初始化2.2 监听客户端连接2.3 处理客户端消息三、创建客户端Client3.1 创建服务端初始化3.2 发送消息3.3 接收消息3.3 线程工作3.4 线程工作是不是挺好玩的呢&#xff1f;也可以作为课程设计哦&a…

【C++】Expression的学习笔记

关于不同类别表达式的举例&#xff0c;请参考博文《C 中的值类别》 1. 左值和右值的简单理解 左值对应了具有内存地址的对象&#xff0c;而右值仅仅是临时使用的值对象。&#xff08;引用自博文《C 中的值类别》&#xff09;左值有名称&#xff08;变量或常量名称&#xff09…

RFC7519规范-JWT - json web token

简介 什么是JWT(JSON Web Token) 在介绍JWT之前&#xff0c;我们先来回顾一下利用token进行用户身份验证的流程&#xff1a; 客户端使用用户名和密码请求登录服务端收到请求&#xff0c;验证用户名和密码验证成功后&#xff0c;服务端会签发一个token&#xff0c;再把这个to…

mybatis-spring-boot-starter中设定多数据源,并实现Durid的监控

实现功能&#xff1a; 1&#xff1a; 配置两个数据源&#xff0c;根据不同的mapper路径使用不同的数据连接 2 &#xff1a;使用Druid连接池 3&#xff1a;Druid 可监控多个数据源的sql执行操作 分析&#xff1a; 查看mybatis_spring_boot_stater中关于自动装配的类可知【如上…

基于动力学模型的无人驾驶车辆主动转向控制

章五 基于动力学模型的无人驾驶车辆主动转向控制 主动转向控制联合仿真 基于动力学模型的无人驾驶车辆主动转向控制 无人驾驶车辆模型预测控制第五章&#xff08;上&#xff09; 无人驾驶车辆模型预测控制第五章&#xff08;下&#xff09; 北理工无人驾驶车辆模型预测控制第4…

测试新版Android Studio的手机镜像效果

学更好的别人&#xff0c; 做更好的自己。 ——《微卡智享》 本文长度为669字&#xff0c;预计阅读2分钟 前言 春节刚上班&#xff0c;就开始了疯狂出差的节奏&#xff0c;期间发现Android Studio发布新的版本2022.1.1(Electric Eel)&#xff0c;里面两个更新的内容蓝牙模拟器和…

ChatGPT 帮我自动编写 Python 爬虫脚本

都知道最近ChatGPT聊天机器人爆火&#xff0c;我也想方设法注册了账号&#xff0c;据说后面要收费了。 ChatGPT是一种基于大语言模型的生成式AI&#xff0c;换句话说它可以自动生成类似人类语言的文本&#xff0c;把梳理好的有逻辑的答案呈现在你面前&#xff0c;这完全不同于…

2023美赛数学建模资料思路模型

美赛我们为大家准备了大量的资料&#xff0c;我们会在比赛期间给大家分析美题目和相关的思路 全文都是干货&#xff0c;大家仔细阅读&#xff0c;资料文末自取&#xff01; 首先我们来看美赛23年题型的一个变化&#xff1a; 美赛23年题目变化&#xff1a; A题&#xff1a;连…

【C语言】初识指针

目录 一、指针是什么 二、指针和指针类型 三、野指针 四、指针运算 五、指针和数组 六、二级指针 七、指针数组 一、指针是什么 指针就是内存地址&#xff0c;指针变量是用来存放内存地址的变量&#xff0c;在同一CPU构架下&#xff0c;不同类型的指针变量所占用的存储单元长度…

2023年2月的十篇深度学习论文推荐

本月的论文包括语言模型、扩散模型、音乐生成、多模态等主题。 1、MusicLM: Generating Music From TextPage https://arxiv.org/abs/2301.11325 By Andrea Agostinelli, Timeo I. Denk, et al. 扩散模型和自回归离散模型都在生成音乐/音频显示出令人印象深刻的性能。 与最…

第45期:一条 SQL 语句优化的基本思路

SQL 语句优化是一个既熟悉又陌生的话题。面对千奇百怪的 SQL 语句&#xff0c;虽然数据库本身对 SQL 语句的优化一直在持续改进、提升&#xff0c;但是我们不能完全依赖数据库&#xff0c;应该在给到数据库之前就替它做好各种准备工作&#xff0c;这样才能让数据库来有精力做它…

FreeMarker生成word文档,固定word模板

该方法也就是通过freemarker生成固定的word文档&#xff0c;动态的word模板布局不能用该方法。 也就是必须有一个固定的模板文档是.ftl类型 如果初始文件为 需要手动改为&#xff1a; 也就是所有需要替换的地方&#xff0c;都需要有${XX}替换。 主要步骤为&#xff1a; 将 w…

JVM学习8: 字符串

基本特性 代表不可变字符序列final不可被继承实现了Serializable、Comparable等接口jdk8及以前使用final char[]存储&#xff0c;jdk9开始改为使用byte[]存储通过字面量方式给一个字符串变量赋值&#xff0c;此时字符串对象在字符串常量池里面 字符串常量池 字符串常量池不会…

《论文阅读》PAL: Persona-Augmented Emotional Support Conversation Generation

《论文阅读》PAL: Persona-Augmented Emotional Support Conversation Generation 前言简介思路出发点相关知识coefficient of determination任务定义模型框架实验结果前言 你是否也对于理解论文存在困惑? 你是否也像我之前搜索论文解读,得到只是中文翻译的解读后感到失望?…

企企通:企业供应商风险管理,如何用采购管理软件赋能?

企业采购过程中&#xff0c;最怕/最担心的事情无非是&#xff1a;供应链异常。供应链异常&#xff0c;也就是我们常说的供应链风险&#xff0c;可以简单分为需求风险、供应商风险、物流风险和财务风险四大类。其中&#xff0c;最为突出的风险便是供应商风险。从寻找合适的供应商…

用VSCode搭建Vue.js开发环境及Vue.js第一个应用

目录 一、VSCode安装 二、VSCode简单配置 三、Vue.js的下载和引入 四、Vue.js第一个应用 一、VSCode安装 Visual Studio Code是一个轻量级但功能强大的源代码编辑器&#xff0c;可在您的桌面上运行&#xff0c;可用于Windows&#xff0c;macOS和Linux。它内置了对JavaScrip…

阿里一P7员工为证明自己年入百万,晒出工资,却被网友...

阿里的工资在行业内确实是比较高的一类&#xff0c;之前网络上流传着阿里P7年入百万的消息也不是空穴来风&#xff0c;日前&#xff0c;有位阿里P7员工&#xff0c;为了证明自己的确年入百万&#xff0c;晒出了他的工资&#xff0c;网友们看完都沸腾了。什么情况&#xff1f;一…

BSN全球伙伴大会于本周五召开在即,重磅嘉宾演讲主题前瞻

“第三届区块链服务网络&#xff08;BSN&#xff09;全球合作伙伴大会”召开在即&#xff0c;将于2023年2月17日&#xff08;本周五&#xff09;在杭州市拱墅区举办。 BSN已邀请到来自国内外的行业专家学者与生态合作伙伴&#xff0c;与各界来宾就“建设数字中国”指导思想中的…