tinymovr 2.0.0a2__tar.gz → 2.2.2a1__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 (61) hide show
  1. tinymovr-2.2.2a1/MANIFEST.in +3 -0
  2. {tinymovr-2.0.0a2 → tinymovr-2.2.2a1}/PKG-INFO +1 -1
  3. tinymovr-2.2.2a1/pyproject.toml +14 -0
  4. {tinymovr-2.0.0a2 → tinymovr-2.2.2a1}/setup.py +1 -0
  5. tinymovr-2.2.2a1/tests/test_amt22.py +159 -0
  6. tinymovr-2.2.2a1/tests/test_as5047.py +210 -0
  7. tinymovr-2.2.2a1/tests/test_board.py +423 -0
  8. tinymovr-2.2.2a1/tests/test_board_config.py +167 -0
  9. tinymovr-2.2.2a1/tests/test_dfu.py +106 -0
  10. tinymovr-2.2.2a1/tests/test_hall.py +105 -0
  11. tinymovr-2.2.2a1/tests/test_homing.py +39 -0
  12. tinymovr-2.2.2a1/tests/test_rates.py +66 -0
  13. tinymovr-2.2.2a1/tests/test_simulation.py +52 -0
  14. tinymovr-2.2.2a1/tests/test_traj_planner.py +93 -0
  15. tinymovr-2.2.2a1/tests/test_watchdog.py +48 -0
  16. tinymovr-2.2.2a1/tinymovr/__init__.py +2 -0
  17. tinymovr-2.2.2a1/tinymovr/bus_manager.py +77 -0
  18. tinymovr-2.2.2a1/tinymovr/bus_router.py +152 -0
  19. {tinymovr-2.0.0a2 → tinymovr-2.2.2a1}/tinymovr/channel.py +4 -4
  20. {tinymovr-2.0.0a2 → tinymovr-2.2.2a1}/tinymovr/cli.py +7 -7
  21. {tinymovr-2.0.0a2 → tinymovr-2.2.2a1}/tinymovr/config/__init__.py +1 -0
  22. {tinymovr-2.0.0a2 → tinymovr-2.2.2a1}/tinymovr/config/config.py +30 -12
  23. tinymovr-2.0.0a2/tinymovr/discovery.py → tinymovr-2.2.2a1/tinymovr/device_discovery.py +6 -6
  24. {tinymovr-2.0.0a2 → tinymovr-2.2.2a1}/tinymovr/dfu.py +8 -7
  25. {tinymovr-2.0.0a2 → tinymovr-2.2.2a1}/tinymovr/gui/__init__.py +4 -1
  26. {tinymovr-2.0.0a2 → tinymovr-2.2.2a1}/tinymovr/gui/gui.py +7 -0
  27. {tinymovr-2.0.0a2 → tinymovr-2.2.2a1}/tinymovr/gui/helpers.py +67 -2
  28. {tinymovr-2.0.0a2 → tinymovr-2.2.2a1}/tinymovr/gui/window.py +193 -14
  29. {tinymovr-2.0.0a2 → tinymovr-2.2.2a1}/tinymovr/gui/worker.py +14 -7
  30. tinymovr-2.2.2a1/tinymovr/resources/icons/app_icon.png +0 -0
  31. tinymovr-2.2.2a1/tinymovr/specs/tinymovr_2_1_x.yaml +622 -0
  32. {tinymovr-2.0.0a2 → tinymovr-2.2.2a1}/tinymovr.egg-info/PKG-INFO +1 -1
  33. {tinymovr-2.0.0a2 → tinymovr-2.2.2a1}/tinymovr.egg-info/SOURCES.txt +18 -3
  34. {tinymovr-2.0.0a2 → tinymovr-2.2.2a1}/tinymovr.egg-info/requires.txt +1 -0
  35. tinymovr-2.0.0a2/MANIFEST.in +0 -16
  36. tinymovr-2.0.0a2/tinymovr/__init__.py +0 -1
  37. tinymovr-2.0.0a2/tinymovr/tee.py +0 -132
  38. {tinymovr-2.0.0a2 → tinymovr-2.2.2a1}/README.md +0 -0
  39. {tinymovr-2.0.0a2 → tinymovr-2.2.2a1}/setup.cfg +0 -0
  40. {tinymovr-2.0.0a2 → tinymovr-2.2.2a1}/tinymovr/codec/__init__.py +0 -0
  41. {tinymovr-2.0.0a2 → tinymovr-2.2.2a1}/tinymovr/codec/codec.py +0 -0
  42. {tinymovr-2.0.0a2 → tinymovr-2.2.2a1}/tinymovr/constants.py +0 -0
  43. {tinymovr-2.0.0a2 → tinymovr-2.2.2a1}/tinymovr/gui/widgets.py +0 -0
  44. {tinymovr-2.0.0a2 → tinymovr-2.2.2a1}/tinymovr/resources/icons/call.png +0 -0
  45. {tinymovr-2.0.0a2 → tinymovr-2.2.2a1}/tinymovr/resources/icons/call@2x.png +0 -0
  46. {tinymovr-2.0.0a2 → tinymovr-2.2.2a1}/tinymovr/resources/icons/call_dark.png +0 -0
  47. {tinymovr-2.0.0a2 → tinymovr-2.2.2a1}/tinymovr/resources/icons/call_dark@2x.png +0 -0
  48. {tinymovr-2.0.0a2 → tinymovr-2.2.2a1}/tinymovr/resources/icons/empty.png +0 -0
  49. {tinymovr-2.0.0a2 → tinymovr-2.2.2a1}/tinymovr/resources/icons/empty@2x.png +0 -0
  50. {tinymovr-2.0.0a2 → tinymovr-2.2.2a1}/tinymovr/resources/icons/empty_dark.png +0 -0
  51. {tinymovr-2.0.0a2 → tinymovr-2.2.2a1}/tinymovr/resources/icons/empty_dark@2x.png +0 -0
  52. {tinymovr-2.0.0a2 → tinymovr-2.2.2a1}/tinymovr/specs/dfu_1_0_x.yaml +0 -0
  53. {tinymovr-2.0.0a2 → tinymovr-2.2.2a1}/tinymovr/specs/dfu_1_1_x.yaml +0 -0
  54. {tinymovr-2.0.0a2 → tinymovr-2.2.2a1}/tinymovr/specs/tinymovr_1_3_x.yaml +0 -0
  55. {tinymovr-2.0.0a2 → tinymovr-2.2.2a1}/tinymovr/specs/tinymovr_1_4_x.yaml +0 -0
  56. {tinymovr-2.0.0a2 → tinymovr-2.2.2a1}/tinymovr/specs/tinymovr_1_5_x.yaml +0 -0
  57. {tinymovr-2.0.0a2 → tinymovr-2.2.2a1}/tinymovr/specs/tinymovr_1_6_x.yaml +0 -0
  58. {tinymovr-2.0.0a2 → tinymovr-2.2.2a1}/tinymovr/specs/tinymovr_2_0_x.yaml +0 -0
  59. {tinymovr-2.0.0a2 → tinymovr-2.2.2a1}/tinymovr.egg-info/dependency_links.txt +0 -0
  60. {tinymovr-2.0.0a2 → tinymovr-2.2.2a1}/tinymovr.egg-info/entry_points.txt +0 -0
  61. {tinymovr-2.0.0a2 → tinymovr-2.2.2a1}/tinymovr.egg-info/top_level.txt +0 -0
