flightanalysis 0.2.14__tar.gz → 0.2.16__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.
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/PKG-INFO +6 -6
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/examples/scoring/f3a_criteria_maker.py +5 -6
- flightanalysis-0.2.16/examples/scoring/temp.py +24 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/analysis/manoeuvre_analysis/alignment.py +8 -1
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/analysis/manoeuvre_analysis/scored.py +6 -1
- flightanalysis-0.2.16/flightanalysis/analysis/sch_analysis.py +123 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/scoring/criteria/criteria.py +4 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/scoring/criteria/f3a_criteria.py +7 -6
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/scoring/criteria/intra/continuous.py +7 -4
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/scoring/measurement.py +3 -3
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/scoring/results.py +48 -3
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/scripts/batch_analyse.py +4 -6
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis.egg-info/PKG-INFO +6 -6
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis.egg-info/SOURCES.txt +14 -13
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis.egg-info/requires.txt +5 -5
- flightanalysis-0.2.16/requirements-dev.txt +11 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/requirements.txt +2 -2
- flightanalysis-0.2.14/flightanalysis/analysis/sch_analysis.py +0 -116
- flightanalysis-0.2.14/requirements-dev.txt +0 -11
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/.github/workflows/publish_pypi.yml +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/.gitignore +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/LICENSE +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/MANIFEST.in +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/README.md +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/examples/__init__.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/examples/data/__init__.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/examples/data/manual_F3A_F23_22_04_28_00000231.json +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/examples/data/manual_F3A_P23_22_05_31_00000350.json +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/examples/data/manual_F3A_P23_23_08_11_00000094.json +0 -0
- {flightanalysis-0.2.14/scripts → flightanalysis-0.2.16/examples/schedule_construction}/AMA_Intermediate2024.py +0 -0
- {flightanalysis-0.2.14/examples/scoring/manoeuvres → flightanalysis-0.2.16/examples/schedule_construction}/__init__.py +0 -0
- {flightanalysis-0.2.14/scripts → flightanalysis-0.2.16/examples/schedule_construction}/create_all.py +0 -0
- {flightanalysis-0.2.14/scripts → flightanalysis-0.2.16/examples/schedule_construction}/f3a_a25.py +0 -0
- {flightanalysis-0.2.14/scripts → flightanalysis-0.2.16/examples/schedule_construction}/f3a_f25.py +0 -0
- {flightanalysis-0.2.14/scripts → flightanalysis-0.2.16/examples/schedule_construction}/f3a_p23.py +0 -0
- {flightanalysis-0.2.14/scripts → flightanalysis-0.2.16/examples/schedule_construction}/f3a_p25.py +0 -0
- {flightanalysis-0.2.14/scripts → flightanalysis-0.2.16/examples/schedule_construction}/f3auk_clubman.py +0 -0
- {flightanalysis-0.2.14/scripts → flightanalysis-0.2.16/examples/schedule_construction}/f3auk_intermediate.py +0 -0
- {flightanalysis-0.2.14/scripts → flightanalysis-0.2.16/examples/schedule_construction}/imac_sport2024.py +0 -0
- {flightanalysis-0.2.14/scripts → flightanalysis-0.2.16/examples/schedule_construction}/imac_unlim2024.py +0 -0
- {flightanalysis-0.2.14/scripts → flightanalysis-0.2.16/examples/schedule_construction}/make_manoeuvre.py +0 -0
- {flightanalysis-0.2.14/scripts → flightanalysis-0.2.16/examples/schedule_construction}/nsrca_inter2024.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/examples/scoring/__init__.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/examples/scoring/judging.py +0 -0
- {flightanalysis-0.2.14/examples/scoring/manoeuvres/mans → flightanalysis-0.2.16/examples/scoring/manoeuvres}/__init__.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/examples/scoring/manoeuvres/inter_analysis.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/examples/scoring/manoeuvres/intra_analysis.py +0 -0
- {flightanalysis-0.2.14/flightanalysis/definition/builders → flightanalysis-0.2.16/examples/scoring/manoeuvres/mans}/__init__.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/examples/scoring/manoeuvres/mans/extract_mans.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/examples/scoring/manoeuvres/mans/tHat.json +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/examples/scoring/manoeuvres/positioning_analysis.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/__init__.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/analysis/__init__.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/analysis/el_analysis.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/analysis/manoeuvre_analysis/__init__.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/analysis/manoeuvre_analysis/analysis.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/analysis/manoeuvre_analysis/basic.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/analysis/manoeuvre_analysis/complete.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/data/IMAC_Unlimited2024_schedule.json +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/data/__init__.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/data/f3a_a25_schedule.json +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/data/f3a_f25_schedule.json +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/data/f3a_p23_schedule.json +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/data/f3a_p25_schedule.json +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/data/f3auk_clubman_schedule.json +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/data/f3auk_inter_schedule.json +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/definition/__init__.py +0 -0
- {flightanalysis-0.2.14/flightanalysis/scoring/criteria/inter → flightanalysis-0.2.16/flightanalysis/definition/builders}/__init__.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/definition/builders/elbuilders.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/definition/builders/lines.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/definition/builders/manbuilder.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/definition/collectors.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/definition/eldef.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/definition/mandef.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/definition/maninfo.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/definition/manoption.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/definition/manparm.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/definition/operations/__init__.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/definition/operations/funopp.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/definition/operations/itemopp.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/definition/operations/mathopp.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/definition/operations/operation.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/definition/scheddef.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/definition/scheduleinfo.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/elements/__init__.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/elements/autorotation.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/elements/element.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/elements/line.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/elements/loop.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/elements/nose_drop.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/elements/pitch_break.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/elements/recovery.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/elements/stall_turn.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/manoeuvre.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/schedule.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/scoring/__init__.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/scoring/criteria/__init__.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/scoring/criteria/exponential.py +0 -0
- {flightanalysis-0.2.14/flightanalysis/scoring/criteria/intra → flightanalysis-0.2.16/flightanalysis/scoring/criteria/inter}/__init__.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/scoring/criteria/inter/combination.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/scoring/criteria/inter/comparison.py +0 -0
- {flightanalysis-0.2.14/scripts → flightanalysis-0.2.16/flightanalysis/scoring/criteria/intra}/__init__.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/scoring/criteria/intra/bounded.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/scoring/criteria/intra/single.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/scoring/downgrade.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/scripts/collect_scores.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/scripts/plot_scores.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis.egg-info/dependency_links.txt +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis.egg-info/entry_points.txt +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis.egg-info/top_level.txt +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/pyproject.toml +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/setup.cfg +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/tests/EmailedBox.f3a +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/tests/__init__.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/tests/conftest.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/tests/data/manual_F3A_P23.json +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/tests/data/p23.BIN +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/tests/data/p23_box.f3a +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/tests/data/p23_fc.json +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/tests/data/p23_flight.json +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/tests/test_criiteria.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/tests/test_data.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/tests/test_schedule/__init__.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/tests/test_schedule/test_definition/__init__.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/tests/test_schedule/test_definition/test_definition_eldef.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/tests/test_schedule/test_definition/test_definition_manparm.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/tests/test_schedule/test_definition/test_definition_mpopp.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/tests/test_schedule/test_definition/test_schedule_definition.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/tests/test_schedule/test_definition/test_schedule_definition_maninfo.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/tests/test_schedule/test_element/__init__.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/tests/test_schedule/test_element/loop_analysis.json +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/tests/test_schedule/test_element/p23_th_e0.csv +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/tests/test_schedule/test_element/p23_th_e0.json +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/tests/test_schedule/test_element/p23_th_e0_template.csv +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/tests/test_schedule/test_element/test_schedule_element.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/tests/test_schedule/test_element/test_schedule_element_line.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/tests/test_schedule/test_element/test_schedule_element_loop.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/tests/test_schedule/test_element/test_schedule_element_nose_drop.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/tests/test_schedule/test_element/test_schedule_element_pitch_break.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/tests/test_schedule/test_element/test_schedule_element_recovery.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/tests/test_schedule/test_element/test_schedule_element_stallturn.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/tests/test_schedule/test_measurement.py +0 -0
- {flightanalysis-0.2.14 → flightanalysis-0.2.16}/tests/test_schedule/test_schedule_manoeuvre.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: flightanalysis
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.16
|
|
4
4
|
Summary: A package for analysing flight data
|
|
5
5
|
Author-email: Thomas David <thomasdavid0@gmail.com>
|
|
6
6
|
License: GNU GPL v3
|
|
@@ -15,8 +15,8 @@ Requires-Dist: fastdtw
|
|
|
15
15
|
Requires-Dist: simplejson
|
|
16
16
|
Requires-Dist: loguru
|
|
17
17
|
Requires-Dist: joblib
|
|
18
|
-
Requires-Dist: pfc-geometry>=0.2.
|
|
19
|
-
Requires-Dist: flightdata>=0.2.
|
|
18
|
+
Requires-Dist: pfc-geometry>=0.2.7
|
|
19
|
+
Requires-Dist: flightdata>=0.2.15
|
|
20
20
|
Provides-Extra: dev
|
|
21
21
|
Requires-Dist: numpy; extra == "dev"
|
|
22
22
|
Requires-Dist: pandas; extra == "dev"
|
|
@@ -25,9 +25,9 @@ Requires-Dist: fastdtw; extra == "dev"
|
|
|
25
25
|
Requires-Dist: simplejson; extra == "dev"
|
|
26
26
|
Requires-Dist: loguru; extra == "dev"
|
|
27
27
|
Requires-Dist: joblib; extra == "dev"
|
|
28
|
-
Requires-Dist: pfc-geometry>=0.2.
|
|
29
|
-
Requires-Dist: flightdata>=0.2.
|
|
30
|
-
Requires-Dist: ardupilot_log_reader>=0.3.
|
|
28
|
+
Requires-Dist: pfc-geometry>=0.2.7; extra == "dev"
|
|
29
|
+
Requires-Dist: flightdata>=0.2.15; extra == "dev"
|
|
30
|
+
Requires-Dist: ardupilot_log_reader>=0.3.3; extra == "dev"
|
|
31
31
|
Requires-Dist: pymavlink; extra == "dev"
|
|
32
32
|
|
|
33
33
|
# FlightAnalysis
|
|
@@ -7,14 +7,13 @@ f3a=dict(
|
|
|
7
7
|
track=Single(Exponential.fit_points(np.radians([30, 90]), [2, 6], 6)),
|
|
8
8
|
roll=Single(Exponential.fit_points(np.radians([30, 90]), [1, 6], 6)),
|
|
9
9
|
angle=Single(Exponential.fit_points(np.radians([30, 90]), [2, 6], 6)),
|
|
10
|
-
# distance = Single(Exponential.fit_points([20, 40], [0.5, 1]))
|
|
11
10
|
),
|
|
12
11
|
intra=dict(
|
|
13
|
-
track=ContAbs(Exponential.fit_points(np.radians([30, 90]), [2, 6], 6)),
|
|
14
|
-
roll=ContAbs(Exponential.fit_points(np.radians([30, 90]), [1.5, 6], 6)),
|
|
15
|
-
radius=ContRat(Exponential.fit_points([1,5], [0.5, 4], 3)),
|
|
16
|
-
speed=ContRat(Exponential.fit_points([1,5], [0.15, 0.75], 1)),
|
|
17
|
-
roll_rate=ContRat(Exponential.fit_points([1,5], [0.15, 0.75], 2)),
|
|
12
|
+
track=ContAbs(Exponential.fit_points(np.radians([30, 90]), [2, 6], 6), 20),
|
|
13
|
+
roll=ContAbs(Exponential.fit_points(np.radians([30, 90]), [1.5, 6], 6), 30),
|
|
14
|
+
radius=ContRat(Exponential.fit_points([1,5], [0.5, 4], 3), 40),
|
|
15
|
+
speed=ContRat(Exponential.fit_points([1,5], [0.15, 0.75], 1), 50),
|
|
16
|
+
roll_rate=ContRat(Exponential.fit_points([1,5], [0.15, 0.75], 2), 40),
|
|
18
17
|
stallturn_speed=InsideBound(Exponential.fit_points([2, 5], [0.3,1.5]), [-2,2]),
|
|
19
18
|
stallturn_width=InsideBound(Exponential.fit_points([2, 5], [0.5,2.5]), [-2,2]),
|
|
20
19
|
spin_entry_length=InsideBound(Exponential.fit_points([2, 5], [0.3,1.5]), [-5,5]),
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
class F3ASingle:
|
|
2
|
+
track=Single(Exponential(3.8197186342054885,0.9999999999999999, 6 ))
|
|
3
|
+
roll=Single(Exponential(2.872721387028467,1.6309297535714575, 6 ))
|
|
4
|
+
angle=Single(Exponential(3.8197186342054885,0.9999999999999999, 6 ))
|
|
5
|
+
class F3AIntra:
|
|
6
|
+
track=ContAbs(Exponential(3.8197186342054885,0.9999999999999999, 6 ), 10, 3)
|
|
7
|
+
roll=ContAbs(Exponential(3.3937161800825275,1.2618595071429148, 6 ), 20, 3)
|
|
8
|
+
radius=ContRat(Exponential(0.5,1.2920296742201793, 3 ), 25, 3)
|
|
9
|
+
speed=ContRat(Exponential(0.15,1.0, 1 ), 50, 3)
|
|
10
|
+
roll_rate=ContRat(Exponential(0.15,1.0, 2 ), 25, 3)
|
|
11
|
+
stallturn_speed=InsideBound(Exponential(0.08879139070041006,1.75647079736603, None ), [-2, 2])
|
|
12
|
+
stallturn_width=InsideBound(Exponential(0.14798565116735013,1.75647079736603, None ), [-2, 2])
|
|
13
|
+
spin_entry_length=InsideBound(Exponential(0.08879139070041006,1.75647079736603, None ), [-5, 5])
|
|
14
|
+
pitch_break_length=InsideBound(Exponential(0.7,2.321928094887362, None ), [-2, 2])
|
|
15
|
+
nose_drop_amount=OutsideBound(Exponential(20,1, None ), [-0.2617993877991494, 0.2617993877991494])
|
|
16
|
+
recovery_length=MaxBound(Exponential(0.7,2.321928094887362, None ), 2)
|
|
17
|
+
box=InsideBound(Exponential(76.39437268410977,1, None ), [-1.0471975511965976, 1.0471975511965976])
|
|
18
|
+
depth=MaxBound(Exponential(0.02500000000000001,0.9999999999999999, None ), 170)
|
|
19
|
+
class F3AInter:
|
|
20
|
+
radius=Comparison(Exponential(1.0,1.0, 2 ))
|
|
21
|
+
speed=Comparison(Exponential(0.25,1.0000000000000002, 1 ))
|
|
22
|
+
roll_rate=Comparison(Exponential(0.25,1.0000000000000002, 1 ))
|
|
23
|
+
length=Comparison(Exponential(1.0,1.0, 2 ))
|
|
24
|
+
free=Comparison(Exponential(0,1, None ))
|
|
@@ -92,6 +92,13 @@ class Alignment(Basic):
|
|
|
92
92
|
**data
|
|
93
93
|
)
|
|
94
94
|
return data
|
|
95
|
-
|
|
95
|
+
|
|
96
|
+
def fcj_results(self):
|
|
97
|
+
df = self.flown.label_ranges('element').iloc[:,:3]
|
|
98
|
+
df.columns = ['name', 'start', 'stop']
|
|
99
|
+
return dict(
|
|
100
|
+
els=df.to_dict('records')
|
|
101
|
+
)
|
|
102
|
+
|
|
96
103
|
from .complete import Complete # noqa: E402
|
|
97
104
|
from .scored import Scored # noqa: E402
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from typing import Self, Union
|
|
3
|
+
from json import load, dump
|
|
4
|
+
from flightdata import Flight, State, Origin, Collection, NumpyEncoder
|
|
5
|
+
from flightanalysis.definition import SchedDef, ScheduleInfo
|
|
6
|
+
from . import manoeuvre_analysis as analysis
|
|
7
|
+
from loguru import logger
|
|
8
|
+
from joblib import Parallel, delayed
|
|
9
|
+
import os
|
|
10
|
+
import pandas as pd
|
|
11
|
+
from importlib.metadata import version
|
|
12
|
+
from packaging import version as pkgversion
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
|
|
15
|
+
class ScheduleAnalysis(Collection):
|
|
16
|
+
VType=analysis.Analysis
|
|
17
|
+
uid='name'
|
|
18
|
+
|
|
19
|
+
def __init__(self, data: list[analysis.Analysis], sinfo: ScheduleInfo):
|
|
20
|
+
super().__init__(data)
|
|
21
|
+
self.sinfo = sinfo
|
|
22
|
+
|
|
23
|
+
@staticmethod
|
|
24
|
+
def from_fcj(file: Union[Union[str, bytes, os.PathLike], dict], info: ScheduleInfo=None) -> ScheduleAnalysis:
|
|
25
|
+
data = file if isinstance(file, dict) else load(open(file, 'r'))
|
|
26
|
+
|
|
27
|
+
flight = Flight.from_fc_json(data)
|
|
28
|
+
|
|
29
|
+
if info is None:
|
|
30
|
+
info = ScheduleInfo.from_str(data["parameters"]["schedule"][1])
|
|
31
|
+
|
|
32
|
+
sdef = SchedDef.load(info)
|
|
33
|
+
box = Origin.from_fcjson_parmameters(data["parameters"])
|
|
34
|
+
state = State.from_flight(flight, box).splitter_labels(data["mans"],sdef.uids)
|
|
35
|
+
direction = -state.get_manoeuvre(1)[0].direction()[0]
|
|
36
|
+
|
|
37
|
+
if 'fcs_scores' in data:
|
|
38
|
+
versions = [pkgversion.parse(res['fa_version']) for res in data['fcs_scores']]
|
|
39
|
+
ilatest = versions.index(max(versions))
|
|
40
|
+
|
|
41
|
+
mas = []
|
|
42
|
+
for i, mdef in enumerate(sdef):
|
|
43
|
+
st = state.get_manoeuvre(mdef.uid)
|
|
44
|
+
|
|
45
|
+
if 'fcs_scores' in data and len(data['fcs_scores']) > 0:
|
|
46
|
+
df = pd.DataFrame(data['fcs_scores'][ilatest]['manresults'][i+1]['els'])
|
|
47
|
+
st = st.splitter_labels(df.to_dict('records'), target_col='element')
|
|
48
|
+
|
|
49
|
+
mas.append(analysis.Basic(i, mdef, st, direction).proceed())
|
|
50
|
+
|
|
51
|
+
return ScheduleAnalysis(mas,info)
|
|
52
|
+
|
|
53
|
+
def append_scores_to_fcj(self, file: Union[str, dict], ofile: str=None) -> dict:
|
|
54
|
+
data = file if isinstance(file, dict) else load(open(file, 'r'))
|
|
55
|
+
|
|
56
|
+
new_results = dict(
|
|
57
|
+
fa_version = version('flightanalysis'),
|
|
58
|
+
manresults = [None] + \
|
|
59
|
+
[man.fcj_results() if hasattr(man, 'fcj_results') else None for man in self]
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
if 'fcs_scores' not in data:
|
|
63
|
+
data['fcs_scores'] = []
|
|
64
|
+
|
|
65
|
+
for res in data['fcs_scores']:
|
|
66
|
+
if res['fa_version'] == new_results['fa_version']:
|
|
67
|
+
res['manresults'] = new_results['manresults']
|
|
68
|
+
break
|
|
69
|
+
else:
|
|
70
|
+
data['fcs_scores'].append(new_results)
|
|
71
|
+
|
|
72
|
+
if ofile:
|
|
73
|
+
if ofile=='same':
|
|
74
|
+
ofile = file
|
|
75
|
+
dump(data, open(ofile, 'w'), cls=NumpyEncoder, indent=2)
|
|
76
|
+
|
|
77
|
+
return data
|
|
78
|
+
|
|
79
|
+
# def export_fcj_and_internals(self, file: Union[str, dict]):
|
|
80
|
+
# data = load(open(file, 'r')) if isinstance(file, str) else file
|
|
81
|
+
# fcj = self.append_scores_to_fcj(data)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def run_all(self) -> Self:
|
|
85
|
+
def parse_analyse_serialise(pad):
|
|
86
|
+
try:
|
|
87
|
+
pad = analysis.parse_dict(pad)
|
|
88
|
+
pad = pad.run_all()
|
|
89
|
+
logger.info(f'Completed {pad.name}')
|
|
90
|
+
except Exception as e:
|
|
91
|
+
logger.error(f'Failed to process {pad.name}: {repr(e)}')
|
|
92
|
+
return pad.to_dict()
|
|
93
|
+
|
|
94
|
+
logger.info(f'Starting {os.cpu_count()} analysis processes')
|
|
95
|
+
madicts = Parallel(n_jobs=os.cpu_count())(
|
|
96
|
+
delayed(parse_analyse_serialise)(ma.to_dict()) for ma in self
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
return ScheduleAnalysis([analysis.Scored.from_dict(mad) for mad in madicts], self.sinfo)
|
|
100
|
+
|
|
101
|
+
def optimize_alignment(self) -> Self:
|
|
102
|
+
|
|
103
|
+
def parse_analyse_serialise(mad):
|
|
104
|
+
an = analysis.Complete.from_dict(mad)
|
|
105
|
+
return an.run_all().to_dict()
|
|
106
|
+
|
|
107
|
+
logger.info(f'Starting {os.cpu_count()} alinment optimisation processes')
|
|
108
|
+
inmadicts = [mdef.to_dict() for mdef in self]
|
|
109
|
+
madicts = Parallel(n_jobs=os.cpu_count())(delayed(parse_analyse_serialise)(mad) for mad in inmadicts)
|
|
110
|
+
return ScheduleAnalysis([analysis.Scored.from_dict(mad) for mad in madicts], self.sinfo)
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def scores(self):
|
|
114
|
+
scores = {}
|
|
115
|
+
total = 0
|
|
116
|
+
scores = {ma.name: (ma.scores.score() if hasattr(ma, 'scores') else 0) for ma in self}
|
|
117
|
+
total = sum([ma.mdef.info.k * v for ma, v in zip(self, scores.values())])
|
|
118
|
+
return total, scores
|
|
119
|
+
|
|
120
|
+
def summarydf(self):
|
|
121
|
+
return pd.DataFrame([ma.scores.summary() if hasattr(ma, 'scores') else {} for ma in self])
|
|
122
|
+
|
|
123
|
+
|
|
@@ -38,6 +38,10 @@ class Criteria:
|
|
|
38
38
|
_so = f"{self.__class__.__name__}(Exponential({self.lookup.factor},{self.lookup.exponent}, {self.lookup.limit} )"
|
|
39
39
|
if hasattr(self, 'bound'):
|
|
40
40
|
_so = f"{_so}, {self.bound}"
|
|
41
|
+
if hasattr(self, 'max_window'):
|
|
42
|
+
_so = f"{_so}, {self.max_window}"
|
|
43
|
+
if hasattr(self, 'window_ratio'):
|
|
44
|
+
_so = f"{_so}, {self.window_ratio}"
|
|
41
45
|
return _so + ')'
|
|
42
46
|
|
|
43
47
|
@dataclass
|
{flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/scoring/criteria/f3a_criteria.py
RENAMED
|
@@ -6,11 +6,11 @@ class F3ASingle:
|
|
|
6
6
|
roll=Single(Exponential(2.872721387028467,1.6309297535714575, 6 ))
|
|
7
7
|
angle=Single(Exponential(3.8197186342054885,0.9999999999999999, 6 ))
|
|
8
8
|
class F3AIntra:
|
|
9
|
-
track=ContAbs(Exponential(3.8197186342054885,0.9999999999999999, 6 ))
|
|
10
|
-
roll=ContAbs(Exponential(3.3937161800825275,1.2618595071429148, 6 ))
|
|
11
|
-
radius=ContRat(Exponential(0.5,1.2920296742201793, 3 ))
|
|
12
|
-
speed=ContRat(Exponential(0.15,1.0, 1 ))
|
|
13
|
-
roll_rate=ContRat(Exponential(0.15,1.0, 2 ))
|
|
9
|
+
track=ContAbs(Exponential(3.8197186342054885,0.9999999999999999, 6 ), 20, 3)
|
|
10
|
+
roll=ContAbs(Exponential(3.3937161800825275,1.2618595071429148, 6 ), 30, 3)
|
|
11
|
+
radius=ContRat(Exponential(0.5,1.2920296742201793, 3 ), 40, 3)
|
|
12
|
+
speed=ContRat(Exponential(0.15,1.0, 1 ), 50, 3)
|
|
13
|
+
roll_rate=ContRat(Exponential(0.15,1.0, 2 ), 40, 3)
|
|
14
14
|
stallturn_speed=InsideBound(Exponential(0.08879139070041006,1.75647079736603, None ), [-2, 2])
|
|
15
15
|
stallturn_width=InsideBound(Exponential(0.14798565116735013,1.75647079736603, None ), [-2, 2])
|
|
16
16
|
spin_entry_length=InsideBound(Exponential(0.08879139070041006,1.75647079736603, None ), [-5, 5])
|
|
@@ -18,7 +18,7 @@ class F3AIntra:
|
|
|
18
18
|
nose_drop_amount=OutsideBound(Exponential(20,1, None ), [-0.2617993877991494, 0.2617993877991494])
|
|
19
19
|
recovery_length=MaxBound(Exponential(0.7,2.321928094887362, None ), 2)
|
|
20
20
|
box=InsideBound(Exponential(76.39437268410977,1, None ), [-1.0471975511965976, 1.0471975511965976])
|
|
21
|
-
depth=MaxBound(Exponential(0.02500000000000001,0.9999999999999999,
|
|
21
|
+
depth=MaxBound(Exponential(0.02500000000000001,0.9999999999999999, None ), 170)
|
|
22
22
|
class F3AInter:
|
|
23
23
|
radius=Comparison(Exponential(1.0,1.0, 2 ))
|
|
24
24
|
speed=Comparison(Exponential(0.25,1.0000000000000002, 1 ))
|
|
@@ -28,6 +28,7 @@ class F3AInter:
|
|
|
28
28
|
|
|
29
29
|
|
|
30
30
|
|
|
31
|
+
|
|
31
32
|
class F3A:
|
|
32
33
|
inter = F3AInter
|
|
33
34
|
intra = F3AIntra
|
{flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/scoring/criteria/intra/continuous.py
RENAMED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
import numpy as np
|
|
3
3
|
import numpy.typing as npt
|
|
4
|
-
import pandas as pd
|
|
5
4
|
from .. import Criteria
|
|
6
5
|
from dataclasses import dataclass
|
|
7
6
|
from flightanalysis.scoring import Measurement, Result
|
|
@@ -13,6 +12,9 @@ class Continuous(Criteria):
|
|
|
13
12
|
only downgrades for increases (away from zero) of the value.
|
|
14
13
|
treats each separate increase (peak - trough) as a new error.
|
|
15
14
|
"""
|
|
15
|
+
max_window: int = 40
|
|
16
|
+
window_ratio: int = 3
|
|
17
|
+
|
|
16
18
|
@staticmethod
|
|
17
19
|
def get_peak_locs(arr, rev=False):
|
|
18
20
|
increasing = np.sign(np.diff(np.abs(arr)))>0
|
|
@@ -66,14 +68,15 @@ class Continuous(Criteria):
|
|
|
66
68
|
_mean = np.mean(sample)
|
|
67
69
|
sample = (sample - _mean) * window / max_window + _mean
|
|
68
70
|
return sample
|
|
69
|
-
|
|
71
|
+
|
|
72
|
+
|
|
70
73
|
class ContAbs(Continuous):
|
|
71
74
|
def prepare(self, values: npt.NDArray, expected: float):
|
|
72
75
|
sample = values - expected
|
|
73
76
|
if len(sample) <= 8:
|
|
74
77
|
return np.linspace(values[0],values[-1], len(sample))
|
|
75
78
|
else:
|
|
76
|
-
return Continuous.convolve_wind(values,
|
|
79
|
+
return Continuous.convolve_wind(values, self.window_ratio, self.max_window)
|
|
77
80
|
|
|
78
81
|
@staticmethod
|
|
79
82
|
def mistakes(data, peaks, troughs):
|
|
@@ -98,7 +101,7 @@ class ContRat(Continuous):
|
|
|
98
101
|
len(values)
|
|
99
102
|
))
|
|
100
103
|
else:
|
|
101
|
-
return np.abs(Continuous.convolve_wind(values,
|
|
104
|
+
return np.abs(Continuous.convolve_wind(values, self.window_ratio, self.max_window))
|
|
102
105
|
|
|
103
106
|
@staticmethod
|
|
104
107
|
def mistakes(data, peaks, troughs):
|
|
@@ -4,7 +4,7 @@ from geometry import Point, Quaternion, PX, PY, PZ
|
|
|
4
4
|
import numpy as np
|
|
5
5
|
import pandas as pd
|
|
6
6
|
import numpy.typing as npt
|
|
7
|
-
from dataclasses import dataclass
|
|
7
|
+
from dataclasses import dataclass
|
|
8
8
|
from typing import Union, Self
|
|
9
9
|
|
|
10
10
|
|
|
@@ -72,7 +72,7 @@ class Measurement:
|
|
|
72
72
|
def _vector_vis(direction: Point, loc: Point) -> Union[Point, npt.NDArray]:
|
|
73
73
|
#a vector error is more visible if it is perpendicular to the viewing vector
|
|
74
74
|
# 0 to np.pi, pi/2 gives max, 0&np.pi give min
|
|
75
|
-
return direction, (1 - 0.
|
|
75
|
+
return direction, (1 - 0.9* np.abs(Point.cos_angle_between(loc, direction))) * Measurement._pos_vis(loc)
|
|
76
76
|
|
|
77
77
|
@staticmethod
|
|
78
78
|
def _roll_vis(fl: State, tp: State) -> Union[Point, npt.NDArray]:
|
|
@@ -89,7 +89,7 @@ class Measurement:
|
|
|
89
89
|
ao[np.abs(afl) > np.abs(atp)] = atp[np.abs(afl) > np.abs(atp)]
|
|
90
90
|
ao[np.sign(azfl) != np.sign(aztp)] = 0 # wings have passed through the view vector
|
|
91
91
|
|
|
92
|
-
rvis = (1-0.
|
|
92
|
+
rvis = (1-0.9*np.abs(ao))
|
|
93
93
|
|
|
94
94
|
return fl.att.transform_point(PZ()), rvis * Measurement._pos_vis(fl.pos)
|
|
95
95
|
|
|
@@ -8,6 +8,16 @@ from flightanalysis.scoring.measurement import Measurement
|
|
|
8
8
|
from dataclasses import dataclass
|
|
9
9
|
|
|
10
10
|
|
|
11
|
+
def ease(val, factor=3):
|
|
12
|
+
'''factor == 3 for hard / no easement'''
|
|
13
|
+
b = 1.3 - factor*0.1
|
|
14
|
+
m = 6 / 6**b
|
|
15
|
+
return m * val**b
|
|
16
|
+
|
|
17
|
+
def trunc(val):
|
|
18
|
+
return np.floor(val * 2) / 2
|
|
19
|
+
|
|
20
|
+
|
|
11
21
|
@dataclass
|
|
12
22
|
class Result:
|
|
13
23
|
"""
|
|
@@ -25,6 +35,10 @@ class Result:
|
|
|
25
35
|
def total(self):
|
|
26
36
|
return float(sum(self.dgs))
|
|
27
37
|
|
|
38
|
+
def score(self, difficulty=3, truncate: None | str=None):
|
|
39
|
+
res = sum(ease(self.dgs, difficulty))
|
|
40
|
+
return trunc(res) if truncate=='result' else res
|
|
41
|
+
|
|
28
42
|
def to_dict(self):
|
|
29
43
|
return dict(
|
|
30
44
|
name = self.name,
|
|
@@ -99,6 +113,10 @@ class Results(Collection):
|
|
|
99
113
|
VType = Result
|
|
100
114
|
uid="name"
|
|
101
115
|
|
|
116
|
+
def score(self, difficulty=3, truncate: None | str=False):
|
|
117
|
+
res = sum([r.score(difficulty, truncate) for r in self])
|
|
118
|
+
return trunc(res) if truncate=='results' else res
|
|
119
|
+
|
|
102
120
|
def __init__(self, name, *args, **kwargs):
|
|
103
121
|
super().__init__(*args, **kwargs)
|
|
104
122
|
self.name = name
|
|
@@ -143,6 +161,9 @@ class ElementsResults(Collection):
|
|
|
143
161
|
VType=Results
|
|
144
162
|
uid="name"
|
|
145
163
|
|
|
164
|
+
def score(self, difficulty=3, truncate=False):
|
|
165
|
+
return sum([r.score(difficulty, truncate) for r in self])
|
|
166
|
+
|
|
146
167
|
@property
|
|
147
168
|
def total(self):
|
|
148
169
|
return sum([r.total for r in self])
|
|
@@ -181,8 +202,19 @@ class ManoeuvreResults:
|
|
|
181
202
|
def summary(self):
|
|
182
203
|
return {k: v.total for k, v in self.__dict__.items() if v is not None}
|
|
183
204
|
|
|
184
|
-
def
|
|
185
|
-
|
|
205
|
+
def score_summary(self, difficulty, truncate):
|
|
206
|
+
intra=self.intra.score(difficulty, 'results' if truncate else None)
|
|
207
|
+
inter=self.inter.score(difficulty, 'result' if truncate else None)
|
|
208
|
+
positioning=self.positioning.score(difficulty, 'result' if truncate else None)
|
|
209
|
+
return dict(
|
|
210
|
+
intra=intra,
|
|
211
|
+
inter=inter,
|
|
212
|
+
positioning=positioning,
|
|
213
|
+
total=max(10 - intra - inter - positioning, 0)
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
def score(self, difficulty=3, truncate: bool=False):
|
|
217
|
+
return self.score_summary(difficulty, truncate)['total']
|
|
186
218
|
|
|
187
219
|
def to_dict(self):
|
|
188
220
|
return dict(
|
|
@@ -199,4 +231,17 @@ class ManoeuvreResults:
|
|
|
199
231
|
Results.from_dict(data['inter']),
|
|
200
232
|
ElementsResults.from_dict(data['intra']),
|
|
201
233
|
Results.from_dict(data['positioning']),
|
|
202
|
-
)
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
def fcj_results(self):
|
|
237
|
+
res = []
|
|
238
|
+
for diff in [1,2,3]:
|
|
239
|
+
for trunc in [False, True]:
|
|
240
|
+
res.append(dict(
|
|
241
|
+
score=self.score_summary(diff, trunc),
|
|
242
|
+
properties=dict(
|
|
243
|
+
difficulty=diff,
|
|
244
|
+
truncate=trunc
|
|
245
|
+
)
|
|
246
|
+
))
|
|
247
|
+
return res
|
|
@@ -40,15 +40,13 @@ def main():
|
|
|
40
40
|
logger.info(f'Processing file {i} of {len(all_logs)} - {file}')
|
|
41
41
|
data = load(open(file, 'r'))
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
else:
|
|
46
|
-
sa = ScheduleAnalysis.from_fcscore(data)
|
|
43
|
+
sa = ScheduleAnalysis.from_fcj(data)
|
|
44
|
+
|
|
47
45
|
logger.info(sa.sinfo)
|
|
48
46
|
sa = sa.run_all()
|
|
49
47
|
|
|
50
|
-
with open(outdir / f'{file.stem}
|
|
51
|
-
dump(sa.
|
|
48
|
+
with open(outdir / f'{file.stem}.json', 'w') as f:
|
|
49
|
+
dump(sa.append_scores_to_fcj(data), f, indent=4, cls=NumpyEncoder)
|
|
52
50
|
logger.info(f'scores:\n{dumps(sa.scores(), indent=2)}')
|
|
53
51
|
except Exception as e:
|
|
54
52
|
logger.error(f'Error processing {file}: {e}')
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: flightanalysis
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.16
|
|
4
4
|
Summary: A package for analysing flight data
|
|
5
5
|
Author-email: Thomas David <thomasdavid0@gmail.com>
|
|
6
6
|
License: GNU GPL v3
|
|
@@ -15,8 +15,8 @@ Requires-Dist: fastdtw
|
|
|
15
15
|
Requires-Dist: simplejson
|
|
16
16
|
Requires-Dist: loguru
|
|
17
17
|
Requires-Dist: joblib
|
|
18
|
-
Requires-Dist: pfc-geometry>=0.2.
|
|
19
|
-
Requires-Dist: flightdata>=0.2.
|
|
18
|
+
Requires-Dist: pfc-geometry>=0.2.7
|
|
19
|
+
Requires-Dist: flightdata>=0.2.15
|
|
20
20
|
Provides-Extra: dev
|
|
21
21
|
Requires-Dist: numpy; extra == "dev"
|
|
22
22
|
Requires-Dist: pandas; extra == "dev"
|
|
@@ -25,9 +25,9 @@ Requires-Dist: fastdtw; extra == "dev"
|
|
|
25
25
|
Requires-Dist: simplejson; extra == "dev"
|
|
26
26
|
Requires-Dist: loguru; extra == "dev"
|
|
27
27
|
Requires-Dist: joblib; extra == "dev"
|
|
28
|
-
Requires-Dist: pfc-geometry>=0.2.
|
|
29
|
-
Requires-Dist: flightdata>=0.2.
|
|
30
|
-
Requires-Dist: ardupilot_log_reader>=0.3.
|
|
28
|
+
Requires-Dist: pfc-geometry>=0.2.7; extra == "dev"
|
|
29
|
+
Requires-Dist: flightdata>=0.2.15; extra == "dev"
|
|
30
|
+
Requires-Dist: ardupilot_log_reader>=0.3.3; extra == "dev"
|
|
31
31
|
Requires-Dist: pymavlink; extra == "dev"
|
|
32
32
|
|
|
33
33
|
# FlightAnalysis
|
|
@@ -11,9 +11,23 @@ examples/data/__init__.py
|
|
|
11
11
|
examples/data/manual_F3A_F23_22_04_28_00000231.json
|
|
12
12
|
examples/data/manual_F3A_P23_22_05_31_00000350.json
|
|
13
13
|
examples/data/manual_F3A_P23_23_08_11_00000094.json
|
|
14
|
+
examples/schedule_construction/AMA_Intermediate2024.py
|
|
15
|
+
examples/schedule_construction/__init__.py
|
|
16
|
+
examples/schedule_construction/create_all.py
|
|
17
|
+
examples/schedule_construction/f3a_a25.py
|
|
18
|
+
examples/schedule_construction/f3a_f25.py
|
|
19
|
+
examples/schedule_construction/f3a_p23.py
|
|
20
|
+
examples/schedule_construction/f3a_p25.py
|
|
21
|
+
examples/schedule_construction/f3auk_clubman.py
|
|
22
|
+
examples/schedule_construction/f3auk_intermediate.py
|
|
23
|
+
examples/schedule_construction/imac_sport2024.py
|
|
24
|
+
examples/schedule_construction/imac_unlim2024.py
|
|
25
|
+
examples/schedule_construction/make_manoeuvre.py
|
|
26
|
+
examples/schedule_construction/nsrca_inter2024.py
|
|
14
27
|
examples/scoring/__init__.py
|
|
15
28
|
examples/scoring/f3a_criteria_maker.py
|
|
16
29
|
examples/scoring/judging.py
|
|
30
|
+
examples/scoring/temp.py
|
|
17
31
|
examples/scoring/manoeuvres/__init__.py
|
|
18
32
|
examples/scoring/manoeuvres/inter_analysis.py
|
|
19
33
|
examples/scoring/manoeuvres/intra_analysis.py
|
|
@@ -92,19 +106,6 @@ flightanalysis/scoring/criteria/intra/single.py
|
|
|
92
106
|
flightanalysis/scripts/batch_analyse.py
|
|
93
107
|
flightanalysis/scripts/collect_scores.py
|
|
94
108
|
flightanalysis/scripts/plot_scores.py
|
|
95
|
-
scripts/AMA_Intermediate2024.py
|
|
96
|
-
scripts/__init__.py
|
|
97
|
-
scripts/create_all.py
|
|
98
|
-
scripts/f3a_a25.py
|
|
99
|
-
scripts/f3a_f25.py
|
|
100
|
-
scripts/f3a_p23.py
|
|
101
|
-
scripts/f3a_p25.py
|
|
102
|
-
scripts/f3auk_clubman.py
|
|
103
|
-
scripts/f3auk_intermediate.py
|
|
104
|
-
scripts/imac_sport2024.py
|
|
105
|
-
scripts/imac_unlim2024.py
|
|
106
|
-
scripts/make_manoeuvre.py
|
|
107
|
-
scripts/nsrca_inter2024.py
|
|
108
109
|
tests/EmailedBox.f3a
|
|
109
110
|
tests/__init__.py
|
|
110
111
|
tests/conftest.py
|
|
@@ -5,8 +5,8 @@ fastdtw
|
|
|
5
5
|
simplejson
|
|
6
6
|
loguru
|
|
7
7
|
joblib
|
|
8
|
-
pfc-geometry>=0.2.
|
|
9
|
-
flightdata>=0.2.
|
|
8
|
+
pfc-geometry>=0.2.7
|
|
9
|
+
flightdata>=0.2.15
|
|
10
10
|
|
|
11
11
|
[dev]
|
|
12
12
|
numpy
|
|
@@ -16,7 +16,7 @@ fastdtw
|
|
|
16
16
|
simplejson
|
|
17
17
|
loguru
|
|
18
18
|
joblib
|
|
19
|
-
pfc-geometry>=0.2.
|
|
20
|
-
flightdata>=0.2.
|
|
21
|
-
ardupilot_log_reader>=0.3.
|
|
19
|
+
pfc-geometry>=0.2.7
|
|
20
|
+
flightdata>=0.2.15
|
|
21
|
+
ardupilot_log_reader>=0.3.3
|
|
22
22
|
pymavlink
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
from typing import Self, Union
|
|
3
|
-
from json import load
|
|
4
|
-
from flightdata import Flight, State, Origin, Collection
|
|
5
|
-
from flightanalysis.definition import SchedDef, ScheduleInfo
|
|
6
|
-
from . import manoeuvre_analysis as analysis
|
|
7
|
-
from loguru import logger
|
|
8
|
-
from joblib import Parallel, delayed
|
|
9
|
-
import os
|
|
10
|
-
import pandas as pd
|
|
11
|
-
from importlib.metadata import version
|
|
12
|
-
import geometry as g
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class ScheduleAnalysis(Collection):
|
|
16
|
-
VType=analysis.Analysis
|
|
17
|
-
uid='name'
|
|
18
|
-
|
|
19
|
-
def __init__(self, data: list[analysis.Analysis], sinfo: ScheduleInfo):
|
|
20
|
-
super().__init__(data)
|
|
21
|
-
self.sinfo = sinfo
|
|
22
|
-
|
|
23
|
-
@staticmethod
|
|
24
|
-
def from_fcj(file: Union[str, dict], info: ScheduleInfo=None) -> ScheduleAnalysis:
|
|
25
|
-
if isinstance(file, str):
|
|
26
|
-
data = load(open(file, 'r'))
|
|
27
|
-
else:
|
|
28
|
-
data = file
|
|
29
|
-
flight = Flight.from_fc_json(data)
|
|
30
|
-
|
|
31
|
-
if info is None:
|
|
32
|
-
info = ScheduleInfo.from_str(data["parameters"]["schedule"][1])
|
|
33
|
-
|
|
34
|
-
sdef = SchedDef.load(info)
|
|
35
|
-
box = Origin.from_fcjson_parmameters(data["parameters"])
|
|
36
|
-
state = State.from_flight(flight, box).splitter_labels(
|
|
37
|
-
data["mans"],
|
|
38
|
-
sdef.uids
|
|
39
|
-
)
|
|
40
|
-
direction = -state.get_manoeuvre(1)[0].direction()[0]
|
|
41
|
-
|
|
42
|
-
return ScheduleAnalysis(
|
|
43
|
-
[analysis.Basic(
|
|
44
|
-
i,
|
|
45
|
-
mdef,
|
|
46
|
-
state.get_manoeuvre(mdef.uid),
|
|
47
|
-
direction
|
|
48
|
-
) for i, mdef in enumerate(sdef)],
|
|
49
|
-
info
|
|
50
|
-
)
|
|
51
|
-
|
|
52
|
-
def run_all(self) -> Self:
|
|
53
|
-
def parse_analyse_serialise(pad):
|
|
54
|
-
res = analysis.Basic.from_dict(pad).run_all()
|
|
55
|
-
logger.info(f'Completed {res.name}')
|
|
56
|
-
return res.to_dict()
|
|
57
|
-
|
|
58
|
-
logger.info(f'Starting {os.cpu_count()} analysis processes')
|
|
59
|
-
madicts = Parallel(n_jobs=os.cpu_count())(
|
|
60
|
-
delayed(parse_analyse_serialise)(ma.to_dict()) for ma in self
|
|
61
|
-
)
|
|
62
|
-
|
|
63
|
-
return ScheduleAnalysis([analysis.Scored.from_dict(mad) for mad in madicts], self.sinfo)
|
|
64
|
-
|
|
65
|
-
def optimize_alignment(self) -> Self:
|
|
66
|
-
|
|
67
|
-
def parse_analyse_serialise(mad):
|
|
68
|
-
an = analysis.Complete.from_dict(mad)
|
|
69
|
-
return an.run_all().to_dict()
|
|
70
|
-
|
|
71
|
-
logger.info(f'Starting {os.cpu_count()} alinment optimisation processes')
|
|
72
|
-
inmadicts = [mdef.to_dict() for mdef in self]
|
|
73
|
-
madicts = Parallel(n_jobs=os.cpu_count())(delayed(parse_analyse_serialise)(mad) for mad in inmadicts)
|
|
74
|
-
return ScheduleAnalysis([analysis.Scored.from_dict(mad) for mad in madicts], self.sinfo)
|
|
75
|
-
|
|
76
|
-
@staticmethod
|
|
77
|
-
def from_fcscore(file: Union[str, dict], fallback=True) -> ScheduleAnalysis:
|
|
78
|
-
if isinstance(file, str) or isinstance(file, os.PathLike):
|
|
79
|
-
data = load(open(file, 'r'))
|
|
80
|
-
else:
|
|
81
|
-
data = file
|
|
82
|
-
sinfo = ScheduleInfo(**data['sinfo'])
|
|
83
|
-
sdef = SchedDef.load(sinfo)
|
|
84
|
-
|
|
85
|
-
mas = []
|
|
86
|
-
for mdef in sdef:
|
|
87
|
-
mas.append(analysis.Scored.from_dict(
|
|
88
|
-
data['data'][mdef.info.short_name],
|
|
89
|
-
fallback
|
|
90
|
-
))
|
|
91
|
-
|
|
92
|
-
return ScheduleAnalysis(mas, sinfo)
|
|
93
|
-
|
|
94
|
-
def scores(self):
|
|
95
|
-
scores = {}
|
|
96
|
-
total = 0
|
|
97
|
-
scores = {ma.name: (ma.scores.score() if hasattr(ma, 'scores') else 0) for ma in self}
|
|
98
|
-
total = sum([ma.mdef.info.k * v for ma, v in zip(self, scores.values())])
|
|
99
|
-
return total, scores
|
|
100
|
-
|
|
101
|
-
def summarydf(self):
|
|
102
|
-
return pd.DataFrame([ma.scores.summary() if hasattr(ma, 'scores') else {} for ma in self])
|
|
103
|
-
|
|
104
|
-
def to_fcscore(self, name: str) -> dict:
|
|
105
|
-
total, scores = self.scores()
|
|
106
|
-
|
|
107
|
-
odata = dict(
|
|
108
|
-
name = name,
|
|
109
|
-
client_version = 'Py',
|
|
110
|
-
server_version = version('flightanalysis'),
|
|
111
|
-
sinfo = self.sinfo.__dict__,
|
|
112
|
-
score = total,
|
|
113
|
-
manscores = scores,
|
|
114
|
-
data = self.to_dict()
|
|
115
|
-
)
|
|
116
|
-
return odata
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{flightanalysis-0.2.14 → flightanalysis-0.2.16}/examples/data/manual_F3A_F23_22_04_28_00000231.json
RENAMED
|
File without changes
|
{flightanalysis-0.2.14 → flightanalysis-0.2.16}/examples/data/manual_F3A_P23_22_05_31_00000350.json
RENAMED
|
File without changes
|
{flightanalysis-0.2.14 → flightanalysis-0.2.16}/examples/data/manual_F3A_P23_23_08_11_00000094.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{flightanalysis-0.2.14/scripts → flightanalysis-0.2.16/examples/schedule_construction}/create_all.py
RENAMED
|
File without changes
|
{flightanalysis-0.2.14/scripts → flightanalysis-0.2.16/examples/schedule_construction}/f3a_a25.py
RENAMED
|
File without changes
|
{flightanalysis-0.2.14/scripts → flightanalysis-0.2.16/examples/schedule_construction}/f3a_f25.py
RENAMED
|
File without changes
|
{flightanalysis-0.2.14/scripts → flightanalysis-0.2.16/examples/schedule_construction}/f3a_p23.py
RENAMED
|
File without changes
|
{flightanalysis-0.2.14/scripts → flightanalysis-0.2.16/examples/schedule_construction}/f3a_p25.py
RENAMED
|
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
|
{flightanalysis-0.2.14 → flightanalysis-0.2.16}/examples/scoring/manoeuvres/inter_analysis.py
RENAMED
|
File without changes
|
{flightanalysis-0.2.14 → flightanalysis-0.2.16}/examples/scoring/manoeuvres/intra_analysis.py
RENAMED
|
File without changes
|
|
File without changes
|
{flightanalysis-0.2.14 → flightanalysis-0.2.16}/examples/scoring/manoeuvres/mans/extract_mans.py
RENAMED
|
File without changes
|
|
File without changes
|
{flightanalysis-0.2.14 → flightanalysis-0.2.16}/examples/scoring/manoeuvres/positioning_analysis.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/analysis/manoeuvre_analysis/basic.py
RENAMED
|
File without changes
|
|
File without changes
|
{flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/data/IMAC_Unlimited2024_schedule.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/data/f3auk_clubman_schedule.json
RENAMED
|
File without changes
|
{flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/data/f3auk_inter_schedule.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/definition/builders/elbuilders.py
RENAMED
|
File without changes
|
|
File without changes
|
{flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/definition/builders/manbuilder.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/definition/operations/__init__.py
RENAMED
|
File without changes
|
{flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/definition/operations/funopp.py
RENAMED
|
File without changes
|
{flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/definition/operations/itemopp.py
RENAMED
|
File without changes
|
{flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/definition/operations/mathopp.py
RENAMED
|
File without changes
|
{flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/definition/operations/operation.py
RENAMED
|
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
|
{flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/scoring/criteria/exponential.py
RENAMED
|
File without changes
|
|
File without changes
|
{flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/scoring/criteria/inter/combination.py
RENAMED
|
File without changes
|
{flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/scoring/criteria/inter/comparison.py
RENAMED
|
File without changes
|
|
File without changes
|
{flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/scoring/criteria/intra/bounded.py
RENAMED
|
File without changes
|
{flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis/scoring/criteria/intra/single.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{flightanalysis-0.2.14 → flightanalysis-0.2.16}/flightanalysis.egg-info/dependency_links.txt
RENAMED
|
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
|
{flightanalysis-0.2.14 → flightanalysis-0.2.16}/tests/test_schedule/test_definition/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{flightanalysis-0.2.14 → flightanalysis-0.2.16}/tests/test_schedule/test_element/__init__.py
RENAMED
|
File without changes
|
{flightanalysis-0.2.14 → flightanalysis-0.2.16}/tests/test_schedule/test_element/loop_analysis.json
RENAMED
|
File without changes
|
{flightanalysis-0.2.14 → flightanalysis-0.2.16}/tests/test_schedule/test_element/p23_th_e0.csv
RENAMED
|
File without changes
|
{flightanalysis-0.2.14 → flightanalysis-0.2.16}/tests/test_schedule/test_element/p23_th_e0.json
RENAMED
|
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
|
{flightanalysis-0.2.14 → flightanalysis-0.2.16}/tests/test_schedule/test_schedule_manoeuvre.py
RENAMED
|
File without changes
|