Skip to content

Commit

Permalink
changed interfaces to value types and Started adding compute methods
Browse files Browse the repository at this point in the history
  • Loading branch information
asap2Go committed Dec 8, 2022
1 parent 7c4a663 commit 0aa6cd0
Show file tree
Hide file tree
Showing 20 changed files with 643 additions and 326 deletions.
12 changes: 10 additions & 2 deletions a2l/characteristic.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type Characteristic struct {
//Deposit is the identifier of the corresponding record layout
Deposit string
DepositSet bool
encoding encodingEnum
maxDiff float64
maxDiffSet bool
conversion string
Expand All @@ -45,7 +46,7 @@ type Characteristic struct {
guardRails guardRailsKeyword
ifData []IfData
mapList []MapList
matrixDim matrixDim
MatrixDim MatrixDim
maxRefresh MaxRefresh
modelLink modelLink
number Number
Expand Down Expand Up @@ -132,6 +133,13 @@ forLoop:
break forLoop
}
log.Info().Msg("characteristic displayIdentifier successfully parsed")
case encodingToken:
c.encoding, err = parseEncodingEnum(tok)
if err != nil {
log.Err(err).Msg("characteristic encoding could not be parsed")
break forLoop
}
log.Info().Msg("characteristic encoding successfully parsed")
case ecuAddressExtensionToken:
c.ecuAddressExtension, err = parseECUAddressExtension(tok)
if err != nil {
Expand Down Expand Up @@ -188,7 +196,7 @@ forLoop:
c.mapList = append(c.mapList, buf)
log.Info().Msg("characteristic mapList successfully parsed")
case matrixDimToken:
c.matrixDim, err = parseMatrixDim(tok)
c.MatrixDim, err = parseMatrixDim(tok)
if err != nil {
log.Err(err).Msg("characteristic matrixDim could not be parsed")
break forLoop
Expand Down
79 changes: 77 additions & 2 deletions a2l/compu_method.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package a2l

import (
"errors"
"math"

"github.com/rs/zerolog/log"
)
Expand All @@ -25,6 +26,41 @@ type compuMethod struct {
statusStringRef statusStringRef
}

func (cm *compuMethod) convDecToPhy(dec float64) (float64, error) {
var err error
switch cm.conversionType {
case Identical:
return dec, nil
case Form:
//implement later.
case Linear:
if !(cm.coeffsLinear.aSet && cm.coeffsLinear.bSet) {
err = errors.New("coeffsLinear not set in compuMethod: " + cm.name)
log.Err(err).Msg("decimal value could not be converted")
return 0, err
}
return cm.coeffsLinear.a*dec + cm.coeffsLinear.b, err
case RatFunc:
if !(cm.coeffs.aSet && cm.coeffs.bSet && cm.coeffs.cSet && cm.coeffs.dSet && cm.coeffs.eSet && cm.coeffs.fSet) {
err = errors.New("coeffs not set in compuMethod: " + cm.name)
log.Err(err).Msg("decimal value could not be converted")
return 0, err
}
phy, err := cm.calcRatFunc(dec)
if err != nil {
log.Err(err).Msg("decimal value could not be converted")
return phy, err
}
case TabIntp:
case TabNointp:
case TabVerb:
default:
err = errors.New("conversion Type undefined in compuMethod: " + cm.name)
log.Err(err).Msg("decimal value could not be converted")
return 0, err
}
}

func parseCompuMethod(tok *tokenGenerator) (compuMethod, error) {
cm := compuMethod{}
var err error
Expand Down Expand Up @@ -77,13 +113,13 @@ forLoop:
log.Info().Msg("compuMethod statusStringRef successfully parsed")
default:
if tok.current() == emptyToken {
err = errors.New("unexpected end of file")
err = errors.New("unedecpected end of file")
log.Err(err).Msg("compuMethod could not be parsed")
break forLoop
} else if tok.current() == endCompuMethodToken {
break forLoop
} else if isKeyword(tok.current()) {
err = errors.New("unexpected token " + tok.current())
err = errors.New("unedecpected token " + tok.current())
log.Err(err).Msg("compuMethod could not be parsed")
break forLoop
} else if !cm.nameSet {
Expand Down Expand Up @@ -115,3 +151,42 @@ forLoop:
}
return cm, err
}

func (cm *compuMethod) calcRatFunc(dec float64) (float64, error) {
//following formula defines f(Physical) = Decimal
//y = (axx + bx + c) / (dxx + ex + f)
//inverted fi(Decimal) = Physical
//y = (e dec - b)/(2 (a - d dec)) ± sqrt((e dec - b)^2 - 4 (d dec - a) (f dec - c))/(2 (a - d dec))
firstDivisor := (2 * (cm.coeffs.a - cm.coeffs.d*dec))
if firstDivisor == 0 {
err = errors.New("rationality function cannot be computed(zero divisor) for compuMethod: " + cm.name)
log.Err(err).Msg("decimal value could not be converted")
return 0, err
}
secondDivisorPositive := (2 * (cm.coeffs.a - cm.coeffs.d*dec)) +
math.Sqrt(math.Pow((cm.coeffs.e*dec-cm.coeffs.b), 2)-4*(cm.coeffs.d*dec-cm.coeffs.a)*(cm.coeffs.f*dec-cm.coeffs.c))/firstDivisor
secondDivisorNegative := (2 * (cm.coeffs.a - cm.coeffs.d*dec)) -
math.Sqrt(math.Pow((cm.coeffs.e*dec-cm.coeffs.b), 2)-4*(cm.coeffs.d*dec-cm.coeffs.a)*(cm.coeffs.f*dec-cm.coeffs.c))/firstDivisor

if secondDivisorPositive != 0 && secondDivisorNegative != 0 {
plusVal := (cm.coeffs.e*dec - cm.coeffs.b) / secondDivisorPositive
minusVal := (cm.coeffs.e*dec - cm.coeffs.b) / secondDivisorNegative
testVal := (cm.coeffs.a*plusVal*plusVal + cm.coeffs.b*plusVal + cm.coeffs.c) / (cm.coeffs.d*plusVal*plusVal + cm.coeffs.e*plusVal + cm.coeffs.f)
if testVal == dec {
return plusVal, err
} else {
return minusVal, err
}
} else if secondDivisorPositive != 0 {
plusVal := (cm.coeffs.e*dec - cm.coeffs.b) / secondDivisorPositive
return plusVal, err
} else if secondDivisorNegative != 0 {
minusVal := (cm.coeffs.e*dec - cm.coeffs.b) / secondDivisorNegative
return minusVal, err
} else {
err = errors.New("rationality function cannot be computed(zero divisor) for compuMethod: " + cm.name)
log.Err(err).Msg("decimal value could not be converted")
return 0, err
}

}
25 changes: 22 additions & 3 deletions a2l/enums.go
Original file line number Diff line number Diff line change
Expand Up @@ -470,9 +470,28 @@ const (
//Identical defines a OneToOne conversion from hex to decimal
Identical conversionTypeEnum = identicalToken
Form conversionTypeEnum = formToken
Linear conversionTypeEnum = linearToken
RatFunc conversionTypeEnum = ratFuncToken
TabIntp conversionTypeEnum = tabIntpToken
/*Linear function of the following type:
f(x)=ax + b
for which:
PHYS=f(INT)
The coefficients a and b have to be
specified by the COEFFS_LINEAR
keyword.*/
Linear conversionTypeEnum = linearToken
/*RatFunc is a fractional rational function of the following type:
f(x)=(axx + bx + c)/(dxx + ex + f)
for which:
INT = f(PHYS)
Coefficients a, b, c, d, e, f have to be specified by the COEFFS keyword.
Note: For linear functions, use the ConversionType LINEAR,
for ident functions the ConversionType IDENT.
For non linear functions it must be possible to invert the formula within the limits of the
AXIS_PTS, CHARACTERISTIC or MEASUREMENT where it is used.
Otherwise use the ConversionType FORM.*/
RatFunc conversionTypeEnum = ratFuncToken
//TabIntp defines a table with interpolation
TabIntp conversionTypeEnum = tabIntpToken
//TabIntp defines a table withOut interpolation
TabNointp conversionTypeEnum = tabNointpToken
//Tab Verb is a table to convert numeric values into strings. e.g.: 1 -> "True"
TabVerb conversionTypeEnum = tabVerbToken
Expand Down
2 changes: 1 addition & 1 deletion a2l/instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ type instance struct {
displayIdentifier DisplayIdentifier
ecuAddressExtension ecuAddressExtension
ifData []IfData
matrixDim matrixDim
matrixDim MatrixDim
maxRefresh MaxRefresh
modelLink modelLink
overwrite overwrite
Expand Down
68 changes: 45 additions & 23 deletions a2l/matrix_dim.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,28 @@ import (
"github.com/rs/zerolog/log"
)

type matrixDim struct {
xDim uint16
xDimSet bool
yDim uint16
yDimSet bool
zDim uint16
zDimSet bool
type MatrixDim struct {
DimX uint16
DimXSet bool
DimY uint16
DimYSet bool
DimZ uint16
DimZSet bool
Dim4 uint16
Dim4Set bool
Dim5 uint16
Dim5Set bool
}

//parseMatrixDim parses the matrix dimensions of higher order Characteristics.
//this function is special because it is the only function that utilizes tokenizer.previous().
//this is the case because matrixDim is not clearly defined in earlier a2l standards (e.g. 1.6.0).
//therefore it is possible to describe a curve with "MATRIX_DIM 1" and "MATRIX_DIM 1 0 0".
//so the parser checks whether the token is a keyword in which case it rolls back the tokenizer one value and exits
//or if it finds a number that can be parsed.
//if it could parse x, y and z dim it will exit normally.
func parseMatrixDim(tok *tokenGenerator) (matrixDim, error) {
md := matrixDim{}
// parseMatrixDim parses the matrix dimensions of higher order Characteristics.
// this function is special because it is the only function that utilizes tokenizer.previous().
// this is the case because matrixDim is not clearly defined in earlier a2l standards (e.g. 1.6.0).
// therefore it is possible to describe a curve with "MATRIX_DIM 1" and "MATRIX_DIM 1 0 0".
// so the parser checks whether the token is a keyword in which case it rolls back the tokenizer one value and exits
// or if it finds a number that can be parsed.
// if it could parse x, y and z dim it will exit normally.
func parseMatrixDim(tok *tokenGenerator) (MatrixDim, error) {
md := MatrixDim{}
var err error
forLoop:
for {
Expand All @@ -39,34 +43,52 @@ forLoop:
tok.previous()
log.Info().Str("previous token", tok.current()).Msg("matrixDim rolled back to:")
break forLoop
} else if !md.xDimSet {
} else if !md.DimXSet {
var buf uint64
buf, err = strconv.ParseUint(tok.current(), 10, 16)
if err != nil {
log.Err(err).Msg("matrixDim xDim could not be parsed")
break forLoop
}
md.xDim = uint16(buf)
md.xDimSet = true
md.DimX = uint16(buf)
md.DimXSet = true
log.Info().Msg("matrixDim xDim successfully parsed")
} else if !md.yDimSet {
} else if !md.DimYSet {
var buf uint64
buf, err = strconv.ParseUint(tok.current(), 10, 16)
if err != nil {
log.Err(err).Msg("matrixDim yDim could not be parsed")
break forLoop
}
md.yDim = uint16(buf)
md.DimY = uint16(buf)
log.Info().Msg("matrixDim yDim successfully parsed")
} else if !md.zDimSet {
} else if !md.DimZSet {
var buf uint64
buf, err = strconv.ParseUint(tok.current(), 10, 16)
if err != nil {
log.Err(err).Msg("matrixDim zDim could not be parsed")
break forLoop
}
md.zDim = uint16(buf)
md.DimZ = uint16(buf)
log.Info().Msg("matrixDim zDim successfully parsed")
} else if !md.Dim4Set {
var buf uint64
buf, err = strconv.ParseUint(tok.current(), 10, 16)
if err != nil {
log.Err(err).Msg("matrixDim 4Dim could not be parsed")
break forLoop
}
md.Dim4 = uint16(buf)
log.Info().Msg("matrixDim 4Dim successfully parsed")
} else if !md.Dim5Set {
var buf uint64
buf, err = strconv.ParseUint(tok.current(), 10, 16)
if err != nil {
log.Err(err).Msg("matrixDim 5Dim could not be parsed")
break forLoop
}
md.Dim5 = uint16(buf)
log.Info().Msg("matrixDim 5Dim successfully parsed")
break forLoop
}
}
Expand Down
2 changes: 1 addition & 1 deletion a2l/measurement.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ type measurement struct {
functionList FunctionList
ifData []IfData
layout layout
matrixDim matrixDim
matrixDim MatrixDim
maxRefresh MaxRefresh
modelLink modelLink
physUnit physUnit
Expand Down
2 changes: 1 addition & 1 deletion a2l/structure_component.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ type structureComponent struct {
addressOffsetSet bool
addressType addrTypeEnum
layout layout
matrixDim matrixDim
matrixDim MatrixDim
symbolTypeLink symbolTypeLink
}

Expand Down
2 changes: 2 additions & 0 deletions a2l/tokens.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ const ecuCalibrationOffsetToken = "ECU_CALIBRATION_OFFSET"
const ecuToken = "ECU"
const eepromToken = "EEPROM"
const emptyToken = ""
const encodingToken = "ENCODING"
const endA2mlToken = "/end A2ML"
const endAnnotationTextToken = "/end ANNOTATION_TEXT"
const endAnnotationToken = "/end ANNOTATION"
Expand Down Expand Up @@ -538,6 +539,7 @@ var keywordMap = map[string]uint8{
"/end VARIANT_CODING": 0,
"/end VIRTUAL_CHARACTERISTIC": 0,
"/end VIRTUAL": 0,
"ENCODING": 0,
"EPK": 0,
"ERROR_MASK": 0,
"EXTENDED_LIMITS": 0,
Expand Down
2 changes: 1 addition & 1 deletion a2l/type_def_characteristic.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ type typeDefCharacteristic struct {
encoding encodingEnum
extendedLimits extendedLimits
format format
matrixDim matrixDim
matrixDim MatrixDim
number Number
physUnit physUnit
stepSize StepSize
Expand Down
2 changes: 1 addition & 1 deletion a2l/type_def_measurement.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ type typeDefMeasurement struct {
errorMask errorMask
format format
layout layout
matrixDim matrixDim
matrixDim MatrixDim
physUnit physUnit
}

Expand Down
Loading

0 comments on commit 0aa6cd0

Please sign in to comment.