@@ -0,0 +1,3 @@
1
+ include README.md
2
+ recursive-include tinymovr/resources/icons *.png
3
+ recursive-include tinymovr/specs *.yaml
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: tinymovr
3
- Version: 2.0.0a2
3
+ Version: 2.2.2a1
4
4
  Summary: Tinymovr Studio
5
5
  Home-page: https://github.com/yconst/Tinymovr
6
6
  Author: Yannis Chatzikonstantinou
@@ -0,0 +1,14 @@
1
+
2
+ [build-system]
3
+ requires = ["setuptools"]
4
+ build-backend = "setuptools.build_meta"
5
+
6
+ [tool.pytest.ini_options]
7
+ markers = [
8
+ "hitl_default: marks default hardware in the loop tests",
9
+ "sensor_amt22: marks tests that need the amt22 sensor",
10
+ "sensor_as5047: marks tests that need the as5047 sensor",
11
+ "sensor_hall: marks tests that need a hall effect sensored motor",
12
+ "eol: marks tests for end-of-line testing",
13
+ "dfu: marks tests for dfu testing",
14
+ ]
@@ -60,6 +60,7 @@ setup(
60
60
  "docopt",
61
61
  "flatten-dict",
62
62
  "pint",
63
+ "pretty_errors"
63
64
  ],
