Skip to content

Commit

Permalink
Merge pull request #4 from jshiv/fix/do_not_shift_ranges_signal_decode
Browse files Browse the repository at this point in the history
Added Decode and DecodePayload signal methods for decoding without sh…
  • Loading branch information
naveenv92 authored Mar 24, 2021
2 parents 9986b66 + f845a4a commit 51c1b50
Show file tree
Hide file tree
Showing 2 changed files with 263 additions and 0 deletions.
54 changes: 54 additions & 0 deletions pkg/descriptor/signal.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,33 @@ func (s *Signal) UnmarshalPhysical(d can.Data) float64 {
}
}

// Decode returns the physical value of the signal in the provided CAN frame.
func (s *Signal) Decode(d can.Data) float64 {
switch {
case uint8(s.Length) == 1:
if d.Bit(uint8(s.Start)) {
return 1
}
return 0
case s.IsSigned:
var value int64
if s.IsBigEndian {
value = d.SignedBitsBigEndian(uint8(s.Start), uint8(s.Length))
} else {
value = d.SignedBitsLittleEndian(uint8(s.Start), uint8(s.Length))
}
return s.Offset + float64(value)*s.Scale
default:
var value uint64
if s.IsBigEndian {
value = d.UnsignedBitsBigEndian(uint8(s.Start), uint8(s.Length))
} else {
value = d.UnsignedBitsLittleEndian(uint8(s.Start), uint8(s.Length))
}
return s.Offset + float64(value)*s.Scale
}
}

