flightdata 0.2.25__tar.gz → 0.2.26__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.25 → flightdata-0.2.26}/PKG-INFO +3 -2
  2. {flightdata-0.2.25 → flightdata-0.2.26}/pyproject.toml +1 -1
  3. {flightdata-0.2.25 → flightdata-0.2.26}/src/flightdata/scripts/flightline.py +53 -37
  4. flightdata-0.2.26/test/data/script_tests/c6_on_0001.BIN +0 -0
  5. flightdata-0.2.26/test/data/script_tests/center_0003.bin +0 -0
  6. flightdata-0.2.26/test/data/script_tests/pilot_0004.BIN +0 -0
  7. flightdata-0.2.26/test/test_scripts.py +25 -0
  8. {flightdata-0.2.25 → flightdata-0.2.26}/.github/workflows/publish_pypi.yml +0 -0
  9. {flightdata-0.2.25 → flightdata-0.2.26}/.gitignore +0 -0
  10. {flightdata-0.2.25 → flightdata-0.2.26}/.vscode/launch.json +0 -0
  11. {flightdata-0.2.25 → flightdata-0.2.26}/.vscode/settings.json +0 -0
  12. {flightdata-0.2.25 → flightdata-0.2.26}/LICENSE +0 -0
  13. {flightdata-0.2.25 → flightdata-0.2.26}/README.md +0 -0
  14. {flightdata-0.2.25 → flightdata-0.2.26}/examples/__init__.py +0 -0
  15. {flightdata-0.2.25 → flightdata-0.2.26}/examples/data/__init__.py +0 -0
  16. {flightdata-0.2.25 → flightdata-0.2.26}/examples/data/manual_F3A_F23_22_04_28_00000231.json +0 -0
  17. {flightdata-0.2.25 → flightdata-0.2.26}/examples/data/manual_F3A_P23_22_05_31_00000350.json +0 -0
  18. {flightdata-0.2.25 → flightdata-0.2.26}/examples/data/manual_F3A_P23_23_08_11_00000094.json +0 -0
  19. {flightdata-0.2.25 → flightdata-0.2.26}/examples/flight_dynamics/00000150.json +0 -0
  20. {flightdata-0.2.25 → flightdata-0.2.26}/examples/flight_dynamics/__init__.py +0 -0
  21. {flightdata-0.2.25 → flightdata-0.2.26}/examples/flight_dynamics/box.f3a +0 -0
  22. {flightdata-0.2.25 → flightdata-0.2.26}/examples/flight_dynamics/param_id.py +0 -0
  23. {flightdata-0.2.25 → flightdata-0.2.26}/examples/state_analysis/__init__.py +0 -0
  24. {flightdata-0.2.25 → flightdata-0.2.26}/examples/state_analysis/axes.py +0 -0
  25. {flightdata-0.2.25 → flightdata-0.2.26}/examples/state_analysis/state_fill_plot.py +0 -0
  26. {flightdata-0.2.25 → flightdata-0.2.26}/src/flightdata/__init__.py +0 -0
  27. {flightdata-0.2.25 → flightdata-0.2.26}/src/flightdata/base/__init__.py +0 -0
  28. {flightdata-0.2.25 → flightdata-0.2.26}/src/flightdata/base/collection.py +0 -0
  29. {flightdata-0.2.25 → flightdata-0.2.26}/src/flightdata/base/constructs.py +0 -0
  30. {flightdata-0.2.25 → flightdata-0.2.26}/src/flightdata/base/labeling.py +0 -0
  31. {flightdata-0.2.25 → flightdata-0.2.26}/src/flightdata/base/numpy_encoder.py +0 -0
  32. {flightdata-0.2.25 → flightdata-0.2.26}/src/flightdata/base/table.py +0 -0
  33. {flightdata-0.2.25 → flightdata-0.2.26}/src/flightdata/bindata.py +0 -0
  34. {flightdata-0.2.25 → flightdata-0.2.26}/src/flightdata/coefficients.py +0 -0
  35. {flightdata-0.2.25 → flightdata-0.2.26}/src/flightdata/environment/__init__.py +0 -0
  36. {flightdata-0.2.25 → flightdata-0.2.26}/src/flightdata/environment/environment.py +0 -0
  37. {flightdata-0.2.25 → flightdata-0.2.26}/src/flightdata/environment/wind.py +0 -0
  38. {flightdata-0.2.25 → flightdata-0.2.26}/src/flightdata/flight/__init__.py +0 -0
  39. {flightdata-0.2.25 → flightdata-0.2.26}/src/flightdata/flight/ardupilot.py +0 -0
  40. {flightdata-0.2.25 → flightdata-0.2.26}/src/flightdata/flight/fields.py +0 -0
  41. {flightdata-0.2.25 → flightdata-0.2.26}/src/flightdata/flight/flight.py +0 -0
  42. {flightdata-0.2.25 → flightdata-0.2.26}/src/flightdata/flight/parameters.py +0 -0
  43. {flightdata-0.2.25 → flightdata-0.2.26}/src/flightdata/flow.py +0 -0
  44. {flightdata-0.2.25 → flightdata-0.2.26}/src/flightdata/model/__init__.py +0 -0
  45. {flightdata-0.2.25 → flightdata-0.2.26}/src/flightdata/model/aerodynamic.py +0 -0
  46. {flightdata-0.2.25 → flightdata-0.2.26}/src/flightdata/model/thrust.py +0 -0
  47. {flightdata-0.2.25 → flightdata-0.2.26}/src/flightdata/origin.py +0 -0
  48. {flightdata-0.2.25 → flightdata-0.2.26}/src/flightdata/py.typed +0 -0
  49. {flightdata-0.2.25 → flightdata-0.2.26}/src/flightdata/schemas/__init__.py +0 -0
  50. {flightdata-0.2.25 → flightdata-0.2.26}/src/flightdata/schemas/fcj.py +0 -0
  51. {flightdata-0.2.25 → flightdata-0.2.26}/src/flightdata/scripts/collect_logs.py +0 -0
  52. {flightdata-0.2.25 → flightdata-0.2.26}/src/flightdata/state.py +0 -0
  53. {flightdata-0.2.25 → flightdata-0.2.26}/test/EmailedBox.f3a +0 -0
  54. {flightdata-0.2.25 → flightdata-0.2.26}/test/__init__.py +0 -0
  55. {flightdata-0.2.25 → flightdata-0.2.26}/test/base/__init__.py +0 -0
  56. {flightdata-0.2.25 → flightdata-0.2.26}/test/base/test_base_constructs.py +0 -0
  57. {flightdata-0.2.25 → flightdata-0.2.26}/test/base/test_table.py +0 -0
  58. {flightdata-0.2.25 → flightdata-0.2.26}/test/conftest.py +0 -0
  59. {flightdata-0.2.25 → flightdata-0.2.26}/test/data/bin_parser_GPS.csv +0 -0
  60. {flightdata-0.2.25 → flightdata-0.2.26}/test/data/bin_parser_POS.csv +0 -0
  61. {flightdata-0.2.25 → flightdata-0.2.26}/test/data/make_inputs.py +0 -0
  62. {flightdata-0.2.25 → flightdata-0.2.26}/test/data/manual_F3A_P23.json +0 -0
  63. {flightdata-0.2.25 → flightdata-0.2.26}/test/data/p23.BIN +0 -0
  64. {flightdata-0.2.25 → flightdata-0.2.26}/test/data/p23.json +0 -0
  65. {flightdata-0.2.25 → flightdata-0.2.26}/test/data/p23_box.f3a +0 -0
  66. {flightdata-0.2.25 → flightdata-0.2.26}/test/data/p23_fc.json +0 -0
  67. {flightdata-0.2.25 → flightdata-0.2.26}/test/data/p23_flight.json +0 -0
  68. {flightdata-0.2.25 → flightdata-0.2.26}/test/data/vtol_hover.bin +0 -0
  69. {flightdata-0.2.25 → flightdata-0.2.26}/test/data/vtol_hover.json +0 -0
  70. {flightdata-0.2.25 → flightdata-0.2.26}/test/data/web_bin_parse.json +0 -0
  71. {flightdata-0.2.25 → flightdata-0.2.26}/test/test_bindata.py +0 -0
  72. {flightdata-0.2.25 → flightdata-0.2.26}/test/test_environment/__init__.py +0 -0
  73. {flightdata-0.2.25 → flightdata-0.2.26}/test/test_environment/test_environment.py +0 -0
  74. {flightdata-0.2.25 → flightdata-0.2.26}/test/test_environment/test_environment_wind.py +0 -0
  75. {flightdata-0.2.25 → flightdata-0.2.26}/test/test_fields.py +0 -0
  76. {flightdata-0.2.25 → flightdata-0.2.26}/test/test_flight.py +0 -0
  77. {flightdata-0.2.25 → flightdata-0.2.26}/test/test_model/__init__.py +0 -0
  78. {flightdata-0.2.25 → flightdata-0.2.26}/test/test_model/test_model_coefficients.py +0 -0
  79. {flightdata-0.2.25 → flightdata-0.2.26}/test/test_model/test_model_flow.py +0 -0
  80. {flightdata-0.2.25 → flightdata-0.2.26}/test/test_origin.py +0 -0
  81. {flightdata-0.2.25 → flightdata-0.2.26}/test/test_state/__init__.py +0 -0
  82. {flightdata-0.2.25 → flightdata-0.2.26}/test/test_state/test_state.py +0 -0
  83. {flightdata-0.2.25 → flightdata-0.2.26}/test/test_state/test_state_builders.py +0 -0
  84. {flightdata-0.2.25 → flightdata-0.2.26}/test/test_state/test_state_conversions.py +0 -0
  85. {flightdata-0.2.25 → flightdata-0.2.26}/test/test_state/test_state_measurements.py +0 -0
  86. {flightdata-0.2.25 → flightdata-0.2.26}/uv.lock +0 -0
