flightdata 0.2.11__tar.gz → 0.2.13__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {flightdata-0.2.11/flightdata.egg-info → flightdata-0.2.13}/PKG-INFO +1 -1
- {flightdata-0.2.11 → flightdata-0.2.13}/flightdata/base/__init__.py +5 -2
- {flightdata-0.2.11 → flightdata-0.2.13}/flightdata/base/table.py +38 -35
- {flightdata-0.2.11 → flightdata-0.2.13}/flightdata/flight/flight.py +39 -14
- {flightdata-0.2.11 → flightdata-0.2.13}/flightdata/scripts/collect_logs.py +4 -1
- {flightdata-0.2.11 → flightdata-0.2.13}/flightdata/scripts/flightline.py +4 -1
- {flightdata-0.2.11 → flightdata-0.2.13}/flightdata/state.py +5 -9
- {flightdata-0.2.11 → flightdata-0.2.13/flightdata.egg-info}/PKG-INFO +1 -1
- {flightdata-0.2.11 → flightdata-0.2.13}/test/base/test_table.py +16 -13
- {flightdata-0.2.11 → flightdata-0.2.13}/.github/workflows/publish_pypi.yml +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/.gitignore +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/.vscode/launch.json +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/.vscode/settings.json +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/LICENSE +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/README.md +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/examples/__init__.py +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/examples/axis_rates.ipynb +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/examples/data/__init__.py +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/examples/data/manual_F3A_F23_22_04_28_00000231.json +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/examples/data/manual_F3A_P23_22_05_31_00000350.json +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/examples/data/manual_F3A_P23_23_08_11_00000094.json +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/examples/flight_data.py +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/examples/flight_dynamics/00000150.json +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/examples/flight_dynamics/__init__.py +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/examples/flight_dynamics/box.f3a +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/examples/flight_dynamics/param_id.py +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/examples/state_analysis/__init__.py +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/examples/state_analysis/axes.py +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/examples/state_analysis/state_fill_plot.py +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/flightdata/__init__.py +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/flightdata/base/collection.py +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/flightdata/base/constructs.py +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/flightdata/base/labeling.py +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/flightdata/base/numpy_encoder.py +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/flightdata/coefficients.py +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/flightdata/environment/__init__.py +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/flightdata/environment/environment.py +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/flightdata/environment/wind.py +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/flightdata/flight/__init__.py +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/flightdata/flight/ardupilot.py +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/flightdata/flight/fields.py +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/flightdata/flight/parameters.py +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/flightdata/flow.py +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/flightdata/model/__init__.py +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/flightdata/model/aerodynamic.py +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/flightdata/model/thrust.py +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/flightdata/origin.py +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/flightdata.egg-info/SOURCES.txt +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/flightdata.egg-info/dependency_links.txt +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/flightdata.egg-info/entry_points.txt +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/flightdata.egg-info/requires.txt +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/flightdata.egg-info/top_level.txt +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/pyproject.toml +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/requirements-dev.txt +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/requirements.txt +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/setup.cfg +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/test/EmailedBox.f3a +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/test/__init__.py +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/test/base/__init__.py +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/test/base/test_base_constructs.py +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/test/conftest.py +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/test/data/make_inputs.py +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/test/data/manual_F3A_P23.json +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/test/data/p23.BIN +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/test/data/p23.json +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/test/data/p23_box.f3a +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/test/data/p23_fc.json +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/test/data/p23_flight.json +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/test/data/vtol_hover.bin +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/test/data/vtol_hover.json +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/test/test_environment/__init__.py +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/test/test_environment/test_environment.py +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/test/test_environment/test_environment_wind.py +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/test/test_fields.py +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/test/test_flight.py +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/test/test_model/__init__.py +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/test/test_model/test_model_coefficients.py +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/test/test_model/test_model_flow.py +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/test/test_origin.py +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/test/test_state/__init__.py +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/test/test_state/test_state.py +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/test/test_state/test_state_builders.py +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/test/test_state/test_state_conversions.py +0 -0
- {flightdata-0.2.11 → flightdata-0.2.13}/test/test_state/test_state_measurements.py +0 -0
|
@@ -80,40 +80,16 @@ class Table:
|
|
|
80
80
|
else:
|
|
81
81
|
raise TypeError(f"Expected Number or slice, got {sli.__class__.__name__}")
|
|
82
82
|
|
|
83
|
-
|
|
84
83
|
def slice_raw_t(self, sli):
|
|
85
84
|
inds = self.data.reset_index(names="t2").set_index("t").loc[sli].t2.to_numpy()#set_index("t", drop=False).columns
|
|
86
85
|
|
|
87
86
|
return self.__class__(self.data.loc[inds])
|
|
88
87
|
|
|
89
|
-
@classmethod
|
|
90
|
-
def stack(Cls, sections: list, overlap: int=1) -> Self:
|
|
91
|
-
"""Stack a list of Tables on top of each other.
|
|
92
|
-
The overlap is the number of rows to overlap between each section
|
|
93
|
-
"""
|
|
94
|
-
# first build list of index offsets, to be added to each dataframe
|
|
95
|
-
if overlap > 0:
|
|
96
|
-
offsets = np.cumsum([0] + [sec.data.index[-overlap] for sec in sections[:-1]])
|
|
97
|
-
dfs = [section.data.iloc[:-overlap] for section in sections[:-1]] + [sections[-1].data]
|
|
98
|
-
elif overlap == 0:
|
|
99
|
-
offsets = np.cumsum([0] + [sec.duration + sec.dt[-1] for sec in sections[:-1]])
|
|
100
|
-
dfs = [section.data for section in sections]
|
|
101
|
-
else:
|
|
102
|
-
raise AttributeError("Overlap must be >= 0")
|
|
103
|
-
|
|
104
|
-
for df, offset in zip(dfs, offsets):
|
|
105
|
-
df.index = np.array(df.index) - df.index[0] + offset
|
|
106
|
-
combo = pd.concat(dfs)
|
|
107
|
-
combo.index.name = "t"
|
|
108
|
-
|
|
109
|
-
combo["t"] = combo.index
|
|
110
|
-
|
|
111
|
-
return Cls(combo)
|
|
112
|
-
|
|
113
88
|
def __iter__(self):
|
|
114
89
|
for ind in list(self.data.index):
|
|
115
90
|
yield self[ind]
|
|
116
91
|
|
|
92
|
+
|
|
117
93
|
@classmethod
|
|
118
94
|
def from_constructs(cls, *args,**kwargs) -> Self:
|
|
119
95
|
kwargs = dict(
|
|
@@ -132,7 +108,7 @@ class Table:
|
|
|
132
108
|
)
|
|
133
109
|
|
|
134
110
|
return cls(df)
|
|
135
|
-
|
|
111
|
+
|
|
136
112
|
def __repr__(self):
|
|
137
113
|
return f"{self.__class__.__name__} Table(duration = {self.duration})"
|
|
138
114
|
|
|
@@ -160,6 +136,30 @@ class Table:
|
|
|
160
136
|
ignore_index=True
|
|
161
137
|
).set_index("t", drop=False))
|
|
162
138
|
|
|
139
|
+
@classmethod
|
|
140
|
+
def stack(Cls, sections: list, overlap: int=1) -> Self:
|
|
141
|
+
"""Stack a list of Tables on top of each other.
|
|
142
|
+
The overlap is the number of rows to overlap between each section
|
|
143
|
+
"""
|
|
144
|
+
# first build list of index offsets, to be added to each dataframe
|
|
145
|
+
if overlap > 0:
|
|
146
|
+
offsets = np.cumsum([0] + [sec.data.index[-overlap] for sec in sections[:-1]])
|
|
147
|
+
dfs = [section.data.iloc[:-overlap] for section in sections[:-1]] + [sections[-1].data]
|
|
148
|
+
elif overlap == 0:
|
|
149
|
+
offsets = np.cumsum([0] + [sec.duration + sec.dt[-1] for sec in sections[:-1]])
|
|
150
|
+
dfs = [section.data for section in sections]
|
|
151
|
+
else:
|
|
152
|
+
raise AttributeError("Overlap must be >= 0")
|
|
153
|
+
|
|
154
|
+
for df, offset in zip(dfs, offsets):
|
|
155
|
+
df.index = np.array(df.index) - df.index[0] + offset
|
|
156
|
+
combo = pd.concat(dfs)
|
|
157
|
+
combo.index.name = "t"
|
|
158
|
+
|
|
159
|
+
combo["t"] = combo.index
|
|
160
|
+
|
|
161
|
+
return Cls(combo)
|
|
162
|
+
|
|
163
163
|
def label(self, **kwargs) -> Self:
|
|
164
164
|
return self.__class__(self.data.assign(**kwargs))
|
|
165
165
|
|
|
@@ -176,9 +176,11 @@ class Table:
|
|
|
176
176
|
|
|
177
177
|
def get_subset_df(self, **kwargs) -> pd.DataFrame:
|
|
178
178
|
dfo = self.data
|
|
179
|
+
sel = np.full(len(self.data), True)
|
|
179
180
|
for k, v in kwargs.items():
|
|
180
|
-
|
|
181
|
-
|
|
181
|
+
sel = sel & (dfo[k] == v)
|
|
182
|
+
|
|
183
|
+
return self.data.loc[sel + (sel.astype(int).diff() == -1)]
|
|
182
184
|
|
|
183
185
|
def get_label_subset(self, min_len=1, **kwargs) -> Self:
|
|
184
186
|
return self.__class__(self.get_subset_df(**kwargs), min_len=min_len)
|
|
@@ -243,13 +245,14 @@ class Table:
|
|
|
243
245
|
return self.label(**labels.to_dict(orient='list'))
|
|
244
246
|
|
|
245
247
|
@classmethod
|
|
246
|
-
def shift_multi(Cls, steps: int, tb1: Self, tb2: Self, min_len=
|
|
248
|
+
def shift_multi(Cls, steps: int, tb1: Self, tb2: Self, min_len=1) -> Tuple[Self, Self]:
|
|
247
249
|
'''Take datapoints off the start of tb2 and add to the end tb1'''
|
|
248
|
-
if (steps>0 and len(tb2)-min_len<steps) or (steps<0 and min_len - len(tb1) > steps):
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
250
|
+
#if (steps>0 and len(tb2)-min_len<steps) or (steps<0 and min_len - len(tb1) > steps):
|
|
251
|
+
# raise ValueError(f'Cannot Squash a Table to less than {min_len} datapoints')
|
|
252
|
+
tj = Cls.stack([tb1, tb2]).shift_label(steps, min_len, **dict(tb1.labels.iloc[0]))
|
|
253
|
+
|
|
254
|
+
return Cls(tj.get_subset_df(**dict(tb1.labels.iloc[0]))), \
|
|
255
|
+
Cls(tj.get_subset_df(**dict(tb2.labels.iloc[0])))
|
|
253
256
|
|
|
254
257
|
def shift_label_ratio(self, ratio: float, min_len=None, **kwargs) -> Self:
|
|
255
258
|
'''shift a label within its allowable bounds, with a ratio of
|
|
@@ -376,7 +379,7 @@ class Table:
|
|
|
376
379
|
if max_bck + max_fwd + get_len(i) < min_len:
|
|
377
380
|
raise Exception(f'{row.iloc[0]},{row.iloc[1]} too short and cannot shorten adjacent labels further')
|
|
378
381
|
else:
|
|
379
|
-
_extend = (min_len - get_len(i)) / 2
|
|
382
|
+
_extend = int(np.ceil((min_len - get_len(i)) / 2))
|
|
380
383
|
ebck = min(max_bck, int(np.floor(_extend)))
|
|
381
384
|
efwd = min(max_fwd, int(np.floor(_extend))+1)
|
|
382
385
|
|
|
@@ -447,6 +447,27 @@ class Flight:
|
|
|
447
447
|
))
|
|
448
448
|
return dfs
|
|
449
449
|
|
|
450
|
+
@staticmethod
|
|
451
|
+
def parse_fcj_data(origin: Origin, df: pd.DataFrame):
|
|
452
|
+
df = Flight.build_cols(
|
|
453
|
+
time_actual = df['time']/1e6 + int(time()),
|
|
454
|
+
time_flight = df['time']/1e6,
|
|
455
|
+
attitude_roll = np.radians(df['r']),
|
|
456
|
+
attitude_pitch = np.radians(df['p']),
|
|
457
|
+
attitude_yaw = np.radians(df['yw']),
|
|
458
|
+
position_N = df['N'],
|
|
459
|
+
position_E = df['E'],
|
|
460
|
+
position_D = df['D'],
|
|
461
|
+
velocity_N = df['VN'],
|
|
462
|
+
velocity_E = df['VE'],
|
|
463
|
+
velocity_D = df['VD'],
|
|
464
|
+
wind_N = df['wN'] if 'wN' in df.columns else None,
|
|
465
|
+
wind_E = df['wE'] if 'wE' in df.columns else None,
|
|
466
|
+
)
|
|
467
|
+
|
|
468
|
+
return Flight(df.set_index('time_flight', drop=False), None, origin, 'position')
|
|
469
|
+
|
|
470
|
+
|
|
450
471
|
@staticmethod
|
|
451
472
|
def from_fc_json(fc_json: Union[str, dict, IO]) -> Self:
|
|
452
473
|
|
|
@@ -473,20 +494,24 @@ class Flight:
|
|
|
473
494
|
wind_N = df['wN'] if 'wN' in df.columns else None,
|
|
474
495
|
wind_E = df['wE'] if 'wE' in df.columns else None,
|
|
475
496
|
)
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
497
|
+
|
|
498
|
+
if 'parameters' in fc_json:
|
|
499
|
+
origin = Origin(
|
|
500
|
+
'fcj_origin',
|
|
501
|
+
GPS(
|
|
502
|
+
float(fc_json['parameters']['pilotLat']),
|
|
503
|
+
float(fc_json['parameters']['pilotLng']),
|
|
504
|
+
float(fc_json['parameters']['pilotAlt'])
|
|
505
|
+
).offset(-Point(
|
|
506
|
+
fc_json['parameters']['moveNorth'],
|
|
507
|
+
fc_json['parameters']['moveEast'],
|
|
508
|
+
0,
|
|
509
|
+
)),
|
|
510
|
+
0
|
|
511
|
+
)
|
|
512
|
+
else:
|
|
513
|
+
origin = Origin('dummy_origin', GPS(0,0,0), -np.pi/2)
|
|
514
|
+
|
|
490
515
|
return Flight(df.set_index('time_flight', drop=False), None, origin, 'position')#.remove_time_flutter()
|
|
491
516
|
|
|
492
517
|
def remove_time_flutter(self):
|
|
@@ -15,7 +15,6 @@ class State(Table):
|
|
|
15
15
|
SVar("vel", g.Point, ["u", "v", "w"] , lambda st: g.P0() if len(st)==1 else st.att.inverse().transform_point(st.pos.diff(st.dt))),
|
|
16
16
|
SVar("rvel", g.Point, ["p", "q", "r"] , lambda st: g.P0() if len(st)==1 else st.att.body_diff(st.dt)),
|
|
17
17
|
SVar("acc", g.Point, ["du", "dv", "dw"] , lambda st : g.P0() if len(st)==1 else st.att.inverse().transform_point(st.att.transform_point(st.vel).diff(st.dt) + g.PZ(9.81, len(st)))),
|
|
18
|
-
SVar("racc", g.Point, ["dp", "dq", "dr"] , lambda st: g.P0() if len(st)==1 else st.rvel.diff(st.dt)),
|
|
19
18
|
])
|
|
20
19
|
_construct_freq = 30
|
|
21
20
|
|
|
@@ -131,7 +130,7 @@ class State(Table):
|
|
|
131
130
|
from scipy.spatial.distance import euclidean
|
|
132
131
|
def get_brv(brv):
|
|
133
132
|
if mirror:
|
|
134
|
-
brv = brv.abs() * g.Point(1, 0, 1) + brv * g.Point(0, 1, 0 )
|
|
133
|
+
brv = g.Point(np.abs(brv.x), brv.y, np.abs(brv.z))#brv.abs() * g.Point(1, 0, 1) + brv * g.Point(0, 1, 0 )
|
|
135
134
|
return brv * weights
|
|
136
135
|
|
|
137
136
|
fl = get_brv(flown.rvel)
|
|
@@ -147,7 +146,7 @@ class State(Table):
|
|
|
147
146
|
|
|
148
147
|
return distance, State.copy_labels(template, flown, path, 3)
|
|
149
148
|
|
|
150
|
-
def splitter_labels(self: State, mans: List[dict], better_names: List[str]=None) -> State:
|
|
149
|
+
def splitter_labels(self: State, mans: List[dict], better_names: List[str]=None, target_col='manoeuvre') -> State:
|
|
151
150
|
"""label the manoeuvres in a State based on the flight coach splitter information
|
|
152
151
|
|
|
153
152
|
TODO this assumes the state only contains the dataset contained in the json
|
|
@@ -164,7 +163,7 @@ class State(Table):
|
|
|
164
163
|
takeoff = self.data.iloc[0:int(mans[0]["stop"])+1]
|
|
165
164
|
|
|
166
165
|
labels = [mans[0]["name"]]
|
|
167
|
-
labelled = [State(takeoff).label(
|
|
166
|
+
labelled = [State(takeoff).label(**{target_col:labels[0]})]
|
|
168
167
|
if better_names:
|
|
169
168
|
better_names.append('land')
|
|
170
169
|
|
|
@@ -179,7 +178,7 @@ class State(Table):
|
|
|
179
178
|
labelled.append(
|
|
180
179
|
State(
|
|
181
180
|
self.data.iloc[int(split_man["start"]):int(split_man["stop"])+1]
|
|
182
|
-
).label(
|
|
181
|
+
).label(**{target_col:name})
|
|
183
182
|
)
|
|
184
183
|
labels.append(split_man["name"])
|
|
185
184
|
|
|
@@ -217,7 +216,7 @@ class State(Table):
|
|
|
217
216
|
|
|
218
217
|
def get_meid(self: State, manid: int, elid: int=None):
|
|
219
218
|
st = self.get_manoeuvre(manid)
|
|
220
|
-
if
|
|
219
|
+
if elid is not None:
|
|
221
220
|
return st.get_element(elid)
|
|
222
221
|
else:
|
|
223
222
|
return st
|
|
@@ -233,7 +232,6 @@ class State(Table):
|
|
|
233
232
|
vel=q.transform_point(self.vel),
|
|
234
233
|
rvel=q.transform_point(self.rvel),
|
|
235
234
|
acc=q.transform_point(self.acc),
|
|
236
|
-
racc=q.transform_point(self.racc),
|
|
237
235
|
))
|
|
238
236
|
|
|
239
237
|
def scale(self: State, factor: float) -> State:
|
|
@@ -244,7 +242,6 @@ class State(Table):
|
|
|
244
242
|
vel=self.vel * factor,
|
|
245
243
|
rvel=self.rvel,
|
|
246
244
|
acc=self.acc * factor,
|
|
247
|
-
racc=self.racc,
|
|
248
245
|
))
|
|
249
246
|
|
|
250
247
|
def mirror_zy(self: State) -> State:
|
|
@@ -456,7 +453,6 @@ class State(Table):
|
|
|
456
453
|
vel=self.vel,
|
|
457
454
|
rvel=self.rvel,
|
|
458
455
|
acc=self.acc,
|
|
459
|
-
racc=self.racc,
|
|
460
456
|
))
|
|
461
457
|
|
|
462
458
|
def move_back(self:State, transform:g.Transformation) -> State:
|
|
@@ -8,7 +8,7 @@ from pytest import fixture
|
|
|
8
8
|
|
|
9
9
|
@fixture
|
|
10
10
|
def df():
|
|
11
|
-
df = pd.DataFrame(np.linspace(0,
|
|
11
|
+
df = pd.DataFrame(np.linspace(0,5, 6), columns=['t'])
|
|
12
12
|
return df.set_index("t", drop=False)
|
|
13
13
|
|
|
14
14
|
@fixture
|
|
@@ -54,12 +54,15 @@ def test_get_subset_df(tab_full, labst):
|
|
|
54
54
|
assert len(tab_full) == len(df)
|
|
55
55
|
|
|
56
56
|
|
|
57
|
-
def test_shift_labels_ratios(tab_full):
|
|
58
|
-
tf =
|
|
59
|
-
|
|
60
|
-
|
|
57
|
+
def test_shift_labels_ratios(tab_full: Table):
|
|
58
|
+
tf: Table = Table.stack([
|
|
59
|
+
tab_full.label(element='e0', manoeuvre='m0'),
|
|
60
|
+
tab_full.label(element='e1', manoeuvre='m0')
|
|
61
|
+
|
|
62
|
+
])
|
|
63
|
+
|
|
61
64
|
assert sum(tf.shift_labels_ratios([0.5],2).element == 'e1') < sum(tf.element == 'e1')
|
|
62
|
-
|
|
65
|
+
|
|
63
66
|
|
|
64
67
|
def test_stack(tab_full):
|
|
65
68
|
tfn = Table.stack([tab_full.label(element='e0'), tab_full.label(element='e1')], overlap=0)
|
|
@@ -72,18 +75,18 @@ def test_stack(tab_full):
|
|
|
72
75
|
|
|
73
76
|
|
|
74
77
|
def test_shift_multi(tab_full):
|
|
75
|
-
|
|
76
|
-
tb1, tb2 = Table.shift_multi(2,
|
|
78
|
+
tabs = Table.stack([tab_full.label(element='e0'), tab_full.label(element='e1')], overlap=1).split_labels()
|
|
79
|
+
tb1, tb2 = Table.shift_multi(2, tabs['e0'], tabs['e1'])
|
|
77
80
|
|
|
78
81
|
assert len(tb1) == len(tab_full) + 2
|
|
79
82
|
assert len(tb2) == len(tab_full) - 2
|
|
80
83
|
assert tb2.duration == tab_full.data.index[-3]
|
|
81
84
|
|
|
82
|
-
tb1, tb2 = Table.shift_multi(-
|
|
85
|
+
tb1, tb2 = Table.shift_multi(-3, tabs['e0'], tabs['e1'])
|
|
83
86
|
|
|
84
|
-
assert len(tb1) == len(tab_full) -
|
|
85
|
-
assert len(tb2) == len(tab_full) +
|
|
86
|
-
assert tb1.duration == tab_full.data.index[-
|
|
87
|
+
assert len(tb1) == len(tab_full) - 3
|
|
88
|
+
assert len(tb2) == len(tab_full) + 3
|
|
89
|
+
assert tb1.duration == tab_full.data.index[-4]
|
|
87
90
|
|
|
88
91
|
|
|
89
92
|
def test_table_cumulative_labels(tab_full):
|
|
@@ -102,6 +105,6 @@ def test_table_cumulative_labels(tab_full):
|
|
|
102
105
|
indexes = np.unique(res, return_index=True)[1]
|
|
103
106
|
np.testing.assert_array_equal(
|
|
104
107
|
[res[index] for index in sorted(indexes)],
|
|
105
|
-
np.array(['
|
|
108
|
+
np.array(['a1_b1_0', 'a2_b1_0', 'a2_b2_0', 'a1_b1_1'])
|
|
106
109
|
)
|
|
107
110
|
pass
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|