iandanforth / pymuscle

A motor unit based model of skeletal muscle and fatigue

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Define motor unit -> damped spring relationship

iandanforth opened this issue · comments

What is the best way to map one to the other?

What experimental values can inform this relationship?

Hooke's Law

F = kx

The force a spring applies (or conversely the tension the spring is under) is equal to the displacement of the spring times a constant k. The displacement is the elongation of the spring past its resting length. The constant is the force required to displace the spring 1 meter.

For example

A spring with a spring-constant of 1000 is elongated 1 meter beyond its resting length. This spring-constant here means it requires 1000 N (~224 lbs) to elongate it 1 meter beyond its resting length. By F = kx where x in this case is 1, the force applied by the spring is equal to the force displacing the spring.

A spring with spring-constant of 500 and a resting length of 10cm is elongated to 20cm. This is a displacement of 10cm (0.1m). F = 500 * 0.1 thus F = 50. 50N (~11.24 lbs) has been applied to this spring.

Most materials are not perfectly elastic. In the above scenario the spring might have gone beyond its elastic limit and deformed plasticly. This would probably mean a drop off in force.

Using (damped) springs

To increase the force applied by a spring you must either 1. Decrease its resting length 2. Increase its stiffness or 3. Both.

Isometric contraction

Changing either or both of the above properties leads to an increase in force produced without (necessarily) a change in muscle length.

Concentric contraction

If the force produced by the muscle is greater than the forces it is trying to over-come the muscle will shorten (up to a limit).

Eccentric contraction

If the force produced by the muscle is less than the forces it is trying to over-come the muscle will lengthen (up to some limit).

After a certain point other tissues (tendons, skin and other connective tissue) start contributing force.

These act like parallel springs with high stiffness but comparatively long resting lengths.

Using MuJoCo tendons

Tendons can act as (damped) springs. They can also have an actuator attached. An actuator directly applies force to the endpoints of a tendon (in line with the length of a tendon).

The maximum force a muscle can produce is related to its current length. Too short and it can't produce much force, and the same if it is too long.

The maximum force a muscle can produce is also related to the velocity of its contraction. The faster a muscle contracts the less (total) force it can produce.

Damping

Ball on a string model

    <tendon>
        <spatial name="string" width="0.02" rgba=".95 .3 .3 1" limited="true" range="0 2.0" stiffness="1000.0" damping="100.0">
            <site site="box_site" />
            <site site="ball_site" />
        </spatial>
    </tendon>

2

image

20

image

200

image

100

image

Stiffness

    <tendon>
        <spatial name="string" width="0.02" rgba=".95 .3 .3 1" limited="true" range="0 2.0" stiffness="3700.0" damping="100.0">
            <site site="box_site" />
            <site site="ball_site" />
        </spatial>
    </tendon>

3700 N/m

While a value of 1700 N/m is supported by the literature (in fit rats - see refs) that produced a spring that was much too springy. (visual evaluation). This was then tuned to match our visual expectations.

image

Hookean vs Exponential Model

In a Hill-type model the passive components of force generation are modeled by an exponential (see comparison of intrinsic properties.

MuJoCo however uses Hookean springs. Instead of implementing our own constraint we can make use of the 'limit' attribute that a <tendon> has and set a max value to a reasonable multiple of the resting length of a muscle (e.g 1.5).

For a continually increasing load this produces a graph like this

screen shot 2018-08-02 at 1 46 19 pm

In the first part of the curve the tendon acts as a hookean spring. In the second it acts like a maxed out spring with max stiffness.

This two-component model is slightly better than a pure linear model.

Varying stiffness by length

Another option is to smoothly vary stiffness by length

screen shot 2018-08-02 at 2 13 05 pm

This gives us a nice non-linear relationship

Hill-type actuator + parallel passive

These experiments were conducted with the following setup. A spherical mass was suspended from a rigid anchor and given 3000 steps to settle.

Then maximum activation was turned on and the system was given 3000 steps to settle.

From 6000 to 9000 steps the mass of the sphere was slowly increased.

From 9000 steps the mass of the sphere was slowly decreased.

    if i > 3000:
        length_factor = force_length_curve(rest_length, cur_length)

        activation = 1.0
        sim.data.ctrl[0] = -(activation * length_factor)

        prev_length = cur_length

    if 6000 < i < 9000:
        sim.model.body_mass[2] = sim.model.body_mass[2] + 0.1

    if i > 9000:
        if sim.model.body_mass[2] > 1:
            sim.model.body_mass[2] = sim.model.body_mass[2] - 0.1

Force-length relationship for contractile element + linear spring

image

Force-length relationship for contractile element + linear spring + proportional stiffness

image

Hill-type with force-length and force-velocity curves

A velocity factor was added to the experimental code

    if i > 3000:
        length_factor = force_length_curve(rest_length, cur_length)

        if not prev_length:
            prev_length = cur_length
        velocity_factor = force_velocity_curve(
            rest_length,
            cur_length,
            time_step
        )

        activation = 1.0
        sim.data.ctrl[0] = -(activation * length_factor * velocity_factor)

        prev_length = cur_length

    if 6000 < i < 9000:
        sim.model.body_mass[2] = sim.model.body_mass[2] + 0.1

    if i > 9000:
        if sim.model.body_mass[2] > 1:
            sim.model.body_mass[2] = sim.model.body_mass[2] - 0.1

image

Closing as this is no longer a mainline concern. PyMuscle should focus on the fatigue model added to other actuators and only implement actuation / force generation when required by a real user need.