c4dynamics 2.0.3__py3-none-any.whl

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 (50) hide show
  1. c4dynamics/__init__.py +240 -0
  2. c4dynamics/datasets/__init__.py +95 -0
  3. c4dynamics/datasets/_manager.py +596 -0
  4. c4dynamics/datasets/_registry.py +80 -0
  5. c4dynamics/detectors/__init__.py +37 -0
  6. c4dynamics/detectors/yolo3_opencv.py +686 -0
  7. c4dynamics/detectors/yolo3_tf.py +124 -0
  8. c4dynamics/eqm/__init__.py +324 -0
  9. c4dynamics/eqm/derivs.py +212 -0
  10. c4dynamics/eqm/integrate.py +359 -0
  11. c4dynamics/filters/__init__.py +1373 -0
  12. c4dynamics/filters/a.py +48 -0
  13. c4dynamics/filters/ekf.py +320 -0
  14. c4dynamics/filters/kalman.py +725 -0
  15. c4dynamics/filters/kalman_v0.py +1071 -0
  16. c4dynamics/filters/kalman_v1.py +821 -0
  17. c4dynamics/filters/lowpass.py +123 -0
  18. c4dynamics/filters/luenberger.py +97 -0
  19. c4dynamics/rotmat/__init__.py +141 -0
  20. c4dynamics/rotmat/animate.py +465 -0
  21. c4dynamics/rotmat/rotmat.py +351 -0
  22. c4dynamics/sensors/__init__.py +72 -0
  23. c4dynamics/sensors/lineofsight.py +78 -0
  24. c4dynamics/sensors/radar.py +740 -0
  25. c4dynamics/sensors/seeker.py +1030 -0
  26. c4dynamics/states/__init__.py +327 -0
  27. c4dynamics/states/lib/__init__.py +320 -0
  28. c4dynamics/states/lib/datapoint.py +660 -0
  29. c4dynamics/states/lib/pixelpoint.py +776 -0
  30. c4dynamics/states/lib/rigidbody.py +677 -0
  31. c4dynamics/states/state.py +1486 -0
  32. c4dynamics/utils/__init__.py +44 -0
  33. c4dynamics/utils/_struct.py +6 -0
  34. c4dynamics/utils/const.py +130 -0
  35. c4dynamics/utils/cprint.py +80 -0
  36. c4dynamics/utils/gen_gif.py +142 -0
  37. c4dynamics/utils/idx2keys.py +4 -0
  38. c4dynamics/utils/images_loader.py +63 -0
  39. c4dynamics/utils/math.py +136 -0
  40. c4dynamics/utils/plottools.py +140 -0
  41. c4dynamics/utils/plottracks.py +304 -0
  42. c4dynamics/utils/printpts.py +36 -0
  43. c4dynamics/utils/slides_gen.py +64 -0
  44. c4dynamics/utils/tictoc.py +167 -0
  45. c4dynamics/utils/video_gen.py +300 -0
  46. c4dynamics/utils/vidgen.py +182 -0
  47. c4dynamics-2.0.3.dist-info/METADATA +242 -0
  48. c4dynamics-2.0.3.dist-info/RECORD +50 -0
  49. c4dynamics-2.0.3.dist-info/WHEEL +5 -0
  50. c4dynamics-2.0.3.dist-info/top_level.txt +1 -0
