1
1
import jax
2
2
3
3
jax .config .update ("jax_enable_x64" , True ) # double precision
4
+ from jax import Array
4
5
from jax import numpy as jnp
5
6
import jsrm
6
7
from functools import partial
7
8
from numpy .testing import assert_allclose
8
9
from pathlib import Path
9
10
10
11
from jsrm .systems import planar_pcs , euler_lagrangian
11
- from jsrm import Tolerance
12
+ from jsrm . utils . tolerance import Tolerance
12
13
13
14
14
- def test_planar_pcs_one_segment ():
15
+ def constant_strain_inverse_kinematics_fn (params , xi_eq , chi , s ) -> Array :
16
+ # split the chi vector into x, y, and th0
17
+ px , py , th = chi
18
+ th0 = params ["th0" ].item ()
19
+ print ("th0 = " , th0 )
20
+ # xi = (th - th0) / (2 * s) * jnp.array([
21
+ # 2.0,
22
+ # (jnp.sin(th0)*px+jnp.cos(th0)*py) - (jnp.cos(th0)*px-jnp.sin(th0)*py)*jnp.sin(th-th0)/(jnp.cos(th-th0)-1),
23
+ # -(jnp.cos(th0)*px-jnp.sin(th0)*py) - (jnp.sin(th0)*px+jnp.cos(th0)*py)*jnp.sin(th-th0)/(jnp.cos(th-th0)-1)
24
+ # ])
25
+ xi = (th - th0 ) / (2 * s ) * jnp .array ([
26
+ 2.0 ,
27
+ (- jnp .sin (th0 )* px + jnp .cos (th0 )* py ) - (jnp .cos (th0 )* px + jnp .sin (th0 )* py )* jnp .sin (th - th0 )/ (jnp .cos (th - th0 )- 1 ),
28
+ - (jnp .cos (th0 )* px + jnp .sin (th0 )* py ) - (- jnp .sin (th0 )* px + jnp .cos (th0 )* py )* jnp .sin (th - th0 )/ (jnp .cos (th - th0 )- 1 )
29
+ ])
30
+ q = xi - xi_eq
31
+ return q
32
+
33
+ def test_planar_cs ():
15
34
sym_exp_filepath = (
16
35
Path (jsrm .__file__ ).parent / "symbolic_expressions" / "planar_pcs_ns-1.dill"
17
36
)
@@ -27,8 +46,9 @@ def test_planar_pcs_one_segment():
27
46
# activate all strains (i.e. bending, shear, and axial)
28
47
strain_selector = jnp .ones ((3 ,), dtype = bool )
29
48
49
+ xi_eq = jnp .array ([0.0 , 0.0 , 1.0 ])
30
50
strain_basis , forward_kinematics_fn , dynamical_matrices_fn , auxiliary_fns = (
31
- planar_pcs .factory (sym_exp_filepath , strain_selector )
51
+ planar_pcs .factory (sym_exp_filepath , strain_selector , xi_eq )
32
52
)
33
53
forward_dynamics_fn = partial (
34
54
euler_lagrangian .forward_dynamics , dynamical_matrices_fn
@@ -63,6 +83,25 @@ def test_planar_pcs_one_segment():
63
83
atol = Tolerance .atol (),
64
84
)
65
85
86
+ # test inverse kinematics
87
+ params_ik = params .copy ()
88
+ ik_th0_ls = [- jnp .pi / 2 , - jnp .pi / 4 , 0.0 , jnp .pi / 4 , jnp .pi / 2 ]
89
+ ik_q_ls = [
90
+ jnp .array ([0.1 , 0.0 , 0.0 ]),
91
+ jnp .array ([0.1 , 0.0 , 0.2 ]),
92
+ jnp .array ([0.1 , 0.5 , 0.1 ]),
93
+ jnp .array ([1.0 , 0.5 , 0.2 ]),
94
+ jnp .array ([- 1.0 , 0.0 , 0.0 ]),
95
+ ]
96
+ for ik_th0 in ik_th0_ls :
97
+ params_ik ["th0" ] = jnp .array (ik_th0 )
98
+ for q in ik_q_ls :
99
+ s = params ["l" ][0 ]
100
+ chi = forward_kinematics_fn (params_ik , q = q , s = s )
101
+ q_ik = constant_strain_inverse_kinematics_fn (params_ik , xi_eq , chi , s )
102
+ print ("q = " , q , "q_ik = " , q_ik )
103
+ assert_allclose (q , q_ik , rtol = Tolerance .rtol (), atol = Tolerance .atol ())
104
+
66
105
# test dynamical matrices
67
106
q , q_d = jnp .zeros ((3 ,)), jnp .zeros ((3 ,))
68
107
B , C , G , K , D , A = dynamical_matrices_fn (params , q , q_d )
@@ -85,4 +124,4 @@ def test_planar_pcs_one_segment():
85
124
86
125
87
126
if __name__ == "__main__" :
88
- test_planar_pcs_one_segment ()
127
+ test_planar_cs ()
0 commit comments