@@ -1,8 +1,9 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: flightdata
3
- Version: 0.2.25
3
+ Version: 0.2.26
4
4
  Summary: Python tools for handling flight data
5
5
  Author-email: Thomas David <thomasdavid0@gmail.com>
6
+ License-File: LICENSE
6
7
  Requires-Python: >=3.12
7
8
  Requires-Dist: numpy>=2.1.3
8
9
  Requires-Dist: pandas>=2.2.3
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "flightdata"
3
- version = "0.2.25"
3
+ version = "0.2.26"
4
4
  description = "Python tools for handling flight data"
5
5
  readme = "README.md"
6
6
  authors = [{ name = "Thomas David", email = "thomasdavid0@gmail.com" }]
@@ -1,8 +1,10 @@
1
+ from ast import In
2
+ import sys
1
3
  from flightdata import Flight, Origin
2
4
  from geometry import GPS
3
5
  from pathlib import Path
4
6
  import argparse
5
-
7
+ import re
6
8
 
7
9
 
8
10
  def get_con_groups(log: Flight, channel: int):
@@ -14,64 +16,78 @@ def box_from_log(log: Flight, channel: int):
14
16
  grps = get_con_groups(log, channel)
15
17
  pilot = grps[0]
16
18
  centre = grps[1]
17
- # c6on = Flight(log.data.loc[log.data[f'rcin_c{channel}']>=1500])
18
- # groups = (c6on.time_flight.diff() > 1).cumsum()
19
- # pilot = Flight(c6on.data.loc[groups==0])
20
- # centre = Flight(c6on.data.loc[groups==1])
21
19
 