@@ -0,0 +1,44 @@
1
+ #
2
+ # utils __init__
3
+ ##
4
+
5
+ # from . import plottools
6
+ # from . import gen_gif
7
+
8
+ import sys
9
+ sys.path.append('.')
10
+ vi = sys.version_info
11
+
12
+ if vi.minor <= 7:
13
+ from c4dynamics.utils.images_loader import *
14
+
15
+ # from . import const
16
+ # from . import math
17
+
18
+
19
+
20
+ if __name__ == "__main__":
21
+
22
+ import doctest, contextlib, os
23
+ from c4dynamics import IgnoreOutputChecker, cprint
24
+
25
+ # Register the custom OutputChecker
26
+ doctest.OutputChecker = IgnoreOutputChecker
27
+
28
+ tofile = False
29
+ optionflags = doctest.FAIL_FAST
30
+
31
+ if tofile:
32
+ with open(os.path.join('tests', '_out', 'output.txt'), 'w') as f:
33
+ with contextlib.redirect_stdout(f), contextlib.redirect_stderr(f):
34
+ result = doctest.testmod(optionflags = optionflags)
35
+ else:
36
+ result = doctest.testmod(optionflags = optionflags)
37
+
38
+ if result.failed == 0:
39
+ cprint(os.path.basename(__file__) + ": all tests passed!", 'g')
40
+ else:
41
+ print(f"{result.failed}")
42
+
43
+
44
+
@@ -0,0 +1,6 @@
1
+ class struct:
2
+ def __init__(self, **kwargs):
3
+ self.__dict__.update(kwargs)
4
+
5
+ def __iter__(self):
6
+ return iter(self.__dict__.items())
@@ -0,0 +1,130 @@
1
+ import numpy as np
2
+
3
+ __doc__ = '''
4
+ Globals and conversion constants.
5
+
6
+
7
+ C4dynamics includes several constants as global quantities
8
+ and conversion units:
9
+
10
+
11
+ Global Constants
12
+ ----------------
13
+
14
+ .. data:: pi
15
+
16
+ The ratio of a circle's circumference to its diameter.
17
+ C4dynamics' pi is a simple assignment of numpy.pi:
18
+
19
+ ``pi = 3.1415926535897932384626433...``
20
+
21
+ .. rubric:: Reference
22
+
23
+ https://en.wikipedia.org/wiki/Pi
24
+
25
+
26
+ .. data:: g_ms2
27
+
28
+ Gravity of earth in meter per square second.
29
+
30
+ ``g = 9.80665``
31
+
32
+ .. rubric:: Reference
33
+
34
+ https://en.wikipedia.org/wiki/Gravity_of_Earth
35
+
36
+
37
+ .. data:: g_fts2
38
+
39
+ Gravity of earth in foot per square second.
40
+
41
+ ``g = 32.1740``
42
+
43
+ .. rubric:: Reference
44
+
45
+ https://en.wikipedia.org/wiki/Gravity_of_Earth
46
+
47
+
48
+
49
+ Conversion Constants
50
+ --------------------
51
+
52
+ .. data:: ft2m
53
+
54
+ foot to meter.
55
+
56
+ ``ft2m = 0.3048``
57
+
58
+
59
+ .. data:: lbft2tokgm2
60
+
61
+ pound square foot to kilogram square meter.
62
+
63
+ ``lbft2tokgm2 = 4.88243``
64
+
65
+
66
+ .. data:: r2d
67
+
68
+ radians to degrees.
69
+
70
+ ``r2d = 57.2958``
71
+
72
+
73
+ .. data:: d2r
74
+
75
+ degrees to radians.
76
+
77
+ ``d2r = 0.0174533``
78
+
79
+ .. data:: k2ms
80
+
81
+ knots to meters per second
82
+
83
+ ``k2ms = 0.514444``
84
+
85
+
86
+ '''
87
+
88
+ import sys
89
+ sys.path.append('.')
90
+
91
+
92
+ # global quantities
93
+ pi = np.pi
94
+ g_ms2 = 9.80665 # m/s^2
95
+ g_fts2 = 32.1740 # ft/s^2
96
+
97
+ # conversion variables
98
+ ft2m = 0.3048 # 1 #
99
+ lbft2tokgm2 = 4.88243 # 47.8803 to include gravity # 1
100
+ r2d = 180 / np.pi
101
+ d2r = np.pi / 180
102
+ kmh2ms = 1000 / 3600
103
+ k2ms = 1852 / 3600 # knots to meter per second
104
+
105
+
106
+
107
+ if __name__ == "__main__":
108
+
109
+ import doctest, contextlib, os
110
+ from c4dynamics import IgnoreOutputChecker, cprint
111
+
112
+ # Register the custom OutputChecker
113
+ doctest.OutputChecker = IgnoreOutputChecker
114
+
115
+ tofile = False
116
+ optionflags = doctest.FAIL_FAST
117
+
118
+ if tofile:
119
+ with open(os.path.join('tests', '_out', 'output.txt'), 'w') as f:
120
+ with contextlib.redirect_stdout(f), contextlib.redirect_stderr(f):
121
+ result = doctest.testmod(optionflags = optionflags)
122
+ else:
123
+ result = doctest.testmod(optionflags = optionflags)
124
+
125
+ if result.failed == 0:
126
+ cprint(os.path.basename(__file__) + ": all tests passed!", 'g')
127
+ else:
128
+ print(f"{result.failed}")
129
+
130
+
@@ -0,0 +1,80 @@
1
+ import sys
2
+ sys.path.append('.')
3
+
4
+ TXTCOLORS = { 'k': '30', 'black': '30'
5
+ , 'r': '31', 'red': '31'
6
+ , 'g': '32', 'green': '32'
7
+ , 'y': '33', 'yellow': '33'
8
+ , 'b': '34', 'blue': '34'
9
+ , 'm': '35', 'magenta': '35'
10
+ , 'c': '36', 'cyan': '36'
11
+ , 'w': '37', 'white': '37'
12
+ }
13
+
14
+ def cprint(txt = '', color = 'white', end = '\n'):
15
+ '''
16
+ Printing colored text in the console.
17
+
18
+ Parameters
19
+ ----------
20
+
21
+ txt : str
22
+ The text to be printed.
23
+
24
+ color : str, optional
25
+ The color of the text. Default is 'white'.
26
+
27
+ Example
28
+ -------
29
+
30
+ .. code::
31
+
32
+ >>> carr = ['y', 'w', 'r', 'm', 'c', 'g', 'k', 'b']
33
+ >>> for c in carr:
34
+ ... c4d.cprint('C4DYNAMICS', c)
35
+
36
+ .. raw:: html
37
+
38
+ <span style="color:yellow">C4DYNAMICS</span><br>
39
+ <span style="color:white">C4DYNAMICS</span><br>
40
+ <span style="color:red">C4DYNAMICS</span><br>
41
+ <span style="color:magenta">C4DYNAMICS</span><br>
42
+ <span style="color:cyan">C4DYNAMICS</span><br>
43
+ <span style="color:green">C4DYNAMICS</span><br>
44
+ <span style="color:black">C4DYNAMICS</span><br>
45
+ <span style="color:blue">C4DYNAMICS</span><br>
46
+
47
+ '''
48
+ settxt = '\033['
49
+
50
+
51
+ settxt += TXTCOLORS[color]
52
+
53
+ print(settxt + 'm' + str(txt) + '\033[0m', end = end)
54
+
55
+
56
+ if __name__ == "__main__":
57
+
58
+ import os
59
+ import doctest, contextlib
60
+ from c4dynamics import IgnoreOutputChecker, cprint
61
+
62
+ # Register the custom OutputChecker
63
+ doctest.OutputChecker = IgnoreOutputChecker
64
+
65
+ tofile = False
66
+ optionflags = doctest.FAIL_FAST
67
+
68
+ if tofile:
69
+ with open(os.path.join('tests', '_out', 'output.txt'), 'w') as f:
70
+ with contextlib.redirect_stdout(f), contextlib.redirect_stderr(f):
71
+ result = doctest.testmod(optionflags = optionflags)
72
+ else:
73
+ result = doctest.testmod(optionflags = optionflags)
74
+
75
+ if result.failed == 0:
76
+ cprint("All tests passed!", 'g')
77
+ else:
78
+ print(f"{result.failed}")
79
+
80
+
@@ -0,0 +1,142 @@
1
+ import os
2
+ import imageio
3
+ import natsort
4
+ import warnings
5
+
6
+ import sys
7
+ sys.path.append('.')
8
+ import c4dynamics as c4d
9
+
10
+
11
+ def gif(dirname, gif_name, duration = None):
12
+ '''
13
+
14
+ Gif creator.
15
+
16
+ `gif` creates a Gif from a directory containing image files.
17
+
18
+ Parameters
19
+ ----------
20
+
21
+ dirname : str
22
+ The path to the directory containing image files.
23
+
24
+ gif_name : str
25
+ The desired name of the output GIF file.
26
+
27
+ duration : float, optional
28
+ The duration (in seconds) for each frame of the GIF.
29
+ If None, default duration is used.
30
+
31
+
32
+ Example
33
+ -------
34
+
35
+ 1. Prepare trajectory to animate.
36
+
37
+
38
+ Import required packages:
39
+
40
+ .. code::
41
+
42
+ >>> import c4dynamics as c4d
43
+ >>> from IPython.display import Image
44
+ >>> import numpy as np
45
+ >>> import os
46
+
47
+
48
+ Settings and initial conditions:
49
+
50
+ .. code::
51
+
52
+ >>> f16 = c4d.rigidbody()
53
+ >>> dt = 0.01
54
+
55
+
56
+ Main loop:
57
+
58
+ .. code::
59
+
60
+ >>> for t in np.arange(0, 9, dt):
61
+ ... # in 3 seconds make 180 deg:
62
+ ... if t < 3:
63
+ ... f16.psi += dt * 180 * c4d.d2r / 3
64
+ ... elif t < 6:
65
+ ... f16.theta += dt * 180 * c4d.d2r / 3
66
+ ... else:
67
+ ... f16.phi -= dt * 180 * c4d.d2r / 3
68
+ ... f16.store(t)
69
+
70
+
71
+ 2. Animate and save image files.
72
+
73
+ (Use c4dynamics' :mod:`datasets <c4dynamics.datasets>` to fetch F16 3D model.)
74
+
75
+ .. code::
76
+
77
+ >>> f16path = c4d.datasets.d3_model('f16')
78
+ Fetched successfully
79
+ >>> x0 = [90 * c4d.d2r, 0, 180 * c4d.d2r]
80
+ >>> outfol = os.path.join('tests', '_out', 'f16b')
81
+ >>> f16.animate(f16path, savedir = outfol, angle0 = x0, modelcolor = [0, 0, 0], cbackground = [230 / 255, 230 / 255, 255 / 255])
82
+
83
+
84
+ 3. Export images as gif.
85
+
86
+ .. code::
87
+
88
+ >>> gifname = 'f16_monochrome_gif.gif'
89
+ >>> c4d.gif(outfol, gifname, duration = 1)
90
+ >>> Image(filename = os.path.join(outfol, gifname)) # doctest: +IGNORE_OUTPUT
91
+
92
+ .. figure:: /_examples/animate/f16_monochrome_gif.gif
93
+
94
+ '''
95
+ dirfiles = natsort.natsorted(os.listdir(dirname))
96
+ imgfiles = [f for f in dirfiles if f.lower().endswith(('.png', '.jpg', '.jpeg', 'bmp', '.tiff'))]
97
+
98
+ if not imgfiles:
99
+ warnings.warn(f"""No image files in {dirfiles}. ('.png', '.jpg', '.jpeg', 'bmp', '.tiff', are supported). """ , c4d.c4warn)
100
+ return None
101
+
102
+ fps = 60 # 60hz (60frames per second) -> 16.6msec
103
+ if duration is None:
104
+ interval = 1
105
+ else:
106
+ # FIXME sth here is wrong. see the test test_specified_fps_effect currently disabled.
107
+ interval = max(int(len(imgfiles) / (duration * fps)), 1)
108
+
109
+ images = []
110
+
111
+ for i in range(0, len(imgfiles), interval):
112
+ images.append(imageio.v2.imread(os.path.join(dirname, imgfiles[i])))
113
+
114
+ gif_name = gif_name if gif_name.endswith('.gif') else gif_name + '.gif'
115
+ imageio.mimsave(os.path.join(dirname, gif_name)
116
+ , images, loop = 0, duration = int(1000 * 1 / fps))
117
+
118
+
119
+ if __name__ == "__main__":
120
+
121
+ import doctest, contextlib
122
+ from c4dynamics import IgnoreOutputChecker, cprint
123
+
124
+ # Register the custom OutputChecker
125
+ doctest.OutputChecker = IgnoreOutputChecker
126
+
127
+ tofile = False
128
+ optionflags = doctest.FAIL_FAST
129
+
130
+ if tofile:
131
+ with open(os.path.join('tests', '_out', 'output.txt'), 'w') as f:
132
+ with contextlib.redirect_stdout(f), contextlib.redirect_stderr(f):
133
+ result = doctest.testmod(optionflags = optionflags)
134
+ else:
135
+ result = doctest.testmod(optionflags = optionflags)
136
+
137
+ if result.failed == 0:
138
+ cprint(os.path.basename(__file__) + ": all tests passed!", 'g')
139
+ else:
140
+ print(f"{result.failed}")
141
+
142
+
@@ -0,0 +1,4 @@
1
+ import numpy as np
2
+
3
+ def idx2keys(xdict, idx):
4
+ return np.array(list(xdict.keys()))[idx]
@@ -0,0 +1,63 @@
1
+ # sngl3
2
+ # load single image as 3 layers rgb
3
+ # snglv
4
+ # load single image as a row vector
5
+ # mltpl3
6
+ # load multiple images as 3 layers rgb
7
+ # mltplv
8
+ # load mulitple images as an array where each row is an image
9
+
10
+ import glob
11
+ import numpy as np
12
+ from matplotlib import image
13
+
14
+ def sngl3(file):
15
+ err1 = False
16
+ if file.lower().endswith(('.png', '.jpg', '.jpeg')):
17
+ img = image.imread(file)
18
+ if img is None:
19
+ err1 = True
20
+ else:
21
+ err1 = True
22
+
23
+ if err1:
24
+ print(file + ' is not an image file')
25
+ else:
26
+ return img
27
+
28
+
29
+ def snglv(file):
30
+ err1 = False
31
+ if file.lower().endswith(('.png', '.jpg', '.jpeg')):
32
+ img = image.imread(file)
33
+ if img is None:
34
+ err1 = True
35
+ else:
36
+ err1 = True
37
+
38
+ if err1:
39
+ print(file + ' is not an image file')
40
+ else:
41
+ img = np.reshape(img, (1, -1)) # the unspecified value is inferred as ..
42
+ return img
43
+
44
+
45
+ def mltpl3(folder):
46
+ images = []
47
+ for f in glob.glob(folder):
48
+ if f.lower().endswith(('.png', '.jpg', '.jpeg')):
49
+ img = image.imread(f)
50
+ if img is not None:
51
+ images.append(img)
52
+ return images
53
+
54
+
55
+ def mltplv(folder):
56
+ images = []
57
+ for f in glob.glob(folder):
58
+ if f.lower().endswith(('.png', '.jpg', '.jpeg')):
59
+ img = image.imread(f)
60
+ if img is not None:
61
+ img = np.reshape(img, (1, -1))
62
+ images.append(img)
63
+ return images
@@ -0,0 +1,136 @@
1
+ import numpy as np
2
+ from scipy.special import erfinv
3
+ import sys
4
+ sys.path.append('.')
5
+ import c4dynamics as c4d
6
+
7
+ __doc__ = '''
8
+ Math functions aliasing.
9
+
10
+
11
+ For convenience, C4dynamics aliases some of
12
+ NumPy's trigonometric functions
13
+ with slight variations in some of them:
14
+
15
+ .. code::
16
+
17
+ import numpy as np
18
+ import c4dynamics as c4d
19
+
20
+
21
+ .. data:: sin
22
+
23
+ ``c4d.sin = np.sin``
24
+
25
+ .. data:: sind
26
+
27
+ ``c4d.sind = lambda n: np.sin(n * c4d.d2r)``
28
+
29
+ .. data:: cos
30
+
31
+ ``c4d.cos = np.cos``
32
+
33
+ .. data:: cosd
34
+
35
+ ``c4d.cosd = lambda n: np.cos(n * c4d.d2r)``
36
+
37
+ .. data:: tan
38
+
39
+ ``c4d.tan = np.tan``
40
+
41
+ .. data:: tand
42
+
43
+ ``c4d.tand = lambda n: np.tan(n * c4d.d2r)``
44
+
45
+
46
+ .. data:: asin
47
+
48
+ ``c4d.asin = np.arcsin``
49
+
50
+ .. data:: asind
51
+
52
+ ``c4d.asind = lambda n: np.arcsin(n) * c4d.r2d``
53
+
54
+ .. data:: acos
55
+
56
+ ``c4d.acos = np.arccos``
57
+
58
+ .. data:: acosd
59
+
60
+ ``c4d.acosd = lambda n: np.arccos(n) * c4d.r2d``
61
+
62
+ .. data:: atan
63
+
64
+ ``c4d.atan = np.arctan``
65
+
66
+ .. data:: atan2
67
+
68
+ ``c4d.atan2 = np.arctan2``
69
+
70
+ .. data:: atan2d
71
+
72
+ ``c4d.atan2d = lambda y, x: np.arctan2(y, x) * c4d.r2d``
73
+
74
+
75
+ .. data:: sqrt
76
+
77
+ ``c4d.sqrt = np.sqrt``
78
+
79
+ .. data:: norm
80
+
81
+ ``c4d.norm = np.linalg.norm``
82
+
83
+
84
+ '''
85
+ sin = np.sin
86
+ sind = lambda n: np.sin(n * c4d.d2r)
87
+ cos = np.cos
88
+ cosd = lambda n: np.cos(n * c4d.d2r)
89
+ tan = np.tan
90
+ tand = lambda n: np.tan(n * c4d.d2r)
91
+
92
+ asin = np.arcsin
93
+ asind = lambda n: np.arcsin(n) * c4d.r2d
94
+ acos = np.arccos
95
+ acosd = lambda n: np.arccos(n) * c4d.r2d
96
+ atan = np.arctan
97
+ atand = lambda n: np.arctan(n) * c4d.r2d
98
+ atan2 = np.arctan2 # atan2(y, x)
99
+ atan2d = lambda y, x: np.arctan2(y, x) * c4d.r2d # atan2(y, x)
100
+
101
+ sqrt = np.sqrt
102
+ norm = np.linalg.norm
103
+
104
+
105
+ # mrandn preserves matlab normal distributed numbers generation
106
+ # XXX it doesnt preserve anything. just a suggested implementation to make in both sides.
107
+ # no more it also doesnt generate normal distribution. see also the test test_mrandn currently disabled.
108
+ mrandn = lambda n = 1: np.sqrt(2) * erfinv(2 * np.random.rand(n) - 1)
109
+
110
+
111
+
112
+ if __name__ == "__main__":
113
+
114
+ import doctest, contextlib, os
115
+ from c4dynamics import IgnoreOutputChecker, cprint
116
+
117
+ # Register the custom OutputChecker
118
+ doctest.OutputChecker = IgnoreOutputChecker
119
+
120
+ tofile = False
121
+ optionflags = doctest.FAIL_FAST
122
+
123
+ if tofile:
124
+ with open(os.path.join('tests', '_out', 'output.txt'), 'w') as f:
125
+ with contextlib.redirect_stdout(f), contextlib.redirect_stderr(f):
126
+ result = doctest.testmod(optionflags = optionflags)
127
+ else:
128
+ result = doctest.testmod(optionflags = optionflags)
129
+
130
+ if result.failed == 0:
131
+ cprint(os.path.basename(__file__) + ": all tests passed!", 'g')
132
+ else:
133
+ print(f"{result.failed}")
134
+
135
+
136
+