最近在工作中,有同事拿了一个excel的dbc表格,在用官方的dbc工具一个一个创建信号,大概看了一下共累计20多个节点,300多个信号,居然在手动处理,顿感无语。。

于是在网络上搜相关的dbc 通过脚本生成方式,竟然没搜到!那只能全网首发一个给广大汽车软件同行谋个福利。

(经过国内一番搜索,一无所获。于是乎转谷歌搜索,在cantools 这个库官网文件下找到这么一个指令:)

import cantools
db = cantools.database.load_file('MS11_E4U2_CCU_PTCANFD_230701.dbc')
cantools.database.dump_file(db, 'bar.dbc')

 上文代码实现了一个读取加转存,读取了一个dbc并转而生成了一个dbc,于是自行分析读取的candbc数据结构,再结合chatgpt给出的示例,进行重构数据。最终简单的示例代码如下:

# -*- coding: utf-8 -*-
"""
Created on Wed Dec 27 18:09:18 2023 @author: xm 如何创建生成canfd还待挖掘 """ import cantools # db = cantools.database.load_file('MS11_E4U2_CCU_PTCANFD_230701.dbc')
# cantools.database.dump_file(db, 'bar.dbc') # 定义一个消息
message1 = cantools.db.Message( #cantools.database.can.message.Message
frame_id=0x19FB5101, #435900673
name='PFC_VacReport',
length=8,
bus_name='PFC',
header_byte_order='big_endian',
is_extended_frame=True,
# is_multiplexed=True,
# refresh=True,
is_fd=False,
send_type='cyclic',
senders=['PFC'],
cycle_time=20,
comment='input voltage',
unused_bit_pattern=255,
# unpack_container=True,
signals=[
cantools.db.Signal(
name='P_VacRpt_VacRms_A',
start=0,
length=12,
is_signed=False,
scale=0.1,
offset=0,
minimum=0,
maximum=409.5,
unit='V',
invalid=None,
initial=0,
# is_multiplexer=False,
# is_float=False,
receivers=['IFB','LC'],
# multiplexer_signal=None,
# multiplexer_ids=None,
byte_order='little_endian', #little_endian big_endian
comment='valid voltage phase A',
),
cantools.db.Signal(
name='P_VacRpt_VacRms_B',
start=12,
length=12,
is_signed=False,
scale=0.1,
offset=0,
minimum=0,
maximum=409.5,
unit='V',
invalid=None,
initial=0,
# is_multiplexer=False,
# is_float=False,
receivers=['IFB','LC'],
# multiplexer_signal=None,
# multiplexer_ids=None,
byte_order='little_endian',
comment='valid voltage phase b',
),
cantools.db.Signal(
name='P_VacRpt_VacRms_C',
start=24,
length=12,
is_signed=False,
scale=0.1,
offset=0,
minimum=0,
maximum=409.5,
unit='V',
invalid=None,
initial=0,
# is_multiplexer=False,
# is_float=False,
receivers=['IFB','LC'],
# multiplexer_signal=None,
# multiplexer_ids=None,
byte_order='little_endian',
comment='valid voltage phase c',
),
]
) node1 = cantools.db.Node(
name='PFC'
) # 定义一个数据库
database = cantools.db.Database(
messages=[message1],
nodes=[node1,],
version='1.0'
) # 保存为DBC文件
cantools.database.dump_file(database, 'example.dbc')

接下来就是解析对应的excel,创建不同的msg和signal再进行组合了。这里要注意,如果excel内涉及合并单元格,以及公式计算,需要用下文代码中的两个 In【0】部分来处理掉

