Skip to content

Encoding of range limited REAL data types in ASN.1 as integers with scaling factor in ACN grammars #339

@freihamer

Description

@freihamer

The ASN1SCC compiler only supports encoding of REAL data types in an ACN grammar as standard IEEE754-1985-32 or IEEE754-1985-64.

However, it is often the case that legacy message protocols call for encoding of decimal numbers as integers, by definition of a decimal value (also known as "scaling factor") associated with the least significant bit.

In order to foster the adoption of the ASN1SCC compiler and make it possible to model a larger number of message protocol, introducing such integer based encoding of real data types is desirable.

######## Use Case Description ########

Following are two examples taken from the message protocol provided by an Inertial Navigation System (INS):

Image

Image

In these examples, we have two data fields which are decimal numbers encoded as signed or unsigned integers of different size, for which the decimal value associated with the least significant bits is defined.

In order to model such message protocols in ASN.1/ACN, the following should be supported by the ASN1SCC compiler:

ASN.1:

systemXBodyRate := REAL(-450..450)
systemXBodyRate [encoding twos-complement, size 32]

ACN:

gnssVerticalAccuracyLevel := REAL(0..655)
gnssVerticalAccuracyLevel [encoding pos-int, size 16]

######## Implementation Formalization ########

An implementation of the described use case can be formalized as follows:

Given a type defined as:

REAL_T ::= REAL(a .. b)

And an integer of n bits, the integer range is:

Unsigned: [0, 2ⁿ - 1]

Signed (two’s complement): [−2ⁿ⁻¹, 2ⁿ⁻¹ − 1]

Let’s define:

val_real ∈ [a, b]: the real-world value

val_int: the encoded integer

int_min, int_max: min and max of the integer type

scale = (b - a) / (int_max - int_min)

Mapping formulas:
Encoding (real → int):

val_int = round(((val_real - a) / (b - a)) * (int_max - int_min) + int_min)

Decoding (int → real):
val_real = a + ((val_int - int_min) / (int_max - int_min)) * (b - a)

Example
Assume:

GnssVerticalAccuracyLevel := REAL(0..655) -- ASN.1 definition
GnssVerticalAccuracyLevel [encoding pos-int, size 16]

Then:

int_min = 0
int_max = 65535
scale ≈ 0.01

So a value of val_real = 12.3232 would be encoded as
val_int = round((12.3232 / 655.0) * 65535) ≈ 1.232,9784 --> 1.233

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions