flightdata 0.2.26__tar.gz → 0.2.28__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.
Files changed (86) hide show
  1. {flightdata-0.2.26 → flightdata-0.2.28}/PKG-INFO +1 -1
  2. {flightdata-0.2.26 → flightdata-0.2.28}/pyproject.toml +5 -1
  3. {flightdata-0.2.26 → flightdata-0.2.28}/src/flightdata/__init__.py +1 -2
  4. {flightdata-0.2.26 → flightdata-0.2.28}/src/flightdata/base/collection.py +8 -0
  5. {flightdata-0.2.26 → flightdata-0.2.28}/src/flightdata/flight/flight.py +2 -1
  6. {flightdata-0.2.26 → flightdata-0.2.28}/src/flightdata/origin.py +17 -27
  7. {flightdata-0.2.26 → flightdata-0.2.28}/src/flightdata/state.py +2 -1
  8. flightdata-0.2.26/src/flightdata/schemas/fcj.py +0 -174
  9. flightdata-0.2.26/test/test_state/__init__.py +0 -0
  10. {flightdata-0.2.26 → flightdata-0.2.28}/.github/workflows/publish_pypi.yml +0 -0
  11. {flightdata-0.2.26 → flightdata-0.2.28}/.gitignore +0 -0
  12. {flightdata-0.2.26 → flightdata-0.2.28}/.vscode/launch.json +0 -0
  13. {flightdata-0.2.26 → flightdata-0.2.28}/.vscode/settings.json +0 -0
  14. {flightdata-0.2.26 → flightdata-0.2.28}/LICENSE +0 -0
  15. {flightdata-0.2.26 → flightdata-0.2.28}/README.md +0 -0
  16. {flightdata-0.2.26 → flightdata-0.2.28}/examples/__init__.py +0 -0
  17. {flightdata-0.2.26 → flightdata-0.2.28}/examples/data/__init__.py +0 -0
  18. {flightdata-0.2.26 → flightdata-0.2.28}/examples/data/manual_F3A_F23_22_04_28_00000231.json +0 -0
  19. {flightdata-0.2.26 → flightdata-0.2.28}/examples/data/manual_F3A_P23_22_05_31_00000350.json +0 -0
  20. {flightdata-0.2.26 → flightdata-0.2.28}/examples/data/manual_F3A_P23_23_08_11_00000094.json +0 -0
  21. {flightdata-0.2.26 → flightdata-0.2.28}/examples/flight_dynamics/00000150.json +0 -0
  22. {flightdata-0.2.26 → flightdata-0.2.28}/examples/flight_dynamics/__init__.py +0 -0
  23. {flightdata-0.2.26 → flightdata-0.2.28}/examples/flight_dynamics/box.f3a +0 -0
  24. {flightdata-0.2.26 → flightdata-0.2.28}/examples/flight_dynamics/param_id.py +0 -0
  25. {flightdata-0.2.26 → flightdata-0.2.28}/examples/state_analysis/__init__.py +0 -0
  26. {flightdata-0.2.26 → flightdata-0.2.28}/examples/state_analysis/axes.py +0 -0
  27. {flightdata-0.2.26 → flightdata-0.2.28}/examples/state_analysis/state_fill_plot.py +0 -0
  28. {flightdata-0.2.26 → flightdata-0.2.28}/src/flightdata/base/__init__.py +0 -0
  29. {flightdata-0.2.26 → flightdata-0.2.28}/src/flightdata/base/constructs.py +0 -0
  30. {flightdata-0.2.26 → flightdata-0.2.28}/src/flightdata/base/labeling.py +0 -0
  31. {flightdata-0.2.26 → flightdata-0.2.28}/src/flightdata/base/numpy_encoder.py +0 -0
  32. {flightdata-0.2.26 → flightdata-0.2.28}/src/flightdata/base/table.py +0 -0
  33. {flightdata-0.2.26 → flightdata-0.2.28}/src/flightdata/bindata.py +0 -0
  34. {flightdata-0.2.26 → flightdata-0.2.28}/src/flightdata/coefficients.py +0 -0
  35. {flightdata-0.2.26 → flightdata-0.2.28}/src/flightdata/environment/__init__.py +0 -0
  36. {flightdata-0.2.26 → flightdata-0.2.28}/src/flightdata/environment/environment.py +0 -0
  37. {flightdata-0.2.26 → flightdata-0.2.28}/src/flightdata/environment/wind.py +0 -0
  38. {flightdata-0.2.26 → flightdata-0.2.28}/src/flightdata/flight/__init__.py +0 -0
  39. {flightdata-0.2.26 → flightdata-0.2.28}/src/flightdata/flight/ardupilot.py +0 -0
  40. {flightdata-0.2.26 → flightdata-0.2.28}/src/flightdata/flight/fields.py +0 -0
  41. {flightdata-0.2.26 → flightdata-0.2.28}/src/flightdata/flight/parameters.py +0 -0
  42. {flightdata-0.2.26 → flightdata-0.2.28}/src/flightdata/flow.py +0 -0
  43. {flightdata-0.2.26 → flightdata-0.2.28}/src/flightdata/model/__init__.py +0 -0
  44. {flightdata-0.2.26 → flightdata-0.2.28}/src/flightdata/model/aerodynamic.py +0 -0
  45. {flightdata-0.2.26 → flightdata-0.2.28}/src/flightdata/model/thrust.py +0 -0
  46. {flightdata-0.2.26 → flightdata-0.2.28}/src/flightdata/py.typed +0 -0
  47. {flightdata-0.2.26 → flightdata-0.2.28}/src/flightdata/scripts/collect_logs.py +0 -0
  48. {flightdata-0.2.26 → flightdata-0.2.28}/src/flightdata/scripts/flightline.py +0 -0
  49. {flightdata-0.2.26 → flightdata-0.2.28}/test/EmailedBox.f3a +0 -0
  50. {flightdata-0.2.26/src/flightdata/schemas → flightdata-0.2.28/test}/__init__.py +0 -0
  51. {flightdata-0.2.26/test → flightdata-0.2.28/test/base}/__init__.py +0 -0
  52. {flightdata-0.2.26 → flightdata-0.2.28}/test/base/test_base_constructs.py +0 -0
  53. {flightdata-0.2.26 → flightdata-0.2.28}/test/base/test_table.py +0 -0
  54. {flightdata-0.2.26 → flightdata-0.2.28}/test/conftest.py +0 -0
  55. {flightdata-0.2.26 → flightdata-0.2.28}/test/data/bin_parser_GPS.csv +0 -0
  56. {flightdata-0.2.26 → flightdata-0.2.28}/test/data/bin_parser_POS.csv +0 -0
  57. {flightdata-0.2.26 → flightdata-0.2.28}/test/data/make_inputs.py +0 -0
  58. {flightdata-0.2.26 → flightdata-0.2.28}/test/data/manual_F3A_P23.json +0 -0
  59. {flightdata-0.2.26 → flightdata-0.2.28}/test/data/p23.BIN +0 -0
  60. {flightdata-0.2.26 → flightdata-0.2.28}/test/data/p23.json +0 -0
  61. {flightdata-0.2.26 → flightdata-0.2.28}/test/data/p23_box.f3a +0 -0
  62. {flightdata-0.2.26 → flightdata-0.2.28}/test/data/p23_fc.json +0 -0
  63. {flightdata-0.2.26 → flightdata-0.2.28}/test/data/p23_flight.json +0 -0
  64. {flightdata-0.2.26 → flightdata-0.2.28}/test/data/script_tests/c6_on_0001.BIN +0 -0
  65. {flightdata-0.2.26 → flightdata-0.2.28}/test/data/script_tests/center_0003.bin +0 -0
  66. {flightdata-0.2.26 → flightdata-0.2.28}/test/data/script_tests/pilot_0004.BIN +0 -0
  67. {flightdata-0.2.26 → flightdata-0.2.28}/test/data/vtol_hover.bin +0 -0
  68. {flightdata-0.2.26 → flightdata-0.2.28}/test/data/vtol_hover.json +0 -0
  69. {flightdata-0.2.26 → flightdata-0.2.28}/test/data/web_bin_parse.json +0 -0
  70. {flightdata-0.2.26 → flightdata-0.2.28}/test/test_bindata.py +0 -0
  71. {flightdata-0.2.26/test/base → flightdata-0.2.28/test/test_environment}/__init__.py +0 -0
  72. {flightdata-0.2.26 → flightdata-0.2.28}/test/test_environment/test_environment.py +0 -0
  73. {flightdata-0.2.26 → flightdata-0.2.28}/test/test_environment/test_environment_wind.py +0 -0
  74. {flightdata-0.2.26 → flightdata-0.2.28}/test/test_fields.py +0 -0
  75. {flightdata-0.2.26 → flightdata-0.2.28}/test/test_flight.py +0 -0
  76. {flightdata-0.2.26/test/test_environment → flightdata-0.2.28/test/test_model}/__init__.py +0 -0
  77. {flightdata-0.2.26 → flightdata-0.2.28}/test/test_model/test_model_coefficients.py +0 -0
  78. {flightdata-0.2.26 → flightdata-0.2.28}/test/test_model/test_model_flow.py +0 -0
  79. {flightdata-0.2.26 → flightdata-0.2.28}/test/test_origin.py +0 -0
  80. {flightdata-0.2.26 → flightdata-0.2.28}/test/test_scripts.py +0 -0
  81. {flightdata-0.2.26/test/test_model → flightdata-0.2.28/test/test_state}/__init__.py +0 -0
  82. {flightdata-0.2.26 → flightdata-0.2.28}/test/test_state/test_state.py +0 -0
  83. {flightdata-0.2.26 → flightdata-0.2.28}/test/test_state/test_state_builders.py +0 -0
  84. {flightdata-0.2.26 → flightdata-0.2.28}/test/test_state/test_state_conversions.py +0 -0
  85. {flightdata-0.2.26 → flightdata-0.2.28}/test/test_state/test_state_measurements.py +0 -0
  86. {flightdata-0.2.26 → flightdata-0.2.28}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flightdata
3
- Version: 0.2.26
3
+ Version: 0.2.28
4
4
  Summary: Python tools for handling flight data
5
5
  Author-email: Thomas David <thomasdavid0@gmail.com>
6
6
  License-File: LICENSE
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "flightdata"
3
- version = "0.2.26"
3
+ version = "0.2.28"
4
4
  description = "Python tools for handling flight data"
5
5
  readme = "README.md"
6
6
  authors = [{ name = "Thomas David", email = "thomasdavid0@gmail.com" }]
@@ -11,6 +11,10 @@ dependencies = [
11
11
  "pfc-geometry>=0.2.13",
12
12
  ]
13
13
 
14
+ [project.scripts]
15
+ collect_logs = "flightdata.scripts.collect_logs:main"
16
+ flightline = "flightdata.scripts.flightline:main"
17
+
14
18
  [build-system]
15
19
  requires = ["hatchling"]
16
20
  build-backend = "hatchling.build"
@@ -1,7 +1,6 @@
1
- from .schemas import fcj
2
1
  from .base import *
3
2
  from .bindata import BinData
4
- from .origin import Origin, FCJOrigin
3
+ from .origin import Origin
5
4
  from .flight import *
6
5
  from .environment import *
7
6
  from .coefficients import Coefficients
@@ -52,6 +52,7 @@ class Collection:
52
52
  def to_list(self) -> list[T]:
