motornet.plants.skeletons#

class motornet_tf.plants.skeletons.PointMass(space_dim: int = 2, mass: float = 1.0, name: str = 'point_mass', **kwargs)#

Bases: Skeleton

A simple point-mass skeleton. The point of the point-mass is considered as a bone at the implementation level, so this can be conceptualized as a “one-bone” skeleton with a length of 0 and no joint. However, note that the number of degrees of freedom is not 0 like the number of joints, but is equal to the space_dim input (see below for details).

Parameters:
  • space_dimInteger, the dimensionality of the space in which the point-mass evolves. For instance, this would be 2 for a point-mass evolving in a cartesian, planar xy space.

  • massFloat, the mass (kg) of the point-mass.

  • nameString, the name of the skeleton.

  • **kwargs – This is passed as-is to the parent Skeleton class. This also allows for some backward compatibility. Do not try to pass a dof input value as this is automatically taken by the space_dim input.

get_save_config()#

Gets the base configuration from the get_base_config() method, and adds the mass value (kg) of the point mass to that dictionnary.

Returns:

A dictionary containing the object instance’s full configuration.

class motornet_tf.plants.skeletons.Skeleton(dof: int, space_dim: int, name: str = 'skeleton', pos_lower_bound: float | list | tuple = -1.0, pos_upper_bound: float | list | tuple = 1.0, vel_lower_bound: float | list | tuple = -1000.0, vel_upper_bound: float | list | tuple = 1000.0, **kwargs)#

Bases: object

Base class for Skeleton objects.

Parameters:
  • dofInteger, number of degrees of freedom of the skeleton. Typically this is the number of joints.

  • space_dimInteger, the dimensionality of the space in which the skeleton evolves. For instance, this would be 2 for a cartesian, planar xy space.

  • nameString, the name of the object instance.

  • pos_upper_boundFloat, list or tuple, indicating the upper boundary of joint position. This should be a n-elements vector or list, with n the number of joints of the skeleton. For instance, for a two degrees-of-freedom arm, we would have n=2.

  • pos_lower_boundFloat, list or tuple, indicating the lower boundary of joint position. This should be a n-elements vector or list, with n the number of joints of the skeleton. For instance, for a two degrees-of-freedom arm, we would have n=2.

  • vel_upper_boundFloat, list or tuple, indicating the upper boundary of joint velocity. This should be a n-elements vector or list, with n the number of joints of the skeleton. For instance, for a two degrees-of-freedom arm, we would have n=2.

  • vel_lower_boundFloat, list or tuple, indicating the lower boundary of joint velocity. This should be a n-elements vector or list, with n the number of joints of the skeleton. For instance, for a two degrees-of-freedom arm, we would have n=2.

OPTIONAL ARGUMENTS
  • input_dimInteger, dimensionality of the control input (e.g. torques). Default: takes the same value as dof.

  • state_dimInteger, typically position and velocity for each degree of freedom. Default: 2 * dof.

  • output_dimInteger, dimensionality of the integrate() output, usually the new state. Default: state_dim.

build(timestep: float, pos_upper_bound, pos_lower_bound, vel_upper_bound, vel_lower_bound, integration_method: str = 'euler')#

This method should be called by the initialization method of the motornet.plants.plants.Plant object class or subclass.

Parameters:
  • timestep – Float, size of a single timestep (sec).

  • pos_upper_boundFloat, list or tuple, indicating the upper boundary of joint position. Should be a n-elements vector or list, with n the number of joints of the skeleton. For instance, for a two degrees-of-freedom arm, we would have n=2.

  • pos_lower_boundFloat, list or tuple, indicating the lower boundary of joint position. Should be a n-elements vector or list, with n the number of joints of the skeleton. For instance, for a two degrees-of-freedom arm, we would have n=2.

  • vel_upper_boundFloat, list or tuple, indicating the upper boundary of joint velocity. Should be a n-elements vector or list, with n the number of joints of the skeleton. For instance, for a two degrees-of-freedom arm, we would have n=2.

  • vel_lower_boundFloat, list or tuple, indicating the lower boundary of joint velocity. Should be a n-elements vector or list, with n the number of joints of the skeleton. For instance, for a two degrees-of-freedom arm, we would have n=2.

  • integration_method – String, “euler” to specify that numerical integration should be done using the Euler method, or “rk4”, “rungekutta4”, “runge-kutta4”, or “runge-kutta-4” to specify the Runge-Kutta 4 method instead. This argument is case-insensitive.

clip_velocity(pos, vel)#

Clips the joint velocities input based on the velocity boundaries as well as the joint positions. Specifically, if a velocity is past the boundary values, it is set to the boundary value exactly. Then, if the position is past or equal to the position boundary, and the clipped velocity would result in moving further past that boundary, then the velocity is set to 0.

Parameters:
  • pos – A tensor containing positions of the plant in joint space.

  • vel – A tensor containing velocities of the plant in joint space.

Returns:

A tensor containing the clipped velocities, with same dimensionality as the vel input argument.

get_base_config()#

