Skip to content

Commit b2f1bf0

Browse files
committed
Run formatting
1 parent 1fb147d commit b2f1bf0

File tree

10 files changed

+173
-103
lines changed

10 files changed

+173
-103
lines changed

examples/analyze_segment_fusion.py

Lines changed: 39 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
import sympy as sp
22

3-
l1, l2 = sp.symbols('l1 l2', nonnegative=True, nonzero=True)
4-
kappa_be1, sigma_sh1, sigma_ax1 = sp.symbols('kappa_be1 sigma_sh1 sigma_ax1', real=True, nonnegative=True, nonzero=True)
5-
kappa_be2, sigma_sh2, sigma_ax2 = sp.symbols('kappa_be2 sigma_sh2 sigma_ax2', real=True, nonnegative=True, nonzero=True)
3+
l1, l2 = sp.symbols("l1 l2", nonnegative=True, nonzero=True)
4+
kappa_be1, sigma_sh1, sigma_ax1 = sp.symbols(
5+
"kappa_be1 sigma_sh1 sigma_ax1", real=True, nonnegative=True, nonzero=True
6+
)
7+
kappa_be2, sigma_sh2, sigma_ax2 = sp.symbols(
8+
"kappa_be2 sigma_sh2 sigma_ax2", real=True, nonnegative=True, nonzero=True
9+
)
610

711
# deactivate shear and axial strains
812
# sigma_sh1, sigma_sh2 = 0.0, 0.0
@@ -19,30 +23,42 @@
1923
# apply the forward kinematics on the individual segments
2024
s_be1, c_be1 = sp.sin(kappa_be1 * l1), sp.cos(kappa_be1 * l1)
2125
s_be2, c_be2 = sp.sin(kappa_be2 * l2), sp.cos(kappa_be2 * l2)
22-
chi1 = sp.Matrix([
23-
[sigma_sh1 * s_be1 / kappa_be1 + sigma_ax1 * (c_be1 - 1) / kappa_be1],
24-
[sigma_sh1 * (1 - c_be1) / kappa_be1 + sigma_ax1 * s_be1 / kappa_be1],
25-
[kappa_be1 * l1],
26-
])
26+
chi1 = sp.Matrix(
27+
[
28+
[sigma_sh1 * s_be1 / kappa_be1 + sigma_ax1 * (c_be1 - 1) / kappa_be1],
29+
[sigma_sh1 * (1 - c_be1) / kappa_be1 + sigma_ax1 * s_be1 / kappa_be1],
30+
[kappa_be1 * l1],
31+
]
32+
)
2733
# rotation matrix
28-
R1 = sp.Matrix([
29-
[c_be1, -s_be1, 0],
30-
[s_be1, c_be1, 0],
31-
[0, 0, 1],
32-
])
33-
chi2_rel = sp.Matrix([
34-
[sigma_sh2 * s_be2 / kappa_be2 + sigma_ax2 * (c_be2 - 1) / kappa_be2],
35-
[sigma_sh2 * (1 - c_be2) / kappa_be2 + sigma_ax2 * s_be2 / kappa_be2],
36-
[kappa_be2 * l2],
37-
])
34+
R1 = sp.Matrix(
35+
[
36+
[c_be1, -s_be1, 0],
37+
[s_be1, c_be1, 0],
38+
[0, 0, 1],
39+
]
40+
)
41+
chi2_rel = sp.Matrix(
42+
[
43+
[sigma_sh2 * s_be2 / kappa_be2 + sigma_ax2 * (c_be2 - 1) / kappa_be2],
44+
[sigma_sh2 * (1 - c_be2) / kappa_be2 + sigma_ax2 * s_be2 / kappa_be2],
45+
[kappa_be2 * l2],
46+
]
47+
)
3848
chi2 = sp.simplify(chi1 + R1 @ chi2_rel)
3949
# print("chi2 =\n", chi2)
4050
# apply the one-segment inverse kinematic on the distal end of the two segments
4151
px, py, th = chi2[0, 0], chi2[1, 0], chi2[2, 0]
4252
s_th, c_th = sp.sin(th), sp.cos(th)
43-
qfkik = sp.simplify(th / (2 * (l1 + l2)) * sp.Matrix([
44-
[2],
45-
[py - px * s_th / (c_th - 1)],
46-
[-px - py * s_th / (c_th - 1)],
47-
]))
53+
qfkik = sp.simplify(
54+
th
55+
/ (2 * (l1 + l2))
56+
* sp.Matrix(
57+
[
58+
[2],
59+
[py - px * s_th / (c_th - 1)],
60+
[-px - py * s_th / (c_th - 1)],
61+
]
62+
)
63+
)
4864
print("qfkik =\n", qfkik)

