motor-python 0.0.4__tar.gz → 0.0.7__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.
@@ -170,3 +170,20 @@ cython_debug/
170
170
  *.egg-info
171
171
 
172
172
  /logs/log_*
173
+
174
+ # Motion capture logs and plots
175
+ data/logs/
176
+
177
+ # Local thesis / working documents that should not go to main
178
+ docs/*.md
179
+ docs/**/*.md
180
+ docs/*.tex
181
+ docs/**/*.tex
182
+ tmp/
183
+
184
+ # Local analysis/workspace artifacts
185
+ .codex
186
+ CSV/
187
+ data/csv_logs/*.csv
188
+ !data/csv_logs/.gitkeep
189
+ repo_tree.py
@@ -0,0 +1,215 @@
1
+ Metadata-Version: 2.4
2
+ Name: motor_python
3
+ Version: 0.0.7
4
+ Summary: CubeMars motor module for Aries exosuits.
5
+ Project-URL: homepage, https://github.com/TUM-Aries-Lab/motor-module
6
+ Author-email: Tsmorz <tony.smoragiewicz@tum.de>, Hannes Nguyen <hannes.nguyen@tum.de>
7
+ License-File: LICENSE
8
+ Requires-Python: <3.14,>=3.11
9
+ Requires-Dist: loguru>=0.7.3
10
+ Requires-Dist: numpy>=2.2.3
11
+ Requires-Dist: pyserial>=3.5
12
+ Requires-Dist: python-can>=4.4.0
13
+ Description-Content-Type: text/markdown
14
+
15
+ # Motor Control Software for Soft Exoskeleton
16
+ [![Coverage Status](https://coveralls.io/repos/github/TUM-Aries-Lab/motor-module/badge.svg?branch=main)](https://coveralls.io/github/TUM-Aries-Lab/motor-module?branch=main)
17
+ ![Docker Image CI](https://github.com/TUM-Aries-Lab/motor-module/actions/workflows/ci.yml/badge.svg)
18
+
19
+ Motor control for the CubeMars AK60-6 actuator module used in Aries soft-exosuit development.
20
+
21
+ ## Current Status
22
+
23
+ - Primary interface: CAN on Jetson Orin Nano via Linux SocketCAN
24
+ - Current maintained CAN path: MIT-only control
25
+ - Supported high-level helpers: `set_position()`, `set_velocity()`, `set_current()`, `stop()`
26
+ - UART support remains available for compatibility and earlier bring-up workflows
27
+
28
+ This repository is the motor-module codebase, not a full exosuit application. Its current focus is a modular actuator-control layer plus the bench-side scripts used to validate it.
29
+
30
+ ## Key Features
31
+
32
+ - Transport-independent motor abstraction through `BaseMotor`
33
+ - Maintained SocketCAN backend for the CubeMars AK60-6
34
+ - MIT-only CAN control path with one consistent command model
35
+ - Background command refresh, feedback decoding, cached state handling, and staged recovery
36
+ - Bench-validation scripts for MIT mode, position stepping, velocity verification, and plotting
37
+
38
+ ## Installation
39
+
40
+ For normal development, testing, and analysis:
41
+
42
+ ```bash
43
+ uv sync --all-groups
44
+ source .venv/bin/activate
45
+ ```
46
+
47
+ If you only want to install the package itself:
48
+
49
+ ```bash
50
+ uv pip install -e .
51
+ ```
52
+
53
+ ## CAN Setup on Jetson Orin Nano
54
+
55
+ ### Recommended: systemd startup
56
+
57
+ Install the tracked `can0.service` once so `can0` comes up automatically on boot:
58
+
59
+ ```bash
60
+ sudo cp can0.service /etc/systemd/system/
61
+ sudo systemctl daemon-reload
62
+ sudo systemctl enable can0.service
63
+ sudo systemctl start can0.service
64
+ ```
65
+
66
+ This brings `can0` up at 1 Mbps with bus-off auto-recovery.
67
+
68
+ Useful checks:
69
+
70
+ ```bash
71
+ systemctl status can0.service
72
+ sudo systemctl restart can0.service
73
+ ip -details link show can0
74
+ ```
75
+
76
+ ### Manual setup
77
+
78
+ If you do not want to use the service, configure the interface manually:
79
+
80
+ ```bash
81
+ sudo ./setup_can.sh
82
+ ```
83
+
84
+ ## Important Hardware Note
85
+
86
+ If the R-Link / UART cable is connected to the motor, CAN commands may be silently ignored even though feedback frames are still visible on the bus. For CAN operation, disconnect the UART cable and then reset the CAN interface.
87
+
88
+ ## Recommended Workflow
89
+
90
+ ### 1. Confirm MIT/CAN communication
91
+
92
+ ```bash
93
+ sudo ./setup_can.sh
94
+ .venv/bin/python scripts/mit_mode_test.py --motor-id 0x03
95
+ ```
96
+
97
+ ### 2. Validate sustained velocity behavior
98
+
99
+ ```bash
100
+ .venv/bin/python scripts/verify_set_velocity.py --motor-id 0x03 --velocity-erpm 3000
101
+ ```
102
+
103
+ ### 3. Run repeated MIT position stepping
104
+
105
+ ```bash
106
+ .venv/bin/python scripts/mit_position_steps.py --motor-id 0x03 --duration 180 --angle-deg 50 --velocity-deg-s 100
107
+ ```
108
+
109
+ ### 4. Generate comparison plots from recorded CSV files
110
+
111
+ ```bash
112
+ .venv/bin/python scripts/plot_graph.py velocity --data-root CSV --out-dir CSV/plots
113
+ .venv/bin/python scripts/plot_graph.py position --data-root CSV --out-dir CSV/plots
114
+ ```
115
+
116
+ ## Python API
117
+
118
+ The default convenience alias is the CAN motor class:
119
+
120
+ ```python
121
+ from motor_python import Motor
122
+
123
+ with Motor(motor_can_id=0x03) as motor:
124
+ motor.enable_mit_mode()
125
+ motor.set_velocity(3000)
126
+ motor.set_position(90.0)
127
+ motor.stop()
128
+ ```
129
+
130
+ For direct access to the specific implementations:
131
+
132
+ ```python
133
+ from motor_python.cube_mars_motor_can import CubeMarsAK606v3CAN
134
+ from motor_python.cube_mars_motor import CubeMarsAK606v3
135
+ ```
136
+
137
+ ### Main CAN lifecycle methods
138
+
139
+ | Method | Purpose |
140
+ | --- | --- |
141
+ | `enable_mit_mode()` | Enter MIT mode |
142
+ | `disable_mit_mode()` | Exit MIT mode |
143
+ | `check_communication()` | Verify that the motor responds on the bus |
144
+ | `get_status()` | Return the latest cached `MotorState` |
145
+ | `close()` | Stop and close transport resources |
146
+
147
+ ### Main CAN control methods
148
+
149
+ | Method | Purpose |
150
+ | --- | --- |
151
+ | `set_position(position_degrees)` | MIT-backed position command |
152
+ | `set_velocity(velocity_erpm, allow_low_speed=False)` | MIT-backed velocity command |
153
+ | `set_current(current_amps)` | Interpreted as MIT torque feedforward |
154
+ | `set_mit_mode(pos_rad, vel_rad_s, kp, kd, torque_ff_nm)` | Direct MIT command |
155
+ | `stop()` | Neutral MIT command and disable |
156
+
157
+ ## Useful Bench Scripts
158
+
159
+ These are the maintained scripts that matter most for the current implementation:
160
+
161
+ | Script | Purpose |
162
+ | --- | --- |
163
+ | `scripts/mit_mode_test.py` | Focused MIT/CAN protocol validation |
164
+ | `scripts/verify_set_velocity.py` | Bench verification of `set_velocity()` |
165
+ | `scripts/mit_position_steps.py` | Long-run MIT position stepping for bench tests |
166
+ | `scripts/plot_graph.py` | Chapter-4-style overlay and summary plots from recorded CSV files |
167
+ | `scripts/diagnose_can.py` | CAN bus diagnostics and recovery support |
168
+ | `scripts/scan_ids.py` | CAN ID discovery |
169
+ | `scripts/reset_degree.py` | Practical MIT recentering helper |
170
+
171
+ Additional exploratory and legacy scripts remain under `scripts/`, but they are not the primary maintained validation path.
172
+
173
+ ## Testing
174
+
175
+ Run unit tests:
176
+
177
+ ```bash
178
+ make test
179
+ ```
180
+
181
+ Run CAN hardware tests:
182
+
183
+ ```bash
184
+ make test-hardware-can
185
+ ```
186
+
187
+ Run all hardware tests:
188
+
189
+ ```bash
190
+ make test-hardware-all
191
+ ```
192
+
193
+ ## Project Structure
194
+
195
+ ```text
196
+ can0.service systemd unit for automatic can0 startup
197
+ setup_can.sh manual CAN setup and reset helper
198
+ src/motor_python/ package source
199
+ scripts/ bench and validation scripts
200
+ tests/ unit and hardware-oriented tests
201
+ data/csv_logs/.gitkeep placeholder for locally generated CSV logs
202
+ Test Rig CAD files/ CAD assets for the bench rig
203
+ ```
204
+
205
+ ## Notes on Scope
206
+
207
+ - The current CAN implementation is MIT-only.
208
+ - Legacy servo transport modes are intentionally not part of the maintained CAN path.
209
+ - The repository includes bench-validation tooling, but not thesis-only notes, temporary files, or local analysis artifacts.
210
+
211
+ ## Run the Package Entry Point
212
+
213
+ ```bash
214
+ uv run python -m motor_python
215
+ ```
@@ -0,0 +1,201 @@
1
+ # Motor Control Software for Soft Exoskeleton
2
+ [![Coverage Status](https://coveralls.io/repos/github/TUM-Aries-Lab/motor-module/badge.svg?branch=main)](https://coveralls.io/github/TUM-Aries-Lab/motor-module?branch=main)
3
+ ![Docker Image CI](https://github.com/TUM-Aries-Lab/motor-module/actions/workflows/ci.yml/badge.svg)
4
+
5
+ Motor control for the CubeMars AK60-6 actuator module used in Aries soft-exosuit development.
6
+
7
+ ## Current Status
8
+
9
+ - Primary interface: CAN on Jetson Orin Nano via Linux SocketCAN
10
+ - Current maintained CAN path: MIT-only control
11
+ - Supported high-level helpers: `set_position()`, `set_velocity()`, `set_current()`, `stop()`
12
+ - UART support remains available for compatibility and earlier bring-up workflows
13
+
14
+ This repository is the motor-module codebase, not a full exosuit application. Its current focus is a modular actuator-control layer plus the bench-side scripts used to validate it.
15
+
16
+ ## Key Features
17
+
18
+ - Transport-independent motor abstraction through `BaseMotor`
19
+ - Maintained SocketCAN backend for the CubeMars AK60-6
20
+ - MIT-only CAN control path with one consistent command model
21
+ - Background command refresh, feedback decoding, cached state handling, and staged recovery
22
+ - Bench-validation scripts for MIT mode, position stepping, velocity verification, and plotting
23
+
24
+ ## Installation
25
+
26
+ For normal development, testing, and analysis:
27
+
28
+ ```bash
29
+ uv sync --all-groups
30
+ source .venv/bin/activate
31
+ ```
32
+
33
+ If you only want to install the package itself:
34
+
35
+ ```bash
36
+ uv pip install -e .
37
+ ```
38
+
39
+ ## CAN Setup on Jetson Orin Nano
40
+
41
+ ### Recommended: systemd startup
42
+
43
+ Install the tracked `can0.service` once so `can0` comes up automatically on boot:
44
+
45
+ ```bash
46
+ sudo cp can0.service /etc/systemd/system/
47
+ sudo systemctl daemon-reload
48
+ sudo systemctl enable can0.service
49
+ sudo systemctl start can0.service
50
+ ```
51
+
52
+ This brings `can0` up at 1 Mbps with bus-off auto-recovery.
53
+
54
+ Useful checks:
55
+
56
+ ```bash
57
+ systemctl status can0.service
58
+ sudo systemctl restart can0.service
59
+ ip -details link show can0
60
+ ```
61
+
62
+ ### Manual setup
63
+
64
+ If you do not want to use the service, configure the interface manually:
65
+
66
+ ```bash
67
+ sudo ./setup_can.sh
68
+ ```
69
+
70
+ ## Important Hardware Note
71
+
72
+ If the R-Link / UART cable is connected to the motor, CAN commands may be silently ignored even though feedback frames are still visible on the bus. For CAN operation, disconnect the UART cable and then reset the CAN interface.
73
+
74
+ ## Recommended Workflow
75
+
76
+ ### 1. Confirm MIT/CAN communication
77
+
78
+ ```bash
79
+ sudo ./setup_can.sh
80
+ .venv/bin/python scripts/mit_mode_test.py --motor-id 0x03
81
+ ```
82
+
83
+ ### 2. Validate sustained velocity behavior
84
+
85
+ ```bash
86
+ .venv/bin/python scripts/verify_set_velocity.py --motor-id 0x03 --velocity-erpm 3000
87
+ ```
88
+
89
+ ### 3. Run repeated MIT position stepping
90
+
91
+ ```bash
92
+ .venv/bin/python scripts/mit_position_steps.py --motor-id 0x03 --duration 180 --angle-deg 50 --velocity-deg-s 100
93
+ ```
94
+
95
+ ### 4. Generate comparison plots from recorded CSV files
96
+
97
+ ```bash
98
+ .venv/bin/python scripts/plot_graph.py velocity --data-root CSV --out-dir CSV/plots
99
+ .venv/bin/python scripts/plot_graph.py position --data-root CSV --out-dir CSV/plots
100
+ ```
101
+
102
+ ## Python API
103
+
104
+ The default convenience alias is the CAN motor class:
105
+
106
+ ```python
107
+ from motor_python import Motor
108
+
109
+ with Motor(motor_can_id=0x03) as motor:
110
+ motor.enable_mit_mode()
111
+ motor.set_velocity(3000)
112
+ motor.set_position(90.0)
113
+ motor.stop()
114
+ ```
115
+
116
+ For direct access to the specific implementations:
117
+
118
+ ```python
119
+ from motor_python.cube_mars_motor_can import CubeMarsAK606v3CAN
120
+ from motor_python.cube_mars_motor import CubeMarsAK606v3
121
+ ```
122
+
123
+ ### Main CAN lifecycle methods
124
+
125
+ | Method | Purpose |
126
+ | --- | --- |
127
+ | `enable_mit_mode()` | Enter MIT mode |
128
+ | `disable_mit_mode()` | Exit MIT mode |
129
+ | `check_communication()` | Verify that the motor responds on the bus |
130
+ | `get_status()` | Return the latest cached `MotorState` |
131
+ | `close()` | Stop and close transport resources |
132
+
133
+ ### Main CAN control methods
134
+
135
+ | Method | Purpose |
136
+ | --- | --- |
137
+ | `set_position(position_degrees)` | MIT-backed position command |
138
+ | `set_velocity(velocity_erpm, allow_low_speed=False)` | MIT-backed velocity command |
139
+ | `set_current(current_amps)` | Interpreted as MIT torque feedforward |
140
+ | `set_mit_mode(pos_rad, vel_rad_s, kp, kd, torque_ff_nm)` | Direct MIT command |
141
+ | `stop()` | Neutral MIT command and disable |
142
+
143
+ ## Useful Bench Scripts
144
+
145
+ These are the maintained scripts that matter most for the current implementation:
146
+
147
+ | Script | Purpose |
148
+ | --- | --- |
149
+ | `scripts/mit_mode_test.py` | Focused MIT/CAN protocol validation |
150
+ | `scripts/verify_set_velocity.py` | Bench verification of `set_velocity()` |
151
+ | `scripts/mit_position_steps.py` | Long-run MIT position stepping for bench tests |
152
+ | `scripts/plot_graph.py` | Chapter-4-style overlay and summary plots from recorded CSV files |
153
+ | `scripts/diagnose_can.py` | CAN bus diagnostics and recovery support |
154
+ | `scripts/scan_ids.py` | CAN ID discovery |
155
+ | `scripts/reset_degree.py` | Practical MIT recentering helper |
156
+
157
+ Additional exploratory and legacy scripts remain under `scripts/`, but they are not the primary maintained validation path.
158
+
159
+ ## Testing
160
+
161
+ Run unit tests:
162
+
163
+ ```bash
164
+ make test
165
+ ```
166
+
167
+ Run CAN hardware tests:
168
+
169
+ ```bash
170
+ make test-hardware-can
171
+ ```
172
+
173
+ Run all hardware tests:
174
+
175
+ ```bash
176
+ make test-hardware-all
177
+ ```
178
+
179
+ ## Project Structure
180
+
181
+ ```text
182
+ can0.service systemd unit for automatic can0 startup
183
+ setup_can.sh manual CAN setup and reset helper
184
+ src/motor_python/ package source
185
+ scripts/ bench and validation scripts
186
+ tests/ unit and hardware-oriented tests
187
+ data/csv_logs/.gitkeep placeholder for locally generated CSV logs
188
+ Test Rig CAD files/ CAD assets for the bench rig
189
+ ```
190
+
191
+ ## Notes on Scope
192
+
193
+ - The current CAN implementation is MIT-only.
194
+ - Legacy servo transport modes are intentionally not part of the maintained CAN path.
195
+ - The repository includes bench-validation tooling, but not thesis-only notes, temporary files, or local analysis artifacts.
196
+
197
+ ## Run the Package Entry Point
198
+
199
+ ```bash
200
+ uv run python -m motor_python
201
+ ```
@@ -0,0 +1,116 @@
1
+ [project]
2
+ name = "motor_python"
3
+ version = "0.0.7"
4
+ description = "CubeMars motor module for Aries exosuits."
5
+ readme = "README.md"
6
+ authors = [{ name = "Tsmorz", email = "tony.smoragiewicz@tum.de"},{ name = "Hannes Nguyen", email = "hannes.nguyen@tum.de" }]
7
+ requires-python = ">=3.11,<3.14"
8
+
9
+ # --- Core dependencies ---
10
+ # The maintained path is the CAN backend, and tests import it in CI.
11
+ dependencies = [
12
+ "numpy>=2.2.3",
13
+ "loguru>=0.7.3",
14
+ "pyserial>=3.5",
15
+ "python-can>=4.4.0",
16
+ ]
17
+
18
+ [dependency-groups]
19
+ dev = [
20
+ "ruff>=0.6.9",
21
+ "mypy>=1.11",
22
+ "pytest>=8.3",
23
+ "pytest-cov>=6.0",
24
+ "pytest-rerunfailures>=15.0",
25
+ "pre-commit>=4.1.0",
26
+ "coveralls>=4.0.1",
27
+ "pyright>=1.1.407",
28
+ ]
29
+ hw = [
30
+ ]
31
+ analysis = [
32
+ "matplotlib>=3.9",
33
+ "scipy>=1.14",
34
+ ]
35
+ no_hw = [
36
+ ]
37
+ [project.urls]
38
+ homepage = "https://github.com/TUM-Aries-Lab/motor-module"
39
+
40
+ [tool.ruff]
41
+ line-length = 88
42
+ fix = true
43
+
44
+ lint.select = [
45
+ "E","F","W","C90","I","N","D","UP","B","S","YTT","Q","PL","RUF","T20","F841","ERA001",
46
+ ]
47
+
48
+ lint.ignore = [
49
+ "D203","D213","E501","N803","N806","D415","S101","E203","E731",
50
+ "D107","PLR2004","S607","S605","S603",
51
+ "RUF002","RUF003", # Unicode × and – in docstrings/comments are intentional
52
+ ]
53
+
54
+ [tool.ruff.lint.extend-per-file-ignores]
55
+ # Lazy subprocess import inside methods is intentional
56
+ # subprocess.run without check= is handled via try/except
57
+ "src/motor_python/can_utils.py" = ["PLC0415", "PLW1510"]
58
+
59
+ # Complexity limit – feedback/refresh loops are inherently complex
60
+ # Too many returns and lazy imports for socket flags
61
+ "src/motor_python/cube_mars_motor_can.py" = ["C901", "PLR0911", "PLC0415"]
62
+
63
+ # Too many return statements in feedback parser
64
+ "src/motor_python/motor_status_parser.py" = ["PLR0911"]
65
+
66
+ # Test helpers may need >5 args for full fixture coverage
67
+ # Pytest fixtures don't need public docstrings
68
+ # Lazy mocks are acceptable in test fixtures
69
+ "tests/*" = ["PLR0913", "D103", "PLC0415"]
70
+ "tests/manual_our_implementation_test.py" = ["T201"]
71
+ "tests/manual_servo_mode_test.py" = ["T201"]
72
+ "scripts/plot_graph.py" = ["PLR0913", "PLR0915"]
73
+
74
+
75
+ [tool.ruff.lint.isort]
76
+ known-first-party = ["motor_python"]
77
+ combine-as-imports = true
78
+
79
+ [tool.ruff.format]
80
+ quote-style = "double"
81
+ indent-style = "space"
82
+ line-ending = "lf"
83
+
84
+ [tool.coverage.run]
85
+ omit = [
86
+ "src/motor_python/examples.py",
87
+ "src/motor_python/examples_can.py",
88
+ "tests/can_test.py",
89
+ "src/motor_python/__main__.py",
90
+ ]
91
+
92
+ [tool.pytest.ini_options]
93
+ markers = [
94
+ "hardware: CAN hardware tests — require motor on can0, NO UART cable (deselect with '-m \"not hardware\"')",
95
+ "hardware_uart: UART/serial hardware tests — require R-Link cable, incompatible with CAN tests",
96
+ ]
97
+ testpaths = ["tests"]
98
+ pythonpath = ["src"]
99
+
100
+ [build-system]
101
+ requires = ["hatchling"]
102
+ build-backend = "hatchling.build"
103
+
104
+ [tool.hatch.metadata]
105
+ allow-direct-references = true
106
+
107
+ # Tell hatchling where the package lives (src layout)
108
+ [tool.hatch.build.targets.wheel]
109
+ packages = ["src/motor_python"]
110
+
111
+ [tool.hatch.build.targets.sdist]
112
+ include = [
113
+ "src/motor_python",
114
+ "README.md",
115
+ "LICENSE",
116
+ ]