所以我制作了一个Python脚本,它可以使用库cantools在Excel中转换DBC并返回。将 DBC 文件转换为 Excel 没有问题,但如果我想从 Excel 文件创建 DBC 并将 J1939 标准分配给消息,则它不会显示在 DBC 文件中。相反,它只显示 CAN 扩展。
我为 J1939 标准的消息提供了属性
protocol="j1939"
,并使用 dumpfile(db, "__.dbc")
保存 DBC 文件。有谁知道是否有特殊设置我必须如何保存 DBC 文件,或者是否可以使用 cantools?
这里是一个简短的代码示例:
signal1 = cantools.db.can.Signal(name="signal1", start=1, length=8,
is_signed=True, scale=1, offset=0, unit=None, spn=1586)
frame1 = cantools.db.can.Message(name="Msg1", frame_id=0x16fd3b09, protocol="j1939",
is_extended_frame=True, length=8, signals=[signal1],
cycle_time=50, senders=["A"])
db_cantools = cantools.db.can.Database(messages=[frame1])
cantools.db.dump_file(db_cantools, "test_db.dbc")
Vector CANdb 中 DBC 文件的
对于我发现的不同 DBC 文件(包含 J1939 消息)
db.dbc.attributes
我的数据库中的属性字典:
OrderedDict([('ProtocolType', attribute('ProtocolType', J1939)),...)
我不知道这是否是创建此属性的关键,但我也不知道如何做到这一点。另外,在消息的属性中,我发现
j1939
但同样的问题(不知道如何创建它们)。
编辑:我尝试创建 J1939 模板 DBC 文件并在其中添加消息。它可以工作,但使用 ID 格式 CAN 标准或 CAN 扩展的消息也会变成 ID 格式 J1939。
文档的质量很差。
但是仔细研究一下,你会发现可以将dbc_specifics
视为kwarg,而kwarg应该是
DBCSpecifics
类型。
为了将数据库协议设置为 J1939,您应该在 ProtocolType
中创建一个键
_attribute_definitions
,其值类型为
AttributeDefinition
。
我不知道 API 中是否有更简单的方法来达到相同的结果(这个方法非常冗长),但以下方法可以工作:
import cantools.database as candb
dbc_spec = candb.can.formats.dbc_specifics.DbcSpecifics(
attribute_definitions = {
"ProtocolType": candb.can.attribute_definition.AttributeDefinition(
name = "ProtocolType",
default_value = 'J1939',
type_name = 'STRING'
)
}
)
signal1 = candb.can.Signal(name="signal1", start=0, length=8,
is_signed=True, unit=None, spn=1586)
frame1 = candb.can.Message(name="Msg1", frame_id=0x16fd3b09, protocol="j1939",
is_extended_frame=True, length=8, signals=[signal1],
cycle_time=50, senders=["A"])
db_cantools = candb.can.Database(messages=[frame1], dbc_specifics=dbc_spec)
candb.dump_file(db_cantools, "test_db.dbc")
请注意,当前版本的Signal
似乎并不将
scale
和
offset
视为kwarg,而是将
conversion
对象。
编辑:您可以使用属性VFrameFormat
单独设置消息协议。应首先将其添加到 dbc 文件的属性定义中。然后作为所需消息的属性:
import cantools.database as candb
vframe_format = candb.can.attribute_definition.AttributeDefinition(
name = "VFrameFormat",
default_value = 0,
type_name = 'INT',
kind='BO_'
)
dbc_spec = candb.can.formats.dbc_specifics.DbcSpecifics(
attribute_definitions = {
"ProtocolType": candb.can.attribute_definition.AttributeDefinition(
name = "ProtocolType",
default_value = 'J1939',
type_name = 'STRING'
),
'VFrameFormat': vframe_format
}
)
signal1 = candb.can.Signal(name="signal1", start=0, length=8,
is_signed=True, unit=None, spn=1586)
msg_spec_ext = candb.can.formats.dbc_specifics.DbcSpecifics(
attributes = {'VFrameFormat': candb.can.attribute.Attribute(
value = 1, # 0: CAN Standard; 1: CAN Extended; 3: J1939
definition = vframe_format
)}
)
frame1 = candb.can.Message(name="Msg1", frame_id=0x16fd3b09, protocol="j1939",
is_extended_frame=True, length=8, signals=[signal1],
cycle_time=50, senders=["A"], dbc_specifics=msg_spec_ext)
db_cantools = candb.can.Database(messages=[frame1], dbc_specifics=dbc_spec)
candb.dump_file(db_cantools, "test_db.dbc")