64
65
  extras_require={"gui": ["pyside6", "pyqtgraph>=0.13.3"]},
65
66
  entry_points={
@@ -0,0 +1,159 @@
1
+ """
2
+ Tinymovr Board Config Tests
3
+ Copyright Ioannis Chatzikonstantinou 2020-2023
4
+
5
+ Tests saving and loading Tinymovr configuration to/from NVRAM.
6
+
7
+ This program is free software: you can redistribute it and/or modify it under
8
+ the terms of the GNU General Public License as published by the Free Software
9
+ Foundation, either version 3 of the License, or (at your option) any later
10
+ version.
11
+ This program is distributed in the hope that it will be useful, but WITHOUT
12
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
14
+ You should have received a copy of the GNU General Public License along with
15
+ this program. If not, see <http://www.gnu.org/licenses/>.
16
+ """
17
+
18
+ import random
19
+ import time
20
+
21
+ from avlos.unit_field import get_registry
22
+
23
+ import unittest
24
+ import pytest
25
+ from tests import TMTestCase
26
+
27
+ ureg = get_registry()
28
+ A = ureg.ampere
29
+ tick = ureg.ticks
30
+ s = ureg.second
31
+ tsleep = 0.80
32
+
33
+
34
+ class TestAMT22(TMTestCase):
35
+
36
+ @pytest.mark.sensor_amt22
37
+ def test_a_position_control_before_after_save_and_load_config(self):
38
+ """
39
+ Test position control after saving and loading config.
40
+ WARNING: This will perform one NVRAM write and two erase cycles.
41
+ """
42
+ self.check_state(0)
43
+ self.tm.erase_config()
44
+ time.sleep(0.2)
45
+
46
+ self.configure_sensors(self.tm.sensors.setup.external_spi.type.AMT22)
47
+ self.select_sensors(self.tm.sensors.select.position_sensor.connection.ONBOARD, self.tm.sensors.select.position_sensor.connection.EXTERNAL_SPI)
48
+
49
+ self.try_calibrate()
50
+
51
+ self.tm.controller.position.p_gain = 9
52
+ self.tm.controller.velocity.p_gain = 3e-5
53
+ self.tm.controller.velocity.i_gain = 0
54
+ self.tm.controller.velocity.limit = 200000
55
+
56
+ self.tm.controller.position_mode()
57
+ self.check_state(2)
58
+
59
+ for _ in range(10):
60
+ new_pos = random.uniform(-1000, 1000)
61
+ self.tm.controller.position.setpoint = new_pos * tick
62
+ time.sleep(tsleep)
63
+ self.assertAlmostEqual(
64
+ self.tm.sensors.user_frame.position_estimate,
65
+ self.tm.controller.position.setpoint,
66
+ delta=200 * tick,
67
+ )
68
+
69
+ self.tm.controller.idle()
70
+
71
+ time.sleep(0.1)
72
+
73
+ self.tm.save_config()
74
+
75
+ time.sleep(0.2)
76
+
77
+ self.reset_and_wait()
78
+
79
+ self.tm.controller.position_mode()
80
+ self.check_state(2)
81
+
82
+ for _ in range(10):
83
+ new_pos = random.uniform(-1000, 1000)
84
+ self.tm.controller.position.setpoint = new_pos * tick
85
+ time.sleep(tsleep)
86
+ self.assertAlmostEqual(
87
+ self.tm.sensors.user_frame.position_estimate,
88
+ self.tm.controller.position.setpoint,
89
+ delta=200 * tick,
90
+ )
91
+
92
+ self.tm.erase_config()
93
+ time.sleep(0.2)
94
+
95
+ @pytest.mark.sensor_amt22
96
+ def test_b_position_control_following_sensor_change(self):
97
+ """
98
+ Test position control before and after changing sensor connection and type.
99
+ This test will alter the sensor configuration from an external SPI connection
100
+ to an onboard connection, and verify if the position control maintains accuracy.
101
+ """
102
+ self.check_state(0)
103
+ self.tm.erase_config()
104
+ time.sleep(0.2)
105
+
106
+ # Initially configure with external SPI sensor
107
+ self.configure_sensors(self.tm.sensors.setup.external_spi.type.AMT22)
108
+ self.select_sensors(self.tm.sensors.select.position_sensor.connection.ONBOARD, self.tm.sensors.select.position_sensor.connection.EXTERNAL_SPI)
109
+ self.try_calibrate()
110
+
111
+ # Set initial controller gains
112
+ self.tm.controller.position.p_gain = 9
113
+ self.tm.controller.velocity.p_gain = 3e-5
114
+ self.tm.controller.velocity.i_gain = 0
115
+ self.tm.controller.velocity.limit = 200000
116
+
117
+ # Start with external SPI sensor
118
+ self.tm.controller.position_mode()
119
+ self.check_state(2)
120
+
121
+ for _ in range(5):
122
+ new_pos = random.uniform(-1000, 1000)
123
+ self.tm.controller.position.setpoint = new_pos * tick
124
+ time.sleep(tsleep)
125
+ self.assertAlmostEqual(
126
+ self.tm.sensors.user_frame.position_estimate,
127
+ self.tm.controller.position.setpoint,
128
+ delta=200 * tick,
129
+ )
130
+
131
+ self.tm.controller.idle()
132
+ time.sleep(0.1)
133
+
134
+ # Change to onboard sensor
135
+ self.select_sensors(self.tm.sensors.select.position_sensor.connection.ONBOARD, self.tm.sensors.select.position_sensor.connection.ONBOARD)
136
+
137
+ # Re-calibrate with new sensor setup
138
+ self.try_calibrate()
139
+ time.sleep(0.1)
140
+
141
+ self.tm.controller.position_mode()
142
+ self.check_state(2)
143
+
144
+ for _ in range(5):
145
+ new_pos = random.uniform(-10000, 10000)
146
+ self.tm.controller.position.setpoint = new_pos * tick
147
+ time.sleep(tsleep)
148
+ self.assertAlmostEqual(
149
+ self.tm.sensors.user_frame.position_estimate,
150
+ self.tm.controller.position.setpoint,
151
+ delta=2000 * tick,
152
+ )
153
+
154
+ self.tm.erase_config()
155
+ time.sleep(0.2)
156
+
157
+
158
+ if __name__ == "__main__":
159
+ unittest.main()
@@ -0,0 +1,210 @@
1
+ """
2
+ Tinymovr Board Config Tests
3
+ Copyright Ioannis Chatzikonstantinou 2020-2023
4
+
5
+ Tests saving and loading Tinymovr configuration to/from NVRAM.
6
+
7
+ This program is free software: you can redistribute it and/or modify it under
8
+ the terms of the GNU General Public License as published by the Free Software
9
+ Foundation, either version 3 of the License, or (at your option) any later
10
+ version.
11
+ This program is distributed in the hope that it will be useful, but WITHOUT
12
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
14
+ You should have received a copy of the GNU General Public License along with
15
+ this program. If not, see <http://www.gnu.org/licenses/>.
16
+ """
17
+
18
+ import random
19
+ import time
20
+
21
+ from avlos.unit_field import get_registry
22
+
23
+ import unittest
24
+ import pytest
25
+ from tests import TMTestCase
26
+
27
+ ureg = get_registry()
28
+ A = ureg.ampere
29
+ tick = ureg.ticks
30
+ s = ureg.second
31
+ tsleep = 0.50
32
+
33
+
34
+ class TestAS5047(TMTestCase):
35
+
36
+ @pytest.mark.sensor_as5047
37
+ def test_a_position_control_before_after_save_and_load_config(self):
38
+ """
39
+ Test position control after saving and loading config.
40
+ WARNING: This will perform one NVRAM write and two erase cycles.
41
+ """
42
+ self.check_state(0)
43
+ self.tm.erase_config()
44
+ time.sleep(0.2)
45
+
46
+ self.configure_sensors(self.tm.sensors.setup.external_spi.type.AS5047)
47
+ self.select_sensors(self.tm.sensors.select.position_sensor.connection.ONBOARD, self.tm.sensors.select.position_sensor.connection.EXTERNAL_SPI)
48
+
49
+ self.try_calibrate()
50
+
51
+ self.tm.controller.position.p_gain = 9
52
+ self.tm.controller.velocity.p_gain = 2e-5
53
+ self.tm.controller.velocity.i_gain = 0
54
+
55
+ self.tm.controller.position_mode()
56
+ self.check_state(2)
57
+
58
+ for _ in range(10):
59
+ new_pos = random.uniform(-20000, 20000)
60
+ self.tm.controller.position.setpoint = new_pos * tick
61
+ time.sleep(tsleep)
62
+ self.assertAlmostEqual(
63
+ self.tm.sensors.user_frame.position_estimate,
64
+ self.tm.controller.position.setpoint,
65
+ delta=2000 * tick,
66
+ )
67
+
68
+ self.tm.controller.idle()
69
+
70
+ time.sleep(0.1)
71
+
72
+ self.tm.save_config()
73
+
74
+ time.sleep(0.2)
75
+
76
+ self.reset_and_wait()
77
+
78
+ self.tm.controller.position_mode()
79
+ self.check_state(2)
80
+
81
+ for _ in range(10):
82
+ new_pos = random.uniform(-20000, 20000)
83
+ self.tm.controller.position.setpoint = new_pos * tick
84
+ time.sleep(tsleep)
85
+ self.assertAlmostEqual(
86
+ self.tm.sensors.user_frame.position_estimate,
87
+ self.tm.controller.position.setpoint,
88
+ delta=2000 * tick,
89
+ )
90
+
91
+ self.tm.erase_config()
92
+ time.sleep(0.2)
93
+
94
+ @pytest.mark.sensor_as5047
95
+ def test_b_position_control_following_sensor_change(self):
96
+ """
97
+ Test position control before and after changing sensor connection and type.
98
+ This test will alter the sensor configuration from an external SPI connection
99
+ to an onboard connection, and verify if the position control maintains accuracy.
100
+ """
101
+ self.check_state(0)
102
+ self.tm.erase_config()
103
+ time.sleep(0.2)
104
+
105
+ # Initially configure with external SPI sensor
106
+ self.configure_sensors(self.tm.sensors.setup.external_spi.type.AS5047)
107
+ self.select_sensors(self.tm.sensors.select.position_sensor.connection.ONBOARD, self.tm.sensors.select.position_sensor.connection.EXTERNAL_SPI)
108
+ self.try_calibrate()
109
+
110
+ # Set initial controller gains
111
+ self.tm.controller.position.p_gain = 9
112
+ self.tm.controller.velocity.p_gain = 3e-5
113
+ self.tm.controller.velocity.i_gain = 0
114
+ self.tm.controller.velocity.limit = 200000
115
+
116
+ # Start with external SPI sensor
117
+ self.tm.controller.position_mode()
118
+ self.check_state(2)
119
+
120
+ for _ in range(5):
121
+ new_pos = random.uniform(-20000, 20000)
122
+ self.tm.controller.position.setpoint = new_pos * tick
123
+ time.sleep(tsleep)
124
+ self.assertAlmostEqual(
125
+ self.tm.sensors.user_frame.position_estimate,
126
+ self.tm.controller.position.setpoint,
127
+ delta=2000 * tick,
128
+ )
129
+
130
+ self.tm.controller.idle()
131
+ time.sleep(0.1)
132
+
133
+ # Change to onboard sensor
134
+ self.select_sensors(self.tm.sensors.select.position_sensor.connection.ONBOARD, self.tm.sensors.select.position_sensor.connection.ONBOARD)
135
+
136
+ # Re-calibrate with new sensor setup
137
+ self.try_calibrate()
138
+ time.sleep(0.1)
139
+
140
+ self.tm.controller.position_mode()
141
+ self.check_state(2)
142
+
143
+ for _ in range(5):
144
+ new_pos = random.uniform(-20000, 20000)
145
+ self.tm.controller.position.setpoint = new_pos * tick
146
+ time.sleep(tsleep)
147
+ self.assertAlmostEqual(
148
+ self.tm.sensors.user_frame.position_estimate,
149
+ self.tm.controller.position.setpoint,
150
+ delta=2000 * tick,
151
+ )
152
+
153
+ self.tm.erase_config()
154
+ time.sleep(0.2)
155
+
156
+ @pytest.mark.sensor_as5047
157
+ def test_c_position_control_change_baud_rates(self):
158
+ """
159
+ Test position control with external sensor and
160
+ different baud rates.
161
+ """
162
+ self.check_state(0)
163
+ self.tm.erase_config()
164
+ time.sleep(0.2)
165
+
166
+ self.configure_sensors(self.tm.sensors.setup.external_spi.type.AS5047)
167
+ self.select_sensors(self.tm.sensors.select.position_sensor.connection.ONBOARD, self.tm.sensors.select.position_sensor.connection.EXTERNAL_SPI)
168
+
169
+ self.try_calibrate()
170
+
171
+ self.tm.controller.position.p_gain = 9
172
+ self.tm.controller.velocity.p_gain = 2e-5
173
+ self.tm.controller.velocity.i_gain = 0
174
+
175
+ self.tm.controller.position_mode()
176
+ self.check_state(2)
177
+
178
+ for _ in range(10):
179
+ new_pos = random.uniform(-20000, 20000)
180
+ self.tm.controller.position.setpoint = new_pos * tick
181
+ time.sleep(tsleep)
182
+ self.assertAlmostEqual(
183
+ self.tm.sensors.user_frame.position_estimate,
184
+ self.tm.controller.position.setpoint,
185
+ delta=2000 * tick,
186
+ )
187
+
188
+ self.tm.controller.idle()
189
+
190
+ self.tm.sensors.setup.external_spi.rate = "1_5Mbps"
191
+ time.sleep(0.1)
192
+
193
+ self.tm.controller.position_mode()
194
+ self.check_state(2)
195
+
196
+ for _ in range(10):
197
+ new_pos = random.uniform(-20000, 20000)
198
+ self.tm.controller.position.setpoint = new_pos * tick
199
+ time.sleep(tsleep)
200
+ self.assertAlmostEqual(
201
+ self.tm.sensors.user_frame.position_estimate,
202
+ self.tm.controller.position.setpoint,
203
+ delta=2000 * tick,
204
+ )
205
+
206
+ self.tm.controller.idle()
207
+
208
+
209
+ if __name__ == "__main__":
210
+ unittest.main()