Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance Forward Dynamics computation by adding motor dynamics #62

Merged
merged 43 commits into from
Dec 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
df52281
Add motor methods in high_level.joint
flferretti Jul 20, 2023
40bb04d
Set motor parameters in high_level.model
flferretti Jul 20, 2023
e6c7410
Add motor parameters in parsers.descriptions.joint
flferretti Jul 20, 2023
64cadbc
Add motor parameters in physics.model.physics_model
flferretti Jul 20, 2023
81ae493
Add test script for aba
flferretti Jul 20, 2023
ac75b67
Update documentation
flferretti Aug 1, 2023
9a622a6
Extract motor inertias
flferretti Aug 1, 2023
ac5ab0f
Add motor inertias in first backward pass
flferretti Aug 1, 2023
430c641
Add motor viscous friction in forward pass
flferretti Aug 1, 2023
25b9dd4
Add motor parameters initialization if the model has no motors
flferretti Aug 1, 2023
56487df
Fix minor typos and delete test_aba
flferretti Aug 1, 2023
dedb032
Compute FD with CRBA considering motor parameters
flferretti Aug 1, 2023
85381c6
Approximate ABA solution considering motor inertias as linear compone…
flferretti Aug 3, 2023
c76a0bf
Add test for forward dynamics with motor parameters
flferretti Aug 3, 2023
22ebf2d
Add dirty fix
flferretti Aug 11, 2023
5768727
Disable `jax.jit` during motors test
flferretti Sep 5, 2023
323b5f2
Add `has_motors` attribute to model
flferretti Sep 5, 2023
4288f3a
Add motor parameters in FD computation with RNEA
flferretti Sep 5, 2023
97c6e0f
Fix formatting
flferretti Sep 5, 2023
3ec90ef
Update ABA and fix formatting
flferretti Sep 5, 2023
203b09b
Update motor dynamics test with latest rebase
flferretti Sep 7, 2023
b42cc60
Rename variables to improve readability
flferretti Sep 12, 2023
dcb13d2
Fix ABA and RNEA with motor dynamics
flferretti Sep 12, 2023
16ff2b3
Refactor code and add oop decorators for JIT compilation
flferretti Sep 12, 2023
4d55ec5
Refactor motor dynamics test
flferretti Sep 12, 2023
58e2ca8
Correct typos in ABA and comment oop decorators
flferretti Sep 20, 2023
dd8e138
Solve deprecation warning
flferretti Oct 20, 2023
5fadf75
Update setters for motor parameters
flferretti Oct 20, 2023
da40016
Remove unnecessary assertion in crb
flferretti Oct 25, 2023
65f4046
Revert `rnea` modification
flferretti Oct 25, 2023
99a6e8e
Refactor and add viscous frictions in ABA
flferretti Oct 25, 2023
a171f95
Change has_motors logic
flferretti Oct 26, 2023
0bcc5dc
Avoid implicit jax.Array to bool conversion
flferretti Oct 26, 2023
4ff83ab
Restore RNEA with motors
flferretti Oct 26, 2023
6c1aab0
Update tests for motors
flferretti Oct 26, 2023
f03e4c8
Remove motor dynamics test
flferretti Nov 8, 2023
2bee17d
Fix motors for floating base
flferretti Nov 8, 2023
af1d537
Fix ABA for viscous friction
flferretti Nov 8, 2023
eb23ad8
Update ABA and RNEA
flferretti Nov 13, 2023
bb64a86
Fix CRB
flferretti Nov 22, 2023
7f4ced4
Fix CRB FD for fixed-based models
flferretti Dec 6, 2023
651a6b1
Enforce dtypes in motor parameters
flferretti Dec 6, 2023
f82e351
Put ABA and RNEA with motors in separate files
flferretti Dec 6, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions src/jaxsim/high_level/joint.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,27 @@ def position_limit(self, dof: int = None) -> tuple[jtp.Float, jtp.Float]:

return jnp.array(low, dtype=float), jnp.array(high, dtype=float)

# =============
# Motor methods
# =============
@functools.partial(oop.jax_tf.method_ro)
def motor_inertia(self) -> jtp.Vector:
""""""

return jnp.array(self.joint_description.motor_inertia, dtype=float)

@functools.partial(oop.jax_tf.method_ro)
def motor_gear_ratio(self) -> jtp.Vector:
""""""

return jnp.array(self.joint_description.motor_gear_ratio, dtype=float)

@functools.partial(oop.jax_tf.method_ro)
def motor_viscous_friction(self) -> jtp.Vector:
""""""

return jnp.array(self.joint_description.motor_viscous_friction, dtype=float)