examples/demo_planar_hsa_motor2ee_jacobian.py

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@
2626
)
2727

2828

29-
def factory_fn(params: Dict[str, Array], verbose: bool = False) -> Tuple[Callable, Callable]:
29+
def factory_fn(
30+
params: Dict[str, Array], verbose: bool = False
31+
) -> Tuple[Callable, Callable]:
3032
"""
3133
Factory function for the planar HSA.
3234
Args:
@@ -45,7 +47,9 @@ def factory_fn(params: Dict[str, Array], verbose: bool = False) -> Tuple[Callabl
4547
sys_helpers,
4648
) = planar_hsa.factory(sym_exp_filepath, strain_selector)
4749
dynamical_matrices_fn = partial(dynamical_matrices_fn, params)
48-
forward_kinematics_end_effector_fn = jit(partial(forward_kinematics_end_effector_fn, params))
50+
forward_kinematics_end_effector_fn = jit(
51+
partial(forward_kinematics_end_effector_fn, params)
52+
)
4953
jacobian_end_effector_fn = jit(partial(jacobian_end_effector_fn, params))
5054

5155
def residual_fn(q: Array, phi: Array) -> Array:
@@ -64,7 +68,9 @@ def residual_fn(q: Array, phi: Array) -> Array:
6468
print("Compiling jac_residual_fn...")
6569
print(jac_residual_fn(jnp.zeros((3,)), jnp.zeros((2,))))
6670

67-
def phi2q_static_model_fn(phi: Array, q0: Array = jnp.zeros((3, ))) -> Tuple[Array, Dict[str, Array]]:
71+
def phi2q_static_model_fn(
72+
phi: Array, q0: Array = jnp.zeros((3,))
73+
) -> Tuple[Array, Dict[str, Array]]:
6874
"""
6975
A static model mapping the motor angles to the planar HSA configuration using scipy.optimize.minimize.
7076
Arguments:
@@ -82,7 +88,12 @@ def phi2q_static_model_fn(phi: Array, q0: Array = jnp.zeros((3, ))) -> Tuple[Arr
8288
options={"disp": True} if verbose else None,
8389
)
8490
if verbose:
85-
print("Optimization converged after", sol.nit, "iterations with residual", sol.fun)
91+
print(
92+
"Optimization converged after",
93+
sol.nit,
94+
"iterations with residual",
95+
sol.fun,
96+
)
8697

8798
# configuration that minimizes the residual
8899
q = jnp.array(sol.x)
@@ -95,7 +106,9 @@ def phi2q_static_model_fn(phi: Array, q0: Array = jnp.zeros((3, ))) -> Tuple[Arr
95106

96107
return q, aux
97108

98-
def phi2chi_static_model_fn(phi: Array, q0: Array = jnp.zeros((3, ))) -> Tuple[Array, Dict[str, Array]]:
109+
def phi2chi_static_model_fn(
110+
phi: Array, q0: Array = jnp.zeros((3,))
111+
) -> Tuple[Array, Dict[str, Array]]:
99112
"""
100113
A static model mapping the motor angles to the planar end-effector pose.
101114
Arguments:
@@ -110,7 +123,9 @@ def phi2chi_static_model_fn(phi: Array, q0: Array = jnp.zeros((3, ))) -> Tuple[A
110123
aux["chi"] = chi
111124
return chi, aux
112125

113-
def jac_phi2chi_static_model_fn(phi: Array, q0: Array = jnp.zeros((3, ))) -> Tuple[Array, Dict[str, Array]]:
126+
def jac_phi2chi_static_model_fn(
127+
phi: Array, q0: Array = jnp.zeros((3,))
128+
) -> Tuple[Array, Dict[str, Array]]:
114129
"""
115130
Compute the Jacobian between the actuation space and the task-space.
116131
Arguments:
@@ -157,17 +172,12 @@ def jac_phi2chi_static_model_fn(phi: Array, q0: Array = jnp.zeros((3, ))) -> Tup
157172
phi = jnp.array([1.0, 1.0])
158173
case _:
159174
rng, subkey = random.split(rng)
160-
phi = random.uniform(
161-
subkey,
162-
phi_max.shape,
163-
minval=0.0,
164-
maxval=phi_max
165-
)
175+
phi = random.uniform(subkey, phi_max.shape, minval=0.0, maxval=phi_max)
166176

167177
print("i", i)
168178

169179
chi, aux = phi2chi_static_model_fn(phi, q0=q0)
170180
print("phi", phi, "q", aux["q"], "chi", chi)
171181

172182
J_phi2chi, aux = jac_phi2chi_static_model_fn(phi, q0=q0)
173-
print("J_phi2chi:\n", J_phi2chi)
183+
print("J_phi2chi:\n", J_phi2chi)

examples/derive_planar_pcs.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,7 @@
1212
/ f"planar_pcs_ns-{NUM_SEGMENTS}.dill"
1313
)
1414
symbolically_derive_planar_pcs_model(
15-
num_segments=NUM_SEGMENTS, filepath=sym_exp_filepath, simplify_expressions=True if NUM_SEGMENTS < 3 else False
15+
num_segments=NUM_SEGMENTS,
16+
filepath=sym_exp_filepath,
17+
simplify_expressions=True if NUM_SEGMENTS < 3 else False,
1618
)