Get the object instance’s base configuration. This is the set of configuration entries that will be useful for any Skeleton class or subclass. This method should be called by the get_save_config() method. Users wanting to save additional configuration entries specific to a Skeleton subclass should then do so in the get_save_config() method, using this method’s output dictionary as a base.

Returns:

A dictionary containing the skeleton’s degrees of freedom, timestep size, and space dimensionality.

get_save_config()#

Get the skeleton object’s configuration as a dictionary. This method should be overwritten by subclass objects, and used to add configuration entries specific to that subclass, on top of the output of the get_base_config() method.

Returns:

By default, this method returns the output of the get_base_config() method.

integrate(dt: float, state_derivative, joint_state)#

Performs one integration step. This method is usually called by the motornet.plants.plants.Plant.integration_step() uring numerical integration by the motornet.plants.plants.Plant wrapper class or subclass.

Parameters:
  • dtFloat, timestep (sec) of the plant. The skeleton object’s dt attribute is not used here because for the Runge-Kutta method, half-timesteps can occasionally be passed.

  • state_derivativeTensor, derivative of joint state. This input and joint_state should have identical dimensionality.

  • joint_stateTensor, joint state that serves as the initial value. This input and state_derivative should have identical dimensionality.

Returns:

The new state following integration. The dimensionality is identical to that of the joint_state input.

joint2cartesian(joint_state)#

Computes the cartesian state given the joint state.

Parameters:

joint_stateTensor, the current joint configuration.

Returns:

A tensor containing the current cartesian configuration (position, velocity).

path2cartesian(path_coordinates, path_fixation_body, joint_state)#

Transforms muscle paths into cartesian paths for each muscle’s fixation points, given a joint configuration. This method is used by the wrapper motornet.plants.plants.Plant object class or subclass to then calculate musculotendon complex length and velocity, as well as moment arms. See [1] for more details.

References

[1] Sherman MA, Seth A, Delp SL. What Is Moment Arm? Calculating Muscle Effectiveness in Biomechanical Models Using Generalized Coordinates. Proc ASME Des Eng Tech Conf. 2013 Aug; DOI: 10.1115/DETC2013-13633. PMID: 25905111; PMCID: PMC4404026.

Parameters:
  • path_coordinates – The coordinates of each muscle’s fixation point. This is an attribute held by the wrapper motornet.plants.plants.Plant object class or subclass.

  • path_fixation_body – The body part (bone) to which each muscle fixation point is attached to. This is an attribute held by the wrapper motornet.plants.plants.Plant object class or subclass.

  • joint_stateTensor, the current joint configuration.

Returns:

  • The position of each fixation point in cartesian space. The dimensionality is n_batch * space_dim * n_fixation_points, with space_dim the dimensionality of the worldspace and n_fixation_points the number of fixation points across all muscles.

  • The derivative with respect to time of each fixation point’s position in cartesian space (velocity). The dimensionality is n_batch * space_dim * n_fixation_points, with space_dim the dimensionality of the worldspace and n_fixation_points the number of fixation points across all muscles.

  • The derivative with respect to joint angle of each fixation point’s position in cartesian space. The dimensionality is n_batch * space_dim * n_dof * n_fixation_points, with space_dim the dimensionality of the worldspace, n_dof the number of degrees of freedoms of the Skeleton object class or subclass, and n_fixation_points the number of fixation points across all muscles.

setattr(name: str, value)#

Changes the value of an attribute held by this object.

Parameters:
  • nameString, attribute to set to a new value.

  • value – Value that the attribute should take.

update_ode(inputs, joint_state, endpoint_load)#

Evaluates the Ordinary Differential Equation (ODE) function.

Parameters:
  • inputsTensor, the control input to the skeleton object (typically torques).

  • joint_stateTensor, the current joint configuration.

  • endpoint_loadTensor, the loads applied to the skeleton’s endpoint. The dimensionality should match the skeleton object or subclass’ space_dim attribute.

Returns:

The derivatives of the joint state. The dimensionality is identical to that of the joint_state input.

class motornet_tf.plants.skeletons.TwoDofArm(name: str = 'two_dof_arm', m1: float = 1.864572, m2: float = 1.534315, l1g: float = 0.180496, l2g: float = 0.181479, i1: float = 0.013193, i2: float = 0.020062, l1: float = 0.309, l2: float = 0.26, **kwargs)#

Bases: Skeleton

A two degrees-of-freedom planar arm.

Parameters:
  • nameString, the name of the skeleton.

  • m1Float, mass (kg) of the first bone.

  • m2Float, mass (kg) of the second bone.

  • l1gFloat, position of the center of gravity of the first bone (m).

  • l2gFloat, position of the center of gravity of the second bone (m).

  • i1Float, inertia (kg.m^2) of the first bone.

  • i2Float, inertia (kg.m^2) of the second bone.

  • l1Float, length (m) of the first bone.

  • l2Float, length (m) of the second bone.

  • **kwargs – All contents are passed to the parent Skeleton base class. Also allows for some backward compatibility.

get_save_config()#

Gets the base configuration from the Skeleton.get_base_config() method, and adds the arm’s properties to the configuration: each bone length, mass, center of gravity, coriolis forces, and viscosity parameters.

Returns:

A dictionary containing the object instance’s full configuration.