# -*- coding: utf-8 -*-
"""
Created on Wed Dec 27 20:35:47 2023 @author: xm Azhe """ import pandas as pd
import cantools
import openpyxl file_path = r'D:\代码\dbc文件处理\xx.xlsx' # In[0] 文件改造,合并单元格填充
# 打开Excel文件
workbook = openpyxl.load_workbook(file_path) # 遍历所有工作表
for worksheet in workbook.worksheets:
# 获取所有合并单元格
merged_cells = worksheet.merged_cells
# if worksheet.title=='IFB协议E2E ':
# print(merged_cells)
# 遍历合并单元格
for merged_cell in list(merged_cells): # 获取合并单元格的起始行、列和结束行、列
start_row, start_col, end_row, end_col = merged_cell.min_row,merged_cell.min_col,merged_cell.max_row,merged_cell.max_col,
# 拆分
worksheet.unmerge_cells(start_row=start_row,start_column=start_col,end_row=end_row,end_column=end_col)
# 获取合并单元格的值
cell_value = worksheet.cell(start_row, start_col).value
# if worksheet.title=='IFB协议E2E ':
# print(merged_cell)
# print('\n')
# 将合并单元格内的所有单元格都替换为该值
for row in range(start_row, end_row + 1):
for col in range(start_col, end_col + 1):
worksheet.cell(row, col).value = cell_value
file_path1=file_path.replace('.xlsx','_dealed.xlsx')
# 保存Excel文件
workbook.save(file_path1) # In[0] excel内包含公式,需要刷新公式,否则会读取为nan
import win32com.client
# Start an instance of Excel
xlapp = win32com.client.DispatchEx("Excel.Application")
# Open the workbook in said instance of Excel
wb = xlapp.workbooks.open(file_path1)
# Optional, e.g. if you want to debug
# xlapp.Visible = True
# Refresh all data connections.
wb.RefreshAll()
wb.Save()
# Quit
xlapp.Quit() # In[1] df读取,删除信号名称为空,忽略第一行
def str_to_num(s):
try:
return int(s)
except ValueError:
try:
return float(s)
except ValueError:
return s df={}
for s in pd.ExcelFile(file_path1).sheet_names:
# print(s)
if ('协议' in s) & (s!='协议说明'):
df[s] = pd.read_excel(file_path1, sheet_name=s,skiprows=1, engine='openpyxl')
df[s] = df[s].dropna(subset=['数据名称']) node_list=[]
msg_list=[]
# cnt=1
for s in list(df.keys()):
node_list.append(cantools.db.Node(name=s.replace(' ','').replace('协议E2E','')))
msg_list_tmp=list(df[s]['ID'].drop_duplicates())
for i in msg_list_tmp:
# if s=='LVDC协议E2E':
# cnt1=1
# print('y')
signals_list_tmp=[]
df_sig_list_tmp=list(df[s]['数据名称'][df[s]['ID']==i])
for j in df_sig_list_tmp:
signals_list_tmp.append(
cantools.db.Signal(
name=j,
start=str_to_num(df[s]['起始位'][df[s]['数据名称']==j]),
length=str_to_num(df[s]['长度'][df[s]['数据名称']==j]),
is_signed=False,
scale=df[s]['精度'][df[s]['数据名称']==j].values[0],
offset=str_to_num(df[s]['OFFSET'][df[s]['数据名称']==j]),
minimum=df[s]['Min'][df[s]['数据名称']==j].values[0],
maximum=df[s]['Max'][df[s]['数据名称']==j].values[0],
unit=str(df[s]['单位'][df[s]['数据名称']==j].values[0]),
invalid=None, #未采用dbc
initial=str_to_num(df[s]['Initial'][df[s]['数据名称']==j]),
# is_multiplexer=False,
# is_float=False,
receivers=df[s]['接收'][df[s]['数据名称']==j].values[0].split('&'),
# multiplexer_signal=None,
# multiplexer_ids=None,
byte_order='little_endian', #little_endian big_endian
comment=str(df[s]['说明'][df[s]['数据名称']==j].values[0]),
# comments=None
)) msg_list.append(cantools.db.Message( #cantools.database.can.message.Message
frame_id=int(i[:i.index("\n")], 16),
name=i[i.index("(")+1:i.index(")")],
length=8,
bus_name=df[s]['发送'][df[s]['ID']==i].values[0],
header_byte_order='big_endian',
is_extended_frame=True,
is_fd=False,
send_type='cyclic',
senders=[df[s]['发送'][df[s]['ID']==i].values[0]],
cycle_time=str_to_num(df[s]['周期'][df[s]['ID']==i].values[0][:df[s]['周期'][df[s]['ID']==i].values[0].index("ms")]),
comment=str(df[s]['备注'][df[s]['ID']==i].values[0]),
unused_bit_pattern=255,
# unpack_container=True,
signals=signals_list_tmp
))
# if s=='LVDC协议E2E':
# cnt1=cnt1+1
# if cnt1==3:
# break
# cnt=cnt+1
# if cnt==5:
# break database = cantools.db.Database(
# messages=[message1],
messages=msg_list,
nodes=node_list,
version='1.0'
) cantools.database.dump_file(database, file_path.split('\\')[-1].replace('.xlsx','.dbc').replace('.xls','.dbc').replace('.csv','.dbc'))

应该是全网首发了哈,有制作dbc的小伙伴们有福了,记得点赞,使用中有问题可以评论联系,会看的。