# =================
# Multi-DoF methods
# =================
Expand Down
99 changes: 99 additions & 0 deletions src/jaxsim/high_level/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -1137,13 +1137,31 @@ def forward_dynamics_crb(
τ = jnp.atleast_1d(τ.squeeze())
τ = jnp.vstack(τ) if τ.size > 0 else jnp.empty(shape=(0, 1))

# Extract motor parameters from the physics model
GR = self.motor_gear_ratios()
IM = self.motor_inertias()
KV = jnp.diag(self.motor_viscous_frictions())

# Compute auxiliary quantities
Γ = jnp.diag(GR)
K̅ᵥ = Γ.T @ KV @ Γ

# Compute terms of the floating-base EoM
M = self.free_floating_mass_matrix()
h = jnp.vstack(self.free_floating_bias_forces())
J = self.generalized_free_floating_jacobian()
f_ext = jnp.vstack(self.external_forces().flatten())
S = jnp.block([jnp.zeros(shape=(self.dofs(), 6)), jnp.eye(self.dofs())]).T

# Configure the slice for fixed/floating base robots
sl = np.s_[0:] if self.physics_model.is_floating_base else np.s_[6:]
sl_m = np.s_[M.shape[0] - self.dofs() :]

# Add the motor related terms to the EoM
M = M.at[sl_m, sl_m].set(M[sl_m, sl_m] + jnp.diag(Γ.T @ IM @ Γ))
h = h.at[sl_m].set(h[sl_m] + K̅ᵥ @ self.joint_velocities()[:, None])
S = S.at[sl_m].set(S[sl_m])

# Compute the generalized acceleration by inverting the EoM
ν̇ = jax.lax.select(
pred=self.floating_base(),
Expand Down Expand Up @@ -1479,6 +1497,87 @@ def integrate(
},
)

# ==============
# Motor dynamics
# ==============

@functools.partial(oop.jax_tf.method_rw, static_argnames=["joint_names"])
def set_motor_inertias(
self, inertias: jtp.Vector, joint_names: tuple[str, ...] = None
) -> None:
joint_names = joint_names or self.joint_names()

if inertias.size != len(joint_names):
raise ValueError("Wrong arguments size", inertias.size, len(joint_names))

self.physics_model._joint_motor_inertia.update(
dict(zip(self.physics_model._joint_motor_inertia, inertias))
)

logging.info("Setting attribute `motor_inertias`")

@functools.partial(oop.jax_tf.method_rw, jit=False)
def set_motor_gear_ratios(
self, gear_ratios: jtp.Vector, joint_names: tuple[str, ...] = None
) -> None:
joint_names = joint_names or self.joint_names()

if gear_ratios.size != len(joint_names):
raise ValueError("Wrong arguments size", gear_ratios.size, len(joint_names))

# Check on gear ratios if motor_inertias are not zero
for idx, gr in enumerate(gear_ratios):
if gr != 0 and self.motor_inertias()[idx] == 0:
raise ValueError(
f"Zero motor inertia with non-zero gear ratio found in position {idx}"
)

self.physics_model._joint_motor_gear_ratio.update(
dict(zip(self.physics_model._joint_motor_gear_ratio, gear_ratios))
)

logging.info("Setting attribute `motor_gear_ratios`")

@functools.partial(oop.jax_tf.method_rw, static_argnames=["joint_names"])
def set_motor_viscous_frictions(
self, viscous_frictions: jtp.Vector, joint_names: tuple[str, ...] = None
) -> None:
joint_names = joint_names or self.joint_names()

if viscous_frictions.size != len(joint_names):
raise ValueError(
"Wrong arguments size", viscous_frictions.size, len(joint_names)
)

self.physics_model._joint_motor_viscous_friction.update(
dict(
zip(
self.physics_model._joint_motor_viscous_friction,
viscous_frictions,
)
)
)

logging.info("Setting attribute `motor_viscous_frictions`")

@functools.partial(oop.jax_tf.method_ro, jit=False)
def motor_inertias(self) -> jtp.Vector:
return jnp.array(
[*self.physics_model._joint_motor_inertia.values()], dtype=float
)

@functools.partial(oop.jax_tf.method_ro, jit=False)
def motor_gear_ratios(self) -> jtp.Vector:
return jnp.array(
[*self.physics_model._joint_motor_gear_ratio.values()], dtype=float
)

@functools.partial(oop.jax_tf.method_ro, jit=False)
def motor_viscous_frictions(self) -> jtp.Vector:
return jnp.array(
[*self.physics_model._joint_motor_viscous_friction.values()], dtype=float
)

# ===============
# Private methods
# ===============
Expand Down
4 changes: 4 additions & 0 deletions src/jaxsim/parsers/descriptions/joint.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ class JointDescription(JaxsimDataclass):
position_limit: Tuple[float, float] = (0.0, 0.0)
initial_position: Union[float, npt.NDArray] = 0.0

motor_inertia: float = 0.0
motor_viscous_friction: float = 0.0
motor_gear_ratio: float = 1.0

def __post_init__(self):
if self.axis is not None:
with self.mutable_context(
Expand Down
Loading
Loading