Channels and Parameters#
Parameters are the abstraction for accessing sampled data.
Each parameter can actually be an aggregate of multiple channels — for example, sampled periodically at multiple rates.
Example
McLaren hardware loggers can capture data at multiple rates, using triggers to define conditions for high-rate collection.
For example, when logging twisting forces within a gearbox, high-rate sampling is only required when changing gear, and can be triggered for a period by the gear-change event.
This makes optimal use of bandwidth and storage in the logging hardware and telemetry uplink.
Each channel can also be presented with multiple parameters.
Channels#
Channel properties are:
Id
(unsigned 32-bit integer):-
Unique id within a configuration, numbered contiguously from
0
or1
.Each parameter should reference one or more channels by id.
Interval
(signed 64-bit integer):- Interval in nanoseconds between samples, or
0
if the channel is not periodically sampled. Data Type
(enum):-
Data type/precision.
Signed/Unsigned integers for 8-bit, 16-bit, and 32-bit; Floating point at 32-bit and 64-bit precision.
Data Source
(enum):-
Data source, which for RTA should be one of
Timestamped
,Periodic
orRowData
.- Timestamped Data is variable-rate and has a delta-encoded timestamp for each sample;
- Periodic Data is sampled at a fixed rate — though sampling may not be continuous;
- Row Data encodes sections of memory — usually from an embedded controller;
Channels can also be assigned a Name
— sometimes used to indicate a memory address.
Note
The Configuration API and JSON schema permit some additional values for the Data Type
and Data Source
.
These have specialized uses and are not supported with RTA at this time.
Parameters#
Identifier
:-
Globally-unique identifier, which should be qualified with the app name:
someParameter:myapp
The prefix (name-part) should follow the same rules as variables in C-like languages: * Use a-z, A-Z, 0-9 and underscore * Don't start with a number
This ensures that the parameter can be used in functions in all situations without problems.
Name
:-
Human-readable name. Usually the same as the
Identifier
, minus the app name qualifier.ATLAS will show this name in the Parameter Browser.
As with
Identifier
, we recommend using only C-like variable names to ensure compatibility with functions. Description
:-
Human-readable description.
ATLAS will show this description in the Parameter Browser.
Channel Ids#
Each parameter should reference one (or more) channels, by Id.
The channels must belong to the same app.
var config = new ConfigurationBuilder
{
Applications =
{
new ApplicationBuilder("demo")
{
ChildParameters =
{
new ParameterBuilder("param:demo", "param", "Example Parameter")
{
ChannelIds =
{
1u
}
}
},
Channels =
{
new ChannelBuilder(1u, 0, DataType.Double64Bit, ChannelDataSource.Timestamped)
}
}
}
}.BuildConfiguration();
{
"demo": {
"tree": {
"params": [
"param:demo"
]
},
"parameters": [
{
"id": "param:demo",
"name": "param",
"desc": "Example Parameter",
"conv": "1to1:demo",
"channels": [
1
]
}
],
"channels": [
{
"id": 1,
"source": "timestamped"
}
],
"conversions": [
{
"name": "1to1:demo",
"unit": "",
"format": "%5.3f"
}
]
}
}
Conversion#
Every parameter must reference a Conversion, and the Configuration API will check that it is in the same app. But, for convenience, the Configuration API will automatically add a 1:1 Rational Conversion if no conversion is specified, as shown in this example:
var config = new ConfigurationBuilder
{
Applications =
{
new ApplicationBuilder("demo")
{
ChildParameters =
{
new ParameterBuilder("param1:demo", "param1", "Example Parameter 1"),
new ParameterBuilder("param2:demo", "param2", "Example Parameter 2")
{
ConversionName = "exampleConv:demo"
}
},
Conversions =
{
new TextConversionBuilder("exampleConv:demo")
{
Table =
{
[0] = "false",
[1] = "true"
},
DefaultValue = "file not found",
Format = "%s"
}
}
}
}
}.BuildConfiguration();
{
"demo": {
"tree": {
"params": [
"param1:demo",
"param2:demo"
]
},
"parameters": [
{
"id": "param1:demo",
"name": "param1",
"desc": "Example Parameter 1",
"conv": "1to1:demo"
},
{
"id": "param2:demo",
"name": "param2",
"desc": "Example Parameter 2",
"conv": "exampleConv:demo"
}
],
"conversions": [
{
"name": "exampleConv:demo",
"unit": "",
"format": "%s",
"text": {
"keys": [
0.0,
1.0
],
"values": [
"false",
"true"
],
"default": "file not found"
}
},
{
"name": "1to1:demo",
"unit": "",
"format": "%5.3f"
}
]
}
}
Range (Min/Max)#
It is quite important to specify the valid data range, as this will enable ATLAS to auto-scale displays.
There are two ranges:
Minimum Value
andMaximum Value
represent the minimum and maximum expected physical range (defaulting to0.0
);
("min"
/"max"
in JSON)Warning Minimum Value
andWarning Maximum Value
represent the minimum and maximum outside which a warning should be triggered — defaulting to the physical range if not specified;
("warnMin"
/"warnMax"
in JSON)
var config = new ConfigurationBuilder
{
Applications =
{
new ApplicationBuilder("demo")
{
ChildParameters =
{
new ParameterBuilder("param:demo", "param", "Example Parameter")
{
MinimumValue = -1500.0,
MaximumValue = +1500.0,
WarningMinimumValue = -1000.0,
WarningMaximumValue = +1000.0
}
}
}
}
}.BuildConfiguration();
{
"demo": {
"tree": {
"params": [
"param:demo"
]
},
"parameters": [
{
"id": "param:demo",
"name": "param",
"desc": "Example Parameter",
"min": -1500.0,
"max": 1500.0,
"warnMin": -1000.0,
"warnMax": 1000.0,
"conv": "1to1:demo"
}
],
"conversions": [
{
"name": "1to1:demo",
"unit": "",
"format": "%5.3f"
}
]
}
}
Format#
Parameter values are formatted using simple C-style format strings — for example, "%5.3f"
Supported Format Types
type | description |
---|---|
i |
signed decimal integer |
d |
signed decimal integer |
u |
unsigned decimal integer |
f |
signed decimal floating point |
g |
shortest representation (%e or %f) |
G |
shortest representation (%E or %F) |
e |
scientific notation — lower-case |
E |
scientific notation — upper-case |
o |
unsigned octal integer |
x |
unsigned hexadecimal integer — lower-case |
X |
unsigned hexadecimal integer — upper-case |
c |
character |
s |
string |
var config = new ConfigurationBuilder
{
Applications =
{
new ApplicationBuilder("demo")
{
ChildParameters =
{
new ParameterBuilder("p1:demo", "p1", "Parameter 1")
{
ConversionName = "myconv:demo"
},
new ParameterBuilder("p2:demo", "p2", "Parameter 2")
{
ConversionName = "myconv:demo",
FormatOverride = "%2.1f"
}
},
Conversions =
{
new RationalConversionBuilder("myconv:demo")
{
Format = "%8.2f"
}
}
}
}
}.BuildConfiguration();
{
"demo": {
"tree": {
"params": [
"p1:demo"
]
},
"parameters": [
{
"id": "p1:demo",
"name": "p1",
"desc": "Parameter 1",
"conv": "myconv:demo"
},
{
"id": "p2:demo",
"name": "p2",
"desc": "Parameter 2",
"format": "%2.1f",
"conv": "myconv:demo"
}
],
"conversions": [
{
"name": "myconv:demo",
"unit": "",
"format": "%8.2f"
}
]
}
}
Unit#
Like the format, parameter units (of measure) are defined in the Conversion rule, but can also be overridden in the parameter definition.
In this example, parameters 1 and 2 units are "rad"
and "deg"
, respectively:
var config = new ConfigurationBuilder
{
Applications =
{
new ApplicationBuilder("demo")
{
ChildParameters =
{
new ParameterBuilder("p1:demo", "p1", "Parameter 1")
{
ConversionName = "myconv:demo"
},
new ParameterBuilder("p2:demo", "p2", "Parameter 2")
{
ConversionName = "myconv:demo",
UnitOverride = "deg"
}
},
Conversions =
{
new RationalConversionBuilder("myconv:demo")
{
Unit = "rad"
}
}
}
}
}.BuildConfiguration();
{
"demo": {
"tree": {
"params": [
"p1:demo",
"p2:demo"
]
},
"parameters": [
{
"id": "p1:demo",
"name": "p1",
"desc": "Parameter 1",
"conv": "myconv:demo"
},
{
"id": "p2:demo",
"name": "p2",
"desc": "Parameter 2",
"unit": "deg",
"conv": "myconv:demo"
}
],
"conversions": [
{
"name": "myconv:demo",
"unit": "rad"
}
]
}
}
Offset#
An Offset
can be applied to the parameter value — for example, to set a zero point.
The offset is applied after conversions.
var config = new ConfigurationBuilder
{
Applications =
{
new ApplicationBuilder("demo")
{
ChildParameters =
{
new ParameterBuilder("param:demo", "param", "Example Parameter")
{
OffsetValue = +18.6
}
}
}
}
}.BuildConfiguration();
{
"demo": {
"tree": {
"params": [
"param:demo"
]
},
"parameters": [
{
"id": "param:demo",
"name": "param",
"desc": "Example Parameter",
"offset": 18.6,
"conv": "1to1:demo"
}
],
"conversions": [
{
"name": "1to1:demo",
"unit": "",
"format": "%5.3f"
}
]
}
}
Shifting and Masking#
A Bit Shift
and Data Bit Mask
can be applied to select specific bits from a channel.
- +ve shift is a right-shift
- -ve shift is a left-shift
- the mask is applied after shift, but before conversions
This can be used to extract many boolean values or flags from a packed section of telemetry.
Info
Shifting and Masking can only be applied to integer channels.
Worked Example
Bit Shift: 4
Data Bit Mask: 0x1
Channel value (u16): 7638
value bits: 0001 1101 1101 0110 (0x1DD6)
shifted value: 0000 0001 1101 1101
mask: 0000 0000 0000 0001 (0x0001)
result value: 0000 0000 0000 0001 (0x0001)
var config = new ConfigurationBuilder
{
Applications =
{
new ApplicationBuilder("demo")
{
ChildParameters =
{
new ParameterBuilder("param:demo", "param", "Example Parameter")
{
ChannelIds = {1u},
BitShift = 4,
DataBitMask = 0x1
}
},
Channels =
{
new ChannelBuilder(1u, 0L, DataType.Unsigned16Bit, ChannelDataSource.RowData)
}
}
}
}.BuildConfiguration();
{
"demo": {
"tree": {
"params": [
"param:demo"
]
},
"parameters": [
{
"id": "param:demo",
"name": "param",
"desc": "Example Parameter",
"mask": "1",
"shift": 4,
"conv": "1to1:demo",
"channels": [
1
]
}
],
"channels": [
{
"id": 1,
"type": "u16"
}
],
"conversions": [
{
"name": "1to1:demo",
"unit": "",
"format": "%5.3f"
}
]
}
}
Note
The "mask"
is serialized in hexadecimal.