pyqt5通过CANoe COM Server来操作CANoe仿真工程

news2025/7/24 3:54:21

文章目录

  • 前言
  • 一、COM接口技术
  • 二、UI界面设计
  • 三、功能实现
  • 四、工程运行测试


前言

继续学习《CANoe开发从入门到精通》。
今天在《CANoe仿真工程开发》的基础上,开发实现pyqt5应用程序来操控CANoe工程。

一、COM接口技术

COM(Component Object Model,组件对象模型)是一种描述如何建立可动态互变组件的规范,此规范提供了为保证能够互相操作,客户端和组件应遵循的一些二进制和网络标准。通过这种标准将可以在任意两个组件之间进行通信,而不用考虑其所处的操作环境是否相同、使用的开发语言是否一致以及是否运行于同一台计算机。

从早期版本开始,CANoe就开始支持COM接口技术。通过COM Server可以实现以下功能:
(1)创建和修改CANoe的配置;
(2)实现测量的自动控制,如工程加载、开始或结束测量、开始测试模块等;
(3)与外部应用软件的数据交换,如读写信号、系统变量等;
(4)开发用户的自定义面板,实现自动化测试;
(5)远程控制CANoe进行测量;
(6)调用CANoe中自定义的CAPL函数。
CANoe COM Server对于大家熟悉的编程语言或脚本语言都有很好的支持,例如Visual Basic、Delphi、C/C++、C#、Python、LabVIEW、VBScript、JScript、Perl和VBA等。

在CANoe安装时,COM Server已经注册好了。如果安装文件夹有变,或者目前注册的CANoe版本不是用户所期望的。可以直接找到CANoe 的安装文件夹( 例 如 CANoe 16 SP4 64-bit 安 装 文 件 夹 D:\Program Files\Vector CANoe 16\Exec64 ) , 执 行RegisterComponents.exe。

二、UI界面设计

1、Pycharm新建工程;

2、右键,找到"External Tools",选择QT Designer,进入QT5的UI设计界面
在这里插入图片描述
3、添加相应的控件、设置好参数。最终的UI界面如下:
在这里插入图片描述
在这里插入图片描述

设计完成后,保存为CanoeDemo.ui。

4、回到PyCharm工程,CanoeDemo.ui文件,然后右键,找到"External Tools",选择PyUIC,将UI设计文件转换为CanoeDemo.py文件。
在这里插入图片描述
CanoeDemo.py文件如下:

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'CanoeDemo.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_CanoeDemo(object):
    def setupUi(self, CanoeDemo):
        CanoeDemo.setObjectName("CanoeDemo")
        CanoeDemo.resize(633, 508)
        CanoeDemo.setMouseTracking(True)
        CanoeDemo.setTabletTracking(True)
        CanoeDemo.setAutoFillBackground(True)
        self.groupBox = QtWidgets.QGroupBox(CanoeDemo)
        self.groupBox.setGeometry(QtCore.QRect(10, 0, 531, 111))
        self.groupBox.setObjectName("groupBox")
        self.lineEdit = QtWidgets.QLineEdit(self.groupBox)
        self.lineEdit.setGeometry(QtCore.QRect(20, 20, 401, 20))
        self.lineEdit.setObjectName("lineEdit")
        self.OpenButton = QtWidgets.QPushButton(self.groupBox)
        self.OpenButton.setGeometry(QtCore.QRect(440, 20, 75, 23))
        self.OpenButton.setObjectName("OpenButton")
        self.StartButton = QtWidgets.QPushButton(self.groupBox)
        self.StartButton.setGeometry(QtCore.QRect(170, 60, 75, 23))
        self.StartButton.setObjectName("StartButton")
        self.AutoButton = QtWidgets.QPushButton(self.groupBox)
        self.AutoButton.setGeometry(QtCore.QRect(300, 60, 75, 23))
        self.AutoButton.setObjectName("AutoButton")
        self.groupBox_2 = QtWidgets.QGroupBox(CanoeDemo)
        self.groupBox_2.setGeometry(QtCore.QRect(10, 120, 531, 191))
        self.groupBox_2.setTabletTracking(True)
        self.groupBox_2.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.groupBox_2.setAcceptDrops(True)
        self.groupBox_2.setObjectName("groupBox_2")
        self.LockButton = QtWidgets.QPushButton(self.groupBox_2)
        self.LockButton.setGeometry(QtCore.QRect(10, 30, 75, 23))
        self.LockButton.setObjectName("LockButton")
        self.UnlockButton = QtWidgets.QPushButton(self.groupBox_2)
        self.UnlockButton.setGeometry(QtCore.QRect(90, 30, 75, 23))
        self.UnlockButton.setObjectName("UnlockButton")
        self.Driver1Button = QtWidgets.QPushButton(self.groupBox_2)
        self.Driver1Button.setGeometry(QtCore.QRect(10, 60, 75, 23))
        self.Driver1Button.setObjectName("Driver1Button")
        self.Driver2Button = QtWidgets.QPushButton(self.groupBox_2)
        self.Driver2Button.setGeometry(QtCore.QRect(90, 60, 75, 23))
        self.Driver2Button.setObjectName("Driver2Button")
        self.LeftButton = QtWidgets.QPushButton(self.groupBox_2)
        self.LeftButton.setGeometry(QtCore.QRect(10, 110, 75, 23))
        self.LeftButton.setObjectName("LeftButton")
        self.RightButton = QtWidgets.QPushButton(self.groupBox_2)
        self.RightButton.setGeometry(QtCore.QRect(90, 110, 75, 23))
        self.RightButton.setObjectName("RightButton")
        self.HazardButton = QtWidgets.QPushButton(self.groupBox_2)
        self.HazardButton.setGeometry(QtCore.QRect(50, 140, 75, 23))
        self.HazardButton.setObjectName("HazardButton")
        self.IgniSlider = QtWidgets.QSlider(self.groupBox_2)
        self.IgniSlider.setGeometry(QtCore.QRect(300, 20, 22, 160))
        self.IgniSlider.setMaximum(3)
        self.IgniSlider.setPageStep(1)
        self.IgniSlider.setOrientation(QtCore.Qt.Vertical)
        self.IgniSlider.setObjectName("IgniSlider")
        self.GearSlider = QtWidgets.QSlider(self.groupBox_2)
        self.GearSlider.setGeometry(QtCore.QRect(430, 20, 22, 160))
        self.GearSlider.setMouseTracking(False)
        self.GearSlider.setTabletTracking(True)
        self.GearSlider.setMaximum(3)
        self.GearSlider.setPageStep(1)
        self.GearSlider.setProperty("value", 0)
        self.GearSlider.setSliderPosition(0)
        self.GearSlider.setOrientation(QtCore.Qt.Vertical)
        self.GearSlider.setObjectName("GearSlider")
        self.label = QtWidgets.QLabel(self.groupBox_2)
        self.label.setGeometry(QtCore.QRect(460, 170, 54, 12))
        self.label.setObjectName("label")
        self.label_2 = QtWidgets.QLabel(self.groupBox_2)
        self.label_2.setGeometry(QtCore.QRect(460, 120, 54, 12))
        self.label_2.setObjectName("label_2")
        self.label_3 = QtWidgets.QLabel(self.groupBox_2)
        self.label_3.setGeometry(QtCore.QRect(460, 70, 54, 12))
        self.label_3.setObjectName("label_3")
        self.label_4 = QtWidgets.QLabel(self.groupBox_2)
        self.label_4.setGeometry(QtCore.QRect(460, 20, 54, 12))
        self.label_4.setObjectName("label_4")
        self.label_5 = QtWidgets.QLabel(self.groupBox_2)
        self.label_5.setGeometry(QtCore.QRect(400, 20, 31, 16))
        self.label_5.setObjectName("label_5")
        self.label_6 = QtWidgets.QLabel(self.groupBox_2)
        self.label_6.setGeometry(QtCore.QRect(330, 70, 54, 12))
        self.label_6.setObjectName("label_6")
        self.label_7 = QtWidgets.QLabel(self.groupBox_2)
        self.label_7.setGeometry(QtCore.QRect(250, 20, 54, 12))
        self.label_7.setObjectName("label_7")
        self.label_8 = QtWidgets.QLabel(self.groupBox_2)
        self.label_8.setGeometry(QtCore.QRect(330, 20, 54, 12))
        self.label_8.setObjectName("label_8")
        self.label_9 = QtWidgets.QLabel(self.groupBox_2)
        self.label_9.setGeometry(QtCore.QRect(330, 170, 54, 12))
        self.label_9.setObjectName("label_9")
        self.label_10 = QtWidgets.QLabel(self.groupBox_2)
        self.label_10.setGeometry(QtCore.QRect(330, 120, 54, 12))
        self.label_10.setObjectName("label_10")
        self.groupBox_3 = QtWidgets.QGroupBox(CanoeDemo)
        self.groupBox_3.setGeometry(QtCore.QRect(10, 320, 531, 121))
        self.groupBox_3.setObjectName("groupBox_3")
        self.label_11 = QtWidgets.QLabel(self.groupBox_3)
        self.label_11.setGeometry(QtCore.QRect(20, 30, 91, 16))
        self.label_11.setObjectName("label_11")
        self.label_12 = QtWidgets.QLabel(self.groupBox_3)
        self.label_12.setGeometry(QtCore.QRect(20, 80, 81, 16))
        self.label_12.setObjectName("label_12")
        self.VehSlider = QtWidgets.QSlider(self.groupBox_3)
        self.VehSlider.setGeometry(QtCore.QRect(110, 30, 160, 22))
        self.VehSlider.setMaximum(220)
        self.VehSlider.setSingleStep(5)
        self.VehSlider.setPageStep(10)
        self.VehSlider.setOrientation(QtCore.Qt.Horizontal)
        self.VehSlider.setObjectName("VehSlider")
        self.EngSlider = QtWidgets.QSlider(self.groupBox_3)
        self.EngSlider.setGeometry(QtCore.QRect(110, 80, 160, 22))
        self.EngSlider.setMaximum(5000)
        self.EngSlider.setSingleStep(10)
        self.EngSlider.setPageStep(40)
        self.EngSlider.setOrientation(QtCore.Qt.Horizontal)
        self.EngSlider.setObjectName("EngSlider")
        self.VehSpeedEdit = QtWidgets.QLineEdit(self.groupBox_3)
        self.VehSpeedEdit.setGeometry(QtCore.QRect(290, 30, 113, 20))
        self.VehSpeedEdit.setObjectName("VehSpeedEdit")
        self.EngSpeedEdit = QtWidgets.QLineEdit(self.groupBox_3)
        self.EngSpeedEdit.setGeometry(QtCore.QRect(290, 80, 113, 20))
        self.EngSpeedEdit.setObjectName("EngSpeedEdit")
        self.label_13 = QtWidgets.QLabel(self.groupBox_3)
        self.label_13.setGeometry(QtCore.QRect(420, 32, 54, 20))
        self.label_13.setObjectName("label_13")
        self.label_14 = QtWidgets.QLabel(self.groupBox_3)
        self.label_14.setGeometry(QtCore.QRect(420, 80, 54, 20))
        self.label_14.setObjectName("label_14")

        self.retranslateUi(CanoeDemo)
        QtCore.QMetaObject.connectSlotsByName(CanoeDemo)

    def retranslateUi(self, CanoeDemo):
        _translate = QtCore.QCoreApplication.translate
        CanoeDemo.setWindowTitle(_translate("CanoeDemo", "Form"))
        self.groupBox.setTitle(_translate("CanoeDemo", "应用控制"))
        self.OpenButton.setText(_translate("CanoeDemo", "打开CANoe"))
        self.StartButton.setText(_translate("CanoeDemo", "开始测量"))
        self.AutoButton.setText(_translate("CanoeDemo", "自动测量"))
        self.groupBox_2.setTitle(_translate("CanoeDemo", "系统变量"))
        self.LockButton.setText(_translate("CanoeDemo", "Lock"))
        self.UnlockButton.setText(_translate("CanoeDemo", "Unlock"))
        self.Driver1Button.setText(_translate("CanoeDemo", "Driver1"))
        self.Driver2Button.setText(_translate("CanoeDemo", "Driver2"))
        self.LeftButton.setText(_translate("CanoeDemo", "Leftturn"))
        self.RightButton.setText(_translate("CanoeDemo", "Rightturn"))
        self.HazardButton.setText(_translate("CanoeDemo", "Hazard"))
        self.label.setText(_translate("CanoeDemo", "P"))
        self.label_2.setText(_translate("CanoeDemo", "R"))
        self.label_3.setText(_translate("CanoeDemo", "N"))
        self.label_4.setText(_translate("CanoeDemo", "D"))
        self.label_5.setText(_translate("CanoeDemo", "Gear:"))
        self.label_6.setText(_translate("CanoeDemo", "RUN"))
        self.label_7.setText(_translate("CanoeDemo", "Ignition:"))
        self.label_8.setText(_translate("CanoeDemo", "CRANK"))
        self.label_9.setText(_translate("CanoeDemo", "OFF"))
        self.label_10.setText(_translate("CanoeDemo", "K15"))
        self.groupBox_3.setTitle(_translate("CanoeDemo", "GroupBox"))
        self.label_11.setText(_translate("CanoeDemo", "Vehicle Speed:"))
        self.label_12.setText(_translate("CanoeDemo", "Engine Speed:"))
        self.label_13.setText(_translate("CanoeDemo", "km/h"))
        self.label_14.setText(_translate("CanoeDemo", "rpm"))