examples/simulate_planar_pcs.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ def draw_robot(
9595

9696

9797
if __name__ == "__main__":
98-
strain_basis, forward_kinematics_fn, dynamical_matrices_fn, auxiliary_fns = planar_pcs.factory(
99-
sym_exp_filepath, strain_selector
98+
strain_basis, forward_kinematics_fn, dynamical_matrices_fn, auxiliary_fns = (
99+
planar_pcs.factory(sym_exp_filepath, strain_selector)
100100
)
101101
batched_forward_kinematics = vmap(
102102
forward_kinematics_fn, in_axes=(None, None, 0), out_axes=-1
@@ -143,7 +143,9 @@ def draw_robot(
143143
q_d_ts = sol.ys[:, n_q:]
144144

145145
# evaluate the forward kinematics along the trajectory
146-
chi_ee_ts = vmap(forward_kinematics_fn, in_axes=(None, 0, None))(params, q_ts, jnp.array([jnp.sum(params["l"])]))
146+
chi_ee_ts = vmap(forward_kinematics_fn, in_axes=(None, 0, None))(
147+
params, q_ts, jnp.array([jnp.sum(params["l"])])
148+
)
147149
# plot the end-effector position along the trajectory
148150
plt.figure()
149151
plt.plot(chi_ee_ts[0, :], chi_ee_ts[1, :])
@@ -166,8 +168,12 @@ def draw_robot(
166168
plt.show()
167169

168170
# plot the energy along the trajectory
169-
kinetic_energy_fn_vmapped = vmap(partial(auxiliary_fns["kinetic_energy_fn"], params))
170-
potential_energy_fn_vmapped = vmap(partial(auxiliary_fns["potential_energy_fn"], params))
171+
kinetic_energy_fn_vmapped = vmap(
172+
partial(auxiliary_fns["kinetic_energy_fn"], params)
173+
)
174+
potential_energy_fn_vmapped = vmap(
175+
partial(auxiliary_fns["potential_energy_fn"], params)
176+
)
171177
U_ts = potential_energy_fn_vmapped(q_ts)
172178
T_ts = kinetic_energy_fn_vmapped(q_ts, q_d_ts)
173179
plt.figure()

src/jsrm/symbolic_derivation/planar_hsa.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,7 @@ def symbolically_derive_planar_hsa_model(
507507
Bpl = sp.simplify(Bpl)
508508
B = B + Bpl
509509
# add the gravitational potential energy of the payload
510-
Upl = sp.simplify(- mpl * g.T @ pCoGpl)
510+
Upl = sp.simplify(-mpl * g.T @ pCoGpl)
511511
U_g = U_g + Upl
512512

513513
# simplify mass matrix

src/jsrm/symbolic_derivation/planar_pcs.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77

88

99
def symbolically_derive_planar_pcs_model(
10-
num_segments: int, filepath: Optional[Union[str, Path]] = None, simplify_expressions: bool = True
10+
num_segments: int,
11+
filepath: Optional[Union[str, Path]] = None,
12+
simplify_expressions: bool = True,
1113
) -> Dict:
1214
"""
1315
Symbolically derive the kinematics and dynamics of a planar continuum soft robot modelled with
@@ -184,9 +186,13 @@ def symbolically_derive_planar_pcs_model(
184186
s, l[-1]
185187
), # expression for end-effector pose of shape (3, )
186188
"J_sms": J_sms, # list of Jacobians (for each segment) of shape (3, num_dof)
187-
"Jee": J_sms[-1].subs(s, l[-1]), # end-effector Jacobian of shape (3, num_dof)
189+
"Jee": J_sms[-1].subs(
190+
s, l[-1]
191+
), # end-effector Jacobian of shape (3, num_dof)
188192
"J_d_sms": J_d_sms, # list of time derivatives of Jacobians (for each segment)
189-
"Jee_d": J_d_sms[-1].subs(s, l[-1]), # time derivative of end-effector Jacobian of shape (3, num_dof)
193+
"Jee_d": J_d_sms[-1].subs(
194+
s, l[-1]
195+
), # time derivative of end-effector Jacobian of shape (3, num_dof)
190196
"B": B, # mass matrix
191197
"C": C, # coriolis matrix
192198
"G": G, # gravity vector

src/jsrm/systems/planar_pcs.py

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ def apply_eps_to_bend_strains(xi: Array, _eps: float) -> Array:
175175

176176
return xi_epsed
177177

178-
def classify_segment(params: Dict[str, Array], s: Array) -> Tuple[Array, Array] :
178+
def classify_segment(params: Dict[str, Array], s: Array) -> Tuple[Array, Array]:
179179
"""
180180
Classify the point along the robot to the corresponding segment
181181
Args:
@@ -192,14 +192,16 @@ def classify_segment(params: Dict[str, Array], s: Array) -> Tuple[Array, Array]
192192
# determine in which segment the point is located
193193
# use argmax to find the last index where the condition is true
194194
segment_idx = (
195-
l_cum.shape[0] - 1 - jnp.argmax((s >= l_cum_padded[:-1])[::-1]).astype(int)
195+
l_cum.shape[0] - 1 - jnp.argmax((s >= l_cum_padded[:-1])[::-1]).astype(int)
196196
)
197197
# point coordinate along the segment in the interval [0, l_segment]
198198
s_segment = s - l_cum_padded[segment_idx]
199199

200200
return segment_idx, s_segment
201201

202-
def stiffness_fn(params: Dict[str, Array], formulate_in_strain_space: bool = False) -> Array:
202+
def stiffness_fn(
203+
params: Dict[str, Array], formulate_in_strain_space: bool = False
204+
) -> Array:
203205
"""
204206
Compute the stiffness matrix of the system.
205207
Args:
@@ -210,7 +212,7 @@ def stiffness_fn(params: Dict[str, Array], formulate_in_strain_space: bool = Fal
210212
"""
211213
# cross-sectional area and second moment of area
212214
A = jnp.pi * params["r"] ** 2
213-
Ib = A ** 2 / (4 * jnp.pi)
215+
Ib = A**2 / (4 * jnp.pi)
214216

215217
# elastic and shear modulus
216218
E, G = params["E"], params["G"]
@@ -260,7 +262,7 @@ def forward_kinematics_fn(
260262

261263
@jit
262264
def jacobian_fn(
263-
params: Dict[str, Array], q: Array, s: Array, eps: float = global_eps
265+
params: Dict[str, Array], q: Array, s: Array, eps: float = global_eps
264266
) -> Array:
265267
"""
266268
Evaluate the forward kinematics the tip of the links
@@ -341,7 +343,6 @@ def dynamical_matrices_fn(
341343
alpha = B_xi.T @ jnp.identity(n_xi) @ B_xi
342344

343345
return B, C, G, K, D, alpha
344-
345346

346347
def kinetic_energy_fn(params: Dict[str, Array], q: Array, q_d: Array) -> Array:
347348
"""
@@ -357,11 +358,12 @@ def kinetic_energy_fn(params: Dict[str, Array], q: Array, q_d: Array) -> Array:
357358

358359
# kinetic energy
359360
T = (0.5 * q_d.T @ B @ q_d).squeeze()
360-
361+
361362
return T
362363

363-
364-
def potential_energy_fn(params: Dict[str, Array], q: Array, eps: float = 1e4 * global_eps) -> Array:
364+
def potential_energy_fn(
365+
params: Dict[str, Array], q: Array, eps: float = 1e4 * global_eps
366+
) -> Array:
365367
"""
366368
Compute the potential energy of the system.
367369
Args:
@@ -460,7 +462,12 @@ def operational_space_dynamical_matrices_fn(
460462
segment_idx, J_lambda_sms, *params_for_lambdify, *xi_epsed, s_segment
461463
).squeeze()
462464
J_d = lax.switch(
463-
segment_idx, J_d_lambda_sms, *params_for_lambdify, *xi_epsed, *xi_d, s_segment
465+
segment_idx,
466+
J_d_lambda_sms,
467+
*params_for_lambdify,
468+
*xi_epsed,
469+
*xi_d,
470+
s_segment,
464471
).squeeze()
465472
# apply the operational_space_selector and strain basis to the J and J_d
466473
J = J[operational_space_selector, :] @ B_xi

0 commit comments

Comments
 (0)