53
53
  return list(self.data.values())
54
54
 
55
+
55
56
  def to_dicts(self, *args, **kwargs) -> list[dict[str, Any]]:
56
57
  return [v.to_dict(*args, **kwargs) for v in self.data.values()]
57
58
 
@@ -86,6 +87,13 @@ class Collection:
86
87
  coll.add(v)
87
88
  return coll
88
89
 
90
+ @classmethod
91
+ def merge(Cls, vs: list[Self]) -> Self:
92
+ coll = vs[0].data
93
+ for v in vs[1:]:
94
+ coll = coll | v.data
95
+ return Cls(coll)
96
+
89
97
  def add_start(self, v: T | Self, inplace=True) -> Self:
90
98
  ocol = self.copy() if not inplace else self
91
99
  if isinstance(v, self.VType):
@@ -21,7 +21,8 @@ from time import time
21
21
  from json import load, dump
22
22
  from flightdata.base.numpy_encoder import NumpyEncoder
23
23
  from .ardupilot import flightmodes
24
- from flightdata import Origin, fcj
24
+ from flightdata import Origin
25
+ from schemas import fcj
25
26
  from numbers import Number
26
27
  from scipy.signal import filtfilt, butter
27
28
  from datetime import datetime
@@ -1,12 +1,11 @@
1
+ from __future__ import annotations
1
2
  import geometry as g