到此,界面设计完成。

三、功能实现

1、通过打开CANoe按钮实现CANoe文件的选择、打开、和关闭。代码如下:

    def open_cfg(self):
        if self.OpenButton.text() == "打开CANoe":
            openfile_name = QFileDialog.getOpenFileName(self,'选择文件','','(*.cfg)')
            file_name = openfile_name[0]
            if file_name:
                print(file_name)
                self.App.Open(file_name)
                self.lineEdit.setText(file_name)
            else:
                print("Open CANoe error")
            self.OpenButton.setText("退出CANoe")
        elif self.OpenButton.text() == "退出CANoe":
            if self.App != None:
                self.App.Quit()
                self.App = None

            self.OpenButton.setText("打开CANoe")

实现效果如下:
在这里插入图片描述
2、开始测量按钮,实现仿真测试的开始、关闭。代码如下:

    def start(self):
        if self.StartButton.text() == "开始测量":
            self.App.Measurement.Start()
            self.StartButton.setText("停止测量")
        elif self.StartButton.text() == "停止测量":
            self.App.Measurement.Stop()
            self.StartButton.setText("开始测量")

3、其他按钮,主要实现操作总线信号和系统变量来实现控制CANoe的信号和系统变量。比如Lock按钮,先读取系统变量Lock_Car的值,再来设置它的值。代码如下:

    def lock(self):
        if(self.get_SysVar("Vehicle_Key","Lock_Car")==0):
            self.set_SysVar("Vehicle_Key","Lock_Car",1)
            time.sleep(1)
            self.set_SysVar("Vehicle_Key", "Lock_Car", 0)
        else:
            time.sleep(1)
            self.set_SysVar("Vehicle_Key", "Lock_Car", 0)