22
20
  return Origin.from_points("new", GPS(pilot.pos)[-1], GPS(centre.pos)[-1])
23
21
 
24
22
  def box_from_logs(pilot: Flight, centre: Flight):
25
23
  return Origin.from_points("new", GPS(*pilot.pos.iloc[-1]), GPS(*centre.pos.iloc[-1]))
26
24
 
25
+ re_logid = re.compile(r'[\d+]$')
26
+ def get_bin_from_number(folder: Path, number: str):
27
+ try:
28
+ return list(folder.glob(f"*{number}.BIN"))[0]
29
+ except IndexError:
30
+ return list(folder.glob(f"*{number}.bin"))[0]
27
31
 
28
- def main():
29
- parser = argparse.ArgumentParser(description='A tool for creating a flightline .f3a file from bin logs')
30
32
 
31
- parser.add_argument('-l', '--logdir', default='', help='folder to look for logs in')
32
- parser.add_argument('-p', '--pilot', default=None, help='flight log bin file to use, None for first')
33
- parser.add_argument('-c', '--centre', default=None, help='centre position bin file to use if input==None')
34
- parser.add_argument('-d', '--direction', default=None, help='heading of the box, if this is specified only pilot will be read')
35
- parser.add_argument('-i', '--input', default=6, help='channel used to indicate pilot or centre postions (pwm>=1500), None for two files')
36
33
 
37
- args = parser.parse_args()
34
+ def create_flightline(args) -> argparse.Namespace:
35
+ logdir = Path(args.logdir)
38
36
 
39
- print(args)
37
+ plog = logdir / args.pilot
38
+ if not plog.exists():
39
+ if args.pilot is None:
40
+ plog=sorted(list(logdir.glob("*.BIN")))[0]
41
+ elif args.pilot.isdigit():
42
+ plog = get_bin_from_number(logdir, args.pilot)
43
+ else:
44
+ raise FileNotFoundError(f'Could not find pilot log file: {args.pilot}')
40
45
 
