4343 ) * params ["l" ][:, None ]).flatten ()
4444)
4545
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+
4654# activate all strains (i.e. bending, shear, and axial)
4755# strain_selector = jnp.ones((3 * num_segments,), dtype=bool)
4856strain_selector = jnp .array ([True , False , True ])[None , :].repeat (num_segments , axis = 0 ).flatten ()
4957
5058B_xi , forward_kinematics_fn , dynamical_matrices_fn , auxiliary_fns = (
5159 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
5361 )
5462)
5563# jit the functions
5967 forward_kinematics_fn ,
6068 auxiliary_fns ["jacobian_fn" ],
6169)
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 ,))))
6371
6472
6573def sweep_actuation_mapping ():
6674 # evaluate the actuation matrix for a straight backbone
6775 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 )
6977 print ("Evaluating actuation matrix for straight backbone: A =\n " , A )
7078
7179 kappa_be_pts = jnp .linspace (- 3 * jnp .pi , 3 * jnp .pi , 500 )
7280 sigma_ax_pts = jnp .zeros_like (kappa_be_pts )
7381 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 )
7583 # mark the points that are not controllable as the u1 and u2 terms share the same sign
7684 non_controllable_selector = A_pts [..., 0 , 0 ] * A_pts [..., 0 , 1 ] >= 0.0
7785 non_controllable_indices = jnp .where (non_controllable_selector )[0 ]
@@ -100,7 +108,7 @@ def sweep_actuation_mapping():
100108 _params = params .copy ()
101109 _params ["r" ] = r * jnp .ones ((num_segments ,))
102110 _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 )
104112 ax .plot (kappa_be_pts , A_pts [:, 0 , 0 ], label = r"$R = " + str (r ) + "$" )
105113 ax .set_xlabel (r"$\kappa_\mathrm{be}$ [rad/m]" )
106114 ax .set_ylabel (r"$\frac{\partial \tau_\mathrm{be}}{\partial u_1}$" )
@@ -117,7 +125,7 @@ def sweep_actuation_mapping():
117125 q_pts = jnp .stack ([kappa_be_grid .flatten (), sigma_ax_grid .flatten ()], axis = - 1 )
118126
119127 # 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 )
121129 # reshape A_pts to match the grid shape
122130 A_grid = A_pts .reshape (kappa_be_grid .shape [:2 ] + A_pts .shape [- 2 :])
123131
0 commit comments