实现了UI这边点击一下Lock按钮,CANoe的钥匙上Lock图标变红,一秒后恢复。

4、自动测量,这个通过一个按钮实现了CANoe的Automation Sequences功能。
在这里插入图片描述
可以看后面的演示视频,Vehicle(Automation Sequences)的RepeatSequence periodically图标和Start Sequence on measurement start图标(如上红框)并未选中,就依次实现了上面的功能。

5、获取和设置系统变量,代码如下:

    def get_SysVar(self, ns_name, sys_name):
        if self.App != None:
            systemCAN = self.App.System.Namespaces
            sys_namespace = systemCAN(ns_name)
            sys_value = sys_namespace.Variables(sys_name)
            return sys_value.Value
        else:
            print("Unable to get EnvVar")

    def set_SysVar(self, ns_name, sys_name, value):
        if self.App != None:
            systemCAN = self.App.System.Namespaces
            sys_namespace = systemCAN(ns_name)
            sys_value = sys_namespace.Variables(sys_name)
            sys_value.Value = value
        else:
            print("Unable to set EnvVar")

四、工程运行测试

编译运行工程,然后开始测试,演示结果如下:

Python调用CANoe

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

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

相关文章

Linux基础命令-find搜索文件位置

文章目录 find 命令介绍 语法格式 命令基本参数 参考实例 1)在root/data目录下搜索*.txt的文件名 2)搜索一天以内最后修改时间的文件;并将文件删除 3)搜索777权限的文件 4)搜索一天之前变动的文件复制到test…