2
3
  import numpy as np
3
4
  from json import load, dump
4
5
  from typing import Self
5
- import json_stream
6
- from pathlib import Path
7
6
  from dataclasses import dataclass
8
- from pydantic import BaseModel
9
- from flightdata import fcj
7
+ from schemas import fcj
8
+
10
9
 
11
10
  @dataclass
12
11
  class Origin(object):
@@ -141,35 +140,26 @@ class Origin(object):
141
140
  ),
142
141
  float(parms.rotation)
143
142
  )
144
-
143
+
145
144
  def gps_to_point(self, gps: g.GPS) -> g.Point:
146
145
  return self.rotation.transform_point(gps - self.pos)
147
146
 
148
-
149
-
150
- class FCJOrigin(BaseModel):
151
- lat: float
152
- lng: float
153
- alt: float
154
- heading: float
155
- move_east: float=0
156
- move_north: float=0
157
-
158
- def origin(self):
159
- """Create a flightdata.Origin object from the FCJOrigin object."""
147
+ @staticmethod
148
+ def from_fcj_origin(fcj_origin: fcj.Origin):
160
149
  return Origin(
161
150
  "fcj",
162
- g.GPS(self.lat, self.lng, self.alt).offset(
163
- g.Point(self.move_north, self.move_east, 0)
151
+ g.GPS(fcj_origin.lat, fcj_origin.lng, fcj_origin.alt).offset(
152
+ g.Point(fcj_origin.move_north, fcj_origin.move_east, 0)
164
153
  ),
165
- np.radians(self.heading),
154
+ np.radians(fcj_origin.heading),
166
155
  )
167
156
 
168
- def shift(self):
169
- return self.origin().rotation.transform_point(
170
- g.Point(self.move_east, -self.move_north, 0)
171
- )
172
157
 
173
- @staticmethod
174
- def zero():
175
- return FCJOrigin(lat=0, lng=0, alt=0, heading=0)
158
+ @property
159
+ def fcj_origin(self):
160
+ return fcj.Origin(
161
+ lat=self.lat,
162
+ lng=self.long,
163
+ alt=self.alt,
164
+ heading=np.degrees(self.heading),
165
+ )
@@ -8,7 +8,8 @@ import numpy.typing as npt
8
8
  import pandas as pd
9
9
 
10
10
  import geometry as g
11
- from flightdata import Constructs, Environment, Flight, Flow, Origin, SVar, Table, fcj
11
+ from flightdata import Constructs, Environment, Flight, Flow, Origin, SVar, Table
12
+ from schemas import fcj
12
13
 
13
14
 
14
15
  class State(Table):
@@ -1,174 +0,0 @@
1
- from __future__ import annotations
2
- from pydantic import BaseModel
3
- import pandas as pd
4
- import datetime
5
- import re
6
-
7
-
8
- class FCJ(BaseModel):
9
- version: str
10
- comments: str
11
- name: str
12
- view: View
13
- parameters: Parameters
14
- scored: bool
15
- scores: list[float]
16
- human_scores: list[HumanResult] = []
17
- fcs_scores: list[Result] = []
18
- mans: list[Man]
19
- data: list[Data]
20
- jhash: int | None = None
21
-
22
-
23
- def score_df(self):
24
- return pd.concat(
25
- {fcjr.fa_version: fcjr.to_df() for fcjr in self.fcs_scores},
26
- axis=0,
27
- names=["version", "manoeuvre", "difficulty", "truncate"],
28
- )
29
-
30
- def man_df(self):
31
- return pd.DataFrame(
32
- [man.__dict__ for man in self.mans[1:-1]],
33
- index=pd.Index(range(len(self.mans[1:-1])), name="manoeuvre"),
34
- )
35
-
36
- def pfc_version_df(self):
37
- sdf = self.score_df().loc[pd.IndexSlice[:, :, 3, False]]
38
- return pd.concat(
39
- [sdf, sdf.mul(self.man_df().k, axis=0)], axis=1, keys=["raw", "kfac"]
40
- )
41
-
42
- def version_summary_df(self):
43
- return self.pfc_version_df().groupby("version").kfac.sum()
44
-
45
- def latest_version(self):
46
- return max([fcjr.fa_version for fcjr in self.fcs_scores])
47
-
48
- @property
49
- def id(self):
50
- return re.search(r"\d{8}", self.name)[0]
51
-
52
- @property
53
- def created(self):
54
- try:
55
- return datetime.datetime.strptime(
56
- re.search(r"_\d{2}_\d{2}_\d{2}_", self.name)[0], "_%y_%m_%d_"
57
- )
58
- except Exception:
59
- return None
60
-
61
-
62
- class View(BaseModel):
63
- position: dict
64
- target: dict
65
-
66
- class Parameters(BaseModel):
67
- rotation: float
68
- start: int
69
- stop: int
70
- moveEast: float
71
- moveNorth: float
72
- wingspan: float
73
- modelwingspan: float
74
- elevate: float
75
- originLat: float
76
- originLng: float
77
- originAlt: float
78
- pilotLat: str | float
79
- pilotLng: str | float
80
- pilotAlt: str | float
81
- centerLat: str | float
82
- centerLng: str | float
83
- centerAlt: str | float
84
- schedule: list[str]
85
-
86
- class HumanResult(BaseModel):
87
- name: str
88
- date: datetime.date
89
- scores: list[float]
90
-
91
- class Result(BaseModel):
92
- fa_version: str
93
- manresults: list[ManResult | None]
94
-
95
- def to_df(self) -> pd.DataFrame:
96
- return pd.concat(
97
- {i: fcjmr.to_df() for i, fcjmr in enumerate(self.manresults[1:]) if fcjmr},
98
- axis=0,
99
- names=["manoeuvre", "difficulty", "truncate"],
100
- )
101
-
102
- class ManResult(BaseModel):
103
- els: list[El]
104
- results: list[Score] = []
105
-
106
- def to_df(self) -> pd.DataFrame:
107
- return pd.DataFrame(
108
- data=[res.score.__dict__ for res in self.results],
109
- index=pd.MultiIndex.from_frame(
110
- pd.DataFrame([res.properties.__dict__ for res in self.results])
111
- ),
112
- )
113
-
114
- def get_score(self, props: ScoreProperties):
115
- for r in self.results:
116
- if r.properties == props:
117
- return r.score
118
-
119
- class El(BaseModel):
120
- name: str
121
- start: int
122
- stop: int
123
-
124
- class Score(BaseModel):
125
- score: ScoreValues
126
- properties: ScoreProperties
127
-
128
- class ScoreValues(BaseModel):
129
- intra: float
130
- inter: float
131
- positioning: float
132
- total: float
133
-
134
- class ScoreProperties(BaseModel):
135
- difficulty: int=3
136
- truncate: bool=False
137
-
138
- def __eq__(self, other):
139
- if not isinstance(other, ScoreProperties):
140
- return False
141
- return self.difficulty == other.difficulty and self.truncate == other.truncate
142
-
143
- class Man(BaseModel):
144
- name: str
145
- k: float
146
- id: str
147
- sp: int
148
- wd: float
149
- start: int
150
- stop: int
151
- sel: bool
152
- background: str
153
-
154
- class Data(BaseModel):
155
- VN: float = None
156
- VE: float = None
157
- VD: float = None
158
- dPD: float = None #
159
- r: float
160
- p: float
161
- yw: float
162
- N: float
163
- E: float
164
- D: float
165
- time: int
166
- roll: float
167
- pitch: float
168
- yaw: float
169
-
170
-
171
-
172
- def get_scores(file: str) -> pd.DataFrame:
173
- fcj = FCJ.model_validate_json(open(file, "r").read())
174
- return fcj.pfc_version_df()
File without changes
File without changes
File without changes
File without changes
File without changes