moro 0.3.0.dev0__tar.gz → 0.4.0__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 (49) hide show
  1. moro-0.4.0/PKG-INFO +187 -0
  2. moro-0.4.0/README.md +160 -0
  3. moro-0.4.0/moro/__init__.py +41 -0
  4. {moro-0.3.0.dev0 → moro-0.4.0}/moro/abc.py +9 -13
  5. moro-0.4.0/moro/core.py +1304 -0
  6. moro-0.4.0/moro/inverse_kinematics.py +1610 -0
  7. moro-0.4.0/moro/lib.py +1 -0
  8. moro-0.4.0/moro/plotting.py +482 -0
  9. moro-0.4.0/moro/transformations.py +1055 -0
  10. {moro-0.3.0.dev0 → moro-0.4.0}/moro/util.py +9 -3
  11. moro-0.4.0/moro/version.py +1 -0
  12. moro-0.4.0/moro/visualization/__init__.py +30 -0
  13. moro-0.4.0/moro/visualization/data.py +41 -0
  14. moro-0.4.0/moro/visualization/evaluation.py +50 -0
  15. moro-0.4.0/moro/visualization/matplotlib_backend.py +216 -0
  16. moro-0.4.0/moro/visualization/style.py +71 -0
  17. moro-0.4.0/moro/visualization/templates/__init__.py +0 -0
  18. moro-0.4.0/moro/visualization/templates/threejs_animation.html +572 -0
  19. moro-0.4.0/moro/visualization/templates/threejs_common.js +937 -0
  20. moro-0.4.0/moro/visualization/templates/threejs_viewer.html +303 -0
  21. moro-0.4.0/moro/visualization/threejs_backend.py +203 -0
  22. moro-0.4.0/moro/visualization/visualizer.py +54 -0
  23. moro-0.4.0/moro/workspace.py +2 -0
  24. moro-0.4.0/moro.egg-info/PKG-INFO +187 -0
  25. moro-0.4.0/moro.egg-info/SOURCES.txt +33 -0
  26. moro-0.4.0/pyproject.toml +57 -0
  27. moro-0.4.0/setup.cfg +4 -0
  28. moro-0.4.0/tests/test_core.py +478 -0
  29. moro-0.4.0/tests/test_inverse_kinematics.py +1459 -0
  30. moro-0.4.0/tests/test_transformations.py +613 -0
  31. moro-0.4.0/tests/test_visualization.py +815 -0
  32. moro-0.3.0.dev0/PKG-INFO +0 -62
  33. moro-0.3.0.dev0/README.md +0 -32
  34. moro-0.3.0.dev0/moro/__init__.py +0 -25
  35. moro-0.3.0.dev0/moro/core.py +0 -893
  36. moro-0.3.0.dev0/moro/inverse_kinematics.py +0 -149
  37. moro-0.3.0.dev0/moro/lib.py +0 -126
  38. moro-0.3.0.dev0/moro/plotting.py +0 -99
  39. moro-0.3.0.dev0/moro/transformations.py +0 -757
  40. moro-0.3.0.dev0/moro/version.py +0 -1
  41. moro-0.3.0.dev0/moro/ws.py +0 -89
  42. moro-0.3.0.dev0/moro.egg-info/PKG-INFO +0 -62
  43. moro-0.3.0.dev0/moro.egg-info/SOURCES.txt +0 -19
  44. moro-0.3.0.dev0/setup.cfg +0 -7
  45. moro-0.3.0.dev0/setup.py +0 -34
  46. {moro-0.3.0.dev0 → moro-0.4.0}/LICENSE.txt +0 -0
  47. {moro-0.3.0.dev0 → moro-0.4.0}/moro.egg-info/dependency_links.txt +0 -0
  48. {moro-0.3.0.dev0 → moro-0.4.0}/moro.egg-info/requires.txt +0 -0
  49. {moro-0.3.0.dev0 → moro-0.4.0}/moro.egg-info/top_level.txt +0 -0