41
- logs = sorted(list(Path(args.logdir).glob("*.BIN")))
42
- logids = [int(log.stem) for log in logs]
43
-
44
- if args.pilot in logs:
45
- plog = args.pilot
46
- elif args.pilot is None:
47
- plog=logs[0]
48
- elif args.pilot.isdigit():
49
- plog = logs[logids.index(int(args.pilot))]
50
-
51
46
  pilot = Flight.from_log(plog)
52
47
 
53
48
  print(f'Pilot position log: {plog}')
54
49
 
55
- if args.centre in logs:
56
- clog = args.centre
57
- elif args.centre is None:
58
- clog=None
59
- elif args.centre.isdigit():
60
- clog = logs[logids.index(int(args.centre))]
61
- if clog:
62
- centre = Flight.from_log(clog)
63
- print(f'Centre position log: {clog}')
64
-
65
50
  if args.centre:
51
+ clog = logdir / args.centre
52
+ if not clog.exists():
53
+ if args.centre is None:
54
+ clog=None
55
+ elif args.centre.isdigit():
56
+ clog = get_bin_from_number(logdir, args.centre)
57
+
58
+ print(f'Centre position log: {clog}' if clog else "No centre position log")
59
+ centre = Flight.from_log(clog) if clog else None
60
+
66
61
  box = Origin.from_points("new", GPS(*pilot.pos.iloc[-1]), GPS(*centre.pos.iloc[-1]))
67
62
  else:
68
- groups = get_con_groups(pilot, args.input)
69
63
  if args.direction:
70
- box = Origin("new", GPS(groups[0].pos)[-1], float(args.direction))
64
+ box = Origin("new", GPS(plog.pos)[-1], float(args.direction))
71
65
  else:
66
+ groups = get_con_groups(pilot, args.input)
72
67
  box = Origin.from_points("new", GPS(groups[0].pos)[-1], GPS(groups[1].pos)[-1])
73
68
 
74
- box.to_f3a_zone(Path(args.logdir) / f'box_{plog.stem}.f3a')
69
+ return box, plog.stem
70
+
71
+
72
+ def parse_args(args):
73
+ parser = argparse.ArgumentParser(description='A tool for creating a flightline .f3a file from bin logs')
74
+
75
+ parser.add_argument('-l', '--logdir', default='', help='folder to look for logs in')
76
+ parser.add_argument('-p', '--pilot', default=None, help='flight log bin file to use, None for first')
77
+ parser.add_argument('-c', '--centre', default=None, help='centre position bin file to use if input==None')
78
+ parser.add_argument('-d', '--direction', default=None, help='heading of the box, if this is specified only pilot will be read')
79
+ parser.add_argument('-i', '--input', default=6, help='channel used to indicate pilot or centre postions (pwm>=1500), None for two files')
80
+
81
+ args = parser.parse_args(args)
82
+
83
+ return args
84
+
85
+
86
+ def main():
87
+ args = parse_args(sys.argv[1:])
88
+ box, name = create_flightline(args)
89
+ box.to_f3a_zone(Path(args.logdir) / f'box_{name}.f3a')
90
+
75
91
 
76
92
  if __name__ == '__main__':
77
93
  main()
@@ -0,0 +1,25 @@
1
+ from flightdata.scripts import flightline as fl
2
+ import geometry as g
3
+ from pathlib import Path
4
+ import numpy as np
5
+ from pytest import approx
6
+
7
+ def test_get_bin_from_number():
8
+ bin = fl.get_bin_from_number(Path("test/data/script_tests"), 1)
9
+ assert bin.stem == "c6_on_0001"
10
+
11
+ bin = fl.get_bin_from_number(Path("test/data/script_tests"), 3)
12
+ assert bin.stem == "center_0003"
13
+
14
+
15
+
16
+ def test_flightline_two_bins():
17
+ box, name = fl.create_flightline(fl.parse_args(["-l", "test/data/script_tests", "-p", "pilot_0004.BIN", "-c", "3"]))
18
+ assert name == "pilot_0004"
19
+ assert isinstance(box.pos, g.GPS)
20
+
21
+ def test_flightline_c6on():
22
+ box, name = fl.create_flightline(fl.parse_args(["-l", "test/data/script_tests", "-p", "1"]))
23
+ assert name == "c6_on_0001"
24
+
25
+ assert np.degrees(box.heading) == approx(-34.44699010)
File without changes
File without changes
File without changes
File without changes