Skip to content

Commit

Permalink
FEAT: Bus.GetLoad
Browse files Browse the repository at this point in the history
  • Loading branch information
FerroO2000 committed May 20, 2024
1 parent 83b712a commit 18294eb
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 1 deletion.
71 changes: 71 additions & 0 deletions bus.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,23 @@ import (
"golang.org/x/exp/slices"
)

// BusType is the type of a [Bus].
type BusType int

const (
// BusTypeCAN2A represents a CAN 2.0A bus.
BusTypeCAN2A BusType = iota
)

func (bt BusType) String() string {
switch bt {
case BusTypeCAN2A:
return "CAN_2.0A"
default:
return "unknown"
}
}

// Bus is the virtual representation of physical CAN bus cable.
// It holds a list of nodes that are connected to it.
type Bus struct {
Expand All @@ -21,9 +38,11 @@ type Bus struct {
nodeIDs *set[NodeID, EntityID]

baudrate int
typ BusType
}

// NewBus creates a new [Bus] with the given name and description.
// By default, the bus is set to be of type CAN 2.0A.
func NewBus(name string) *Bus {
return &Bus{
attributeEntity: newAttributeEntity(name, AttributeRefKindBus),
Expand All @@ -37,6 +56,7 @@ func NewBus(name string) *Bus {
nodeIDs: newSet[NodeID, EntityID](),

baudrate: 0,
typ: BusTypeCAN2A,
}
}

Expand Down Expand Up @@ -255,3 +275,54 @@ func (b *Bus) SetCANIDBuilder(canIDBuilder *CANIDBuilder) {
func (b *Bus) CANIDBuilder() *CANIDBuilder {
return b.canIDBuilder
}

// SetType sets the type of the [Bus].
func (b *Bus) SetType(typ BusType) {
b.typ = typ
}

// Type returns the type of the [Bus].
func (b *Bus) Type() BusType {
return b.typ
}

// GetLoad returns the estimed load of the [Bus] in the worst case scenario.
// If the bus does not have the baudrate set, it returns 0.
// If a [Message] within the bus does not have the cycle time set,
// a default cycle time of 500ms is used.
func (b *Bus) GetLoad() float64 {
if b.baudrate == 0 {
return 0
}

var headerBits int
var trailerBits int
var stuffingBits int
switch b.typ {
case BusTypeCAN2A:
// start of frame + id + rtr + ide + r0 + dlc
headerBits = 19
// crc + delim crc + slot ack + delim ack + eof
trailerBits = 25
// worst case scenario
stuffingBits = 19
}

consumedBitsPerSec := float64(0)
for _, tmpInt := range b.nodeInts.getValues() {
for _, tmpMsg := range tmpInt.messages.getValues() {
msgBits := tmpMsg.sizeByte*8 + headerBits + trailerBits + stuffingBits

var cycleTime int
if tmpMsg.cycleTime == 0 {
cycleTime = 500
} else {
cycleTime = tmpMsg.cycleTime
}

consumedBitsPerSec += float64(msgBits) / float64(cycleTime) * 1000
}
}

return consumedBitsPerSec / float64(b.baudrate) * 100
}
20 changes: 20 additions & 0 deletions bus_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,3 +105,23 @@ func Test_Bus_UpdateName(t *testing.T) {
// should return an error because bus_00 is already taken
assert.Error(bus1.UpdateName("bus_00"))
}

func Test_Bus_GetLoad(t *testing.T) {
assert := assert.New(t)

bus := NewBus("bus")
bus.SetBaudrate(250_000)

node := NewNode("node", 1, 1)
nodeInt := node.Interfaces()[0]
assert.NoError(bus.AddNodeInterface(nodeInt))

msg0 := NewMessage("msg_0", 1, 8)
msg0.SetCycleTime(10)
assert.NoError(nodeInt.AddMessage(msg0))
msg1 := NewMessage("msg_1", 2, 8)
msg1.SetCycleTime(10)
assert.NoError(nodeInt.AddMessage(msg1))

assert.Equal(10.16, bus.GetLoad())
}
2 changes: 1 addition & 1 deletion message.go
Original file line number Diff line number Diff line change
Expand Up @@ -551,7 +551,7 @@ func (m *Message) Priority() MessagePriority {
return m.priority
}

// SetCycleTime sets the message cycle time.
// SetCycleTime sets the message cycle time in ms.
func (m *Message) SetCycleTime(cycleTime int) {
m.cycleTime = cycleTime
}
Expand Down

0 comments on commit 18294eb

Please sign in to comment.