moro-0.4.0/PKG-INFO ADDED
@@ -0,0 +1,187 @@
1
+ Metadata-Version: 2.4
2
+ Name: moro
3
+ Version: 0.4.0
4
+ Summary: Python library for kinematic and dynamic modeling of robots
5
+ Author-email: Pedro Jorge De Los Santos <delossantosmfq@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/JorgeDeLosSantos/moro
8
+ Project-URL: Repository, https://github.com/JorgeDeLosSantos/moro
9
+ Project-URL: Issues, https://github.com/JorgeDeLosSantos/moro/issues
10
+ Keywords: robotics,kinematics,dynamics
11
+ Classifier: Development Status :: 2 - Pre-Alpha
12
+ Classifier: Intended Audience :: Education
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: Implementation :: CPython
21
+ Requires-Python: >=3.9
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE.txt
24
+ Requires-Dist: sympy
25
+ Requires-Dist: matplotlib
26
+ Dynamic: license-file
27
+
28
+ # moro
29
+
30
+ [![PyPI version](https://img.shields.io/pypi/v/moro.svg)](https://pypi.org/project/moro/)
31
+ [![License](https://img.shields.io/github/license/JorgeDeLosSantos/moro.svg)](https://github.com/JorgeDeLosSantos/moro/blob/master/LICENSE.txt)
32
+
33
+ `moro` is a Python library for symbolic modeling, analysis, and visualization of serial robot manipulators.
34
+
35
+ It is designed primarily for robotics education and for workflows where inspecting the underlying kinematic and dynamic expressions is as important as evaluating them numerically.
36
+
37
+ ## Features
38
+
39
+ * **Robot modeling:** Define serial manipulators with revolute and prismatic joints using Denavit-Hartenberg parameters.
40
+ * **Transformations:** Work with `SO(3)` rotation matrices, `SE(3)` homogeneous transformations, Euler angles, and axis-angle representations.
41
+ * **Forward kinematics:** Compute symbolic end-effector and intermediate-frame transformations.
42
+ * **Differential kinematics:** Compute geometric Jacobians for the end-effector and other points.
43
+ * **Inverse kinematics:** Solve numerical Cartesian position IK using Levenberg-Marquardt, Newton-Raphson, or CCD.
44
+ * **IK trajectories:** Solve ordered sequences of Cartesian position targets using warm-started inverse kinematics.
45
+ * **Dynamics:** Derive symbolic equations of motion and the standard `M(q) qdd + C(q, qd) qd + G(q) = tau` model.
46
+ * **Visualization:** Plot and animate robot configurations using Matplotlib or an interactive Three.js backend.
47
+
48
+ ## Installation
49
+
50
+ Install the latest stable release from PyPI:
51
+
52
+ ```bash
53
+ pip install moro
54
+ ```
55
+
56
+ To install the current development version from the `develop` branch:
57
+
58
+ ```bash
59
+ pip install git+https://github.com/JorgeDeLosSantos/moro.git@develop
60
+ ```
61
+
62
+ `moro` requires Python 3.9 or newer.
63
+
64
+ ## Quick Start
65
+
66
+ The following example creates a symbolic planar 2R manipulator and evaluates its forward kinematics and Jacobian at one configuration:
67
+
68
+ ```python
69
+ from moro import Robot
70
+ from moro.abc import q1, q2, l1, l2
71
+
72
+ robot = Robot(
73
+ (l1, 0, 0, q1, "r"),
74
+ (l2, 0, 0, q2, "r"),
75
+ )
76
+
77
+ T = robot.T
78
+ J = robot.J
79
+
80
+ values = {
81
+ l1: 1.0,
82
+ l2: 1.0,
83
+ q1: 0.5,
84
+ q2: 0.8,
85
+ }
86
+
87
+ T_num = T.subs(values).evalf()
88
+ J_num = J.subs(values).evalf()
89
+ ```
90
+
91
+ The same symbolic model can also be visualized:
92
+
93
+ ```python
94
+ from moro.visualization import RobotVisualizer
95
+
96
+ viz = RobotVisualizer(robot)
97
+ viz.plot(values)
98
+ ```
99
+
100
+ For interactive visualization in a notebook:
101
+
102
+ ```python
103
+ viz.plot(values, backend="threejs")
104
+ ```
105
+
106
+ ## Inverse Kinematics
107
+
108
+ A Cartesian position target can be solved numerically with:
109
+
110
+ ```python
111
+ from moro.inverse_kinematics import solve_position_ik
112
+
113
+ solution = solve_position_ik(
114
+ robot,
115
+ [1.5, 0.5, 0.0],
116
+ q0=[0.1, 0.1],
117
+ parameters={
118
+ l1: 1.0,
119
+ l2: 1.0,
120
+ },
121
+ )
122
+
123
+ if solution.converged:
124
+ print(solution.q)
125
+ else:
126
+ print(solution.message)
127
+ ```
128
+
129
+ Current inverse-kinematics support is focused on Cartesian position. Full-pose IK with orientation constraints is not yet included.
130
+
131
+ ## Dynamics
132
+
133
+ Dynamic models can be built by assigning masses, centers of mass, inertia tensors, and gravity to an existing `Robot` model.
134
+
135
+ For example:
136
+
137
+ ```python
138
+ import sympy as sp
139
+
140
+ from moro.abc import m1, m2, lc1, lc2, g
141
+
142
+ I1, I2 = sp.symbols("I1 I2", positive=True)
143
+
144
+ robot.masses = [m1, m2]
145
+ robot.cm_positions = [
146
+ (-lc1, 0, 0),
147
+ (-lc2, 0, 0),
148
+ ]
149
+ robot.inertia_tensors = [
150
+ sp.diag(0, 0, I1),
151
+ sp.diag(0, 0, I2),
152
+ ]
153
+ robot.gravity = (0, -g, 0)
154
+
155
+ M = robot.inertia_matrix()
156
+ C = robot.coriolis_matrix()
157
+ G = robot.gravity_vector()
158
+
159
+ model = robot.dynamic_model_matrix_form()
160
+ ```
161
+
162
+ The current dynamics API derives symbolic equations of motion and supports inverse-dynamics-style evaluation. Forward dynamics integration is not currently included.
163
+
164
+ ## Documentation
165
+
166
+ The complete documentation is available at:
167
+
168
+ https://jorgedelossantos.github.io/moro/
169
+
170
+ It includes:
171
+
172
+ * Getting Started guides;
173
+ * a practical User Guide;
174
+ * complete worked examples;
175
+ * API Reference;
176
+ * mathematical Theory notes;
177
+ * contributor documentation and naming conventions.
178
+
179
+ ## Roadmap
180
+
181
+ Want to know what may come next? See the [Moro Roadmap Wiki](https://github.com/JorgeDeLosSantos/moro/wiki/Roadmap).
182
+
183
+ ## Bug Reports and Contributions
184
+
185
+ If you encounter a bug, have a question, or want to request a feature, please open an issue in the [GitHub Issue Tracker](https://github.com/JorgeDeLosSantos/moro/issues).
186
+
187
+ Contributions are welcome. See the contributor documentation included in the project documentation for the recommended development workflow.
moro-0.4.0/README.md ADDED
@@ -0,0 +1,160 @@
1
+ # moro
2
+
3
+ [![PyPI version](https://img.shields.io/pypi/v/moro.svg)](https://pypi.org/project/moro/)
4
+ [![License](https://img.shields.io/github/license/JorgeDeLosSantos/moro.svg)](https://github.com/JorgeDeLosSantos/moro/blob/master/LICENSE.txt)
5
+
6
+ `moro` is a Python library for symbolic modeling, analysis, and visualization of serial robot manipulators.
7
+
8
+ It is designed primarily for robotics education and for workflows where inspecting the underlying kinematic and dynamic expressions is as important as evaluating them numerically.
9
+
10
+ ## Features
11
+
12
+ * **Robot modeling:** Define serial manipulators with revolute and prismatic joints using Denavit-Hartenberg parameters.
13
+ * **Transformations:** Work with `SO(3)` rotation matrices, `SE(3)` homogeneous transformations, Euler angles, and axis-angle representations.
14
+ * **Forward kinematics:** Compute symbolic end-effector and intermediate-frame transformations.
15
+ * **Differential kinematics:** Compute geometric Jacobians for the end-effector and other points.
16
+ * **Inverse kinematics:** Solve numerical Cartesian position IK using Levenberg-Marquardt, Newton-Raphson, or CCD.
17
+ * **IK trajectories:** Solve ordered sequences of Cartesian position targets using warm-started inverse kinematics.
18
+ * **Dynamics:** Derive symbolic equations of motion and the standard `M(q) qdd + C(q, qd) qd + G(q) = tau` model.
19
+ * **Visualization:** Plot and animate robot configurations using Matplotlib or an interactive Three.js backend.
20
+
21
+ ## Installation
22
+
23
+ Install the latest stable release from PyPI:
24
+
25
+ ```bash
26
+ pip install moro
27
+ ```
28
+
29
+ To install the current development version from the `develop` branch:
30
+
31
+ ```bash
32
+ pip install git+https://github.com/JorgeDeLosSantos/moro.git@develop
33
+ ```
34
+
35
+ `moro` requires Python 3.9 or newer.
36
+
37
+ ## Quick Start
38
+
39
+ The following example creates a symbolic planar 2R manipulator and evaluates its forward kinematics and Jacobian at one configuration:
40
+
41
+ ```python
42
+ from moro import Robot
43
+ from moro.abc import q1, q2, l1, l2
44
+
45
+ robot = Robot(
46
+ (l1, 0, 0, q1, "r"),
47
+ (l2, 0, 0, q2, "r"),
48
+ )
49
+
50
+ T = robot.T
51
+ J = robot.J
52
+
53
+ values = {
54
+ l1: 1.0,
55
+ l2: 1.0,
56
+ q1: 0.5,
57
+ q2: 0.8,
58
+ }
59
+
60
+ T_num = T.subs(values).evalf()
61
+ J_num = J.subs(values).evalf()
62
+ ```
63
+
64
+ The same symbolic model can also be visualized:
65
+
66
+ ```python
67
+ from moro.visualization import RobotVisualizer
68
+
69
+ viz = RobotVisualizer(robot)
70
+ viz.plot(values)
71
+ ```
72
+
73
+ For interactive visualization in a notebook:
74
+
75
+ ```python
76
+ viz.plot(values, backend="threejs")
77
+ ```
78
+
79
+ ## Inverse Kinematics
80
+
81
+ A Cartesian position target can be solved numerically with:
82
+
83
+ ```python
84
+ from moro.inverse_kinematics import solve_position_ik
85
+
86
+ solution = solve_position_ik(
87
+ robot,
88
+ [1.5, 0.5, 0.0],
89
+ q0=[0.1, 0.1],
90
+ parameters={
91
+ l1: 1.0,
92
+ l2: 1.0,
93
+ },
94
+ )
95
+
96
+ if solution.converged:
97
+ print(solution.q)
98
+ else:
99
+ print(solution.message)
100
+ ```
101
+
102
+ Current inverse-kinematics support is focused on Cartesian position. Full-pose IK with orientation constraints is not yet included.
103
+
104
+ ## Dynamics
105
+
106
+ Dynamic models can be built by assigning masses, centers of mass, inertia tensors, and gravity to an existing `Robot` model.
107
+
108
+ For example:
109
+
110
+ ```python
111
+ import sympy as sp
112
+
113
+ from moro.abc import m1, m2, lc1, lc2, g
114
+
115
+ I1, I2 = sp.symbols("I1 I2", positive=True)
116
+
117
+ robot.masses = [m1, m2]
118
+ robot.cm_positions = [
119
+ (-lc1, 0, 0),
120
+ (-lc2, 0, 0),
121
+ ]
122
+ robot.inertia_tensors = [
123
+ sp.diag(0, 0, I1),
124
+ sp.diag(0, 0, I2),
125
+ ]
126
+ robot.gravity = (0, -g, 0)
127
+
128
+ M = robot.inertia_matrix()
129
+ C = robot.coriolis_matrix()
130
+ G = robot.gravity_vector()
131
+
132
+ model = robot.dynamic_model_matrix_form()
133
+ ```
134
+
135
+ The current dynamics API derives symbolic equations of motion and supports inverse-dynamics-style evaluation. Forward dynamics integration is not currently included.
136
+
137
+ ## Documentation
138
+
139
+ The complete documentation is available at:
140
+
141
+ https://jorgedelossantos.github.io/moro/
142
+
143
+ It includes:
144
+
145
+ * Getting Started guides;
146
+ * a practical User Guide;
147
+ * complete worked examples;
148
+ * API Reference;
149
+ * mathematical Theory notes;
150
+ * contributor documentation and naming conventions.
151
+
152
+ ## Roadmap
153
+
154
+ Want to know what may come next? See the [Moro Roadmap Wiki](https://github.com/JorgeDeLosSantos/moro/wiki/Roadmap).
155
+
156
+ ## Bug Reports and Contributions
157
+
158
+ If you encounter a bug, have a question, or want to request a feature, please open an issue in the [GitHub Issue Tracker](https://github.com/JorgeDeLosSantos/moro/issues).
159
+
160
+ Contributions are welcome. See the contributor documentation included in the project documentation for the recommended development workflow.
@@ -0,0 +1,41 @@
1
+ """
2
+ Numython R&D, (c) 2026
3
+ Moro is a Python library for kinematic and dynamic modeling of serial robots.
4
+ This library has been designed, mainly, for academic and research purposes,
5
+ using SymPy as base library.
6
+ """
7
+ from .version import __version__
8
+
9
+ from .core import Robot
10
+ from .util import enable_vprinting
11
+ from .transformations import (
12
+ rotx, roty, rotz,
13
+ rot2eul, eul2rot,
14
+ axa2rot, rot2axa,
15
+ htmtra, htmrot,
16
+ rot2htm, rt2htm,
17
+ htm2rot, htm2tra,
18
+ invhtm,
19
+ dh
20
+ )
21
+
22
+ __all__ = [
23
+ "__version__",
24
+ "Robot",
25
+ "enable_vprinting",
26
+ "rotx",
27
+ "roty",
28
+ "rotz",
29
+ "rot2eul",
30
+ "eul2rot",
31
+ "axa2rot",
32
+ "rot2axa",
33
+ "htmtra",
34
+ "htmrot",
35
+ "rot2htm",
36
+ "rt2htm",
37
+ "htm2rot",
38
+ "htm2tra",
39
+ "invhtm",
40
+ "dh"
41
+ ]
@@ -3,17 +3,15 @@ from sympy.physics.mechanics import dynamicsymbols
3
3
 
4
4
  t = symbols("t") # time
5
5
  q1,q2,q3,q4,q5,q6 = dynamicsymbols('q_1:7') # joint variables
6
- q1p,q2p,q3p,q4p,q5p,q6p = [q.diff(t) for q in (q1,q2,q3,q4,q5,q6)] # joint velocities
7
- q1pp,q2pp,q3pp,q4pp,q5pp,q6pp = [qp.diff(t) for qp in (q1p,q2p,q3p,q4p,q5p,q6p)] # joint accelerations
8
- t1,t2,t3,t4,t5,t6 = symbols('theta_1:7', real=True) # theta parameter
6
+ qd1,qd2,qd3,qd4,qd5,qd6 = [q.diff(t) for q in (q1,q2,q3,q4,q5,q6)] # joint velocities
7
+ qdd1,qdd2,qdd3,qdd4,qdd5,qdd6 = [qd.diff(t) for qd in (qd1,qd2,qd3,qd4,qd5,qd6)] # joint accelerations
8
+ theta1,theta2,theta3,theta4,theta5,theta6 = symbols('theta_1:7', real=True) # theta parameter
9
9
  l1,l2,l3,l4,l5,l6 = symbols('l_1:7', real=True) # parameters for constant lengths of the robot
10
10
  lc1,lc2,lc3,lc4,lc5,lc6 = symbols('l_c1:7', real=True) # parameters for center of mass location
11
11
  d1,d2,d3,d4,d5,d6 = symbols('d_1:7', real=True) # for constant lengths of the robot
12
12
  m1,m2,m3,m4,m5,m6 = symbols('m_1:7', real=True) # for mass symbols
13
13
  a1,a2,a3,a4,a5,a6 = symbols('a_1:7', real=True) # for constant lengths of the robot
14
- x0,x1,x2,x3,x4,x5,x6 = symbols("x_0:7", real=True)
15
- y0,y1,y2,y3,y4,y5,y6 = symbols("y_0:7", real=True)
16
- z0,z1,z2,z3,z4,z5,z6 = symbols("z_0:7", real=True)
14
+ alpha1,alpha2,alpha3,alpha4,alpha5,alpha6 = symbols('alpha_1:7', real=True) # for DH parameters
17
15
  g = symbols("g") # gravity
18
16
  tau1,tau2,tau3,tau4,tau5,tau6 = symbols("tau_1:7", real=True) # for generalized forces/torques
19
17
 
@@ -25,20 +23,18 @@ xi,omicron,rho,sigma = symbols("xi,omicron,rho,sigma", real=True)
25
23
  tau,upsilon,phi,chi = symbols("tau,upsilon,phi,chi", real=True)
26
24
  psi,omega = symbols("psi,omega", real=True)
27
25
 
28
- # ~ del pi # Delete "pi" symbolic variable -> conflict with pi number
26
+
29
27
  available_symvars = [g,t,
30
28
  q1,q2,q3,q4,q5,q6,
31
- q1p,q2p,q3p,q4p,q5p,q6p,
32
- q1pp,q2pp,q3pp,q4pp,q5pp,q6pp,
33
- t1,t2,t3,t4,t5,t6,
29
+ qd1,qd2,qd3,qd4,qd5,qd6,
30
+ qdd1,qdd2,qdd3,qdd4,qdd5,qdd6,
31
+ theta1,theta2,theta3,theta4,theta5,theta6,
32
+ alpha1,alpha2,alpha3,alpha4,alpha5,alpha6,
34
33
  l1,l2,l3,l4,l5,l6,
35
34
  lc1,lc2,lc3,lc4,lc5,lc6,
36
35
  d1,d2,d3,d4,d5,d6,
37
36
  m1,m2,m3,m4,m5,m6,
38
37
  a1,a2,a3,a4,a5,a6,
39
- x0,x1,x2,x3,x4,x5,x6,
40
- y0,y1,y2,y3,y4,y5,y6,
41
- z0,z1,z2,z3,z4,z5,z6,
42
38
  alpha,beta,gamma,delta,
43
39
  epsilon,zeta,eta,theta,
44
40
  iota,kappa,mu,nu,