list_of_strings
list_of_strings (strings:str)
*split a string separated by ‘,’, ‘;’, or ‘’ to a list of strings. Descripttion: split a long string to a list of strings.
Args: strings (str): The string to split.
Returns: list: The list of strings.*
test_eq(list_of_strings(r'foo;123, bar ebi' ), ['foo' ,'123' ,'bar' ,'ebi' ])
list_of_strings(r'"/PROJECT/MODULE[0]/MOD_COMMON, /PROJECT/IF_DATA[0]/Blob[0]/, /PROJECT/MODULE[0]/CHARACTERISTIC, TQD_trqTrqSetNormal_MAP_v"' )
['"/PROJECT/MODULE[0]/MOD_COMMON',
'/PROJECT/IF_DATA[0]/Blob[0]/',
'/PROJECT/MODULE[0]/CHARACTERISTIC',
'TQD_trqTrqSetNormal_MAP_v"']
JsonNodePathSegment
JsonNodePathSegment (name:str, indices:list[int]=None,
index_range:list[int]=None)
*result of parsing json node path segment
Args: name (str): name of the node indices (list[int]): indices of the node index_range (list[int]): index range of the node
if both indices and index_range are None, then the node is a dict, otherwise it is a list*
JsonNodePath
JsonNodePath (node_path:str)
*result of parsing json node path
Args: segments (listJsonNodePathSegment ): list of JsonNodePathSegment*
node_path = r"/PROJECT[0]/MODULE[0,3,5]/IF_DATA[3:2:8]/CHARACTERISTIC[3:5]/TQD_trqTrqSetNormal_MAP_v"
jnode_path = JsonNodePath(node_path)
print (jnode_path)
res = ['<PROJECT[0] list>' , '<MODULE[0,3,5] list>' , '<IF_DATA[3:2:8] list>' , '<CHARACTERISTIC[3:5] list>' , '<TQD_trqTrqSetNormal_MAP_v dict>' ]
for (s,r) in zip (jnode_path,res):
print (s)
test_eq(s.__str__ (), r)
<JsonNodePath [<PROJECT[0] list>, <MODULE[0,3,5] list>, <IF_DATA[3:2:8] list>, <CHARACTERISTIC[3:5] list>, <TQD_trqTrqSetNormal_MAP_v dict>]>
<PROJECT[0] list>
<MODULE[0,3,5] list>
<IF_DATA[3:2:8] list>
<CHARACTERISTIC[3:5] list>
<TQD_trqTrqSetNormal_MAP_v dict>
get_argparser
get_argparser ()
*Get the argument parser for the command line interface. Descripttion: Get the argument parser for the command line interface.
Returns: argparse.ArgumentParser: The argument parser for the command line interface.*
# jnode_paths = []
# for p in args.node_paths:
# print(p)
# jnode_path = JsonNodePath(p)
# print(jnode_path)
# jnode_paths.append(jnode_path)
# pprint(jnode_path.lazy_path)
# pprint(re.split(r'\.', jnode_path.lazy_path))
# pprint(jnode_path.leaf.name)
# print()
print (args.node_path)
jnode_path = JsonNodePath(args.node_path)
print (jnode_path)
pprint(jnode_path.lazy_path)
pprint(re.split(r'\.' , jnode_path.lazy_path))
pprint(jnode_path.leaf.name)
print ()
# node_path = r"/PROJECT/MODULE[]/CHARACTERISTIC[]"
# node_path = args.node_path
# jnode_path = JsonNodePath(node_path)
# res = ['<PROJECT[0] list>', '<MODULE[0,3,5] list>', '<IF_DATA[3:2:8] list>', '<CHARACTERISTIC[3:5] list>', '<TQD_trqTrqSetNormal_MAP_v dict>']
for s in jnode_path:
print (s)
/PROJECT/MODULE[],
<JsonNodePath [<PROJECT dict>, <MODULE[] list>]>
'PROJECT.MODULE.item'
['PROJECT', 'MODULE', 'item']
'MODULE'
<PROJECT dict>
<MODULE[] list>
node_path = r"/PROJECT/MODULE[]/CHARACTERISTIC[]"
re.split(r',\s*|;\s*|/\s*|\s+' , node_path)
re.split('(?:\[\d\])' , 'foo, a[0], bar' )
['', 'PROJECT', 'MODULE[]', 'CHARACTERISTIC[]']
prog = re.compile ('(\[\d\])' )
result = prog.search('/PROJECT/MODULE[0]/CHARACTERISTIC[0]' ).group(1 )
print (result)
re.search('(?:\[(\d)\])' , 'foo, a[0], bar' ).groups()
re.search('(?:\[(\d,?\s*\d*)\])' , 'foo, a[0, 4], bar' ).groups()
try :
res = re.search('(?:\[(\d+),?\s*(\d*)\])' , 'foo, a[0, 24], bar' ).groups()
print (res)
# re.search('(?:\[(\d,?\s*\d*)\])', 'foo, a[0, 4], bar').groups()
except AttributeError as exc:
print (exc)
try :
res = re.search('(?:\[(\d+),?\s*(\d*)\])' , 'foo, bar' ).groups()
print (res)
# re.search('(?:\[(\d,?\d*)\])', 'foo').groups()
except AttributeError as exc:
print (exc)
'NoneType' object has no attribute 'groups'
# node_path = args.node_paths[0]
test_node_path = r"/PROJECT[0]/MODULE[0,3,5]/IF_DATA[3:2:8]/CHARACTERISTIC[3:5]/TQD_trqTrqSetNormal_MAP_v"
path_segments = re.split(r'/\s*' , test_node_path)[1 :]
print (path_segments)
['PROJECT[0]', 'MODULE[0,3,5]', 'IF_DATA[3:2:8]', 'CHARACTERISTIC[3:5]', 'TQD_trqTrqSetNormal_MAP_v']
# prefix = '.'.join(jnode_path.lazy_path.split('.')[:-1])
prefix = JsonNodePath(args.node_path).lazy_path
args.path, prefix
objects = ijson.items(open (args.path, 'r' ), prefix)
module_items = list (objects)[0 ]
# pprint(module_items)
pprint(module_items['CHARACTERISTIC' ][0 ]['Name' ])
print (' \n ' )
l = {k:v for k,v in module_items['CHARACTERISTIC' ][0 ]['AXIS_DESCR' ][0 ].items()}
pprint(l)
('/home/n/devel/candycan/res/vbu_sample.json', 'PROJECT.MODULE.item')
{'Value': 'TQD_trqTrqSetNormal_MAP_v'}
{'AXIS_PTS_REF': {'AxisPoints': {'Value': 'TQD_vSgndSpd_MAP_y'}},
'Attribute': 'COM_AXIS',
'Conversion': {'Value': 'VBU_L045A_CWP_05_09T_AImode_CM_single'},
'InputQuantity': {'Value': 'TQD_vVehSpd'},
'LowerLimit': {'DecimalSize': 5,
'IntegralSign': '-',
'IntegralSize': 1,
'Value': Decimal('-3.4E+38')},
'MaxAxisPoints': {'Base': 10, 'Size': 2, 'Value': 14},
'UpperLimit': {'DecimalSize': 5,
'IntegralSize': 1,
'Value': Decimal('3.4E+38')}}
args.path, args.node_path, args.leaves
('/home/n/devel/candycan/res/vbu_sample.json',
'/PROJECT/MODULE[], ',
['TQD_trqTrqSetNormal_MAP_v',
'VBU_L045A_CWP_05_09T_AImode_CM_single',
'Lookup2D_FLOAT32_IEEE',
'Lookup2D_X_FLOAT32_IEEE',
'Scalar_FLOAT32_IEEE',
'TQD_vVehSpd',
'TQD_vSgndSpd_MAP_y',
'TQD_pctAccPedPosFlt',
'TQD_pctAccPdl_MAP_x'])
calibs = []
node_paths = [r"/PROJECT/MODULE[]/CHARACTERISTIC[]" ,
r"/PROJECT/MODULE[]/MEASUREMENT[]" ,
r"/PROJECT/MODULE[]/AXIS_PTS[]" ,
r"/PROJECT/MODULE[]/COMPU_METHOD[]" ]
jnode_paths = [JsonNodePath(p) for p in node_paths]
for jp in jnode_paths:
prefix = jp.lazy_path
objects = ijson.items(open (args.path, "r" ), prefix)
# calib = [o for o in objects for k, v in o.items() if k == 'Name']
# pprint(calib)
# len(calib)
# print(prefix)
for o in objects:
for k, v in o.items():
if k == 'Name' :
if v['Value' ] in args.leaves:
calibs.append(o)
pprint(calibs[3 ])
# calib['LowerLimit']['Value'], calib['UpperLimit']['Value']
# for c in calibs:
# pprint(c)
{'Address': {'Base': 16, 'Size': 8, 'Value': '1879071450'},
'Conversion': {'Value': 'VBU_L045A_CWP_05_09T_AImode_CM_single'},
'DepositR': {'Value': 'Lookup2D_X_FLOAT32_IEEE'},
'InputQuantity': {'Value': 'TQD_vVehSpd'},
'LongIdentifier': {},
'LowerLimit': {'DecimalSize': 5,
'IntegralSign': '-',
'IntegralSize': 1,
'Value': Decimal('-3.4E+38')},
'MaxAxisPoints': {'Base': 10, 'Size': 2, 'Value': 14},
'MaxDiff': {},
'Name': {'Value': 'TQD_vSgndSpd_MAP_y'},
'UpperLimit': {'DecimalSize': 5,
'IntegralSize': 1,
'Value': Decimal('3.4E+38')}}
Bunch
Bunch (key, **kwargs)
collector of a bunch of named stuff into one object; a generic record/struct type, indexed by keys
Record
Record (**kwargs)
object with dynamic attributes
Calibration
Calibration (**kwargs)
*Target calibration object for torque map; a2l section [“PROJECT”][“MODULE”][“CHARACTERISTIC”]
First level keys will be turned into attributes of the object, encoded registered values will be replaced with the corresponding objects. Otherwiese the key-value pairs will be kept as is.*
Measurement
Measurement (**kwargs)
Measurement object like speed, acc pedal position, etc; a2l section [“PROJECT”][“MODULE”][“MEAUREMENT”]]
AxisScale
AxisScale (**kwargs)
Target calibration object for torque map; a2l section [“PROJECT”][“MODULE”][“AXIS_PTS”]
DataConversion
DataConversion (**kwargs)
Data conversion object for calibration; a2l section [“PROJECT”][“MODULE”][“COMPU_METHOD”]]
DataLayout
DataLayout (**kwargs)
Data type object for calibration; a2l section [“PROJECT”][“MODULE”][“RECORD_LAYOUT”]
{'CHARACTERISTIC': 'Calibration',
'MEASUREMENT': 'Measurement',
'AXIS_PTS': 'AxisScale',
'COMPU_METHOD': 'DataConversion',
'RECORD_LAYOUT': 'DataLayout'}
load_class_type_a2l_lazy
load_class_type_a2l_lazy (path:pathlib.Path,
jnode_path:Optional[__main__.JsonNodePath]=<Jso
nNodePath [<PROJECT dict>, <MODULE[] list>]>)
*Search for the calibration key in the A2L file. Descripttion: Load the A2L file as a dictionary.
Create record type (enum class) for the calibration parameter for the given a2l json file
Args: path (str): The path to the A2L file. section_key (str): The section key to search for the calibration type.
Returns: dict: The A2L file as a dictionary.*
path
Path
jnode_path
OptionalJsonNodePath
<JsonNodePath [, <MODULE[] list>]>
Returns
type(Enum)
return a class type
pprint(RecordTypes)
set (RecordTypes.__members__.keys())
Record.record_registry
{'AXIS_PTS',
'CHARACTERISTIC',
'COMPU_METHOD',
'GROUP',
'IF_DATA',
'LongIdentifier',
'MEASUREMENT',
'MOD_COMMON',
'MOD_PAR',
'Name',
'RECORD_LAYOUT'}
load_records_lazy
load_records_lazy (path:pathlib.Path, leaves:list[str],
jnode_path:Optional[__main__.JsonNodePath]=<JsonNodePa
th [<PROJECT dict>, <MODULE[] list>]>)
*load records from a json file lazily
Args: path (Path): path to the json file # use ijson no need for jnode_paths, though sacrificing a little bit efficiency (listJsonNodePath ): list of JsonNodePath to the leaves leaves (list[str]): list of leaf indices to the records, needs to be unique and in the first item of the a2l json file
Returns: dict[str, Record]: dict of Records and its subclasses, indexed by the leaf indices*
# jnode_path = '.'.join(jnode_paths[0].lazy_path.split('.')[:-2])
args.path, args.leaves, args.node_path
('/home/n/devel/candycan/res/vbu_sample.json',
['TQD_trqTrqSetNormal_MAP_v',
'VBU_L045A_CWP_05_09T_AImode_CM_single',
'Lookup2D_FLOAT32_IEEE',
'Lookup2D_X_FLOAT32_IEEE',
'Scalar_FLOAT32_IEEE',
'TQD_vVehSpd',
'TQD_vSgndSpd_MAP_y',
'TQD_pctAccPedPosFlt',
'TQD_pctAccPdl_MAP_x'],
'/PROJECT/MODULE[], ')
Record.load_records(args.path, args.leaves, JsonNodePath(args.node_path)) #, jnode_path= args.node_path.lazy_path)
Record.subclass_registry
sorted (Record.record_registry)
{'CHARACTERISTIC': 'Calibration',
'MEASUREMENT': 'Measurement',
'AXIS_PTS': 'AxisScale',
'COMPU_METHOD': 'DataConversion',
'RECORD_LAYOUT': 'DataLayout'}
['AxisScale.TQD_pctAccPdl_MAP_x',
'AxisScale.TQD_vSgndSpd_MAP_y',
'Calibration.TQD_trqTrqSetNormal_MAP_v',
'DataConversion.VBU_L045A_CWP_05_09T_AImode_CM_single',
'DataLayout.Lookup2D_FLOAT32_IEEE',
'DataLayout.Lookup2D_X_FLOAT32_IEEE',
'DataLayout.Scalar_FLOAT32_IEEE',
'Measurement.TQD_pctAccPedPosFlt',
'Measurement.TQD_vVehSpd']
['TQD_trqTrqSetNormal_MAP_v',
'VBU_L045A_CWP_05_09T_AImode_CM_single',
'Lookup2D_FLOAT32_IEEE',
'Lookup2D_X_FLOAT32_IEEE',
'Scalar_FLOAT32_IEEE',
'TQD_vVehSpd',
'TQD_vSgndSpd_MAP_y',
'TQD_pctAccPedPosFlt',
'TQD_pctAccPdl_MAP_x']
records = load_records_lazy(args.path, args.leaves, JsonNodePath(args.node_path))
pprint(list (records.keys()))
len (records)
key = 'AxisScale.' + args.leaves[6 ]
print (key)
measurement = records[key]
measurement, measurement.record_type,
measurement.__dict__
key = 'AxisScale.' + args.leaves[8 ]
print (key)
measurement = records[key]
measurement, measurement.record_type,
measurement.__dict__
['Calibration.TQD_trqTrqSetNormal_MAP_v',
'Measurement.TQD_vVehSpd',
'Measurement.TQD_pctAccPedPosFlt',
'AxisScale.TQD_vSgndSpd_MAP_y',
'AxisScale.TQD_pctAccPdl_MAP_x',
'DataConversion.VBU_L045A_CWP_05_09T_AImode_CM_single',
'DataLayout.Scalar_FLOAT32_IEEE',
'DataLayout.Lookup2D_FLOAT32_IEEE',
'DataLayout.Lookup2D_X_FLOAT32_IEEE']
AxisScale.TQD_vSgndSpd_MAP_y
AxisScale.TQD_pctAccPdl_MAP_x
(<AxisScale: 'TQD_vSgndSpd_MAP_y'>, <DataLayout: 'Lookup2D_X_FLOAT32_IEEE'>)
{'Name': 'TQD_vSgndSpd_MAP_y',
'LongIdentifier': {},
'Address': {'Value': '1879071450', 'Base': 16, 'Size': 8},
'InputQuantity': {'Value': 'TQD_vVehSpd'},
'DepositR': {'Value': 'Lookup2D_X_FLOAT32_IEEE'},
'MaxDiff': {},
'Conversion': {'Value': 'VBU_L045A_CWP_05_09T_AImode_CM_single'},
'MaxAxisPoints': {'Value': 14, 'Base': 10, 'Size': 2},
'LowerLimit': {'Value': Decimal('-3.4E+38'),
'IntegralSign': '-',
'IntegralSize': 1,
'DecimalSize': 5},
'UpperLimit': {'Value': Decimal('3.4E+38'),
'IntegralSize': 1,
'DecimalSize': 5},
'record_type': <DataLayout: 'Lookup2D_X_FLOAT32_IEEE'>}
(<AxisScale: 'TQD_pctAccPdl_MAP_x'>, <DataLayout: 'Lookup2D_X_FLOAT32_IEEE'>)
{'Name': 'TQD_pctAccPdl_MAP_x',
'LongIdentifier': {},
'Address': {'Value': '1879073310', 'Base': 16, 'Size': 8},
'InputQuantity': {'Value': 'TQD_pctAccPedPosFlt'},
'DepositR': {'Value': 'Lookup2D_X_FLOAT32_IEEE'},
'MaxDiff': {},
'Conversion': {'Value': 'VBU_L045A_CWP_05_09T_AImode_CM_single'},
'MaxAxisPoints': {'Value': 17, 'Base': 10, 'Size': 2},
'LowerLimit': {'Value': Decimal('-3.4E+38'),
'IntegralSign': '-',
'IntegralSize': 1,
'DecimalSize': 5},
'UpperLimit': {'Value': Decimal('3.4E+38'),
'IntegralSize': 1,
'DecimalSize': 5},
'record_type': <DataLayout: 'Lookup2D_X_FLOAT32_IEEE'>}
key = 'Measurement.' + args.leaves[5 ]
print (key)
measurement = records[key]
measurement, measurement.record_type,
measurement.__dict__
key = 'Measurement.' + args.leaves[7 ]
print (key)
measurement = records[key]
measurement, measurement.record_type,
measurement.__dict__
Measurement.TQD_vVehSpd
Measurement.TQD_pctAccPedPosFlt
(<Measurement: 'TQD_vVehSpd'>, <DataLayout: 'Scalar_FLOAT32_IEEE'>)
{'Name': 'TQD_vVehSpd',
'LongIdentifier': {},
'DataType': {'Value': 'FLOAT32_IEEE'},
'Conversion': {'Value': 'VBU_L045A_CWP_05_09T_AImode_CM_single'},
'Resolution': {'Base': 10, 'Size': 1},
'Accuracy': {},
'LowerLimit': {'Value': Decimal('-3.4E+38'),
'IntegralSign': '-',
'IntegralSize': 1,
'DecimalSize': 5},
'UpperLimit': {'Value': Decimal('3.4E+38'),
'IntegralSize': 1,
'DecimalSize': 5},
'ECU_ADDRESS': {'Address': {'Value': '1879113976', 'Base': 16, 'Size': 8}},
'record_type': <DataLayout: 'Scalar_FLOAT32_IEEE'>}
(<Measurement: 'TQD_pctAccPedPosFlt'>, <DataLayout: 'Scalar_FLOAT32_IEEE'>)
{'Name': 'TQD_pctAccPedPosFlt',
'LongIdentifier': {},
'DataType': {'Value': 'FLOAT32_IEEE'},
'Conversion': {'Value': 'VBU_L045A_CWP_05_09T_AImode_CM_single'},
'Resolution': {'Base': 10, 'Size': 1},
'Accuracy': {},
'LowerLimit': {'Value': Decimal('-3.4E+38'),
'IntegralSign': '-',
'IntegralSize': 1,
'DecimalSize': 5},
'UpperLimit': {'Value': Decimal('3.4E+38'),
'IntegralSize': 1,
'DecimalSize': 5},
'ECU_ADDRESS': {'Address': {'Value': '1879113888', 'Base': 16, 'Size': 8}},
'record_type': <DataLayout: 'Scalar_FLOAT32_IEEE'>}
key = 'DataLayout.' + args.leaves[4 ]
print (key)
record_type = records[key]
record_type, record_type.data_type,
record_type.__dict__
key = 'DataLayout.' + args.leaves[3 ]
print (key)
record_type = records[key]
record_type, record_type.data_type,
record_type.__dict__
DataLayout.Scalar_FLOAT32_IEEE
DataLayout.Lookup2D_X_FLOAT32_IEEE
(<DataLayout: 'Scalar_FLOAT32_IEEE'>, 'FLOAT32_IEEE')
{'Name': 'Scalar_FLOAT32_IEEE',
'FNC_VALUES': {'Position': {'Value': 1, 'Base': 10, 'Size': 1},
'DataType': {'Value': 'FLOAT32_IEEE'},
'IndexMode': 'COLUMN_DIR',
'AddressType': {'Value': 'DIRECT'}}}
(<DataLayout: 'Lookup2D_X_FLOAT32_IEEE'>, 'FLOAT32_IEEE')
{'Name': 'Lookup2D_X_FLOAT32_IEEE',
'AXIS_PTS_X': {'Position': {'Value': 1, 'Base': 10, 'Size': 1},
'DataType': {'Value': 'FLOAT32_IEEE'},
'IndexIncr': {'Value': 'INDEX_INCR'},
'Addressing': {'Value': 'DIRECT'}}}
key = 'Calibration.' + args.leaves[0 ]
print (key)
records[key]
Calibration.TQD_trqTrqSetNormal_MAP_v
<Calibration: 'TQD_trqTrqSetNormal_MAP_v'>
calib = Record.fetch(key)
pprint(calib)
calib.axes[0 ].axis_scale.input
calib.axes[0 ].axis_scale.input .record_type
calib.axes[0 ].axis_scale.input .record_type.type_size
<Calibration: 'TQD_trqTrqSetNormal_MAP_v'>
<Measurement: 'TQD_vVehSpd'>
<DataLayout: 'Scalar_FLOAT32_IEEE'>
calib.record_type
calib.record_type.data_type
calib.record_type.type_size
calib.axes[0 ].axis_scale.record_type.type_size
<DataLayout: 'Lookup2D_FLOAT32_IEEE'>
calib.axes[0 ].axis_scale.input .record_type
calib.axes[0 ].axis_scale.input .record_type.type_size
calib.axes[0 ].axis_scale.data_conversion
calib.axes[0 ].data_conversion.Format
<DataLayout: 'Scalar_FLOAT32_IEEE'>
<DataConversion: 'VBU_L045A_CWP_05_09T_AImode_CM_single'>
for k,v in records.items():
pprint(v)
pprint(records['Calibration.TQD_trqTrqSetNormal_MAP_v' ].axes[0 ].measurement.data_conversion.Name)
<Calibration: 'TQD_trqTrqSetNormal_MAP_v'>
<Measurement: 'TQD_vVehSpd'>
<Measurement: 'TQD_pctAccPedPosFlt'>
<AxisScale: 'TQD_vSgndSpd_MAP_y'>
<AxisScale: 'TQD_pctAccPdl_MAP_x'>
<DataConversion: 'VBU_L045A_CWP_05_09T_AImode_CM_single'>
<DataLayout: 'Scalar_FLOAT32_IEEE'>
<DataLayout: 'Lookup2D_FLOAT32_IEEE'>
<DataLayout: 'Lookup2D_X_FLOAT32_IEEE'>
'VBU_L045A_CWP_05_09T_AImode_CM_single'
XCPConfig
XCPConfig (channel:typing.Annotated[int,Ge(ge=0),Le(le=10000)]=3,
download:typing.Annotated[int,Ge(ge=0),Lt(lt=10000)]=630,
upload:typing.Annotated[int,Ge(ge=0),Lt(lt=10000)]=631)
XCP configuration for the calibration parameter
config = XCPConfig(channel= 3 , download= 630 , upload= 631 )
c = config.model_dump()
pprint(c)
# {**c}
# type(config.download_can_id), config.download_can_id, config.channel
# config.model_dump()
config.model_json_schema()
{'channel': 3, 'download_can_id': 630, 'upload_can_id': 631}
{'description': 'XCP configuration for the calibration parameter',
'properties': {'channel': {'default': 3,
'description': 'XCP channel',
'maximum': 10000,
'minimum': 0,
'title': 'Channel',
'type': 'integer'},
'download': {'default': 630,
'description': 'CAN ID for downloading',
'exclusiveMaximum': 10000,
'minimum': 0,
'title': 'Download',
'type': 'integer'},
'upload': {'default': 631,
'description': 'CAN ID for uploading',
'exclusiveMaximum': 10000,
'minimum': 0,
'title': 'Upload',
'type': 'integer'}},
'title': 'XCPConfig',
'type': 'object'}
check_a2l_type
check_a2l_type (v:str)
class MyModel(BaseModel):
foo: A2LDataType
try :
m = MyModel(foo= 'FLOAT32_IEEE1' )
except ValidationError as exc:
print (exc)
1 validation error for MyModel
foo
Assertion failed, Invalid data type FLOAT32_IEEE1 [type=assertion_error, input_value='FLOAT32_IEEE1', input_type=str]
For further information visit https://errors.pydantic.dev/2.6/v/assertion_error
t = A2LDataType('FLOAT32_IEEE' )
t in type_collection
t = A2LDataType(23 )
t
t in type_collection
'FLOAT32_IEEE1' in type_collection
t = A2LDataType('FLOAT32_IEEE1' )
t
t in type_collection
k
'DataLayout.Lookup2D_X_FLOAT32_IEEE'
# Testing forward referencing
class MyClass:
def __init__ (self , value: int ):
self .value = value
def compare(self , other: MyClass): # this is default for python 3.7+ or "other: 'MyClass'"
if self .value > other.value:
print ("This instance has a greater value." )
else :
print ("The other instance has a greater or equal value." )
# Create instances
instance1 = MyClass(10 )
instance2 = MyClass(5 )
# Call the compare method on instance1, passing instance2 as an argument
instance2.compare(instance1) # Output: "This instance has a greater value."
The other instance has a greater or equal value.
def func_a():
print (func_b()) # Forward reference to func_b
def func_b():
return "Hello from func_b!"
func_a() # Output: "Hello from func_b!"
XCPData
XCPData (name:str='TQD_trqTrqSetNormal_MAP_v', address:Annotated[Optional
[str],_PydanticGeneralMetadata(pattern='^[0-9A-Fa-
f]{8}$')]='7000aa2a', dim:Annotated[List[Annotated[int,FieldInfo
(annotation=NoneType,required=True,frozen=True,metadata=[Gt(gt=0
),Lt(lt=50)])]],Len(min_length=2,max_length=2)], value_type:typi
ng.Annotated[str,AfterValidator(func=<functioncheck_a2l_typeat0x
7f1cede5ab60>)]='FLOAT32_IEEE', value_length:typing.Annotated[in
t,Gt(gt=0),MultipleOf(multiple_of=2)]=4, value:typing.Annotated[
str,MinLen(min_length=1),MaxLen(max_length=3000),_PydanticGenera
lMetadata(pattern='^[0-9A-Fa-f]{0,3000}$')])
XCP data for the calibration parameter
Get_Init_XCPData
Get_Init_XCPData
(path:pathlib.Path=Path('../res/init_value_17rows.json'
))
try :
xcp_data_list = Get_Init_XCPData('../res/init_value_17rows.json' )
len (xcp_data_list)
except ValidationError as exc:
print (exc)
# xcp_data[0], f'value byte length: {len(xcp_data[0].value)}'
# xcp_data[1], f'value byte length: {len(xcp_data[1].value)}'
xcp_data_list[0 ].value_bytes[:2 ], f" { xcp_data_list[0 ]. value_bytes[:2 ]. hex ()} "
xcp_data_list[0 ]
len (xcp_data_list[0 ].value_bytes), len (xcp_data_list[0 ].value)
{ 'address': '7000aa2a',
'dim': [21, 17],
'name': 'TQD_trqTrqSetNormal_MAP_v',
'type_size': 4,
'value': '1f5a84441f...444',
'value_array_view': array([[ 1058.816, 1058.816, 1058.816, ..., 4075.653, 4435.98 ,
4435.98 ],
[ 70.079, 152.178, 234.277, ..., 4026.657, 4526.757,
4526.757],
[-3235.127, -1510.53 , 214.067, ..., 4006.447, 4566.45 ,
4566.45 ],
...,
[-2999.402, -2441.199, -1882.996, ..., 1958.867, 1984.853,
1984.853],
[-2973.497, -2419.99 , -1866.482, ..., 1810.322, 1826.58 ,
1826.58 ],
[-2946.278, -2461.24 , -1976.201, ..., 1667.968, 1826.58 ,
1826.58 ]], dtype=float32),
'value_bytes': "b'\\x1f'...b'D'",
'value_length': 4,
'value_type': 'FLOAT32_IEEE'}
t = tuple (xcp_data_list[0 ].dim)
t
xcp_data_0 = xcp_data_list[0 ].value_array_view
xcp_data_0
array([[ 1058.816, 1058.816, 1058.816, ..., 4075.653, 4435.98 ,
4435.98 ],
[ 70.079, 152.178, 234.277, ..., 4026.657, 4526.757,
4526.757],
[-3235.127, -1510.53 , 214.067, ..., 4006.447, 4566.45 ,
4566.45 ],
...,
[-2999.402, -2441.199, -1882.996, ..., 1958.867, 1984.853,
1984.853],
[-2973.497, -2419.99 , -1866.482, ..., 1810.322, 1826.58 ,
1826.58 ],
[-2946.278, -2461.24 , -1976.201, ..., 1667.968, 1826.58 ,
1826.58 ]], dtype=float32)
a = xcp_data_list[0 ].value_array_view
a.shape, a.dtype
a
((21, 17), dtype('float32'))
array([[ 1058.816, 1058.816, 1058.816, ..., 4075.653, 4435.98 ,
4435.98 ],
[ 70.079, 152.178, 234.277, ..., 4026.657, 4526.757,
4526.757],
[-3235.127, -1510.53 , 214.067, ..., 4006.447, 4566.45 ,
4566.45 ],
...,
[-2999.402, -2441.199, -1882.996, ..., 1958.867, 1984.853,
1984.853],
[-2973.497, -2419.99 , -1866.482, ..., 1810.322, 1826.58 ,
1826.58 ],
[-2946.278, -2461.24 , -1976.201, ..., 1667.968, 1826.58 ,
1826.58 ]], dtype=float32)
# xcp_data[0].hex_to_float(a)
# s = ''.join([h[i:i+2] for i in range(0, len(h), 2)][::-1])
# xcp_data[0].value
b = bytes .fromhex(xcp_data_list[0 ].value) # fromhex() takes a string and returns a bytes object
b.hex ()
xcp_data_list[0 ].value
b[0 ], b[1 ]
hex (b[0 ])
hex (b[1 ])
'1f5a84441f5a84441f5a84441f5a84441f5a84441f5a84444ec38f44f1d9aa4494f0c5443707e14496d40445902519458a762d457f18564573ba7e45d79f8a45d79f8a4576288c42972d1843f3466a43057ee14349ec26448f195d446aa389440dbaa444b0d0bf4453e7da44a4c401459e15164599662a458d08534582aa7b450e768d450e768d4508324ac5f4d0bcc4381156432863d743dade2144200c5844b31c87445633a244f949bd449c60d8444881004543d214453d23294531c5514526677a459ab38e459ab38e4508e449c58f07c4c4118fbb4229579a4347e50244f99e3844ab586e442f09924408e6ac44e1c2c744270ef044b62c0c45595220459f9d4845e4e87045d79f8a45d79f8a45008149c5bf6002c5f6016dc43dfc3d435b8ac9434c0b1a446b514f44c54b8244d4ee9c44e391b7447a86df4488bd0345d4b717456bac3f4502a16745ccca8745d79f8a45f10849c5b2ed02c5d14973c49f8c14433d04b34316e10d440c404244039f7644fd7e954479aeaf44b2f5d644eb3cfe4412c212454b093a4584506145df4b8445d79f8a45da7b48c5f35c03c535f878c4201bdc4267f69d4303730244d2ea3544a1626944386d8e442029a844fcc2ce44d75cf54459fb0d4535953445102f5b4576e48045d79f8a45bbd947c5459011c5a08db6c46af513c4d7608a432782ef43bb512a4463e25c4485b98744d901a14457eec644d5daec44a963094527502f45a53c554523297b45d79f8a45942247c5d39711c5231ab8c43f091ac41f8770439096db43c8741f44481e5144e4638144a4389a44c577bf44e5b6e44402fb0445233a2a4543794f4563b87445dff58545665646c5338511c5ff67b9c4318b1fc470e64e435584c843b9ca144448534544d7db7544333293449e98b74409ffdb44ba3200452599244590ff4845fb656d45446c7145317545c56b5511c54b6bbac4815724c4549e3043651eb743d0f60a446d5e3a440ac66944d4968c448a24b04440b2d344f63ff744b12d1f4567bb4245dc916245dc916245f37e44c50b0319c5440edbc4731684c4877ab4c3be64a7430bf90144b73f304462865e4487668644881ba94489d0cb448a85ee44c6f71945c7ac3c45646b5345646b5345ae7343c5298718c54735dbc43d5c85c4c90cbec361579943d6a2f34325f72644e01c54444da18044997da244e559c4443036e64464f7144594b6354594b6354594b63545615342c59cf617c5ad33dbc4227a86c45c02c7c3cfe38b437eabe14397b91b446e9d46444581714484eb98446616b9444741d94485cb0c459ab325459ab325459ab325450d1e41c5074417c501d4dac4f41f87c49eafcdc3942081437d64d24333d4114428763a441c18634485059044fd7eae4474f8cc44b2f50445296f23453d2827453d282745b1d33fc58e6f16c5d616dac4914e87c42e19d2c3cf0f7243e3e0c443ef5c08446d492e44eb355444548c8644b2fda244116fbf44cd51f844d54d1845d54d1845d54d18454d743ec5cdd31ac59966eec49825a7c42fc93fc4ba1c45c3a575ba43da710044e1a82344e8df464473b27b447f429844c4abb2444f7ee7446d7309456d7309456d730945e1ff3cc582c419c54712edc4899ba6c4964940c46a704dc3c222b343e325f44382941a4412163b446bd86b44624d8e448eaea644e770d7445278024552780245527802456e763bc5309318c5e35febc46799a5c4d4a53fc46e6350c33be8ae436e80ea43510c13446bd83044918a5d445c1e85446f779b449629c844bcdbf4444e1bf8444e1bf844f3d739c5d53f17c56e4fe9c4311fa4c4eadd3dc4c5f54dc30fc6ad4355f3e3434e100d44f1262844e5c85044da6a7944670691445ca8b944504ae2448f52e4448f52e444712438c5d5d319c57206f7c43a65bac404887bc4944502c4403210c2977ee04378a00844a40121446793454429256a44765b874438edab44fb7ed0448f52e4448f52e444'
'1f5a84441f5a84441f5a84441f5a84441f5a84441f5a84444ec38f44f1d9aa4494f0c5443707e14496d40445902519458a762d457f18564573ba7e45d79f8a45d79f8a4576288c42972d1843f3466a43057ee14349ec26448f195d446aa389440dbaa444b0d0bf4453e7da44a4c401459e15164599662a458d08534582aa7b450e768d450e768d4508324ac5f4d0bcc4381156432863d743dade2144200c5844b31c87445633a244f949bd449c60d8444881004543d214453d23294531c5514526677a459ab38e459ab38e4508e449c58f07c4c4118fbb4229579a4347e50244f99e3844ab586e442f09924408e6ac44e1c2c744270ef044b62c0c45595220459f9d4845e4e87045d79f8a45d79f8a45008149c5bf6002c5f6016dc43dfc3d435b8ac9434c0b1a446b514f44c54b8244d4ee9c44e391b7447a86df4488bd0345d4b717456bac3f4502a16745ccca8745d79f8a45f10849c5b2ed02c5d14973c49f8c14433d04b34316e10d440c404244039f7644fd7e954479aeaf44b2f5d644eb3cfe4412c212454b093a4584506145df4b8445d79f8a45da7b48c5f35c03c535f878c4201bdc4267f69d4303730244d2ea3544a1626944386d8e442029a844fcc2ce44d75cf54459fb0d4535953445102f5b4576e48045d79f8a45bbd947c5459011c5a08db6c46af513c4d7608a432782ef43bb512a4463e25c4485b98744d901a14457eec644d5daec44a963094527502f45a53c554523297b45d79f8a45942247c5d39711c5231ab8c43f091ac41f8770439096db43c8741f44481e5144e4638144a4389a44c577bf44e5b6e44402fb0445233a2a4543794f4563b87445dff58545665646c5338511c5ff67b9c4318b1fc470e64e435584c843b9ca144448534544d7db7544333293449e98b74409ffdb44ba3200452599244590ff4845fb656d45446c7145317545c56b5511c54b6bbac4815724c4549e3043651eb743d0f60a446d5e3a440ac66944d4968c448a24b04440b2d344f63ff744b12d1f4567bb4245dc916245dc916245f37e44c50b0319c5440edbc4731684c4877ab4c3be64a7430bf90144b73f304462865e4487668644881ba94489d0cb448a85ee44c6f71945c7ac3c45646b5345646b5345ae7343c5298718c54735dbc43d5c85c4c90cbec361579943d6a2f34325f72644e01c54444da18044997da244e559c4443036e64464f7144594b6354594b6354594b63545615342c59cf617c5ad33dbc4227a86c45c02c7c3cfe38b437eabe14397b91b446e9d46444581714484eb98446616b9444741d94485cb0c459ab325459ab325459ab325450d1e41c5074417c501d4dac4f41f87c49eafcdc3942081437d64d24333d4114428763a441c18634485059044fd7eae4474f8cc44b2f50445296f23453d2827453d282745b1d33fc58e6f16c5d616dac4914e87c42e19d2c3cf0f7243e3e0c443ef5c08446d492e44eb355444548c8644b2fda244116fbf44cd51f844d54d1845d54d1845d54d18454d743ec5cdd31ac59966eec49825a7c42fc93fc4ba1c45c3a575ba43da710044e1a82344e8df464473b27b447f429844c4abb2444f7ee7446d7309456d7309456d730945e1ff3cc582c419c54712edc4899ba6c4964940c46a704dc3c222b343e325f44382941a4412163b446bd86b44624d8e448eaea644e770d7445278024552780245527802456e763bc5309318c5e35febc46799a5c4d4a53fc46e6350c33be8ae436e80ea43510c13446bd83044918a5d445c1e85446f779b449629c844bcdbf4444e1bf8444e1bf844f3d739c5d53f17c56e4fe9c4311fa4c4eadd3dc4c5f54dc30fc6ad4355f3e3434e100d44f1262844e5c85044da6a7944670691445ca8b944504ae2448f52e4448f52e444712438c5d5d319c57206f7c43a65bac404887bc4944502c4403210c2977ee04378a00844a40121446793454429256a44765b874438edab44fb7ed0448f52e4448f52e444'
bb = bytes .fromhex(xcp_data_list[0 ].value)[::- 1 ]
len (bb), len (xcp_data_list[0 ].value), xcp_data_list[0 ].dim
bb
b'D\xe4R\x8fD\xe4R\x8fD\xd0~\xfbD\xab\xed8D\x87[vDj%)DE\x93gD!\x01\xa4D\x08\xa0xC\xe0~\x97\xc2\x102@\xc4\x02E\x94\xc4{\x88\x04\xc4\xbae:\xc4\xf7\x06r\xc5\x19\xd3\xd5\xc58$qD\xe4R\x8fD\xe4R\x8fD\xe2JPD\xb9\xa8\\D\x91\x06gDyj\xdaDP\xc8\xe5D(&\xf1D\r\x10NC\xe3\xf3UC\xad\xc6\x0f\xc3M\xf5\xc5\xc4=\xdd\xea\xc4\xa4\x1f1\xc4\xe9On\xc5\x17?\xd5\xc59\xd7\xf3D\xf8\x1bND\xf8\x1bND\xf4\xdb\xbcD\xc8)\x96D\x9bwoD\x85\x1e\\D]\x8a\x91D0\xd8kD\x13\x0cQC\xea\x80nC\xae\xe8;\xc3Pcn\xc4?\xa5\xd4\xc4\xa5\x99g\xc4\xeb_\xe3\xc5\x18\x930\xc5;vnE\x02xRE\x02xRE\x02xRD\xd7p\xe7D\xa6\xae\x8eD\x8eMbDk\xd8kD;\x16\x12D\x1a\x94\x82C\xf4%\xe3C\xb3"\xc2\xc3Mpj\xc4@I\x96\xc4\xa6\x9b\x89\xc4\xed\x12G\xc5\x19\xc4\x82\xc5<\xff\xe1E\tsmE\tsmE\tsmD\xe7~OD\xb2\xab\xc4D\x98B\x7fD{\xb2sDF\xdf\xe8D#\xa8\xe1D\x00q\xdaC\xbau\xa5\xc3E\x1c\xba\xc4?\xc9/\xc4\xa7%\x98\xc4\xeef\x99\xc5\x1a\xd3\xcd\xc5>tME\x18M\xd5E\x18M\xd5E\x18M\xd5D\xf8Q\xcdD\xbfo\x11D\xa2\xfd\xb2D\x86\x8cTDT5\xebD.ImD\x08\\\xefC\xc4\xe0\xe3Cr\x0f\xcf\xc3\xd2\x19.\xc4\x87N\x91\xc4\xda\x16\xd6\xc5\x16o\x8e\xc5?\xd3\xb1E\'(=E\'(=E#o)E\x04\xf5\xb2D\xcc\xf8tD\xae~\xfdD\x90\x05\x85Dc\x18\x1cD:v(D\x11\xd43C\xd2d}C\x81 \x94\xc3\xcd\xaf\x9e\xc4\x87\x1f\xf4\xc4\xda\xd4\x01\xc5\x17D\x07\xc5A\x1e\rE%\xb3\x9aE%\xb3\x9aE%\xb3\x9aE\x0c\xcb\x85D\xd9AGD\xb9\x16fD\x98\xeb\x84Dq\x81EDF\x9dnD\x1b\xb9\x97C\xe1\xab~C\x8b\xe3\xcf\xc3\xc7\x02\\\xc4\x86z"\xc4\xdb3\xad\xc5\x17\xf6\x9c\xc5BSaE5\xb6\x94E5\xb6\x94E5\xb6\x94E\x14\xf7dD\xe660D\xc4Y\xe5D\xa2}\x99D\x80\xa1MDT\x1c\xe0D&\xf7%C\xf3\xa2\xd6C\x99Wa\xc3\xbe\x0c\xc9\xc4\x85\\=\xc4\xdb5G\xc5\x18\x87)\xc5Cs\xaeESkdESkdE<\xac\xc7E\x19\xf7\xc6D\xee\x85\x8aD\xcb\xd0\x89D\xa9\x1b\x88D\x86f\x87D^\x86bD0?\xb7D\x01\xf9\x0bC\xa7d\xbe\xc3\xb4z\x87\xc4\x84\x16s\xc4\xdb\x0eD\xc5\x19\x03\x0b\xc5D~\xf3Eb\x91\xdcEb\x91\xdcEB\xbbgE\x1f-\xb1D\xf7?\xf6D\xd3\xb2@D\xb0$\x8aD\x8c\x96\xd4Di\xc6\nD:^mD\n\xf6\xd0C\xb7\x1eeC0\x9eT\xc4$W\x81\xc4\xbakK\xc5\x11Uk\xc5Eu1EqlDEme\xfbEH\xff\x90E$\x99%E\x002\xbaD\xdb\xff\tD\xb7\x98\x9eD\x9323Du\xdb\xd7DESHD\x14\xca\xb9C\xc8\x84UCN\xe6p\xc4\x1f\x8b1\xc4\xb9g\xff\xc5\x11\x853\xc5FVfE\x85\xf5\xdfEt\xb8cEOyCE*:#E\x04\xfb\x02D\xe4\xb6\xe5D\xbfw\xc5D\x9a8\xa4D\x81c\xe4DQ\x1eHD\x1ft\xc8C\xdb\x96\x90Cp\x87\x1f\xc4\x1a\t?\xc4\xb8\x1a#\xc5\x11\x97\xd3\xc5G"\x94E\x8a\x9f\xd7E{)#EU<\xa5E/P\'E\tc\xa9D\xec\xda\xd5D\xc6\xeeWD\xa1\x01\xd9D\x87\xb9\x85D\\\xe2cD*Q\xbbC\xef\x82\'C\x8a`\xd7\xc4\x13\xf5j\xc4\xb6\x8d\xa0\xc5\x11\x90E\xc5G\xd9\xbbE\x8a\x9f\xd7E\x80\xe4vE[/\x10E4\x955E\r\xfbYD\xf5\\\xd7D\xce\xc2\xfcD\xa8) D\x8em8Dib\xa1D5\xea\xd2D\x02s\x03C\x9d\xf6gB\xdc\x1b \xc4x\xf85\xc5\x03\\\xf3\xc5H{\xdaE\x8a\x9f\xd7E\x84K\xdfEaP\x84E:\tKE\x12\xc2\x12D\xfe<\xebD\xd6\xf5\xb2D\xaf\xaeyD\x95~\xfdDv\x9f\x03DB@\x0cD\r\xe1\x16C\xb3\x04=C\x14\x8c\x9f\xc4sI\xd1\xc5\x02\xed\xb2\xc5I\x08\xf1E\x8a\x9f\xd7E\x87\xca\xccEg\xa1\x02E?\xackE\x17\xb7\xd4E\x03\xbd\x88D\xdf\x86zD\xb7\x91\xe3D\x9c\xee\xd4D\x82K\xc5DOQkD\x1a\x0bLC\xc9\x8a[C=\xfc=\xc4m\x01\xf6\xc5\x02`\xbf\xc5I\x81\x00E\x8a\x9f\xd7E\x8a\x9f\xd7Ep\xe8\xe4EH\x9d\x9fE RYE\x0c,\xb6D\xf0\x0e\'D\xc7\xc2\xe1D\xac\xe6\x08D\x92\t/DnX\xabD8\x9e\xf9D\x02\xe5GC\x9aW)B\xbb\x8f\x11\xc4\xc4\x07\x8f\xc5I\xe4\x08E\x8e\xb3\x9aE\x8e\xb3\x9aEzg&EQ\xc51E)#=E\x14\xd2CE\x00\x81HD\xd8`\x9cD\xbdI\xf9D\xa23VD\x87\x1c\xb3DX\x0c D!\xde\xdaC\xd7c(CV\x118\xc4\xbc\xd0\xf4\xc5J2\x08E\x8dv\x0eE\x8dv\x0eE{\xaa\x82ES\x08\x8dE*f\x99E\x16\x15\x9eE\x01\xc4\xa4D\xda\xe7SD\xbf\xd0\xb0D\xa4\xba\rD\x89\xa3jD]\x19\x8fD&\xecIC\xe1~\x05CjF\xf3C\x18-\x97B\x8c(vE\x8a\x9f\xd7E\x8a\x9f\xd7E~\xbasEV\x18\x7fE-v\x8aE\x19%\x90E\x04\xd4\x96D\xe1\x077D\xc5\xf0\x94D\xaa\xd9\xf1D\x8f\xc3ND\x84Z\x1fD\x84Z\x1fD\x84Z\x1fD\x84Z\x1fD\x84Z\x1fD\x84Z\x1f'
# bb = b[::-1]
a = [struct.unpack('!f' ,bb[i:i+ 4 ])[0 ] for i in range (0 , len (bb), 4 )]
n = np.array(a)
n
array([1826.58 , 1826.58 , 1667.968, ..., 1058.816, 1058.816, 1058.816])
len (xcp_data_list[0 ].value), xcp_data_list[0 ].value
len (bytes .fromhex(xcp_data_list[0 ].value)), bytes .fromhex(xcp_data_list[0 ].value)
len (xcp_data_list[0 ].value_bytes), xcp_data_list[0 ].value_bytes
xcp_data_list[0 ].dim, xcp_data_list[0 ].value_array_view.dtype
xcp_data_list[0 ].value_array_view
(2856,
'1f5a84441f5a84441f5a84441f5a84441f5a84441f5a84444ec38f44f1d9aa4494f0c5443707e14496d40445902519458a762d457f18564573ba7e45d79f8a45d79f8a4576288c42972d1843f3466a43057ee14349ec26448f195d446aa389440dbaa444b0d0bf4453e7da44a4c401459e15164599662a458d08534582aa7b450e768d450e768d4508324ac5f4d0bcc4381156432863d743dade2144200c5844b31c87445633a244f949bd449c60d8444881004543d214453d23294531c5514526677a459ab38e459ab38e4508e449c58f07c4c4118fbb4229579a4347e50244f99e3844ab586e442f09924408e6ac44e1c2c744270ef044b62c0c45595220459f9d4845e4e87045d79f8a45d79f8a45008149c5bf6002c5f6016dc43dfc3d435b8ac9434c0b1a446b514f44c54b8244d4ee9c44e391b7447a86df4488bd0345d4b717456bac3f4502a16745ccca8745d79f8a45f10849c5b2ed02c5d14973c49f8c14433d04b34316e10d440c404244039f7644fd7e954479aeaf44b2f5d644eb3cfe4412c212454b093a4584506145df4b8445d79f8a45da7b48c5f35c03c535f878c4201bdc4267f69d4303730244d2ea3544a1626944386d8e442029a844fcc2ce44d75cf54459fb0d4535953445102f5b4576e48045d79f8a45bbd947c5459011c5a08db6c46af513c4d7608a432782ef43bb512a4463e25c4485b98744d901a14457eec644d5daec44a963094527502f45a53c554523297b45d79f8a45942247c5d39711c5231ab8c43f091ac41f8770439096db43c8741f44481e5144e4638144a4389a44c577bf44e5b6e44402fb0445233a2a4543794f4563b87445dff58545665646c5338511c5ff67b9c4318b1fc470e64e435584c843b9ca144448534544d7db7544333293449e98b74409ffdb44ba3200452599244590ff4845fb656d45446c7145317545c56b5511c54b6bbac4815724c4549e3043651eb743d0f60a446d5e3a440ac66944d4968c448a24b04440b2d344f63ff744b12d1f4567bb4245dc916245dc916245f37e44c50b0319c5440edbc4731684c4877ab4c3be64a7430bf90144b73f304462865e4487668644881ba94489d0cb448a85ee44c6f71945c7ac3c45646b5345646b5345ae7343c5298718c54735dbc43d5c85c4c90cbec361579943d6a2f34325f72644e01c54444da18044997da244e559c4443036e64464f7144594b6354594b6354594b63545615342c59cf617c5ad33dbc4227a86c45c02c7c3cfe38b437eabe14397b91b446e9d46444581714484eb98446616b9444741d94485cb0c459ab325459ab325459ab325450d1e41c5074417c501d4dac4f41f87c49eafcdc3942081437d64d24333d4114428763a441c18634485059044fd7eae4474f8cc44b2f50445296f23453d2827453d282745b1d33fc58e6f16c5d616dac4914e87c42e19d2c3cf0f7243e3e0c443ef5c08446d492e44eb355444548c8644b2fda244116fbf44cd51f844d54d1845d54d1845d54d18454d743ec5cdd31ac59966eec49825a7c42fc93fc4ba1c45c3a575ba43da710044e1a82344e8df464473b27b447f429844c4abb2444f7ee7446d7309456d7309456d730945e1ff3cc582c419c54712edc4899ba6c4964940c46a704dc3c222b343e325f44382941a4412163b446bd86b44624d8e448eaea644e770d7445278024552780245527802456e763bc5309318c5e35febc46799a5c4d4a53fc46e6350c33be8ae436e80ea43510c13446bd83044918a5d445c1e85446f779b449629c844bcdbf4444e1bf8444e1bf844f3d739c5d53f17c56e4fe9c4311fa4c4eadd3dc4c5f54dc30fc6ad4355f3e3434e100d44f1262844e5c85044da6a7944670691445ca8b944504ae2448f52e4448f52e444712438c5d5d319c57206f7c43a65bac404887bc4944502c4403210c2977ee04378a00844a40121446793454429256a44765b874438edab44fb7ed0448f52e4448f52e444')
(1428,
b'\x1fZ\x84D\x1fZ\x84D\x1fZ\x84D\x1fZ\x84D\x1fZ\x84D\x1fZ\x84DN\xc3\x8fD\xf1\xd9\xaaD\x94\xf0\xc5D7\x07\xe1D\x96\xd4\x04E\x90%\x19E\x8av-E\x7f\x18VEs\xba~E\xd7\x9f\x8aE\xd7\x9f\x8aEv(\x8cB\x97-\x18C\xf3FjC\x05~\xe1CI\xec&D\x8f\x19]Dj\xa3\x89D\r\xba\xa4D\xb0\xd0\xbfDS\xe7\xdaD\xa4\xc4\x01E\x9e\x15\x16E\x99f*E\x8d\x08SE\x82\xaa{E\x0ev\x8dE\x0ev\x8dE\x082J\xc5\xf4\xd0\xbc\xc48\x11VC(c\xd7C\xda\xde!D \x0cXD\xb3\x1c\x87DV3\xa2D\xf9I\xbdD\x9c`\xd8DH\x81\x00EC\xd2\x14E=#)E1\xc5QE&gzE\x9a\xb3\x8eE\x9a\xb3\x8eE\x08\xe4I\xc5\x8f\x07\xc4\xc4\x11\x8f\xbbB)W\x9aCG\xe5\x02D\xf9\x9e8D\xabXnD/\t\x92D\x08\xe6\xacD\xe1\xc2\xc7D\'\x0e\xf0D\xb6,\x0cEYR E\x9f\x9dHE\xe4\xe8pE\xd7\x9f\x8aE\xd7\x9f\x8aE\x00\x81I\xc5\xbf`\x02\xc5\xf6\x01m\xc4=\xfc=C[\x8a\xc9CL\x0b\x1aDkQOD\xc5K\x82D\xd4\xee\x9cD\xe3\x91\xb7Dz\x86\xdfD\x88\xbd\x03E\xd4\xb7\x17Ek\xac?E\x02\xa1gE\xcc\xca\x87E\xd7\x9f\x8aE\xf1\x08I\xc5\xb2\xed\x02\xc5\xd1Is\xc4\x9f\x8c\x14C=\x04\xb3C\x16\xe1\rD\x0c@BD\x03\x9fvD\xfd~\x95Dy\xae\xafD\xb2\xf5\xd6D\xeb<\xfeD\x12\xc2\x12EK\t:E\x84PaE\xdfK\x84E\xd7\x9f\x8aE\xda{H\xc5\xf3\\\x03\xc55\xf8x\xc4 \x1b\xdcBg\xf6\x9dC\x03s\x02D\xd2\xea5D\xa1biD8m\x8eD )\xa8D\xfc\xc2\xceD\xd7\\\xf5DY\xfb\rE5\x954E\x10/[Ev\xe4\x80E\xd7\x9f\x8aE\xbb\xd9G\xc5E\x90\x11\xc5\xa0\x8d\xb6\xc4j\xf5\x13\xc4\xd7`\x8aC\'\x82\xefC\xbbQ*Dc\xe2\\D\x85\xb9\x87D\xd9\x01\xa1DW\xee\xc6D\xd5\xda\xecD\xa9c\tE\'P/E\xa5<UE#){E\xd7\x9f\x8aE\x94"G\xc5\xd3\x97\x11\xc5#\x1a\xb8\xc4?\t\x1a\xc4\x1f\x87pC\x90\x96\xdbC\xc8t\x1fDH\x1eQD\xe4c\x81D\xa48\x9aD\xc5w\xbfD\xe5\xb6\xe4D\x02\xfb\x04E#:*ECyOEc\xb8tE\xdf\xf5\x85EfVF\xc53\x85\x11\xc5\xffg\xb9\xc41\x8b\x1f\xc4p\xe6NCU\x84\xc8C\xb9\xca\x14DHSED\xd7\xdbuD32\x93D\x9e\x98\xb7D\t\xff\xdbD\xba2\x00E%\x99$E\x90\xffHE\xfbemEDlqE1uE\xc5kU\x11\xc5Kk\xba\xc4\x81W$\xc4T\x9e0Ce\x1e\xb7C\xd0\xf6\nDm^:D\n\xc6iD\xd4\x96\x8cD\x8a$\xb0D@\xb2\xd3D\xf6?\xf7D\xb1-\x1fEg\xbbBE\xdc\x91bE\xdc\x91bE\xf3~D\xc5\x0b\x03\x19\xc5D\x0e\xdb\xc4s\x16\x84\xc4\x87z\xb4\xc3\xbed\xa7C\x0b\xf9\x01D\xb7?0Db\x86^D\x87f\x86D\x88\x1b\xa9D\x89\xd0\xcbD\x8a\x85\xeeD\xc6\xf7\x19E\xc7\xac<EdkSEdkSE\xaesC\xc5)\x87\x18\xc5G5\xdb\xc4=\\\x85\xc4\xc9\x0c\xbe\xc3aW\x99C\xd6\xa2\xf3C%\xf7&D\xe0\x1cTDM\xa1\x80D\x99}\xa2D\xe5Y\xc4D06\xe6Dd\xf7\x14E\x94\xb65E\x94\xb65E\x94\xb65EaSB\xc5\x9c\xf6\x17\xc5\xad3\xdb\xc4"z\x86\xc4\\\x02\xc7\xc3\xcf\xe3\x8bC~\xab\xe1C\x97\xb9\x1bDn\x9dFDE\x81qD\x84\xeb\x98Df\x16\xb9DGA\xd9D\x85\xcb\x0cE\x9a\xb3%E\x9a\xb3%E\x9a\xb3%E\r\x1eA\xc5\x07D\x17\xc5\x01\xd4\xda\xc4\xf4\x1f\x87\xc4\x9e\xaf\xcd\xc3\x94 \x81C}d\xd2C3\xd4\x11D(v:D\x1c\x18cD\x85\x05\x90D\xfd~\xaeDt\xf8\xccD\xb2\xf5\x04E)o#E=(\'E=(\'E\xb1\xd3?\xc5\x8eo\x16\xc5\xd6\x16\xda\xc4\x91N\x87\xc4.\x19\xd2\xc3\xcf\x0frC\xe3\xe0\xc4C\xef\\\x08DmI.D\xeb5TDT\x8c\x86D\xb2\xfd\xa2D\x11o\xbfD\xcdQ\xf8D\xd5M\x18E\xd5M\x18E\xd5M\x18EMt>\xc5\xcd\xd3\x1a\xc5\x99f\xee\xc4\x98%\xa7\xc4/\xc9?\xc4\xba\x1cE\xc3\xa5u\xbaC\xdaq\x00D\xe1\xa8#D\xe8\xdfFDs\xb2{D\x7fB\x98D\xc4\xab\xb2DO~\xe7Dms\tEms\tEms\tE\xe1\xff<\xc5\x82\xc4\x19\xc5G\x12\xed\xc4\x89\x9b\xa6\xc4\x96I@\xc4jpM\xc3\xc2"\xb3C\xe3%\xf4C\x82\x94\x1aD\x12\x16;Dk\xd8kDbM\x8eD\x8e\xae\xa6D\xe7p\xd7DRx\x02ERx\x02ERx\x02Env;\xc50\x93\x18\xc5\xe3_\xeb\xc4g\x99\xa5\xc4\xd4\xa5?\xc4ncP\xc3;\xe8\xaeCn\x80\xeaCQ\x0c\x13Dk\xd80D\x91\x8a]D\\\x1e\x85Dow\x9bD\x96)\xc8D\xbc\xdb\xf4DN\x1b\xf8DN\x1b\xf8D\xf3\xd79\xc5\xd5?\x17\xc5nO\xe9\xc41\x1f\xa4\xc4\xea\xdd=\xc4\xc5\xf5M\xc3\x0f\xc6\xadCU\xf3\xe3CN\x10\rD\xf1&(D\xe5\xc8PD\xdajyDg\x06\x91D\\\xa8\xb9DPJ\xe2D\x8fR\xe4D\x8fR\xe4Dq$8\xc5\xd5\xd3\x19\xc5r\x06\xf7\xc4:e\xba\xc4\x04\x88{\xc4\x94E\x02\xc4@2\x10\xc2\x97~\xe0Cx\xa0\x08D\xa4\x01!Dg\x93ED)%jDv[\x87D8\xed\xabD\xfb~\xd0D\x8fR\xe4D\x8fR\xe4D')
(1428,
b'\x1fZ\x84D\x1fZ\x84D\x1fZ\x84D\x1fZ\x84D\x1fZ\x84D\x1fZ\x84DN\xc3\x8fD\xf1\xd9\xaaD\x94\xf0\xc5D7\x07\xe1D\x96\xd4\x04E\x90%\x19E\x8av-E\x7f\x18VEs\xba~E\xd7\x9f\x8aE\xd7\x9f\x8aEv(\x8cB\x97-\x18C\xf3FjC\x05~\xe1CI\xec&D\x8f\x19]Dj\xa3\x89D\r\xba\xa4D\xb0\xd0\xbfDS\xe7\xdaD\xa4\xc4\x01E\x9e\x15\x16E\x99f*E\x8d\x08SE\x82\xaa{E\x0ev\x8dE\x0ev\x8dE\x082J\xc5\xf4\xd0\xbc\xc48\x11VC(c\xd7C\xda\xde!D \x0cXD\xb3\x1c\x87DV3\xa2D\xf9I\xbdD\x9c`\xd8DH\x81\x00EC\xd2\x14E=#)E1\xc5QE&gzE\x9a\xb3\x8eE\x9a\xb3\x8eE\x08\xe4I\xc5\x8f\x07\xc4\xc4\x11\x8f\xbbB)W\x9aCG\xe5\x02D\xf9\x9e8D\xabXnD/\t\x92D\x08\xe6\xacD\xe1\xc2\xc7D\'\x0e\xf0D\xb6,\x0cEYR E\x9f\x9dHE\xe4\xe8pE\xd7\x9f\x8aE\xd7\x9f\x8aE\x00\x81I\xc5\xbf`\x02\xc5\xf6\x01m\xc4=\xfc=C[\x8a\xc9CL\x0b\x1aDkQOD\xc5K\x82D\xd4\xee\x9cD\xe3\x91\xb7Dz\x86\xdfD\x88\xbd\x03E\xd4\xb7\x17Ek\xac?E\x02\xa1gE\xcc\xca\x87E\xd7\x9f\x8aE\xf1\x08I\xc5\xb2\xed\x02\xc5\xd1Is\xc4\x9f\x8c\x14C=\x04\xb3C\x16\xe1\rD\x0c@BD\x03\x9fvD\xfd~\x95Dy\xae\xafD\xb2\xf5\xd6D\xeb<\xfeD\x12\xc2\x12EK\t:E\x84PaE\xdfK\x84E\xd7\x9f\x8aE\xda{H\xc5\xf3\\\x03\xc55\xf8x\xc4 \x1b\xdcBg\xf6\x9dC\x03s\x02D\xd2\xea5D\xa1biD8m\x8eD )\xa8D\xfc\xc2\xceD\xd7\\\xf5DY\xfb\rE5\x954E\x10/[Ev\xe4\x80E\xd7\x9f\x8aE\xbb\xd9G\xc5E\x90\x11\xc5\xa0\x8d\xb6\xc4j\xf5\x13\xc4\xd7`\x8aC\'\x82\xefC\xbbQ*Dc\xe2\\D\x85\xb9\x87D\xd9\x01\xa1DW\xee\xc6D\xd5\xda\xecD\xa9c\tE\'P/E\xa5<UE#){E\xd7\x9f\x8aE\x94"G\xc5\xd3\x97\x11\xc5#\x1a\xb8\xc4?\t\x1a\xc4\x1f\x87pC\x90\x96\xdbC\xc8t\x1fDH\x1eQD\xe4c\x81D\xa48\x9aD\xc5w\xbfD\xe5\xb6\xe4D\x02\xfb\x04E#:*ECyOEc\xb8tE\xdf\xf5\x85EfVF\xc53\x85\x11\xc5\xffg\xb9\xc41\x8b\x1f\xc4p\xe6NCU\x84\xc8C\xb9\xca\x14DHSED\xd7\xdbuD32\x93D\x9e\x98\xb7D\t\xff\xdbD\xba2\x00E%\x99$E\x90\xffHE\xfbemEDlqE1uE\xc5kU\x11\xc5Kk\xba\xc4\x81W$\xc4T\x9e0Ce\x1e\xb7C\xd0\xf6\nDm^:D\n\xc6iD\xd4\x96\x8cD\x8a$\xb0D@\xb2\xd3D\xf6?\xf7D\xb1-\x1fEg\xbbBE\xdc\x91bE\xdc\x91bE\xf3~D\xc5\x0b\x03\x19\xc5D\x0e\xdb\xc4s\x16\x84\xc4\x87z\xb4\xc3\xbed\xa7C\x0b\xf9\x01D\xb7?0Db\x86^D\x87f\x86D\x88\x1b\xa9D\x89\xd0\xcbD\x8a\x85\xeeD\xc6\xf7\x19E\xc7\xac<EdkSEdkSE\xaesC\xc5)\x87\x18\xc5G5\xdb\xc4=\\\x85\xc4\xc9\x0c\xbe\xc3aW\x99C\xd6\xa2\xf3C%\xf7&D\xe0\x1cTDM\xa1\x80D\x99}\xa2D\xe5Y\xc4D06\xe6Dd\xf7\x14E\x94\xb65E\x94\xb65E\x94\xb65EaSB\xc5\x9c\xf6\x17\xc5\xad3\xdb\xc4"z\x86\xc4\\\x02\xc7\xc3\xcf\xe3\x8bC~\xab\xe1C\x97\xb9\x1bDn\x9dFDE\x81qD\x84\xeb\x98Df\x16\xb9DGA\xd9D\x85\xcb\x0cE\x9a\xb3%E\x9a\xb3%E\x9a\xb3%E\r\x1eA\xc5\x07D\x17\xc5\x01\xd4\xda\xc4\xf4\x1f\x87\xc4\x9e\xaf\xcd\xc3\x94 \x81C}d\xd2C3\xd4\x11D(v:D\x1c\x18cD\x85\x05\x90D\xfd~\xaeDt\xf8\xccD\xb2\xf5\x04E)o#E=(\'E=(\'E\xb1\xd3?\xc5\x8eo\x16\xc5\xd6\x16\xda\xc4\x91N\x87\xc4.\x19\xd2\xc3\xcf\x0frC\xe3\xe0\xc4C\xef\\\x08DmI.D\xeb5TDT\x8c\x86D\xb2\xfd\xa2D\x11o\xbfD\xcdQ\xf8D\xd5M\x18E\xd5M\x18E\xd5M\x18EMt>\xc5\xcd\xd3\x1a\xc5\x99f\xee\xc4\x98%\xa7\xc4/\xc9?\xc4\xba\x1cE\xc3\xa5u\xbaC\xdaq\x00D\xe1\xa8#D\xe8\xdfFDs\xb2{D\x7fB\x98D\xc4\xab\xb2DO~\xe7Dms\tEms\tEms\tE\xe1\xff<\xc5\x82\xc4\x19\xc5G\x12\xed\xc4\x89\x9b\xa6\xc4\x96I@\xc4jpM\xc3\xc2"\xb3C\xe3%\xf4C\x82\x94\x1aD\x12\x16;Dk\xd8kDbM\x8eD\x8e\xae\xa6D\xe7p\xd7DRx\x02ERx\x02ERx\x02Env;\xc50\x93\x18\xc5\xe3_\xeb\xc4g\x99\xa5\xc4\xd4\xa5?\xc4ncP\xc3;\xe8\xaeCn\x80\xeaCQ\x0c\x13Dk\xd80D\x91\x8a]D\\\x1e\x85Dow\x9bD\x96)\xc8D\xbc\xdb\xf4DN\x1b\xf8DN\x1b\xf8D\xf3\xd79\xc5\xd5?\x17\xc5nO\xe9\xc41\x1f\xa4\xc4\xea\xdd=\xc4\xc5\xf5M\xc3\x0f\xc6\xadCU\xf3\xe3CN\x10\rD\xf1&(D\xe5\xc8PD\xdajyDg\x06\x91D\\\xa8\xb9DPJ\xe2D\x8fR\xe4D\x8fR\xe4Dq$8\xc5\xd5\xd3\x19\xc5r\x06\xf7\xc4:e\xba\xc4\x04\x88{\xc4\x94E\x02\xc4@2\x10\xc2\x97~\xe0Cx\xa0\x08D\xa4\x01!Dg\x93ED)%jDv[\x87D8\xed\xabD\xfb~\xd0D\x8fR\xe4D\x8fR\xe4D')
([21, 17], dtype('float32'))
array([[ 1058.816, 1058.816, 1058.816, ..., 4075.653, 4435.98 ,
4435.98 ],
[ 70.079, 152.178, 234.277, ..., 4026.657, 4526.757,
4526.757],
[-3235.127, -1510.53 , 214.067, ..., 4006.447, 4566.45 ,
4566.45 ],
...,
[-2999.402, -2441.199, -1882.996, ..., 1958.867, 1984.853,
1984.853],
[-2973.497, -2419.99 , -1866.482, ..., 1810.322, 1826.58 ,
1826.58 ],
[-2946.278, -2461.24 , -1976.201, ..., 1667.968, 1826.58 ,
1826.58 ]], dtype=float32)
struct.unpack('!f' , bytes .fromhex('41973333' ))[0 ]
s = '1f5a8444'
# s = bytearray(s, encoding='utf-8')
# s.reverse()
b = [s[i:i+ 2 ] for i in range (0 , len (s), 2 )]
b = '' .join(b[::- 1 ])
"b:" ,b
"bytes.fromhex(b):" , bytes .fromhex(b)
struct.unpack('!f' , bytes .fromhex(b))[0 ]
# s.reverse()
# ss = struct.pack('<I', s)
# struct.unpack('!f', bytes.fromhex('1f5a8444'))[0]
# s = s[::-1]
# s
# s = '44845a1f'
# struct.unpack('!f', bytes.fromhex(s))[0]
# struct.unpack('!f', bytes.fromhex('25ea8d44'))[0]
# struct.unpack('!f', bytes.fromhex('f647d344'))[0]
# struct.unpack('!f', bytes.fromhex('41995C29'))[0]
('bytes.fromhex(b):', b'D\x84Z\x1f')
addr_dec = int (xcp_data_list[0 ].address, 16 )
addr_dec
addr_hex = hex (addr_dec)
addr_hex
addr_oct = oct (addr_dec)
add_dec_o = int (addr_oct,8 )
add_dec_o
xcp_data_list[0 ].__dict__
# xcp_data[0].value_array_view
# xcp_data[0].__dict__
# f"{xcp_data[0].value:.10s}...{xcp_data[0].value[-3:]}"
# xcp_data[0].value_array_view
{'name': 'TQD_trqTrqSetNormal_MAP_v',
'address': '7000aa2a',
'dim': [21, 17],
'value_type': 'FLOAT32_IEEE',
'value_length': 4,
'value': '1f5a84441f5a84441f5a84441f5a84441f5a84441f5a84444ec38f44f1d9aa4494f0c5443707e14496d40445902519458a762d457f18564573ba7e45d79f8a45d79f8a4576288c42972d1843f3466a43057ee14349ec26448f195d446aa389440dbaa444b0d0bf4453e7da44a4c401459e15164599662a458d08534582aa7b450e768d450e768d4508324ac5f4d0bcc4381156432863d743dade2144200c5844b31c87445633a244f949bd449c60d8444881004543d214453d23294531c5514526677a459ab38e459ab38e4508e449c58f07c4c4118fbb4229579a4347e50244f99e3844ab586e442f09924408e6ac44e1c2c744270ef044b62c0c45595220459f9d4845e4e87045d79f8a45d79f8a45008149c5bf6002c5f6016dc43dfc3d435b8ac9434c0b1a446b514f44c54b8244d4ee9c44e391b7447a86df4488bd0345d4b717456bac3f4502a16745ccca8745d79f8a45f10849c5b2ed02c5d14973c49f8c14433d04b34316e10d440c404244039f7644fd7e954479aeaf44b2f5d644eb3cfe4412c212454b093a4584506145df4b8445d79f8a45da7b48c5f35c03c535f878c4201bdc4267f69d4303730244d2ea3544a1626944386d8e442029a844fcc2ce44d75cf54459fb0d4535953445102f5b4576e48045d79f8a45bbd947c5459011c5a08db6c46af513c4d7608a432782ef43bb512a4463e25c4485b98744d901a14457eec644d5daec44a963094527502f45a53c554523297b45d79f8a45942247c5d39711c5231ab8c43f091ac41f8770439096db43c8741f44481e5144e4638144a4389a44c577bf44e5b6e44402fb0445233a2a4543794f4563b87445dff58545665646c5338511c5ff67b9c4318b1fc470e64e435584c843b9ca144448534544d7db7544333293449e98b74409ffdb44ba3200452599244590ff4845fb656d45446c7145317545c56b5511c54b6bbac4815724c4549e3043651eb743d0f60a446d5e3a440ac66944d4968c448a24b04440b2d344f63ff744b12d1f4567bb4245dc916245dc916245f37e44c50b0319c5440edbc4731684c4877ab4c3be64a7430bf90144b73f304462865e4487668644881ba94489d0cb448a85ee44c6f71945c7ac3c45646b5345646b5345ae7343c5298718c54735dbc43d5c85c4c90cbec361579943d6a2f34325f72644e01c54444da18044997da244e559c4443036e64464f7144594b6354594b6354594b63545615342c59cf617c5ad33dbc4227a86c45c02c7c3cfe38b437eabe14397b91b446e9d46444581714484eb98446616b9444741d94485cb0c459ab325459ab325459ab325450d1e41c5074417c501d4dac4f41f87c49eafcdc3942081437d64d24333d4114428763a441c18634485059044fd7eae4474f8cc44b2f50445296f23453d2827453d282745b1d33fc58e6f16c5d616dac4914e87c42e19d2c3cf0f7243e3e0c443ef5c08446d492e44eb355444548c8644b2fda244116fbf44cd51f844d54d1845d54d1845d54d18454d743ec5cdd31ac59966eec49825a7c42fc93fc4ba1c45c3a575ba43da710044e1a82344e8df464473b27b447f429844c4abb2444f7ee7446d7309456d7309456d730945e1ff3cc582c419c54712edc4899ba6c4964940c46a704dc3c222b343e325f44382941a4412163b446bd86b44624d8e448eaea644e770d7445278024552780245527802456e763bc5309318c5e35febc46799a5c4d4a53fc46e6350c33be8ae436e80ea43510c13446bd83044918a5d445c1e85446f779b449629c844bcdbf4444e1bf8444e1bf844f3d739c5d53f17c56e4fe9c4311fa4c4eadd3dc4c5f54dc30fc6ad4355f3e3434e100d44f1262844e5c85044da6a7944670691445ca8b944504ae2448f52e4448f52e444712438c5d5d319c57206f7c43a65bac404887bc4944502c4403210c2977ee04378a00844a40121446793454429256a44765b874438edab44fb7ed0448f52e4448f52e444',
'type_size': 4,
'value_bytes': b'\x1fZ\x84D\x1fZ\x84D\x1fZ\x84D\x1fZ\x84D\x1fZ\x84D\x1fZ\x84DN\xc3\x8fD\xf1\xd9\xaaD\x94\xf0\xc5D7\x07\xe1D\x96\xd4\x04E\x90%\x19E\x8av-E\x7f\x18VEs\xba~E\xd7\x9f\x8aE\xd7\x9f\x8aEv(\x8cB\x97-\x18C\xf3FjC\x05~\xe1CI\xec&D\x8f\x19]Dj\xa3\x89D\r\xba\xa4D\xb0\xd0\xbfDS\xe7\xdaD\xa4\xc4\x01E\x9e\x15\x16E\x99f*E\x8d\x08SE\x82\xaa{E\x0ev\x8dE\x0ev\x8dE\x082J\xc5\xf4\xd0\xbc\xc48\x11VC(c\xd7C\xda\xde!D \x0cXD\xb3\x1c\x87DV3\xa2D\xf9I\xbdD\x9c`\xd8DH\x81\x00EC\xd2\x14E=#)E1\xc5QE&gzE\x9a\xb3\x8eE\x9a\xb3\x8eE\x08\xe4I\xc5\x8f\x07\xc4\xc4\x11\x8f\xbbB)W\x9aCG\xe5\x02D\xf9\x9e8D\xabXnD/\t\x92D\x08\xe6\xacD\xe1\xc2\xc7D\'\x0e\xf0D\xb6,\x0cEYR E\x9f\x9dHE\xe4\xe8pE\xd7\x9f\x8aE\xd7\x9f\x8aE\x00\x81I\xc5\xbf`\x02\xc5\xf6\x01m\xc4=\xfc=C[\x8a\xc9CL\x0b\x1aDkQOD\xc5K\x82D\xd4\xee\x9cD\xe3\x91\xb7Dz\x86\xdfD\x88\xbd\x03E\xd4\xb7\x17Ek\xac?E\x02\xa1gE\xcc\xca\x87E\xd7\x9f\x8aE\xf1\x08I\xc5\xb2\xed\x02\xc5\xd1Is\xc4\x9f\x8c\x14C=\x04\xb3C\x16\xe1\rD\x0c@BD\x03\x9fvD\xfd~\x95Dy\xae\xafD\xb2\xf5\xd6D\xeb<\xfeD\x12\xc2\x12EK\t:E\x84PaE\xdfK\x84E\xd7\x9f\x8aE\xda{H\xc5\xf3\\\x03\xc55\xf8x\xc4 \x1b\xdcBg\xf6\x9dC\x03s\x02D\xd2\xea5D\xa1biD8m\x8eD )\xa8D\xfc\xc2\xceD\xd7\\\xf5DY\xfb\rE5\x954E\x10/[Ev\xe4\x80E\xd7\x9f\x8aE\xbb\xd9G\xc5E\x90\x11\xc5\xa0\x8d\xb6\xc4j\xf5\x13\xc4\xd7`\x8aC\'\x82\xefC\xbbQ*Dc\xe2\\D\x85\xb9\x87D\xd9\x01\xa1DW\xee\xc6D\xd5\xda\xecD\xa9c\tE\'P/E\xa5<UE#){E\xd7\x9f\x8aE\x94"G\xc5\xd3\x97\x11\xc5#\x1a\xb8\xc4?\t\x1a\xc4\x1f\x87pC\x90\x96\xdbC\xc8t\x1fDH\x1eQD\xe4c\x81D\xa48\x9aD\xc5w\xbfD\xe5\xb6\xe4D\x02\xfb\x04E#:*ECyOEc\xb8tE\xdf\xf5\x85EfVF\xc53\x85\x11\xc5\xffg\xb9\xc41\x8b\x1f\xc4p\xe6NCU\x84\xc8C\xb9\xca\x14DHSED\xd7\xdbuD32\x93D\x9e\x98\xb7D\t\xff\xdbD\xba2\x00E%\x99$E\x90\xffHE\xfbemEDlqE1uE\xc5kU\x11\xc5Kk\xba\xc4\x81W$\xc4T\x9e0Ce\x1e\xb7C\xd0\xf6\nDm^:D\n\xc6iD\xd4\x96\x8cD\x8a$\xb0D@\xb2\xd3D\xf6?\xf7D\xb1-\x1fEg\xbbBE\xdc\x91bE\xdc\x91bE\xf3~D\xc5\x0b\x03\x19\xc5D\x0e\xdb\xc4s\x16\x84\xc4\x87z\xb4\xc3\xbed\xa7C\x0b\xf9\x01D\xb7?0Db\x86^D\x87f\x86D\x88\x1b\xa9D\x89\xd0\xcbD\x8a\x85\xeeD\xc6\xf7\x19E\xc7\xac<EdkSEdkSE\xaesC\xc5)\x87\x18\xc5G5\xdb\xc4=\\\x85\xc4\xc9\x0c\xbe\xc3aW\x99C\xd6\xa2\xf3C%\xf7&D\xe0\x1cTDM\xa1\x80D\x99}\xa2D\xe5Y\xc4D06\xe6Dd\xf7\x14E\x94\xb65E\x94\xb65E\x94\xb65EaSB\xc5\x9c\xf6\x17\xc5\xad3\xdb\xc4"z\x86\xc4\\\x02\xc7\xc3\xcf\xe3\x8bC~\xab\xe1C\x97\xb9\x1bDn\x9dFDE\x81qD\x84\xeb\x98Df\x16\xb9DGA\xd9D\x85\xcb\x0cE\x9a\xb3%E\x9a\xb3%E\x9a\xb3%E\r\x1eA\xc5\x07D\x17\xc5\x01\xd4\xda\xc4\xf4\x1f\x87\xc4\x9e\xaf\xcd\xc3\x94 \x81C}d\xd2C3\xd4\x11D(v:D\x1c\x18cD\x85\x05\x90D\xfd~\xaeDt\xf8\xccD\xb2\xf5\x04E)o#E=(\'E=(\'E\xb1\xd3?\xc5\x8eo\x16\xc5\xd6\x16\xda\xc4\x91N\x87\xc4.\x19\xd2\xc3\xcf\x0frC\xe3\xe0\xc4C\xef\\\x08DmI.D\xeb5TDT\x8c\x86D\xb2\xfd\xa2D\x11o\xbfD\xcdQ\xf8D\xd5M\x18E\xd5M\x18E\xd5M\x18EMt>\xc5\xcd\xd3\x1a\xc5\x99f\xee\xc4\x98%\xa7\xc4/\xc9?\xc4\xba\x1cE\xc3\xa5u\xbaC\xdaq\x00D\xe1\xa8#D\xe8\xdfFDs\xb2{D\x7fB\x98D\xc4\xab\xb2DO~\xe7Dms\tEms\tEms\tE\xe1\xff<\xc5\x82\xc4\x19\xc5G\x12\xed\xc4\x89\x9b\xa6\xc4\x96I@\xc4jpM\xc3\xc2"\xb3C\xe3%\xf4C\x82\x94\x1aD\x12\x16;Dk\xd8kDbM\x8eD\x8e\xae\xa6D\xe7p\xd7DRx\x02ERx\x02ERx\x02Env;\xc50\x93\x18\xc5\xe3_\xeb\xc4g\x99\xa5\xc4\xd4\xa5?\xc4ncP\xc3;\xe8\xaeCn\x80\xeaCQ\x0c\x13Dk\xd80D\x91\x8a]D\\\x1e\x85Dow\x9bD\x96)\xc8D\xbc\xdb\xf4DN\x1b\xf8DN\x1b\xf8D\xf3\xd79\xc5\xd5?\x17\xc5nO\xe9\xc41\x1f\xa4\xc4\xea\xdd=\xc4\xc5\xf5M\xc3\x0f\xc6\xadCU\xf3\xe3CN\x10\rD\xf1&(D\xe5\xc8PD\xdajyDg\x06\x91D\\\xa8\xb9DPJ\xe2D\x8fR\xe4D\x8fR\xe4Dq$8\xc5\xd5\xd3\x19\xc5r\x06\xf7\xc4:e\xba\xc4\x04\x88{\xc4\x94E\x02\xc4@2\x10\xc2\x97~\xe0Cx\xa0\x08D\xa4\x01!Dg\x93ED)%jDv[\x87D8\xed\xabD\xfb~\xd0D\x8fR\xe4D\x8fR\xe4D',
'value_array_view': array([[ 1058.816, 1058.816, 1058.816, ..., 4075.653, 4435.98 ,
4435.98 ],
[ 70.079, 152.178, 234.277, ..., 4026.657, 4526.757,
4526.757],
[-3235.127, -1510.53 , 214.067, ..., 4006.447, 4566.45 ,
4566.45 ],
...,
[-2999.402, -2441.199, -1882.996, ..., 1958.867, 1984.853,
1984.853],
[-2973.497, -2419.99 , -1866.482, ..., 1810.322, 1826.58 ,
1826.58 ],
[-2946.278, -2461.24 , -1976.201, ..., 1667.968, 1826.58 ,
1826.58 ]], dtype=float32)}
# xcp_data[0].value_array_view
xcp_data_list[0 ]
xcp_data_list[0 ].__dict__
xcp_data_list[0 ].model_dump()
test_eq(xcp_data_list[0 ].value_array_view.tobytes(), xcp_data_list[0 ].value_bytes)
{ 'address': '7000aa2a',
'dim': [21, 17],
'name': 'TQD_trqTrqSetNormal_MAP_v',
'type_size': 4,
'value': '1f5a84441f...444',
'value_array_view': array([[ 1058.816, 1058.816, 1058.816, ..., 4075.653, 4435.98 ,
4435.98 ],
[ 70.079, 152.178, 234.277, ..., 4026.657, 4526.757,
4526.757],
[-3235.127, -1510.53 , 214.067, ..., 4006.447, 4566.45 ,
4566.45 ],
...,
[-2999.402, -2441.199, -1882.996, ..., 1958.867, 1984.853,
1984.853],
[-2973.497, -2419.99 , -1866.482, ..., 1810.322, 1826.58 ,
1826.58 ],
[-2946.278, -2461.24 , -1976.201, ..., 1667.968, 1826.58 ,
1826.58 ]], dtype=float32),
'value_bytes': "b'\\x1f'...b'D'",
'value_length': 4,
'value_type': 'FLOAT32_IEEE'}
{'name': 'TQD_trqTrqSetNormal_MAP_v',
'address': '7000aa2a',
'dim': [21, 17],
'value_type': 'FLOAT32_IEEE',
'value_length': 4,
'value': '1f5a84441f5a84441f5a84441f5a84441f5a84441f5a84444ec38f44f1d9aa4494f0c5443707e14496d40445902519458a762d457f18564573ba7e45d79f8a45d79f8a4576288c42972d1843f3466a43057ee14349ec26448f195d446aa389440dbaa444b0d0bf4453e7da44a4c401459e15164599662a458d08534582aa7b450e768d450e768d4508324ac5f4d0bcc4381156432863d743dade2144200c5844b31c87445633a244f949bd449c60d8444881004543d214453d23294531c5514526677a459ab38e459ab38e4508e449c58f07c4c4118fbb4229579a4347e50244f99e3844ab586e442f09924408e6ac44e1c2c744270ef044b62c0c45595220459f9d4845e4e87045d79f8a45d79f8a45008149c5bf6002c5f6016dc43dfc3d435b8ac9434c0b1a446b514f44c54b8244d4ee9c44e391b7447a86df4488bd0345d4b717456bac3f4502a16745ccca8745d79f8a45f10849c5b2ed02c5d14973c49f8c14433d04b34316e10d440c404244039f7644fd7e954479aeaf44b2f5d644eb3cfe4412c212454b093a4584506145df4b8445d79f8a45da7b48c5f35c03c535f878c4201bdc4267f69d4303730244d2ea3544a1626944386d8e442029a844fcc2ce44d75cf54459fb0d4535953445102f5b4576e48045d79f8a45bbd947c5459011c5a08db6c46af513c4d7608a432782ef43bb512a4463e25c4485b98744d901a14457eec644d5daec44a963094527502f45a53c554523297b45d79f8a45942247c5d39711c5231ab8c43f091ac41f8770439096db43c8741f44481e5144e4638144a4389a44c577bf44e5b6e44402fb0445233a2a4543794f4563b87445dff58545665646c5338511c5ff67b9c4318b1fc470e64e435584c843b9ca144448534544d7db7544333293449e98b74409ffdb44ba3200452599244590ff4845fb656d45446c7145317545c56b5511c54b6bbac4815724c4549e3043651eb743d0f60a446d5e3a440ac66944d4968c448a24b04440b2d344f63ff744b12d1f4567bb4245dc916245dc916245f37e44c50b0319c5440edbc4731684c4877ab4c3be64a7430bf90144b73f304462865e4487668644881ba94489d0cb448a85ee44c6f71945c7ac3c45646b5345646b5345ae7343c5298718c54735dbc43d5c85c4c90cbec361579943d6a2f34325f72644e01c54444da18044997da244e559c4443036e64464f7144594b6354594b6354594b63545615342c59cf617c5ad33dbc4227a86c45c02c7c3cfe38b437eabe14397b91b446e9d46444581714484eb98446616b9444741d94485cb0c459ab325459ab325459ab325450d1e41c5074417c501d4dac4f41f87c49eafcdc3942081437d64d24333d4114428763a441c18634485059044fd7eae4474f8cc44b2f50445296f23453d2827453d282745b1d33fc58e6f16c5d616dac4914e87c42e19d2c3cf0f7243e3e0c443ef5c08446d492e44eb355444548c8644b2fda244116fbf44cd51f844d54d1845d54d1845d54d18454d743ec5cdd31ac59966eec49825a7c42fc93fc4ba1c45c3a575ba43da710044e1a82344e8df464473b27b447f429844c4abb2444f7ee7446d7309456d7309456d730945e1ff3cc582c419c54712edc4899ba6c4964940c46a704dc3c222b343e325f44382941a4412163b446bd86b44624d8e448eaea644e770d7445278024552780245527802456e763bc5309318c5e35febc46799a5c4d4a53fc46e6350c33be8ae436e80ea43510c13446bd83044918a5d445c1e85446f779b449629c844bcdbf4444e1bf8444e1bf844f3d739c5d53f17c56e4fe9c4311fa4c4eadd3dc4c5f54dc30fc6ad4355f3e3434e100d44f1262844e5c85044da6a7944670691445ca8b944504ae2448f52e4448f52e444712438c5d5d319c57206f7c43a65bac404887bc4944502c4403210c2977ee04378a00844a40121446793454429256a44765b874438edab44fb7ed0448f52e4448f52e444',
'type_size': 4,
'value_bytes': b'\x1fZ\x84D\x1fZ\x84D\x1fZ\x84D\x1fZ\x84D\x1fZ\x84D\x1fZ\x84DN\xc3\x8fD\xf1\xd9\xaaD\x94\xf0\xc5D7\x07\xe1D\x96\xd4\x04E\x90%\x19E\x8av-E\x7f\x18VEs\xba~E\xd7\x9f\x8aE\xd7\x9f\x8aEv(\x8cB\x97-\x18C\xf3FjC\x05~\xe1CI\xec&D\x8f\x19]Dj\xa3\x89D\r\xba\xa4D\xb0\xd0\xbfDS\xe7\xdaD\xa4\xc4\x01E\x9e\x15\x16E\x99f*E\x8d\x08SE\x82\xaa{E\x0ev\x8dE\x0ev\x8dE\x082J\xc5\xf4\xd0\xbc\xc48\x11VC(c\xd7C\xda\xde!D \x0cXD\xb3\x1c\x87DV3\xa2D\xf9I\xbdD\x9c`\xd8DH\x81\x00EC\xd2\x14E=#)E1\xc5QE&gzE\x9a\xb3\x8eE\x9a\xb3\x8eE\x08\xe4I\xc5\x8f\x07\xc4\xc4\x11\x8f\xbbB)W\x9aCG\xe5\x02D\xf9\x9e8D\xabXnD/\t\x92D\x08\xe6\xacD\xe1\xc2\xc7D\'\x0e\xf0D\xb6,\x0cEYR E\x9f\x9dHE\xe4\xe8pE\xd7\x9f\x8aE\xd7\x9f\x8aE\x00\x81I\xc5\xbf`\x02\xc5\xf6\x01m\xc4=\xfc=C[\x8a\xc9CL\x0b\x1aDkQOD\xc5K\x82D\xd4\xee\x9cD\xe3\x91\xb7Dz\x86\xdfD\x88\xbd\x03E\xd4\xb7\x17Ek\xac?E\x02\xa1gE\xcc\xca\x87E\xd7\x9f\x8aE\xf1\x08I\xc5\xb2\xed\x02\xc5\xd1Is\xc4\x9f\x8c\x14C=\x04\xb3C\x16\xe1\rD\x0c@BD\x03\x9fvD\xfd~\x95Dy\xae\xafD\xb2\xf5\xd6D\xeb<\xfeD\x12\xc2\x12EK\t:E\x84PaE\xdfK\x84E\xd7\x9f\x8aE\xda{H\xc5\xf3\\\x03\xc55\xf8x\xc4 \x1b\xdcBg\xf6\x9dC\x03s\x02D\xd2\xea5D\xa1biD8m\x8eD )\xa8D\xfc\xc2\xceD\xd7\\\xf5DY\xfb\rE5\x954E\x10/[Ev\xe4\x80E\xd7\x9f\x8aE\xbb\xd9G\xc5E\x90\x11\xc5\xa0\x8d\xb6\xc4j\xf5\x13\xc4\xd7`\x8aC\'\x82\xefC\xbbQ*Dc\xe2\\D\x85\xb9\x87D\xd9\x01\xa1DW\xee\xc6D\xd5\xda\xecD\xa9c\tE\'P/E\xa5<UE#){E\xd7\x9f\x8aE\x94"G\xc5\xd3\x97\x11\xc5#\x1a\xb8\xc4?\t\x1a\xc4\x1f\x87pC\x90\x96\xdbC\xc8t\x1fDH\x1eQD\xe4c\x81D\xa48\x9aD\xc5w\xbfD\xe5\xb6\xe4D\x02\xfb\x04E#:*ECyOEc\xb8tE\xdf\xf5\x85EfVF\xc53\x85\x11\xc5\xffg\xb9\xc41\x8b\x1f\xc4p\xe6NCU\x84\xc8C\xb9\xca\x14DHSED\xd7\xdbuD32\x93D\x9e\x98\xb7D\t\xff\xdbD\xba2\x00E%\x99$E\x90\xffHE\xfbemEDlqE1uE\xc5kU\x11\xc5Kk\xba\xc4\x81W$\xc4T\x9e0Ce\x1e\xb7C\xd0\xf6\nDm^:D\n\xc6iD\xd4\x96\x8cD\x8a$\xb0D@\xb2\xd3D\xf6?\xf7D\xb1-\x1fEg\xbbBE\xdc\x91bE\xdc\x91bE\xf3~D\xc5\x0b\x03\x19\xc5D\x0e\xdb\xc4s\x16\x84\xc4\x87z\xb4\xc3\xbed\xa7C\x0b\xf9\x01D\xb7?0Db\x86^D\x87f\x86D\x88\x1b\xa9D\x89\xd0\xcbD\x8a\x85\xeeD\xc6\xf7\x19E\xc7\xac<EdkSEdkSE\xaesC\xc5)\x87\x18\xc5G5\xdb\xc4=\\\x85\xc4\xc9\x0c\xbe\xc3aW\x99C\xd6\xa2\xf3C%\xf7&D\xe0\x1cTDM\xa1\x80D\x99}\xa2D\xe5Y\xc4D06\xe6Dd\xf7\x14E\x94\xb65E\x94\xb65E\x94\xb65EaSB\xc5\x9c\xf6\x17\xc5\xad3\xdb\xc4"z\x86\xc4\\\x02\xc7\xc3\xcf\xe3\x8bC~\xab\xe1C\x97\xb9\x1bDn\x9dFDE\x81qD\x84\xeb\x98Df\x16\xb9DGA\xd9D\x85\xcb\x0cE\x9a\xb3%E\x9a\xb3%E\x9a\xb3%E\r\x1eA\xc5\x07D\x17\xc5\x01\xd4\xda\xc4\xf4\x1f\x87\xc4\x9e\xaf\xcd\xc3\x94 \x81C}d\xd2C3\xd4\x11D(v:D\x1c\x18cD\x85\x05\x90D\xfd~\xaeDt\xf8\xccD\xb2\xf5\x04E)o#E=(\'E=(\'E\xb1\xd3?\xc5\x8eo\x16\xc5\xd6\x16\xda\xc4\x91N\x87\xc4.\x19\xd2\xc3\xcf\x0frC\xe3\xe0\xc4C\xef\\\x08DmI.D\xeb5TDT\x8c\x86D\xb2\xfd\xa2D\x11o\xbfD\xcdQ\xf8D\xd5M\x18E\xd5M\x18E\xd5M\x18EMt>\xc5\xcd\xd3\x1a\xc5\x99f\xee\xc4\x98%\xa7\xc4/\xc9?\xc4\xba\x1cE\xc3\xa5u\xbaC\xdaq\x00D\xe1\xa8#D\xe8\xdfFDs\xb2{D\x7fB\x98D\xc4\xab\xb2DO~\xe7Dms\tEms\tEms\tE\xe1\xff<\xc5\x82\xc4\x19\xc5G\x12\xed\xc4\x89\x9b\xa6\xc4\x96I@\xc4jpM\xc3\xc2"\xb3C\xe3%\xf4C\x82\x94\x1aD\x12\x16;Dk\xd8kDbM\x8eD\x8e\xae\xa6D\xe7p\xd7DRx\x02ERx\x02ERx\x02Env;\xc50\x93\x18\xc5\xe3_\xeb\xc4g\x99\xa5\xc4\xd4\xa5?\xc4ncP\xc3;\xe8\xaeCn\x80\xeaCQ\x0c\x13Dk\xd80D\x91\x8a]D\\\x1e\x85Dow\x9bD\x96)\xc8D\xbc\xdb\xf4DN\x1b\xf8DN\x1b\xf8D\xf3\xd79\xc5\xd5?\x17\xc5nO\xe9\xc41\x1f\xa4\xc4\xea\xdd=\xc4\xc5\xf5M\xc3\x0f\xc6\xadCU\xf3\xe3CN\x10\rD\xf1&(D\xe5\xc8PD\xdajyDg\x06\x91D\\\xa8\xb9DPJ\xe2D\x8fR\xe4D\x8fR\xe4Dq$8\xc5\xd5\xd3\x19\xc5r\x06\xf7\xc4:e\xba\xc4\x04\x88{\xc4\x94E\x02\xc4@2\x10\xc2\x97~\xe0Cx\xa0\x08D\xa4\x01!Dg\x93ED)%jDv[\x87D8\xed\xabD\xfb~\xd0D\x8fR\xe4D\x8fR\xe4D',
'value_array_view': array([[ 1058.816, 1058.816, 1058.816, ..., 4075.653, 4435.98 ,
4435.98 ],
[ 70.079, 152.178, 234.277, ..., 4026.657, 4526.757,
4526.757],
[-3235.127, -1510.53 , 214.067, ..., 4006.447, 4566.45 ,
4566.45 ],
...,
[-2999.402, -2441.199, -1882.996, ..., 1958.867, 1984.853,
1984.853],
[-2973.497, -2419.99 , -1866.482, ..., 1810.322, 1826.58 ,
1826.58 ],
[-2946.278, -2461.24 , -1976.201, ..., 1667.968, 1826.58 ,
1826.58 ]], dtype=float32)}
{'name': 'TQD_trqTrqSetNormal_MAP_v',
'address': '7000aa2a',
'dim': [21, 17],
'value_type': 'FLOAT32_IEEE',
'value_length': 4,
'value': '1f5a84441f5a84441f5a84441f5a84441f5a84441f5a84444ec38f44f1d9aa4494f0c5443707e14496d40445902519458a762d457f18564573ba7e45d79f8a45d79f8a4576288c42972d1843f3466a43057ee14349ec26448f195d446aa389440dbaa444b0d0bf4453e7da44a4c401459e15164599662a458d08534582aa7b450e768d450e768d4508324ac5f4d0bcc4381156432863d743dade2144200c5844b31c87445633a244f949bd449c60d8444881004543d214453d23294531c5514526677a459ab38e459ab38e4508e449c58f07c4c4118fbb4229579a4347e50244f99e3844ab586e442f09924408e6ac44e1c2c744270ef044b62c0c45595220459f9d4845e4e87045d79f8a45d79f8a45008149c5bf6002c5f6016dc43dfc3d435b8ac9434c0b1a446b514f44c54b8244d4ee9c44e391b7447a86df4488bd0345d4b717456bac3f4502a16745ccca8745d79f8a45f10849c5b2ed02c5d14973c49f8c14433d04b34316e10d440c404244039f7644fd7e954479aeaf44b2f5d644eb3cfe4412c212454b093a4584506145df4b8445d79f8a45da7b48c5f35c03c535f878c4201bdc4267f69d4303730244d2ea3544a1626944386d8e442029a844fcc2ce44d75cf54459fb0d4535953445102f5b4576e48045d79f8a45bbd947c5459011c5a08db6c46af513c4d7608a432782ef43bb512a4463e25c4485b98744d901a14457eec644d5daec44a963094527502f45a53c554523297b45d79f8a45942247c5d39711c5231ab8c43f091ac41f8770439096db43c8741f44481e5144e4638144a4389a44c577bf44e5b6e44402fb0445233a2a4543794f4563b87445dff58545665646c5338511c5ff67b9c4318b1fc470e64e435584c843b9ca144448534544d7db7544333293449e98b74409ffdb44ba3200452599244590ff4845fb656d45446c7145317545c56b5511c54b6bbac4815724c4549e3043651eb743d0f60a446d5e3a440ac66944d4968c448a24b04440b2d344f63ff744b12d1f4567bb4245dc916245dc916245f37e44c50b0319c5440edbc4731684c4877ab4c3be64a7430bf90144b73f304462865e4487668644881ba94489d0cb448a85ee44c6f71945c7ac3c45646b5345646b5345ae7343c5298718c54735dbc43d5c85c4c90cbec361579943d6a2f34325f72644e01c54444da18044997da244e559c4443036e64464f7144594b6354594b6354594b63545615342c59cf617c5ad33dbc4227a86c45c02c7c3cfe38b437eabe14397b91b446e9d46444581714484eb98446616b9444741d94485cb0c459ab325459ab325459ab325450d1e41c5074417c501d4dac4f41f87c49eafcdc3942081437d64d24333d4114428763a441c18634485059044fd7eae4474f8cc44b2f50445296f23453d2827453d282745b1d33fc58e6f16c5d616dac4914e87c42e19d2c3cf0f7243e3e0c443ef5c08446d492e44eb355444548c8644b2fda244116fbf44cd51f844d54d1845d54d1845d54d18454d743ec5cdd31ac59966eec49825a7c42fc93fc4ba1c45c3a575ba43da710044e1a82344e8df464473b27b447f429844c4abb2444f7ee7446d7309456d7309456d730945e1ff3cc582c419c54712edc4899ba6c4964940c46a704dc3c222b343e325f44382941a4412163b446bd86b44624d8e448eaea644e770d7445278024552780245527802456e763bc5309318c5e35febc46799a5c4d4a53fc46e6350c33be8ae436e80ea43510c13446bd83044918a5d445c1e85446f779b449629c844bcdbf4444e1bf8444e1bf844f3d739c5d53f17c56e4fe9c4311fa4c4eadd3dc4c5f54dc30fc6ad4355f3e3434e100d44f1262844e5c85044da6a7944670691445ca8b944504ae2448f52e4448f52e444712438c5d5d319c57206f7c43a65bac404887bc4944502c4403210c2977ee04378a00844a40121446793454429256a44765b874438edab44fb7ed0448f52e4448f52e444'}
xcp_data = Get_Init_XCPData('../res/init_value_17rows_broken.json' )
# xcp_data[0], f'value byte length: {len(xcp_data[0].value)}'
# xcp_data[1], f'value byte length: {len(xcp_data[1].value)}'
1 validation error for XCPData
Value error, value length 2855!=(dimension [21, 17])*(value length 2856)! [type=value_error, input_value={'name': 'TQD_trqTrqSetNo...7ed0448f52e4448f52e444'}, input_type=dict]
For further information visit https://errors.pydantic.dev/2.6/v/value_error
1 validation error for XCPData
value_type
Assertion failed, Invalid data type FLOAT32_IEEE1 [type=assertion_error, input_value='FLOAT32_IEEE1', input_type=str]
For further information visit https://errors.pydantic.dev/2.6/v/assertion_error
1 validation error for XCPData
Value error, Value length 8 doesn't match data type FLOAT32_IEEE(4)! [type=value_error, input_value={'name': 'TQD_trqTrqSetEC...7ed0448f52e4448f52e444'}, input_type=dict]
For further information visit https://errors.pydantic.dev/2.6/v/value_error
XCPCalib
XCPCalib (config:__main__.XCPConfig=None,
data:List[__main__.XCPData]=None)
XCP calibration parameter
data
Any
Returns
None
type: ignore
Get_XCPCalib_From_XCPJSon
Get_XCPCalib_From_XCPJSon
(path:pathlib.Path=Path('../res/download.json'
))
Generate_Init_XCPData_From_A2L
Generate_Init_XCPData_From_A2L
(a2l:pathlib.Path=Path('../res/vbu_sample
.json'), keys:List[str]=['TQD_trqTrqSetNo
rmal_MAP_v',
'VBU_L045A_CWP_05_09T_AImode_CM_single',
'Lookup2D_FLOAT32_IEEE',
'Lookup2D_X_FLOAT32_IEEE, TQD_vVehSpd',
'TQD_vSgndSpd_MAP_y',
'TQD_pctAccPedPosFlt',
'TQD_pctAccPdl_MAP_x'],
node_path:str='/PROJECT/MODULE[]')
*Generate XCP calibration header from A2L file and calibration parameter name
Args: a2l (Path): path to the A2L file keys (List[str]): calibration parameter name node_path (str): path to the calibration parameter in the A2L json file
Returns: XCPCalib: XCP calibration parameter*
args.leaves, args.node_path
(['TQD_trqTrqSetNormal_MAP_v',
'VBU_L045A_CWP_05_09T_AImode_CM_single',
'Lookup2D_FLOAT32_IEEE',
'Lookup2D_X_FLOAT32_IEEE',
'Scalar_FLOAT32_IEEE',
'TQD_vVehSpd',
'TQD_vSgndSpd_MAP_y',
'TQD_pctAccPedPosFlt',
'TQD_pctAccPdl_MAP_x'],
'/PROJECT/MODULE[], ')
# init_xcpdata = Get_Init_XCPData('../res/init_value_17rows.json')
init_xcp_calib = Get_XCPCalib_From_XCPJSon('../res/download.json' )
init_xcp_calib.config
len (init_xcp_calib.data)
init_xcp_calib.data[0 ]
type (init_xcp_calib.data[0 ])
init_xcp_calib.model_dump()
init_xcp_calib.data[0 ].value_array_view.shape
XCPConfig(channel=3, download_can_id=630, upload_can_id=631)
{ 'address': '7000aa2a',
'dim': [14, 17],
'name': 'TQD_trqTrqSetNormal_MAP_v',
'type_size': 4,
'value': '0000000025...344',
'value_array_view': array([[ 0. , 1135.317, 1135.317, ..., 4436. , 4436. ,
4436. ],
[ 0. , 148.09 , 148.09 , ..., 4436. , 4436. ,
4436. ],
[-1338.534, -833.344, -328.155, ..., 4436. , 4436. ,
4436. ],
...,
[-1316.842, -1086.408, -855.974, ..., 2034.368, 2034.368,
2034.368],
[-1141.171, -926.042, -710.912, ..., 1859.521, 1859.521,
1859.521],
[ -286.008, -135.973, 14.062, ..., 1690.249, 1690.249,
1690.249]], dtype=float32),
'value_bytes': "b'\\x00'...b'D'",
'value_length': 4,
'value_type': 'FLOAT32_IEEE'}
{'config': {'channel': 3, 'download_can_id': 630, 'upload_can_id': 631},
'data': [{'name': 'TQD_trqTrqSetNormal_MAP_v',
'address': '7000aa2a',
'dim': [14, 17],
'value_type': 'FLOAT32_IEEE',
'value_length': 4,
'value': '0000000025ea8d4425ea8d4425ea8d4425ea8d44db349544b31eb6448c08d74464f2f7441e6e0c45811d2545e3cc3d45467c564585ed834500a08a4500a08a4500a08a4500000000ed161443ed1614434eba8d431a791e44cb4c60443e10914417fab144efe3d244c8cdf34446961245a9452b450bf54345d053754500a08a4500a08a4500a08a451451a7c40b5650c4dd13a4c3b80831434da9f94356254144847c81445c66a2443550c3440d3ae44469cc0a45cb7b23452e2b3c45f3896d4500a08a4500a08a4500a08a45fffc0fc5a4fcd0c44bff81c4c807ccc339db5f4376a00944f8d74744bd0783447f23a244403fc144e2e8ef4442490f45139e2645b5475545abf8814500a08a4500a08a45771f0dc59f6adac451969ac4078435c4ab6d57c3629a9343eb8d18443f2953444ae28644f42fa4447424d044f318fc44b906144539fb3f45b8ef6b4500a08a4500a08a45483e09c51dd0dcc4a923a7c46cee62c40a2befc3dcc943c29338be43be142944e413604485898b44e1c8b4443e08de44cda303452ae32c4586225645e3617f4500a08a45735904c5aa24dac46c96abc45f107ac4e5f31cc4ac5d7fc37928ea4212c3f443ff0b3e44f76e7144b5419f44efcbc5442856ec444eb51c45873f4345c1c96945f1378345efe1fcc4bac2d3c485a3aac44f8481c434ca30c49117bdc3ddd544c21ae28b43782f1844d5ca5444823a8e44990fb244b0e4d5446fc70e45869c32459e715645d52c5745ab09efc4be0dcac4d111a5c4e31580c4eb3336c42178d8c3d81009c393ce1e43ff56e3435aa33b4499f082448d10a4448130c54435b8034529d8244576423545764235451a2adfc4846cbcc4eeae99c4b0e26dc4846728c4afd8c5c35b89ebc2032820435a0adb4359003344857b784494a89a446513b94408e9f544555f194515471e4515471e453c43cdc4c4f8acc44dae8cc4abc758c4bc3218c49b3bafc3f646b8c240302643fd41d443eeb52a44dc4a6b44cce696447b9cb244d807ea44ef260e45ef260e45ef260e45f49aa4c40fcd87c455fe55c48c621cc4868dc5c3e8ab24c3798683423019944361a803442a443d44f3df7644de3d98446b3eb144833fe344c44bfe44c44bfe44c44bfe447ba58ec4ae8267c466ba31c43ce4f7c3ac538cc3700c83c2e89a1543045eb6434af7104492bf4644da877c4411289944149ab444e730e144ab70e844ab70e844ab70e8440b018fc329f907c359fc6041b4182443d1109d434815e843e08c19441b0f3f4457916444c9098544e7ca9744058caa44224dbd44f647d344f647d344f647d344f647d344'}]}
# xcp_data[0].name, xcp_data[0].dim, xcp_data[0].value_type, xcp_data[0].value_length, len(xcp_data[0].value)
xcp_data = Generate_Init_XCPData_From_A2L(a2l= Path('../res/VBU_AI.json' ),
keys= args.leaves,
node_path= args.node_path)
# len(xcp_data.value)
xcp_data.value = 12
try :
XCPData.model_validate(xcp_data)
except ValidationError as exc:
print (exc)
1 validation error for XCPData
value
Input should be a valid string [type=string_type, input_value=12, input_type=int]
For further information visit https://errors.pydantic.dev/2.6/v/string_type
xcp_data.value = init_xcp_calib.data[0 ].value
xcp_data
# xcp_data.value_array_view
{ 'address': '7000aa2a',
'dim': [14, 17],
'name': 'TQD_trqTrqSetNormal_MAP_v',
'type_size': 4,
'value': '0000000025...344',
'value_array_view': array([[ 0. , 1135.317, 1135.317, ..., 4436. , 4436. ,
4436. ],
[ 0. , 148.09 , 148.09 , ..., 4436. , 4436. ,
4436. ],
[-1338.534, -833.344, -328.155, ..., 4436. , 4436. ,
4436. ],
...,
[-1316.842, -1086.408, -855.974, ..., 2034.368, 2034.368,
2034.368],
[-1141.171, -926.042, -710.912, ..., 1859.521, 1859.521,
1859.521],
[ -286.008, -135.973, 14.062, ..., 1690.249, 1690.249,
1690.249]], dtype=float32),
'value_bytes': "b'\\x00'...b'D'",
'value_length': 4,
'value_type': 'FLOAT32_IEEE'}
xcp_calib = XCPCalib(config= XCPConfig(channel= 3 , download= 630 , upload= 631 ),data= [xcp_data])
xcp_calib.model_dump()
xcp_calib
{'config': {'channel': 3, 'download_can_id': 630, 'upload_can_id': 631},
'data': [{'name': 'TQD_trqTrqSetNormal_MAP_v',
'address': '7000aa2a',
'dim': [14, 17],
'value_type': 'FLOAT32_IEEE',
'value_length': 4,
'value': '0000000025ea8d4425ea8d4425ea8d4425ea8d44db349544b31eb6448c08d74464f2f7441e6e0c45811d2545e3cc3d45467c564585ed834500a08a4500a08a4500a08a4500000000ed161443ed1614434eba8d431a791e44cb4c60443e10914417fab144efe3d244c8cdf34446961245a9452b450bf54345d053754500a08a4500a08a4500a08a451451a7c40b5650c4dd13a4c3b80831434da9f94356254144847c81445c66a2443550c3440d3ae44469cc0a45cb7b23452e2b3c45f3896d4500a08a4500a08a4500a08a45fffc0fc5a4fcd0c44bff81c4c807ccc339db5f4376a00944f8d74744bd0783447f23a244403fc144e2e8ef4442490f45139e2645b5475545abf8814500a08a4500a08a45771f0dc59f6adac451969ac4078435c4ab6d57c3629a9343eb8d18443f2953444ae28644f42fa4447424d044f318fc44b906144539fb3f45b8ef6b4500a08a4500a08a45483e09c51dd0dcc4a923a7c46cee62c40a2befc3dcc943c29338be43be142944e413604485898b44e1c8b4443e08de44cda303452ae32c4586225645e3617f4500a08a45735904c5aa24dac46c96abc45f107ac4e5f31cc4ac5d7fc37928ea4212c3f443ff0b3e44f76e7144b5419f44efcbc5442856ec444eb51c45873f4345c1c96945f1378345efe1fcc4bac2d3c485a3aac44f8481c434ca30c49117bdc3ddd544c21ae28b43782f1844d5ca5444823a8e44990fb244b0e4d5446fc70e45869c32459e715645d52c5745ab09efc4be0dcac4d111a5c4e31580c4eb3336c42178d8c3d81009c393ce1e43ff56e3435aa33b4499f082448d10a4448130c54435b8034529d8244576423545764235451a2adfc4846cbcc4eeae99c4b0e26dc4846728c4afd8c5c35b89ebc2032820435a0adb4359003344857b784494a89a446513b94408e9f544555f194515471e4515471e453c43cdc4c4f8acc44dae8cc4abc758c4bc3218c49b3bafc3f646b8c240302643fd41d443eeb52a44dc4a6b44cce696447b9cb244d807ea44ef260e45ef260e45ef260e45f49aa4c40fcd87c455fe55c48c621cc4868dc5c3e8ab24c3798683423019944361a803442a443d44f3df7644de3d98446b3eb144833fe344c44bfe44c44bfe44c44bfe447ba58ec4ae8267c466ba31c43ce4f7c3ac538cc3700c83c2e89a1543045eb6434af7104492bf4644da877c4411289944149ab444e730e144ab70e844ab70e844ab70e8440b018fc329f907c359fc6041b4182443d1109d434815e843e08c19441b0f3f4457916444c9098544e7ca9744058caa44224dbd44f647d344f647d344f647d344f647d344'}]}
XCPCalib(config=XCPConfig(channel=3, download_can_id=630, upload_can_id=631), data=[{ 'address': '7000aa2a',
'dim': [14, 17],
'name': 'TQD_trqTrqSetNormal_MAP_v',
'type_size': 4,
'value': '0000000025...344',
'value_array_view': array([[ 0. , 1135.317, 1135.317, ..., 4436. , 4436. ,
4436. ],
[ 0. , 148.09 , 148.09 , ..., 4436. , 4436. ,
4436. ],
[-1338.534, -833.344, -328.155, ..., 4436. , 4436. ,
4436. ],
...,
[-1316.842, -1086.408, -855.974, ..., 2034.368, 2034.368,
2034.368],
[-1141.171, -926.042, -710.912, ..., 1859.521, 1859.521,
1859.521],
[ -286.008, -135.973, 14.062, ..., 1690.249, 1690.249,
1690.249]], dtype=float32),
'value_bytes': "b'\\x00'...b'D'",
'value_length': 4,
'value_type': 'FLOAT32_IEEE'}])
{'Calibration.TQD_trqTrqSetNormal_MAP_v': <Calibration: 'TQD_trqTrqSetNormal_MAP_v'>,
'Measurement.TQD_vVehSpd': <Measurement: 'TQD_vVehSpd'>,
'Measurement.TQD_pctAccPedPosFlt': <Measurement: 'TQD_pctAccPedPosFlt'>,
'AxisScale.TQD_vSgndSpd_MAP_y': <AxisScale: 'TQD_vSgndSpd_MAP_y'>,
'AxisScale.TQD_pctAccPdl_MAP_x': <AxisScale: 'TQD_pctAccPdl_MAP_x'>,
'DataConversion.VBU_L045A_CWP_05_09T_AImode_CM_single': <DataConversion: 'VBU_L045A_CWP_05_09T_AImode_CM_single'>,
'DataLayout.Scalar_FLOAT32_IEEE': <DataLayout: 'Scalar_FLOAT32_IEEE'>,
'DataLayout.Lookup2D_FLOAT32_IEEE': <DataLayout: 'Lookup2D_FLOAT32_IEEE'>,
'DataLayout.Lookup2D_X_FLOAT32_IEEE': <DataLayout: 'Lookup2D_X_FLOAT32_IEEE'>}
key = 'DataLayout.FLOAT32_IEEE'
key.split('.' )[- 1 ]
calib = Record.fetch('Calibration.TQD_trqTrqSetNormal_MAP_v' )
pprint(calib)
calib.record_type
calib.axes[0 ].axis_scale.record_type
calib.axes[0 ].axis_scale.record_type.data_type
<Calibration: 'TQD_trqTrqSetNormal_MAP_v'>
<DataLayout: 'Lookup2D_FLOAT32_IEEE'>
<DataLayout: 'Lookup2D_X_FLOAT32_IEEE'>
calib.axes[0 ].axis_scale.input
calib.axes[0 ].axis_scale.input .address
calib.axes[0 ].axis_scale.input .record_type
calib.axes[0 ].axis_scale.input .record_type.data_type
calib.axes[0 ].axis_scale.record_type
calib.axes[0 ].axis_scale.data_conversion
calib.axes[0 ].data_conversion.Format
<Measurement: 'TQD_vVehSpd'>
<DataLayout: 'Scalar_FLOAT32_IEEE'>
<DataLayout: 'Lookup2D_X_FLOAT32_IEEE'>
<DataConversion: 'VBU_L045A_CWP_05_09T_AImode_CM_single'>
calib.axes[1 ].axis_scale.input
calib.axes[1 ].axis_scale.input .address
calib.axes[1 ].axis_scale.input .record_type
calib.axes[1 ].axis_scale.input .record_type.data_type
calib.axes[1 ].axis_scale.record_type
calib.axes[1 ].axis_scale.data_conversion
calib.axes[1 ].data_conversion.Format
<Measurement: 'TQD_pctAccPedPosFlt'>
<DataLayout: 'Scalar_FLOAT32_IEEE'>
<DataLayout: 'Lookup2D_X_FLOAT32_IEEE'>
<DataConversion: 'VBU_L045A_CWP_05_09T_AImode_CM_single'>
load_a2l_lazy
load_a2l_lazy (path:pathlib.Path, leaves:list[str])
*Search for the calibration key in the A2L file. Descripttion: Load the A2L file as a dictionary.
Args: path (str): The path to the A2L file. calib_key (str): The node path to the calibration parameters.
Returns: dict: The A2L file as a dictionary.*
# parser = get_argparser()
args = parser.parse_args(
[
"-p" ,
# r"../res/VBU_AI.json",
r"../res/VBU_AI.json" ,
"-n" ,
r"/PROJECT/MODULE[], " ,
# r"/PROJECT/MODULE[]/CHARACTERISTIC[], "
# r"/PROJECT/MODULE[]/MEASUREMENT[], "
# r"/PROJECT/MODULE[]/AXIS_PTS[], "
# r"/PROJECT/MODULE[]/COMPU_METHOD[]",
"-l" ,
r"TQD_trqTrqSetNormal_MAP_v, "
r"VBU_L045A_CWP_05_09T_AImode_CM_single, "
r"Lookup2D_FLOAT32_IEEE, "
r"Lookup2D_X_FLOAT32_IEEE, "
r"TQD_vVehSpd, "
r"TQD_vSgndSpd_MAP_y, "
r"TQD_pctAccPedPosFlt, "
r"TQD_pctAccPdl_MAP_x" ,
]
)
# args.__dict__
args.path, args.leaves, args.node_path
('../res/VBU_AI.json',
['TQD_trqTrqSetNormal_MAP_v',
'VBU_L045A_CWP_05_09T_AImode_CM_single',
'Lookup2D_FLOAT32_IEEE',
'Lookup2D_X_FLOAT32_IEEE',
'TQD_vVehSpd',
'TQD_vSgndSpd_MAP_y',
'TQD_pctAccPedPosFlt',
'TQD_pctAccPdl_MAP_x'],
'/PROJECT/MODULE[], ')
load_a2l_eager
load_a2l_eager (path:pathlib.Path,
jnode_path:__main__.JsonNodePath=<JsonNodePath [<PROJECT
dict>, <MODULE[] list>]>)
*Load the A2L file as a dictionary. Descripttion: Load the A2L file as a dictionary.
Args: path (Path): The path to the A2L file. node (str): The node to search for, e.g. “/PROJECT/MODULE[0]/CHARACTERISTIC”.
Returns: dict: The A2L file as a dictionary.*
args.path, args.node_path, args.leaves
('../res/VBU_AI.json',
'/PROJECT/MODULE[], ',
['TQD_trqTrqSetNormal_MAP_v',
'VBU_L045A_CWP_05_09T_AImode_CM_single',
'Lookup2D_FLOAT32_IEEE',
'Lookup2D_X_FLOAT32_IEEE',
'TQD_vVehSpd',
'TQD_vSgndSpd_MAP_y',
'TQD_pctAccPedPosFlt',
'TQD_pctAccPdl_MAP_x'])
records = load_records_lazy(args.path, args.leaves, JsonNodePath(args.node_path))
918 ms ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)
records = load_a2l_lazy(args.path, args.leaves)
3.45 s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)
# %%timeit -n 1 -r 1
calibs = load_a2l_eager(args.path, JsonNodePath(args.node_path))
calibs[0 ]['CHARACTERISTIC' ][0 ]
{'Name': {'Value': 'INP_pVacPres_CUR_v'},
'LongIdentifier': {},
'Type': 'CURVE',
'Address': {'Value': '1879065574', 'Base': 16, 'Size': 8},
'Deposit': {'Value': 'Lookup1D_FLOAT32_IEEE'},
'MaxDiff': {},
'Conversion': {'Value': 'VBU_L045A_CWP_05_09T_AImode_CM_single'},
'LowerLimit': {'Value': -3.4e+38,
'IntegralSign': '-',
'IntegralSize': 1,
'DecimalSize': 5},
'UpperLimit': {'Value': 3.4e+38, 'IntegralSize': 1, 'DecimalSize': 5},
'AXIS_DESCR': [{'Attribute': 'COM_AXIS',
'InputQuantity': {'Value': 'NO_INPUT_QUANTITY'},
'Conversion': {'Value': 'VBU_L045A_CWP_05_09T_AImode_CM_single'},
'MaxAxisPoints': {'Value': 6, 'Base': 10, 'Size': 1},
'LowerLimit': {'Value': -3.4e+38,
'IntegralSign': '-',
'IntegralSize': 1,
'DecimalSize': 5},
'UpperLimit': {'Value': 3.4e+38, 'IntegralSize': 1, 'DecimalSize': 5},
'AXIS_PTS_REF': {'AxisPoints': {'Value': 'INP_uVacPres_CUR_x'}}}]}