不懂什么是智慧工厂,看这篇文章就够了!

一、智慧工厂是什么? 一直以来,自动化在某种程度上始终是工厂的一部分,甚至高水平的自动化也非新生事物。然而,“自动化”一词通常表示单一且独立的任务或流程的执行。过去,机器自行“决策”的情况往往是以自动化为基…

【基础篇】9 # 排序:冒泡排序(Bubble Sort)、插入排序(Insertion Sort)、选择排序(Selection Sort)

说明 【数据结构与算法之美】专栏学习笔记 如何分析一个排序算法? 1、排序算法的执行效率 最好情况、最坏情况、平均情况时间复杂度时间复杂度的系数、常数 、低阶比较次数和交换(或移动)次数 2、排序算法的内存消耗 3、排序算法的稳定…

Fabric.js使用说明Part 2

目录一、Fabric.js使用说明Part 1Fabric.js简介 开始方法事件canvas常用属性对象属性图层层级操作复制和粘贴二、Fabric.js使用说明Part 2锁定拖拽和缩放画布分组动画图像滤镜渐变右键菜单删除三、Fabric.js使用说明Part 3自由绘画绘制背景图片绘制文本绘制线和路径一、锁定Fab…

传统豪华品牌引领?智能座舱进入「沉浸式娱乐体验」新周期

智能座舱正在进入硬件定型、软件(功能)升级以及多应用融合的新周期。 高工智能汽车研究院监测数据显示,2022年中国市场(不含进出口)乘用车搭载智能数字座舱(大屏语音车联网OTA)前装标配交付795…

【死磕数据库专栏启动】在CentOS7中安装 MySQL5.7版本实战

文章目录前言实验环境一. 安装MySQL1.1 配置yum源1.2 安装之前的环境检查1.3 下载MySQL的包1.4 开始使用yum安装1.5 启动并测试二. 设置新密码并重新启动2.1 设置新密码2.2 重新登录测试总结前言 学习MySQL是一件比较枯燥的事情,学习开始之前要先安装MySQL数据库&a…

【Linux修炼】14.磁盘结构/文件系统/软硬链接/动静态库

每一个不曾起舞的日子,都是对生命的辜负。 磁盘结构/文件系统/软硬链接/动静态库前言一.磁盘结构1.1 磁盘的物理结构1.2 磁盘的存储结构1.3 磁盘的逻辑结构二.理解文件系统2.1 对IO单位的优化2.2 磁盘分区与分组2.3 分组的管理方法2.4 文件操作三.软硬链接3.1理解硬…

测试4年裸辞失业,面试17k的测试岗被按在地上摩擦,结局让我崩溃大哭...

作为IT行业的大热岗位——软件测试,只要你付出了,就会有回报。说它作为IT热门岗位之一是完全不虚的。可能很多人回说软件测试是吃青春饭的,但放眼望去,哪个工作不是这样的呢?会有哪家公司愿意养一些闲人呢?…

「smardaten」上架钉钉应用中心!让进步再一次发生

使用钉钉的团队小伙伴们,smardaten给您送来福利啦~为了给更多团队提供更优质的应用开发体验,方便用户在线、快速使用无代码,数睿数据近期在【钉钉应用中心】发布smardaten在线版本。继与华为云、亚马逊云建立战略合作之后,smardat…

