rlmf 0.1.0__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.
@@ -0,0 +1,307 @@
1
+ Metadata-Version: 2.4
2
+ Name: rlmf
3
+ Version: 0.1.0
4
+ Summary: Robot Locomotion & Morphology Framework — universal legged-robot API
5
+ Project-URL: Homepage, https://github.com/Wafula_Ian01/rlmf
6
+ Project-URL: Documentation, https://github.com/Wafula_Ian01/rlmf#readme
7
+ Project-URL: Repository, https://github.com/Wafula_Ian01/rlmf.git
8
+ Project-URL: Bug Tracker, https://github.com/Wafula_Ian01/rlmf/issues
9
+ Author-email: Wafula Ian Elmer <ianwelmer01@gmail.com>
10
+ License: MIT
11
+ License-File: LICENSE
12
+ Keywords: gait,hexapod,inverse kinematics,locomotion,quadruped,robotics,servo
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Intended Audience :: Education
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Topic :: Scientific/Engineering
23
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
24
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
25
+ Requires-Python: >=3.10
26
+ Requires-Dist: pyyaml>=6.0
27
+ Provides-Extra: dev
28
+ Requires-Dist: build>=1.2; extra == 'dev'
29
+ Requires-Dist: hatchling>=1.24; extra == 'dev'
30
+ Requires-Dist: mypy>=1.10; extra == 'dev'
31
+ Requires-Dist: pytest-cov>=5.0; extra == 'dev'
32
+ Requires-Dist: pytest>=8.0; extra == 'dev'
33
+ Requires-Dist: ruff>=0.4; extra == 'dev'
34
+ Requires-Dist: twine>=5.1; extra == 'dev'
35
+ Provides-Extra: pi
36
+ Requires-Dist: adafruit-circuitpython-servokit>=1.3; extra == 'pi'
37
+ Requires-Dist: gpiozero>=2.0; extra == 'pi'
38
+ Requires-Dist: pigpio>=1.78; extra == 'pi'
39
+ Description-Content-Type: text/markdown
40
+
41
+ # rlmf — Robot Locomotion & Morphology Framework
42
+
43
+ [![PyPI](https://img.shields.io/pypi/v/rlmf)](https://pypi.org/project/rlmf/)
44
+ [![Python](https://img.shields.io/pypi/pyversions/rlmf)](https://pypi.org/project/rlmf/)
45
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
46
+ [![Tests](https://img.shields.io/badge/tests-passing-brightgreen)]()
47
+
48
+ A universal robot body model and locomotion API.
49
+ Define any legged robot in YAML, then call `robot.walk()`.
50
+
51
+ ```python
52
+ from rlmf import Robot
53
+
54
+ robot = Robot.load("hexapod.yaml")
55
+ robot.walk()
56
+ robot.turn_left(45)
57
+ robot.climb()
58
+ robot.follow_path([(0.5, 0), (0.5, 0.5), (0, 0.5)])
59
+ ```
60
+
61
+ The API is **identical** regardless of morphology — 4-leg, 6-leg, 8-leg, 12-leg.
62
+ No gait code. No IK math. No synchronization logic. No motor coordination code.
63
+
64
+ ---
65
+
66
+ ## Installation
67
+
68
+ ```bash
69
+ pip install rlmf
70
+ ```
71
+
72
+ With Raspberry Pi hardware support (PCA9685 + GPIO servos):
73
+
74
+ ```bash
75
+ pip install "rlmf[pi]"
76
+ ```
77
+
78
+ ---
79
+
80
+ ## Quickstart
81
+
82
+ ```python
83
+ from rlmf import Robot
84
+ import rlmf.robots as robots
85
+
86
+ # Use a bundled robot definition
87
+ robot = Robot.load(robots.get("hexapod"))
88
+
89
+ # Or load your own YAML
90
+ robot = Robot.load("my_robot.yaml")
91
+
92
+ # Behaviours — same API for any morphology
93
+ robot.walk()
94
+ robot.turn_left(45)
95
+ robot.turn_right(30)
96
+ robot.climb()
97
+ robot.stop()
98
+ robot.follow_path([(0.5, 0.0), (0.5, 0.5)])
99
+
100
+ # Low-level access
101
+ robot.reach("leg_0", (0.20, 0.05, -0.10)) # IK to world target
102
+ robot.move_joint("leg_0.hip", 30.0) # direct joint control
103
+ ```
104
+
105
+ ---
106
+
107
+ ## Morphology Description Language
108
+
109
+ Define any robot in YAML — the framework handles the rest:
110
+
111
+ ```yaml
112
+ name: HexaBot
113
+ body:
114
+ segments: [thorax]
115
+ length: 0.30
116
+ width: 0.18
117
+ height: 0.09
118
+ limbs:
119
+ - type: leg
120
+ count: 6
121
+ joints:
122
+ hip: {min: -90, max: 90}
123
+ knee: {min: 0, max: 120}
124
+ ankle: {min: -45, max: 45}
125
+ segment_lengths: [0.07, 0.12, 0.10]
126
+ physics:
127
+ mass: 1.2kg
128
+ ```
129
+
130
+ After loading, the full model is immediately introspectable:
131
+
132
+ ```python
133
+ robot.topology.family # "hexapod"
134
+ robot.topology.limb_count # 6
135
+ robot.topology.total_joints # 18
136
+ robot.mass # 1.2
137
+ robot.limbs # List[Limb]
138
+ robot.joints # Dict[str, JointDef]
139
+ ```
140
+
141
+ ---
142
+
143
+ ## Bundled robots
144
+
145
+ ```python
146
+ import rlmf.robots as robots
147
+
148
+ robots.list_robots() # ['centipede', 'hexapod', 'quadruped', 'spider']
149
+ path = robots.get("hexapod") # Path to bundled hexapod.yaml
150
+ ```
151
+
152
+ ---
153
+
154
+ ## Architecture
155
+
156
+ ```
157
+ User API robot.walk() / robot.turn_left() / robot.climb()
158
+
159
+ Gait Engine TripodGait / WaveGait / RippleGait / TrotGait
160
+
161
+ Kinematics solve_ik() / solve_fk() per limb
162
+
163
+ Balance Engine support polygon · stability margin · tip risk
164
+
165
+ Motor Layer SimulatedDriver / PCA9685 / your hardware
166
+ ```
167
+
168
+ ### Gait engine
169
+
170
+ | Gait | Class | Best for | Duty factor |
171
+ |------|-------|----------|-------------|
172
+ | tripod | `TripodGait` | hexapods, fast walking | 0.50 |
173
+ | wave | `WaveGait` | any, climbing | 0.83 |
174
+ | ripple | `RippleGait` | octopods, medium speed | 0.67 |
175
+ | trot | `TrotGait` | quadrupeds | 0.50 |
176
+
177
+ Gait selection is automatic — `robot.walk()` picks the right pattern for your morphology.
178
+ Override it when needed:
179
+
180
+ ```python
181
+ from rlmf import select_gait, TrotGait
182
+
183
+ gait = select_gait("hexapod", "climb") # → WaveGait
184
+ frames = robot.get_gait_frames("ripple", num_frames=60)
185
+ ```
186
+
187
+ ### Balance engine
188
+
189
+ ```python
190
+ state = robot.balance_state()
191
+
192
+ state.center_of_mass # (x, y, z) world space
193
+ state.support_polygon # convex hull of stance feet
194
+ state.stability_margin # metres to nearest polygon edge (>0 = stable)
195
+ state.is_stable # bool
196
+ state.tip_risk # 0.0 (safe) … 1.0 (falling)
197
+ ```
198
+
199
+ ### Motor abstraction
200
+
201
+ Swap the hardware driver without touching any robot code:
202
+
203
+ ```python
204
+ from rlmf import Robot, MotorAbstractionLayer
205
+ from my_hardware import MyServoDriver # your implementation
206
+
207
+ robot = Robot(
208
+ Robot.load("hexapod.yaml")._model,
209
+ motor_layer=MotorAbstractionLayer(driver=MyServoDriver()),
210
+ )
211
+ robot.walk() # drives your hardware
212
+ ```
213
+
214
+ Implement `MotorDriver` for any servo bus:
215
+
216
+ ```python
217
+ from rlmf import MotorDriver
218
+
219
+ class MyDriver(MotorDriver):
220
+ def set_angle(self, joint_id, angle_deg, speed=1.0): ...
221
+ def get_angle(self, joint_id) -> float: ...
222
+ def enable(self, joint_id): ...
223
+ def disable(self, joint_id): ...
224
+ ```
225
+
226
+ ---
227
+
228
+ ## CLI
229
+
230
+ ```bash
231
+ rlmf robots # list bundled robots
232
+ rlmf describe hexapod # print topology
233
+ rlmf describe path/to/mybot.yaml # your own robot
234
+ rlmf walk hexapod --gait wave # simulate gait, print stats
235
+ rlmf balance quadruped # print balance state
236
+ ```
237
+
238
+ ---
239
+
240
+ ## Raspberry Pi deployment
241
+
242
+ Install with hardware extras:
243
+
244
+ ```bash
245
+ pip install "rlmf[pi]"
246
+ ```
247
+
248
+ Wire a PCA9685 to the Pi over I2C, then:
249
+
250
+ ```python
251
+ from adafruit_servokit import ServoKit
252
+ from rlmf import Robot, MotorAbstractionLayer
253
+ from rlmf.motors import MotorDriver
254
+
255
+ class PCA9685Driver(MotorDriver):
256
+ def __init__(self):
257
+ self._kit = ServoKit(channels=16)
258
+ self._map = {}
259
+
260
+ def assign(self, joint_id, channel):
261
+ self._map[joint_id] = channel
262
+
263
+ def set_angle(self, joint_id, angle_deg, speed=1.0):
264
+ ch = self._map.get(joint_id)
265
+ if ch is not None:
266
+ self._kit.servo[ch].angle = max(0, min(180, angle_deg + 90))
267
+
268
+ def get_angle(self, joint_id): return 0.0
269
+ def enable(self, joint_id): pass
270
+ def disable(self, joint_id): pass
271
+
272
+ driver = PCA9685Driver()
273
+ driver.assign("leg_0.hip", 0)
274
+ # … assign all 18 joints …
275
+
276
+ import rlmf.robots as robots
277
+ robot = Robot(
278
+ Robot.load(robots.get("hexapod"))._model,
279
+ motor_layer=MotorAbstractionLayer(driver=driver),
280
+ )
281
+ robot.walk() # moves physical servos
282
+ ```
283
+
284
+ ---
285
+
286
+ ## Roadmap
287
+
288
+ - **v0.1** — Phase 1: 3–12 leg robots, four gait patterns, analytical IK, balance engine, motor abstraction
289
+ - **v0.2** — Phase 2: biped support, dynamic balance, weight shifting, fall recovery
290
+ - **v0.3** — Phase 3: arbitrary morphologies, terrain adaptation, path planning
291
+
292
+ ---
293
+
294
+ ## Development
295
+
296
+ ```bash
297
+ git clone https://github.com/Wafula_Ian01/rlmf
298
+ cd rlmf
299
+ pip install -e ".[dev]"
300
+ pytest
301
+ ```
302
+
303
+ ---
304
+
305
+ ## License
306
+
307
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,5 @@
1
+ rlmf-0.1.0.dist-info/METADATA,sha256=9Yqhr_baLPBHZL-JtQ0ILZl1L1NvgwPBwx5QwCJKspg,8053
2
+ rlmf-0.1.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
3
+ rlmf-0.1.0.dist-info/entry_points.txt,sha256=4E05XVA_bXoF70yq8Q913pbn8woVYrJg6ElIFoVxCTY,40
4
+ rlmf-0.1.0.dist-info/licenses/LICENSE,sha256=AHDmKS0ZzvxZ7hzCAM-W-uds-RQhJfyKEBx2F-ba0OQ,1073
5
+ rlmf-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.29.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ rlmf = rlmf._cli:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Wafula Ian Elmer
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.