Setup the environment if this is executed on Google Colab.
Make sure to change the runtime type to GPU
. To do this go to Runtime
-> Change runtime type
-> GPU
Otherwise, rendering won't work in Google Colab.
import os
try:
import google.colab
IN_COLAB = True
except:
IN_COLAB = False
if IN_COLAB:
os.system("pip install -q imt-ring")
os.system("pip install -q matplotlib")
import ring
# automatically detects colab or not
ring.utils.setup_colab_env()
import jax
import jax.numpy as jnp
import numpy as np
import matplotlib.pyplot as plt
import mediapy as media
sys_str = """
<x_xy model="knee">
<options dt="0.01" gravity="0 0 9.81"></options>
<worldbody>
<body euler="0 0 140" joint="frozen" name="femur" pos="0 0 0.5">
<geom dim="0.1" type="xyz"></geom>
<geom dim="0.05 0.4" mass="1" pos="0 0 -0.2" type="capsule"></geom>
<body joint="frozen" name="imu_femur" pos="0 .06 -.2" pos_max=".05 .08 -.1" pos_min="-.05 0 -.3">
<geom dim="0.05" type="xyz"></geom>
<geom color="orange" dim="0.05 0.02 0.05" mass="0.1" type="box"></geom>
</body>
<body damping="3" joint="rx" name="tibia" pos="0 0 -0.4">
<geom dim="0.1" type="xyz"></geom>
<geom dim="0.04 0.4" mass="1" pos="0 0 -0.2" type="capsule"></geom>
<geom dim="0.05 0.15 0.025" mass="0.1" pos="0 0.04 -0.45" type="box"></geom>
<body joint="frozen" name="imu_tibia" pos="0 0.05 -0.2" pos_max=".05 .07 -.1" pos_min="-.05 0 -.3">
<geom dim="0.05" type="xyz"></geom>
<geom color="orange" dim="0.05 0.02 0.05" mass="0.1" type="box"></geom>
</body>
</body>
</body>
</worldbody>
</x_xy>
""" # noqa: E501
sys = ring.System.create(sys_str)
media.show_image(sys.render(width=640, height=480, camera="custom", add_cameras = {-1:'<camera euler="80 0 0" mode="fixed" name="custom" pos="0 -1.8 0.4"></camera>'})[0])
(X, _), (_, qs, xs, _) = ring.RCMG(sys, ring.MotionConfig(T=20.0, t_min=0.3, t_max=1.5), keep_output_extras=1, add_X_imus=1).to_list()[0]
media.show_video(sys.render(xs, width=640, height=480, camera="custom",
add_cameras = {-1:'<camera euler="80 0 0" mode="fixed" name="custom" pos="0 -1.8 0.4"></camera>'}, render_every_nth=4), fps=25)
X.keys()
X["femur"].keys()
# number of timesteps
T = 2000
# graph
lam = (-1, 0)
# number of bodies (excluding IMUs); so tibia and femur
N = len(lam)
ringnet = ring.RING(lam, None)
X_ring = np.zeros((T, N, 10))
X_ring[:, 0, :3] = X["femur"]["acc"]
X_ring[:, 0, 3:6] = X["femur"]["gyr"]
X_ring[:, 1, :3] = X["tibia"]["acc"]
X_ring[:, 1, 3:6] = X["tibia"]["gyr"]
# time-delta between timesteps or inverse of sampling rate
X_ring[:, :, 9] = float(sys.dt)
# We could assume that we don't know the hinge joint axis direction
KNOWN_JOINT_AXIS = True
if KNOWN_JOINT_AXIS:
# the components 6:9 store the axis direction; here it is rx-joint; Revolute x-axis
X_ring[:, 1, 6] = 1.0
quaternions, _ = ringnet.apply(X_ring, lam=lam)
quaternions.shape
# quaternions[:, 0]
# inclination: orientation from femur to earth
# quaternioins[:, 1]
# orientation from tibia to femur
ts = np.arange(0, 20.0, step=sys.dt)
plt.plot(ts, ring.maths.quat_angle_constantAxisOverTime(quaternions[:, 1]), label="knee angle prediction")
plt.plot(ts, -qs, label="knee angle truth")
plt.grid()
plt.legend()
plt.xlabel("Time [s]")
plt.ylabel("Knee Angle [rad]")