微信小程序实现分享到朋友圈的功能

分享朋友圈官方API:分享到朋友圈 1、分享到朋友圈接口设置事项 2、onShareTimeline()注意事项 3、分享朋友圈后,测试发现,没有数据请求。 用户在朋友圈打开分享的小程序页面,并不会真正打开小程序,而是进入一个“小程…

浏览器缓存策略

先走强缓存,再走协商缓存 强缓存 不发送请求,直接使用缓存的内容 状态码200 当前会话没有关闭的话就是走memory cache,否则就是disk cache 由响应头的 Pragma(逐渐废弃,优先级最高),catch-…

LeetCode 817. 链表组件

LeetCode 817. 链表组件 难度:middle\color{orange}{middle}middle 题目描述 给定链表头结点 headheadhead,该链表上的每个结点都有一个 唯一的整型值 。同时给定列表 numsnumsnums,该列表是上述链表中整型值的一个子集。 返回列表 numsnu…

自动驾驶仿真:ECU TEST 、VTD、VERISTAND连接配置

文章目录一、ECU TEST 连接配置简介二、TBC配置 test bench configuration三、TCF配置 test configuration提示:以下是本篇文章正文内容,下面案例可供参考 一、ECU TEST 连接配置简介 1、ECU TEST(简称ET),用于HIL仿…

MySQL tinyint(1) 、int(32) 与 varchar(255) 长度含义不同

MySQL tinyint(1) 、int(32) 与 varchar(255) 长度含义不同 发现 tinyint(1),int(32) 和 varchar(255) 这里面的数字的含义是不同的。 先说数字类型 tinyint 和 int 等 他们能存储的字节大小是与类型绑定的,即定义了 tinyint 或者 int 就确定了能存储…

【C++的OpenCV】第六课-OpenCV图像常用操作(三):OpenCV的图像的侵蚀和扩张

让我们继续一、图像的侵蚀和扩张1.1 侵蚀1.1.1 函数原型1.1.2 侵蚀的效果1.1.3 关于侵蚀的解释1.2 扩张1.2.1 函数原型1.2.2 扩张的效果二、实例一、图像的侵蚀和扩张 本章节中我们将会学习到: cv::erode() 函数详情cv::dilate() 函数详情 两个函数的基本使用方法…

java 接口 详解

目录 一、概述 1.介绍 : 2.定义 : 二、特点 1.接口成员变量的特点 : 2.接口成员方法的特点 : 3.接口构造方法的特点 : 4.接口创建对象的特点 : 5.接口继承关系的特点 : 三、应用 : 1.情景 : 2.多态 : ①多态的传递性 : ②关于接口的多态参数和多态…

Android ION 相关信息查看方法

目录 查看DMA buffer 信息 查看ion buffer 的总体分配情况 分配的ION buffer 都会设置为DMA buffer,以fd的形式交给使用方, 如app, camera等。 查看ion 的使用情况,可以查看ion 的各个heap分配情况, 也可以从DMA buffer 入手查…

勒索软件BlackByte出现新变种,系Go语言编写

BlackByte 是一个提供勒索软件即服务(RaaS)的攻击组织,自从 2021 年 7 月以来一直保持活跃。最初,BlackByte 使用 C# 开发,最近攻击者使用 Go 重写了恶意软件。FBI 也已经发布公告披露 BlackByte 已经攻击了许多公司&a…

文献阅读 An implementation of the seismic resolution enhancing network based on GAN

题目 An implementation of the seismic resolution enhancing network based on GAN 基于GAN的地震分辨率增强网络的实现 摘要 对于地震数据,本文利用深度学习来学习不同层次的特征并将它们合并以恢复缺失的分辨率。 将GAN网络引入到地震数据处理;对…

劳保防护用品穿戴检测 python

劳保防护用品穿戴检测算法通过pythonOpencv深度学习技术,劳保防护用品穿戴检测算法对现场人员防护穿戴用品进行全天候检测,当检测到未按照要求进行穿戴,立即对现场违规人员进行抓拍。Python是一种由Guido van Rossum开发的通用编程语言&#…