43
43
) * params ["l" ][:, None ]).flatten ()
44
44
)
45
45
46
+ # specify the rest strain
47
+ xi_eq = jnp .zeros ((3 * num_segments ,))
48
+ # by default, set the axial rest strain (local y-axis) along the entire rod to 1.0
49
+ rest_strain_reshaped = xi_eq .reshape ((- 1 , 3 ))
50
+ rest_strain_reshaped = rest_strain_reshaped .at [:, - 1 ].set (1.0 )
51
+ xi_eq = rest_strain_reshaped .flatten ()
52
+ print ("xi_eq:\n " , xi_eq )
53
+
46
54
# activate all strains (i.e. bending, shear, and axial)
47
55
# strain_selector = jnp.ones((3 * num_segments,), dtype=bool)
48
56
strain_selector = jnp .array ([True , False , True ])[None , :].repeat (num_segments , axis = 0 ).flatten ()
49
57
50
58
B_xi , forward_kinematics_fn , dynamical_matrices_fn , auxiliary_fns = (
51
59
pneumatically_actuated_planar_pcs .factory (
52
- num_segments , sym_exp_filepath , strain_selector , # simplified_actuation_mapping=True
60
+ num_segments , sym_exp_filepath , strain_selector = strain_selector , xi_eq = xi_eq , # simplified_actuation_mapping=True
53
61
)
54
62
)
55
63
# jit the functions
59
67
forward_kinematics_fn ,
60
68
auxiliary_fns ["jacobian_fn" ],
61
69
)
62
- print ("A=" , actuation_mapping_fn (params , B_xi , jnp .zeros ((2 * num_segments ,))))
70
+ print ("A=" , actuation_mapping_fn (params , B_xi , xi_eq , jnp .zeros ((2 * num_segments ,))))
63
71
64
72
65
73
def sweep_actuation_mapping ():
66
74
# evaluate the actuation matrix for a straight backbone
67
75
q = jnp .zeros ((2 * num_segments ,))
68
- A = actuation_mapping_fn (params , B_xi , q )
76
+ A = actuation_mapping_fn (params , B_xi , xi_eq , q )
69
77
print ("Evaluating actuation matrix for straight backbone: A =\n " , A )
70
78
71
79
kappa_be_pts = jnp .linspace (- 3 * jnp .pi , 3 * jnp .pi , 500 )
72
80
sigma_ax_pts = jnp .zeros_like (kappa_be_pts )
73
81
q_pts = jnp .stack ([kappa_be_pts , sigma_ax_pts ], axis = - 1 )
74
- A_pts = vmap (actuation_mapping_fn , in_axes = (None , None , 0 ))(params , B_xi , q_pts )
82
+ A_pts = vmap (actuation_mapping_fn , in_axes = (None , None , None , 0 ))(params , B_xi , xi_eq , q_pts )
75
83
# mark the points that are not controllable as the u1 and u2 terms share the same sign
76
84
non_controllable_selector = A_pts [..., 0 , 0 ] * A_pts [..., 0 , 1 ] >= 0.0
77
85
non_controllable_indices = jnp .where (non_controllable_selector )[0 ]
@@ -100,7 +108,7 @@ def sweep_actuation_mapping():
100
108
_params = params .copy ()
101
109
_params ["r" ] = r * jnp .ones ((num_segments ,))
102
110
_params ["r_cham_out" ] = r_cham_out * jnp .ones ((num_segments ,))
103
- A_pts = vmap (actuation_mapping_fn , in_axes = (None , None , 0 ))(_params , B_xi , q_pts )
111
+ A_pts = vmap (actuation_mapping_fn , in_axes = (None , None , None , 0 ))(_params , B_xi , xi_eq , q_pts )
104
112
ax .plot (kappa_be_pts , A_pts [:, 0 , 0 ], label = r"$R = " + str (r ) + "$" )
105
113
ax .set_xlabel (r"$\kappa_\mathrm{be}$ [rad/m]" )
106
114
ax .set_ylabel (r"$\frac{\partial \tau_\mathrm{be}}{\partial u_1}$" )
@@ -117,7 +125,7 @@ def sweep_actuation_mapping():
117
125
q_pts = jnp .stack ([kappa_be_grid .flatten (), sigma_ax_grid .flatten ()], axis = - 1 )
118
126
119
127
# evaluate the actuation mapping on the grid
120
- A_pts = vmap (actuation_mapping_fn , in_axes = (None , None , 0 ))(params , B_xi , q_pts )
128
+ A_pts = vmap (actuation_mapping_fn , in_axes = (None , None , None , 0 ))(params , B_xi , xi_eq , q_pts )
121
129
# reshape A_pts to match the grid shape
122
130
A_grid = A_pts .reshape (kappa_be_grid .shape [:2 ] + A_pts .shape [- 2 :])
123
131
0 commit comments