// UnmarshalPhysicalPayload returns the physical value of the signal in the provided CAN frame.
func (s *Signal) UnmarshalPhysicalPayload(p *can.Payload) float64 {
switch {
Expand Down Expand Up @@ -136,6 +163,33 @@ func (s *Signal) UnmarshalPhysicalPayload(p *can.Payload) float64 {
}
}

// DecodePayload returns the physical value of the signal in the provided CAN frame.
func (s *Signal) DecodePayload(p *can.Payload) float64 {
switch {
case uint8(s.Length) == 1:
if p.Bit(s.Start) {
return 1
}
return 0
case s.IsSigned:
var value int64
if s.IsBigEndian {
value = p.SignedBitsBigEndian(s.Start, s.Length)
} else {
value = p.SignedBitsLittleEndian(s.Start, s.Length)
}
return s.Offset + float64(value)*s.Scale
default:
var value uint64
if s.IsBigEndian {
value = p.UnsignedBitsBigEndian(s.Start, s.Length)
} else {
value = p.UnsignedBitsLittleEndian(s.Start, s.Length)
}
return s.Offset + float64(value)*s.Scale
}
}

// UnmarshalUnsigned returns the unsigned value of the signal in the provided CAN frame.
func (s *Signal) UnmarshalUnsigned(d can.Data) uint64 {
if s.IsBigEndian {
Expand Down
209 changes: 209 additions & 0 deletions pkg/descriptor/signal_test.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,222 @@
package descriptor

import (
"encoding/hex"
"math"
"testing"

"go.einride.tech/can"
"gotest.tools/v3/assert"
)

func TestSignal_Decode_UnsignedBigEndian(t *testing.T) {
s := &Signal{
Name: "TestSignal",
IsSigned: false,
IsBigEndian: true,
Offset: -1,
Scale: 3.0517578125e-05,
Length: 10,
Start: 32,
Min: 0,
Max: 1,
}
const value uint64 = 180

// Testing can.Data
var data can.Data
data.SetUnsignedBitsBigEndian(uint8(s.Start), uint8(s.Length), value)
actual := s.Decode(data)
assert.DeepEqual(t, s.Offset+float64(value)*s.Scale, actual)

// Testing payload
p, _ := can.PayloadFromHex(hex.EncodeToString(data[:]))
actual = s.DecodePayload(&p)
assert.DeepEqual(t, s.Offset+float64(value)*s.Scale, actual)
}

func TestSignal_Decode_SignedBigEndian(t *testing.T) {
s := &Signal{
Name: "TestSignal",
IsSigned: true,
IsBigEndian: true,
Offset: -1,
Scale: 3.0517578125e-05,
Length: 10,
Start: 32,
Min: -1,
Max: 1,
}
const value int64 = -180

// Testing can.Data
var data can.Data
data.SetSignedBitsBigEndian(uint8(s.Start), uint8(s.Length), value)
actual := s.Decode(data)
assert.DeepEqual(t, s.Offset+float64(value)*s.Scale, actual)

// Testing payload
p, _ := can.PayloadFromHex(hex.EncodeToString(data[:]))
actual = s.DecodePayload(&p)
assert.DeepEqual(t, s.Offset+float64(value)*s.Scale, actual)
}

func TestSignal_Decode_UnsignedLittleEndian(t *testing.T) {
s := &Signal{
Name: "TestSignal",
IsSigned: false,
IsBigEndian: false,
Offset: -1,
Scale: 3.0517578125e-05,
Length: 10,
Start: 32,
Min: 0,
Max: 1,
}
const value uint64 = 180

// Testing can.Data
var data can.Data
data.SetUnsignedBitsLittleEndian(uint8(s.Start), uint8(s.Length), value)
actual := s.Decode(data)
assert.DeepEqual(t, s.Offset+float64(value)*s.Scale, actual)

// Testing payload
p, _ := can.PayloadFromHex(hex.EncodeToString(data[:]))
actual = s.DecodePayload(&p)
assert.DeepEqual(t, s.Offset+float64(value)*s.Scale, actual)
}

func TestSignal_Decode_SignedLittleEndian(t *testing.T) {
s := &Signal{
Name: "TestSignal",
IsSigned: true,
IsBigEndian: false,
Offset: -1,
Scale: 3.0517578125e-05,
Length: 10,
Start: 32,
Min: -1,
Max: 1,
}
const value int64 = -180

// Testing can.Data
var data can.Data
data.SetSignedBitsLittleEndian(uint8(s.Start), uint8(s.Length), value)
actual := s.Decode(data)
assert.DeepEqual(t, s.Offset+float64(value)*s.Scale, actual)

// Testing payload
p, _ := can.PayloadFromHex(hex.EncodeToString(data[:]))
actual = s.DecodePayload(&p)
assert.DeepEqual(t, s.Offset+float64(value)*s.Scale, actual)
}

func TestSignal_UnmarshalPhysical_UnsignedBigEndian(t *testing.T) {
s := &Signal{
Name: "TestSignal",
IsSigned: false,
IsBigEndian: true,
Offset: -1,
Scale: 0.5,
Length: 10,
Start: 32,
Min: 0,
Max: 50,
}
const value uint64 = 180

// Testing can.Data
var data can.Data
data.SetUnsignedBitsBigEndian(uint8(s.Start), uint8(s.Length), value)
actual := s.UnmarshalPhysical(data)
assert.DeepEqual(t, s.Max, actual)

// Testing payload
p, _ := can.PayloadFromHex(hex.EncodeToString(data[:]))
actual = s.UnmarshalPhysicalPayload(&p)
assert.DeepEqual(t, s.Max, actual)
}

func TestSignal_UnmarshalPhysical_SignedBigEndian(t *testing.T) {
s := &Signal{
Name: "TestSignal",
IsSigned: true,
IsBigEndian: true,
Offset: -1,
Scale: 0.5,
Length: 10,
Start: 32,
Min: -50,
Max: 0,
}
const value int64 = -180

// Testing can.Data
var data can.Data
data.SetSignedBitsBigEndian(uint8(s.Start), uint8(s.Length), value)
actual := s.UnmarshalPhysical(data)
assert.DeepEqual(t, s.Min, actual)

// Testing payload
p, _ := can.PayloadFromHex(hex.EncodeToString(data[:]))
actual = s.UnmarshalPhysicalPayload(&p)
assert.DeepEqual(t, s.Min, actual)
}

func TestSignal_UnmarshalPhysical_UnsignedLittleEndian(t *testing.T) {
s := &Signal{
Name: "TestSignal",
IsSigned: false,
IsBigEndian: false,
Offset: -1,
Scale: 0.5,
Length: 10,
Start: 32,
Min: 0,
Max: 50,
}
const value uint64 = 180

// Testing can.Data
var data can.Data
data.SetUnsignedBitsLittleEndian(uint8(s.Start), uint8(s.Length), value)
actual := s.UnmarshalPhysical(data)
assert.DeepEqual(t, s.Max, actual)

// Testing payload
p, _ := can.PayloadFromHex(hex.EncodeToString(data[:]))
actual = s.UnmarshalPhysicalPayload(&p)
assert.DeepEqual(t, s.Max, actual)
}

func TestSignal_UnmarshalPhysical_SignedLittleEndian(t *testing.T) {
s := &Signal{
Name: "TestSignal",
IsSigned: true,
IsBigEndian: false,
Offset: -1,
Scale: 0.5,
Length: 10,
Start: 32,
Min: -50,
Max: 0,
}
const value int64 = -180

// Testing can.Data
var data can.Data
data.SetSignedBitsLittleEndian(uint8(s.Start), uint8(s.Length), value)
actual := s.UnmarshalPhysical(data)
assert.DeepEqual(t, s.Min, actual)

// Testing payload
p, _ := can.PayloadFromHex(hex.EncodeToString(data[:]))
actual = s.UnmarshalPhysicalPayload(&p)
assert.DeepEqual(t, s.Min, actual)
}

func TestSignal_FromPhysical_SaturatedCast(t *testing.T) {
s := &Signal{
Name: "TestSignal",
Expand Down

0 comments on commit 51c1b50

Please sign in to comment.