from dataclasses import dataclass
from dataclasses import field
from struct import Struct
from math import sqrt
from collections import namedtuple
import sys
@dataclass
class vecf:
x: float
y: float
z: float
packer: Struct = field(init=False, repr=False, default=Struct( "fff" ))
def normalize(self):
return sqrt(self.x*self.x + self.y*self.y + self.z*self.z)
def pack(self):
return self.packer.pack(*self.to_list())
def unpack(self, pkt):
return self.packer.unpack(pkt)
def to_list(self):
ret = []
for a in self.__dict__.values():
if isinstance(a,float) or isinstance(a,int):
ret.append(a)
else:
for i in a.to_list():
ret.append(i)
return ret
@dataclass
class imu:
id: int # something
accel: vecf
gyro: vecf
mag: vecf
pressure: float
temperature: float
timestamp: int
packer: Struct = field(init=False, repr=False, default=Struct( "BfffffffffffI" ))
def pack(self):
data = self.to_list()
print(data)
return self.packer.pack(*data)
def unpack(self, pkt):
return self.packer.unpack(pkt)
def to_list(self):
ret = []
for a in self.__dict__.values():
if isinstance(a,float) or isinstance(a,int):
ret.append(a)
else:
for i in a.to_list():
ret.append(i)
return ret
v = vecf(1,2,3)
print(v)
import dataclasses
f = dataclasses.fields(v)[0]
l = []
for a in v.__dict__.values():
if isinstance(a,float) or isinstance(a,int):
l.append(a)
else:
for i in a.to_list():
l.append(i)
l
# f.values()
# for ff in f:
# print(ff)
vecf(x=1, y=2, z=3)
[1, 2, 3]
v.to_list()
[1, 2, 3]
pkt = v.pack()
print(pkt)
b'\x00\x00\x80?\x00\x00\x00@\x00\x00@@'
m = v.unpack(pkt)
print(v)
vecf(x=1, y=2, z=3)
i = imu(1,vecf(1,2,3),vecf(4,5,6),vecf(7,8,9),1,2,3)
print(i)
imu(id=1, accel=vecf(x=1, y=2, z=3), gyro=vecf(x=4, y=5, z=6), mag=vecf(x=7, y=8, z=9), pressure=1, temperature=2, timestamp=3)
pkt = i.pack()
print(pkt)
[1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3] b'\x01\x00\x00\x00\x00\x00\x80?\x00\x00\x00@\x00\x00@@\x00\x00\x80@\x00\x00\xa0@\x00\x00\xc0@\x00\x00\xe0@\x00\x00\x00A\x00\x00\x10A\x00\x00\x80?\x00\x00\x00@\x03\x00\x00\x00'
class Base:
def flatten(self, data):
"""
(0, (1, 2, 3), (4, 5, 6)) -> (0, 1, 2, 3, 4, 5, 6)
"""
if isinstance(data, tuple):
for x in data:
yield from self.flatten(x)
else:
yield data
def serialize(self):
return tuple(self.flatten(dataclasses.astuple(self)))
@dataclass(frozen=True)
class vec_t(Base):
x: float
y: float
z: float
def __yivo__(self):
return ("fff", 12, vec_t) # (struct format, number bytes)
@dataclass(frozen=True)
class twist_t(Base):
linear: vec_t
angular: vec_t
def __yivo__(self):
return ("3f3f", 120, twist_t) # (struct format, number bytes)
# def __init__(self,lx,ly,lz,ax,ay,az):
# object.__setattr__(self, "linear", vec_t(lx,ly,lz))
# object.__setattr__(self, "angular", vec_t(ax,ay,az))
def fmt(a):
return a.__yivo__()[0]
def sizeof(a):
return a.__yivo__()[1]
def cls(a):
return a.__yivo__()[2]
t=twist_t(vec_t(0,1,2),vec_t(3,4,5))
t
twist_t(linear=vec_t(x=0, y=1, z=2), angular=vec_t(x=3, y=4, z=5))
t.serialize()
(0, 1, 2, 3, 4, 5)
dataclasses.astuple(t)
((0, 1, 2), (3, 4, 5))
t2=twist_t(vec_t(0,1,2),vec_t(3,4,5))
t == t2
True
fmt(t)
'3f3f'
sizeof(t)
120
x=cls(t)
x(1,2)
twist_t(linear=1, angular=2)
v = vec_t(1,2,3)
cls(v)
__main__.vec_t
t.linear = 4
--------------------------------------------------------------------------- FrozenInstanceError Traceback (most recent call last) Cell In[110], line 1 ----> 1 t.linear = 4 File <string>:4, in __setattr__(self, name, value) FrozenInstanceError: cannot assign to field 'linear'
dir(t)
['__annotations__', '__class__', '__dataclass_fields__', '__dataclass_params__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__match_args__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '__yivo__', 'angular', 'flatten', 'linear', 'serialize']
t.__yivo__()
('3f3f', 120, __main__.twist_t)