如何用python脚本制作生成CANdbc的更多相关文章

  1. python脚本批量生成数据

    在平时的工作中,经常会遇到造数据,特别是性能测试的时候更是需要大量的数据.如果一条条的插入数据库或者一条条的创建数据,效率未免有点低.如何快速的造大量的测试数据呢?在不熟悉存储过程的情况下,今天给大家 ...

  2. 如何用Python脚本从文件读取数据?

    最近自学Python的进度比较慢,工作之余断断续续的看着效率比较低,看来还是要狠下心来每天进步一点点. 还记得前段时间陈大猫提了一口"先实现用python读取本地文件",碰巧今天看 ...

  3. python 脚本制作

    U盘拷贝 当U盘插入主机时 被系统识别挂载后 通过python代码自动的去读取U盘中的资料并且进行拷贝 寄存在U盘上的 把硬盘上的资料进行读取并移动到U盘里 有点像 繁殖性 传输性 破坏性 破坏系统或 ...

  4. python脚本批量生成50000条插入数据的sql语句

    f = open("xx.txt",'w') for i in range(1,50001): str_i = str(i) realname = "lxs"+ ...

  5. 如何用python脚本采集某网图片

    一.前言: 今天学了两个工具urlopen  和etree,这两个小工具至关重要.urllib.request模块提供了最基本的构造HTTP请求的方法,利用它可以模拟浏览器的一个请求发起过程,同时它还 ...

  6. 渗透脚本快速生成工具Intersect

    渗透脚本快速生成工具Intersect   当渗透人员获取目标系统的执行权限,往往需要编写相应的脚本,实现更多的渗透操作.Kali Linux提供一款Python脚本快速生成工具Intersect.该 ...

  7. 如何用python抓取js生成的数据 - SegmentFault

    如何用python抓取js生成的数据 - SegmentFault 如何用python抓取js生成的数据 1赞 踩 收藏 想写一个爬虫,但是需要抓去的的数据是js生成的,在源代码里看不到,要怎么才能抓 ...

  8. 从零开始制作数据集所需要的所有python脚本

    最近一直在做图片数据集,积累了很多心得.我把我所使用的python脚本全部拿出来,当然这些脚本大部分网上都有,只不过比较分散. 我已经把所有代码上传到github上,觉得写的好的话,请给我一个star ...

  9. Python脚本生成可执行文件&(恋爱小脚本)

    Python脚本生成可执行文件&(恋爱小脚本) 参考文献: http://c.biancheng.net/view/2690.html; https://blog.csdn.net/qq_39 ...

  10. 用 Python脚本生成 Android SALT 扰码

    发布Android 有偿应用时需要随机生成 SALT 扰码夹在文件中,以下是 Python脚本(当然你选择 C/Java/SHELL/Perl 或别的都行) #!/usr/bin/python # F ...

随机推荐

  1. 在 Net7.0环境下通过反射创建泛型实例和调用泛型方法

    一.介绍 最近没事干,就用闲暇时间写点东西,也记录一下温习历程.老人说的好,好记性,不如烂笔头.时间一长,当时记忆的再清楚,都会变得模糊,索性就写博客记录下来,如果下次需要,直接打开博客就找到了,不用 ...

  2. Solution -「洛谷 P5176」公约数

    Description Link. 求 \[\sum_{i=1}^n\sum_{j=1}^m\sum_{k=1}^p\gcd(i\cdot j,i\cdot k,j\cdot k)\times \gc ...

  3. Mysql忘记密码后如何重置密码

    长时间不使用本机的Mysql后把密码忘记了咋整?直接上干货: 第一步(Mysql部署的位置,若自己能找到就忽略这一步):任务管理器中也可以找到 第二步:修改配置文件 在my.ini末尾加上 skip- ...

  4. QFluentWidgets: 基于 C++ Qt 的 Fluent Design 组件库

    简介 QFluentWidgets 是一个基于 Qt 的 Fluent Designer 组件库,内置超过 150 个开箱即用的 Fluent Designer 组件,支持亮暗主题无缝切换和自定义主题 ...

  5. 【matplotlib 实战】--直方图

    直方图,又称质量分布图,用于表示数据的分布情况,是一种常见的统计图表. 一般用横轴表示数据区间,纵轴表示分布情况,柱子越高,则落在该区间的数量越大.构建直方图时,首先首先就是对数据划分区间,通俗的说即 ...

  6. JAVA图搜索算法之DFS-BFS

    图算法DFS与BFS BFS和DFS代表对图进行遍历,即搜索的算法,搜索算法中常用的只要有两种算法:深度优先遍历(Depth-First-Search : DFS)和广度优先遍历(Breadth-Fi ...

  7. 如何在 Ubuntu上使用snap安装Docker

    1 检查系统版本 具有sudo或root用户权限 2 安装 SNAP ctrl+alt+T 打开终端 运行以下命令以安装 SNAP sudo apt update sudo apt install s ...

  8. 字符串小记 II:字符串自动机

    OI 中的自动机指的是"有限状态自动机",它是对一串信号进行处理的数学模型,一般由以下三部分构成: 字符集(\(\Sigma\)),能够输入进自动机的字符集合. 状态集合(\(Q\ ...

  9. 1.参考例5.2.1,设计一个序列检测器。功能是检测出串行输入数据Sin中的4位二进制序列0101(自左至右输入),当检测到该序列时,输入Out=1;没有检测到该序列时,输入Out=0。要求不考虑序列重叠,如010101的序列中只包含一个0101序列。

    设计块: module Detector2 ( input CP,Sin,nCR, output reg Out ); reg [1:0] Current_state,Next_state; para ...

  10. 手撕Vuex-模块化共享数据上

    前言 好,经过上一篇的介绍,实现了 Vuex 当中的 actions 方法,接下来我们来实现 Vuex 当中的模块化共享数据(modules). modules 方法用于模块化共享数据,那么什么叫模块 ...