From 2a55e658e3c96e509295fb443b6f6a0a8c225059 Mon Sep 17 00:00:00 2001 From: FerroO2000 <30318301+FerroO2000@users.noreply.github.com> Date: Thu, 30 May 2024 12:13:35 +0200 Subject: [PATCH] dbc importer improvements --- bus.go | 6 ++-- bus_test.go | 6 ++-- exporter.go | 2 +- importer.go | 80 ++++++++++++++++++++++++++++++++++-------------- importer_test.go | 17 ++++++++++ md_exporter.go | 4 +-- 6 files changed, 83 insertions(+), 32 deletions(-) diff --git a/bus.go b/bus.go index 1a3e9ad..7340c3f 100644 --- a/bus.go +++ b/bus.go @@ -121,7 +121,7 @@ func (b *Bus) stringify(builder *strings.Builder, tabs int) { } builder.WriteString(fmt.Sprintf("%sattached_node_interfaces:\n", tabStr)) - for _, nodeInt := range b.Nodes() { + for _, nodeInt := range b.NodeInterfaces() { nodeInt.stringify(builder, tabs+1) builder.WriteRune('\n') } @@ -230,8 +230,8 @@ func (b *Bus) RemoveAllNodeInterfaces() { b.nodeIDs.clear() } -// Nodes returns a slice of all nodes in the [Bus] sorted by node id. -func (b *Bus) Nodes() []*NodeInterface { +// NodeInterfaces returns a slice of all node interfaces connected to the [Bus] sorted by node id. +func (b *Bus) NodeInterfaces() []*NodeInterface { nodeSlice := b.nodeInts.getValues() slices.SortFunc(nodeSlice, func(a, b *NodeInterface) int { return int(a.node.id) - int(b.node.id) }) return nodeSlice diff --git a/bus_test.go b/bus_test.go index 65fb131..886931a 100644 --- a/bus_test.go +++ b/bus_test.go @@ -21,7 +21,7 @@ func Test_Bus_AddNodeInterface(t *testing.T) { assert.NoError(bus.AddNodeInterface(node2)) expectedIDs := []NodeID{0, 1, 2} expectedNames := []string{"node_0", "node_1", "node_2"} - for idx, tmpNode := range bus.Nodes() { + for idx, tmpNode := range bus.NodeInterfaces() { assert.Equal(expectedIDs[idx], tmpNode.node.ID()) assert.Equal(expectedNames[idx], tmpNode.node.Name()) } @@ -54,7 +54,7 @@ func Test_Bus_RemoveNodeInterface(t *testing.T) { assert.NoError(bus.RemoveNodeInterface(node2.EntityID())) expectedIDs := []NodeID{0, 1, 3} expectedNames := []string{"node_0", "node_1", "node_3"} - for idx, tmpNode := range bus.Nodes() { + for idx, tmpNode := range bus.NodeInterfaces() { assert.Equal(expectedIDs[idx], tmpNode.node.ID()) assert.Equal(expectedNames[idx], tmpNode.node.Name()) } @@ -80,7 +80,7 @@ func Test_Bus_RemoveAllNodeInterfaces(t *testing.T) { bus.RemoveAllNodeInterfaces() - assert.Equal(0, len(bus.Nodes())) + assert.Equal(0, len(bus.NodeInterfaces())) } func Test_Bus_UpdateName(t *testing.T) { diff --git a/exporter.go b/exporter.go index 93e6eaf..ab3fd63 100644 --- a/exporter.go +++ b/exporter.go @@ -263,7 +263,7 @@ func (e *exporter) exportBus(bus *Bus) *dbc.File { Baudrate: uint32(bus.baudrate), } - e.exportNodeInterfaces(bus.Nodes()) + e.exportNodeInterfaces(bus.NodeInterfaces()) for _, sigEnum := range e.sigEnums { e.exportSignalEnum(sigEnum) diff --git a/importer.go b/importer.go index 7e644e2..4fdb215 100644 --- a/importer.go +++ b/importer.go @@ -35,6 +35,9 @@ type importer struct { signals map[string]Signal flagSigType *SignalType + signalTypes map[string]*SignalType + + signalUnits map[string]*SignalUnit signalEnumRegistry []*SignalEnum signalEnums map[string]*SignalEnum @@ -55,6 +58,9 @@ func newImporter() *importer { signals: make(map[string]Signal), flagSigType: NewFlagSignalType("flag"), + signalTypes: make(map[string]*SignalType), + + signalUnits: make(map[string]*SignalUnit), signalEnumRegistry: []*SignalEnum{}, signalEnums: make(map[string]*SignalEnum), @@ -71,6 +77,14 @@ func (i *importer) getSignalKey(dbcMsgID uint32, sigName string) string { return fmt.Sprintf("%d_%s", dbcMsgID, sigName) } +func (i *importer) getSignalTypeKey(dbcSig *dbc.Signal) string { + signStr := "u" + if dbcSig.ValueType == dbc.SignalSigned { + signStr = "s" + } + return fmt.Sprintf("%s%d_%g-%g_%g_%g", signStr, dbcSig.Size, dbcSig.Min, dbcSig.Max, dbcSig.Factor, dbcSig.Offset) +} + func (i *importer) importFile(dbcFile *dbc.File) (*Bus, error) { bus := NewBus(dbcFile.Location().Filename) i.bus = bus @@ -654,27 +668,9 @@ func (i *importer) importSignal(dbcSig *dbc.Signal, dbcMsgID uint32) (Signal, er sig = enumSig } else { - signed := false - if dbcSig.ValueType == dbc.SignalSigned { - signed = true - } - - sigSize := int(dbcSig.Size) - var sigType *SignalType - if sigSize == 1 && dbcSig.ValueType == dbc.SignalUnsigned { - sigType = i.flagSigType - } else { - tmpSigType, err := NewIntegerSignalType(fmt.Sprintf("%s_Type", sigName), sigSize, signed) - if err != nil { - return nil, i.errorf(dbcSig, err) - } - - tmpSigType.SetMin(dbcSig.Min) - tmpSigType.SetMax(dbcSig.Max) - tmpSigType.SetScale(dbcSig.Factor) - tmpSigType.SetOffset(dbcSig.Offset) - - sigType = tmpSigType + sigType, err := i.importSignalType(dbcSig) + if err != nil { + return nil, err } stdSig, err := NewStandardSignal(sigName, sigType) @@ -682,8 +678,15 @@ func (i *importer) importSignal(dbcSig *dbc.Signal, dbcMsgID uint32) (Signal, er return nil, i.errorf(dbcSig, err) } - if dbcSig.Unit != "" { - stdSig.SetUnit(NewSignalUnit(fmt.Sprintf("%s_Unit", sigName), SignalUnitKindCustom, dbcSig.Unit)) + symbol := dbcSig.Unit + if symbol != "" { + if sigUnit, ok := i.signalUnits[symbol]; ok { + stdSig.SetUnit(sigUnit) + } else { + sigUnit := NewSignalUnit(symbol, SignalUnitKindCustom, symbol) + stdSig.SetUnit(sigUnit) + i.signalUnits[symbol] = sigUnit + } } sig = stdSig @@ -697,3 +700,34 @@ func (i *importer) importSignal(dbcSig *dbc.Signal, dbcMsgID uint32) (Signal, er return sig, nil } + +func (i *importer) importSignalType(dbcSig *dbc.Signal) (*SignalType, error) { + signed := false + if dbcSig.ValueType == dbc.SignalSigned { + signed = true + } + + sigSize := int(dbcSig.Size) + if sigSize == 1 && !signed { + return i.flagSigType, nil + } + + sigTypeKey := i.getSignalTypeKey(dbcSig) + if sigType, ok := i.signalTypes[sigTypeKey]; ok { + return sigType, nil + } + + sigType, err := NewIntegerSignalType(sigTypeKey, sigSize, signed) + if err != nil { + return nil, i.errorf(dbcSig, err) + } + + sigType.SetMin(dbcSig.Min) + sigType.SetMax(dbcSig.Max) + sigType.SetScale(dbcSig.Factor) + sigType.SetOffset(dbcSig.Offset) + + i.signalTypes[sigTypeKey] = sigType + + return sigType, nil +} diff --git a/importer_test.go b/importer_test.go index e40bd8c..257824b 100644 --- a/importer_test.go +++ b/importer_test.go @@ -39,4 +39,21 @@ func Test_ImportDBCFile(t *testing.T) { fileStr := strings.ReplaceAll(fileBuf.String(), "\n", "") assert.Equal(expectedFileStr, fileStr) + + // testing signal types aggregation + sigTypeIDs := make(map[EntityID]bool) + for _, tmpNodeInt := range bus.NodeInterfaces() { + for _, tmpMsg := range tmpNodeInt.Messages() { + for _, sig := range tmpMsg.signals.getValues() { + if sig.Kind() != SignalKindStandard { + continue + } + + stdSig, err := sig.ToStandard() + assert.NoError(err) + sigTypeIDs[stdSig.Type().EntityID()] = true + } + } + } + assert.Len(sigTypeIDs, 1) } diff --git a/md_exporter.go b/md_exporter.go index 6d2bfbf..48e39ba 100644 --- a/md_exporter.go +++ b/md_exporter.go @@ -57,7 +57,7 @@ func (e *mdExporter) exportNetwork(net *Network) { func (e *mdExporter) exportTOC(net *Network) { for _, bus := range net.Buses() { e.w.BulletList(e.getHeaderLink(bus.name)) - for _, nodeInt := range bus.Nodes() { + for _, nodeInt := range bus.NodeInterfaces() { e.w.PlainTextf("\t- %s", e.getHeaderLink(nodeInt.node.name)) for _, msg := range nodeInt.Messages() { e.w.PlainTextf("\t\t- %s", e.getHeaderLink(msg.name)) @@ -80,7 +80,7 @@ func (e *mdExporter) exportBus(bus *Bus) { } e.w.PlainTextf("Baudrate: %s bps", baudrateStr).LF() - for _, node := range bus.Nodes() { + for _, node := range bus.NodeInterfaces() { e.exportNode(node) } }