motor-python 0.0.4__tar.gz → 0.0.6__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.
- {motor_python-0.0.4 → motor_python-0.0.6}/PKG-INFO +17 -17
- {motor_python-0.0.4 → motor_python-0.0.6}/README.md +15 -15
- {motor_python-0.0.4 → motor_python-0.0.6}/pyproject.toml +2 -9
- {motor_python-0.0.4 → motor_python-0.0.6}/src/motor_python/__init__.py +1 -1
- {motor_python-0.0.4 → motor_python-0.0.6}/src/motor_python/cube_mars_motor.py +6 -5
- {motor_python-0.0.4 → motor_python-0.0.6}/src/motor_python/definitions.py +2 -2
- {motor_python-0.0.4 → motor_python-0.0.6}/src/motor_python/examples.py +6 -6
- {motor_python-0.0.4 → motor_python-0.0.6}/.gitignore +0 -0
- {motor_python-0.0.4 → motor_python-0.0.6}/LICENSE +0 -0
- {motor_python-0.0.4 → motor_python-0.0.6}/src/motor_python/__main__.py +0 -0
- {motor_python-0.0.4 → motor_python-0.0.6}/src/motor_python/motor_status_parser.py +0 -0
- {motor_python-0.0.4 → motor_python-0.0.6}/src/motor_python/utils.py +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: motor_python
|
|
3
|
-
Version: 0.0.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 0.0.6
|
|
4
|
+
Summary: CubeMars motor module for Aries exosuits.
|
|
5
5
|
Project-URL: homepage, https://github.com/TUM-Aries-Lab/motor-module
|
|
6
6
|
Author-email: Tsmorz <tony.smoragiewicz@tum.de>, Hannes <hannes.nguyen@tum.de>
|
|
7
7
|
License-File: LICENSE
|
|
@@ -44,11 +44,13 @@ The package can then be found at: https://pypi.org/project/motor_python
|
|
|
44
44
|
|
|
45
45
|
from loguru import logger
|
|
46
46
|
|
|
47
|
-
from motor_python import
|
|
47
|
+
from motor_python.cube_mars_motor import CubeMarsAK606v3
|
|
48
48
|
|
|
49
49
|
def main() -> None:
|
|
50
50
|
"""Run a simple demonstration."""
|
|
51
|
-
|
|
51
|
+
motor = CubeMarsAK606v3()
|
|
52
|
+
motor.get_status()
|
|
53
|
+
motor.set_position(position_degrees=0.0)
|
|
52
54
|
|
|
53
55
|
if __name__ == "__main__":
|
|
54
56
|
main()
|
|
@@ -59,21 +61,20 @@ if __name__ == "__main__":
|
|
|
59
61
|
uv run python -m motor_python
|
|
60
62
|
```
|
|
61
63
|
|
|
62
|
-
## Testing
|
|
63
|
-
|
|
64
|
-
### Unit Tests (No Hardware Required)
|
|
65
|
-
Run unit tests without hardware (using mocks):
|
|
66
|
-
```bash
|
|
67
|
-
make test # Run unit tests only (no hardware required)
|
|
68
|
-
make test-hardware # Run hardware integration tests (requires motor connected)
|
|
69
|
-
make test-all # Run all tests including hardware tests (full coverage)
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
**Note:** Hardware tests are skipped automatically if motor hardware is not available.
|
|
73
|
-
|
|
74
64
|
## Structure
|
|
75
65
|
<!-- TREE-START -->
|
|
76
66
|
```
|
|
67
|
+
├── Test Rig CAD files
|
|
68
|
+
│ ├── Foot.3mf
|
|
69
|
+
│ ├── Jetson_Mount.3mf
|
|
70
|
+
│ ├── Leg_with_2_IMU's.3mf
|
|
71
|
+
│ ├── Motor_Case.3mf
|
|
72
|
+
│ ├── Rod_Adapter_Jetson.3mf
|
|
73
|
+
│ ├── Rod_Adapter_Motor.3mf
|
|
74
|
+
│ └── Spool_V2.3mf
|
|
75
|
+
├── docs
|
|
76
|
+
│ ├── AK60-6 Manual.pdf
|
|
77
|
+
│ └── Jetson-Orin-Nano-DevKit.pdf
|
|
77
78
|
├── src
|
|
78
79
|
│ └── motor_python
|
|
79
80
|
│ ├── config
|
|
@@ -88,7 +89,6 @@ make test-all # Run all tests including hardware tests (full coverage)
|
|
|
88
89
|
│ ├── __init__.py
|
|
89
90
|
│ ├── conftest.py
|
|
90
91
|
│ ├── cube_mars_motor_test.py
|
|
91
|
-
│ ├── hardware_test.py
|
|
92
92
|
│ ├── motor_status_parser_test.py
|
|
93
93
|
│ └── utils_test.py
|
|
94
94
|
├── .dockerignore
|
|
@@ -31,11 +31,13 @@ The package can then be found at: https://pypi.org/project/motor_python
|
|
|
31
31
|
|
|
32
32
|
from loguru import logger
|
|
33
33
|
|
|
34
|
-
from motor_python import
|
|
34
|
+
from motor_python.cube_mars_motor import CubeMarsAK606v3
|
|
35
35
|
|
|
36
36
|
def main() -> None:
|
|
37
37
|
"""Run a simple demonstration."""
|
|
38
|
-
|
|
38
|
+
motor = CubeMarsAK606v3()
|
|
39
|
+
motor.get_status()
|
|
40
|
+
motor.set_position(position_degrees=0.0)
|
|
39
41
|
|
|
40
42
|
if __name__ == "__main__":
|
|
41
43
|
main()
|
|
@@ -46,21 +48,20 @@ if __name__ == "__main__":
|
|
|
46
48
|
uv run python -m motor_python
|
|
47
49
|
```
|
|
48
50
|
|
|
49
|
-
## Testing
|
|
50
|
-
|
|
51
|
-
### Unit Tests (No Hardware Required)
|
|
52
|
-
Run unit tests without hardware (using mocks):
|
|
53
|
-
```bash
|
|
54
|
-
make test # Run unit tests only (no hardware required)
|
|
55
|
-
make test-hardware # Run hardware integration tests (requires motor connected)
|
|
56
|
-
make test-all # Run all tests including hardware tests (full coverage)
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
**Note:** Hardware tests are skipped automatically if motor hardware is not available.
|
|
60
|
-
|
|
61
51
|
## Structure
|
|
62
52
|
<!-- TREE-START -->
|
|
63
53
|
```
|
|
54
|
+
├── Test Rig CAD files
|
|
55
|
+
│ ├── Foot.3mf
|
|
56
|
+
│ ├── Jetson_Mount.3mf
|
|
57
|
+
│ ├── Leg_with_2_IMU's.3mf
|
|
58
|
+
│ ├── Motor_Case.3mf
|
|
59
|
+
│ ├── Rod_Adapter_Jetson.3mf
|
|
60
|
+
│ ├── Rod_Adapter_Motor.3mf
|
|
61
|
+
│ └── Spool_V2.3mf
|
|
62
|
+
├── docs
|
|
63
|
+
│ ├── AK60-6 Manual.pdf
|
|
64
|
+
│ └── Jetson-Orin-Nano-DevKit.pdf
|
|
64
65
|
├── src
|
|
65
66
|
│ └── motor_python
|
|
66
67
|
│ ├── config
|
|
@@ -75,7 +76,6 @@ make test-all # Run all tests including hardware tests (full coverage)
|
|
|
75
76
|
│ ├── __init__.py
|
|
76
77
|
│ ├── conftest.py
|
|
77
78
|
│ ├── cube_mars_motor_test.py
|
|
78
|
-
│ ├── hardware_test.py
|
|
79
79
|
│ ├── motor_status_parser_test.py
|
|
80
80
|
│ └── utils_test.py
|
|
81
81
|
├── .dockerignore
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "motor_python"
|
|
3
|
-
version = "0.0.
|
|
4
|
-
description = "
|
|
3
|
+
version = "0.0.6"
|
|
4
|
+
description = "CubeMars motor module for Aries exosuits."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
authors = [{ name = "Tsmorz", email = "tony.smoragiewicz@tum.de"},{ name = "Hannes", email = "hannes.nguyen@tum.de" }]
|
|
7
7
|
requires-python = ">=3.11,<3.14"
|
|
@@ -52,13 +52,6 @@ quote-style = "double"
|
|
|
52
52
|
indent-style = "space"
|
|
53
53
|
line-ending = "lf"
|
|
54
54
|
|
|
55
|
-
[tool.pytest.ini_options]
|
|
56
|
-
markers = [
|
|
57
|
-
"hardware: tests that require actual motor hardware (deselect with '-m \"not hardware\"')",
|
|
58
|
-
]
|
|
59
|
-
testpaths = ["tests"]
|
|
60
|
-
pythonpath = ["src"]
|
|
61
|
-
|
|
62
55
|
[build-system]
|
|
63
56
|
requires = ["hatchling"]
|
|
64
57
|
build-backend = "hatchling.build"
|
|
@@ -233,19 +233,20 @@ class CubeMarsAK606v3:
|
|
|
233
233
|
def set_position(self, position_degrees: float) -> None:
|
|
234
234
|
"""Set motor position in degrees.
|
|
235
235
|
|
|
236
|
-
|
|
236
|
+
Hardware limited to approximately ±2147.5° (~6 rotations) due to int32 encoding.
|
|
237
237
|
|
|
238
|
-
:param position_degrees: Target position in degrees
|
|
238
|
+
:param position_degrees: Target position in degrees
|
|
239
239
|
:return: None
|
|
240
240
|
"""
|
|
241
|
+
# Check hardware limits (int32 range)
|
|
241
242
|
if (
|
|
242
243
|
position_degrees > MOTOR_LIMITS.max_position_degrees
|
|
243
244
|
or position_degrees < MOTOR_LIMITS.min_position_degrees
|
|
244
245
|
):
|
|
245
246
|
logger.warning(
|
|
246
|
-
f"Position {position_degrees:.2f}° exceeds limits "
|
|
247
|
-
f"[{MOTOR_LIMITS.min_position_degrees:.
|
|
248
|
-
f"Clamping to
|
|
247
|
+
f"Position {position_degrees:.2f}° exceeds hardware limits "
|
|
248
|
+
f"[{MOTOR_LIMITS.min_position_degrees:.1f}°, {MOTOR_LIMITS.max_position_degrees:.1f}°]. "
|
|
249
|
+
f"Clamping to hardware range."
|
|
249
250
|
)
|
|
250
251
|
position_degrees = np.clip(
|
|
251
252
|
position_degrees,
|
|
@@ -139,8 +139,8 @@ class MotorLimits:
|
|
|
139
139
|
min_current_amps: float = -60.0 # Minimum current in amps
|
|
140
140
|
max_velocity_electrical_rpm: int = 100000 # Maximum velocity in Electrical RPM
|
|
141
141
|
min_velocity_electrical_rpm: int = -100000 # Minimum velocity in Electrical RPM
|
|
142
|
-
max_position_degrees: float =
|
|
143
|
-
min_position_degrees: float = -
|
|
142
|
+
max_position_degrees: float = 2147.483647 # Maximum position based on int32 limit
|
|
143
|
+
min_position_degrees: float = -2147.483648 # Minimum position based on int32 limit
|
|
144
144
|
max_movement_time: float = 5.0 # Maximum movement time cap in seconds
|
|
145
145
|
|
|
146
146
|
|
|
@@ -22,7 +22,7 @@ def run_position_control(
|
|
|
22
22
|
for step in range(num_steps):
|
|
23
23
|
# Sine wave: -max_angle_degrees to +max_angle_degrees over num_steps
|
|
24
24
|
angle = max_angle_degrees * math.sin(step * 2 * math.pi / num_steps)
|
|
25
|
-
motor.set_position(
|
|
25
|
+
motor.set_position(angle)
|
|
26
26
|
time.sleep(0.1)
|
|
27
27
|
|
|
28
28
|
# Query status periodically
|
|
@@ -38,16 +38,16 @@ def run_velocity_control(motor: CubeMarsAK606v3, velocity_erpm: int = 5000) -> N
|
|
|
38
38
|
:return: None
|
|
39
39
|
"""
|
|
40
40
|
logger.info("Forward velocity...")
|
|
41
|
-
motor.set_velocity(velocity_erpm
|
|
41
|
+
motor.set_velocity(velocity_erpm) # Forward
|
|
42
42
|
time.sleep(0.5)
|
|
43
43
|
motor.get_status()
|
|
44
44
|
|
|
45
45
|
logger.info("Reverse velocity...")
|
|
46
|
-
motor.set_velocity(velocity_erpm
|
|
46
|
+
motor.set_velocity(-velocity_erpm) # Reverse
|
|
47
47
|
time.sleep(0.5)
|
|
48
48
|
motor.get_status()
|
|
49
49
|
|
|
50
|
-
motor.set_velocity(
|
|
50
|
+
motor.set_velocity(0) # Stop
|
|
51
51
|
|
|
52
52
|
|
|
53
53
|
def run_duty_cycle_control(motor: CubeMarsAK606v3) -> None:
|
|
@@ -57,7 +57,7 @@ def run_duty_cycle_control(motor: CubeMarsAK606v3) -> None:
|
|
|
57
57
|
:return: None
|
|
58
58
|
"""
|
|
59
59
|
for duty in [0.1, 0.0, -0.1, 0.0]:
|
|
60
|
-
motor.set_duty_cycle(
|
|
60
|
+
motor.set_duty_cycle(duty)
|
|
61
61
|
time.sleep(0.3)
|
|
62
62
|
motor.get_status()
|
|
63
63
|
|
|
@@ -69,7 +69,7 @@ def run_current_control(motor: CubeMarsAK606v3) -> None:
|
|
|
69
69
|
:return: None
|
|
70
70
|
"""
|
|
71
71
|
for current in [1.0, 0.0, -1.0, 0.0]:
|
|
72
|
-
motor.set_current(
|
|
72
|
+
motor.set_current(current)
|
|
73
73
|
time.sleep(0.3)
|
|
74
74
|
motor.get_status()
|
|
75
75
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|