def animate_run(
    root, arma, targets, steps_per_sec=1, body=True, motion=True, squash_gait_pct=0.1
):
    """
    Animate creature by moving its IK targets
    """

    assert arma.type == "ARMATURE"

    stride_length = 0.7 * clip_gaussian(0.4, 0.3, 0.3, 0.6) * arma.dimensions.x
    spread = clip_gaussian(0.15, 0.1, 0, 0.5)
    stride_height = U(0.15, 0.4)
    body_height = stride_height * clip_gaussian(0.6, 0.4, 0.3, 1.2)

    base_offset = U(0, 1)
    offset = U(0.5, 0.7)

    frame_period = int(bpy.context.scene.render.fps / steps_per_sec)

    def get_targets(k):
        return [t for t in targets if k in t.name]

    feet_targets = get_targets("foot")

    foot_paths = []
    foot_paths += follow_gait_path(
        targets=feet_targets[:2],
        period=frame_period,
        path_dims=(stride_length, stride_height, 0.0, 0.0),
        offset=base_offset,
        spread=spread,
    )
    foot_paths += follow_gait_path(
        targets=feet_targets[2:],
        period=frame_period,
        path_dims=(stride_length, stride_height, 0.0, 0.0),
        offset=base_offset + offset,
        spread=spread,
    )

    for p in foot_paths:
        p.parent = root

    feet_targets = get_targets("knee")
    knee_paths = []
    knee_paths += follow_gait_path(
        targets=feet_targets[:2],
        period=frame_period,
        path_dims=(0.1 * stride_length, 0.1 * stride_height, 0.0, 0.0),
        offset=base_offset,
        spread=spread,
    )
    knee_paths += follow_gait_path(
        targets=feet_targets[2:],
        period=frame_period,
        path_dims=(0.1 * stride_length, 0.1 * stride_height, 0.0, 0.0),
        offset=base_offset + offset,
        spread=spread,
    )
    for p in knee_paths:
        p.location.z = -0.1
        p.parent = root

    body_paths = []
    if body:
        body_paths += follow_gait_path(
            targets=get_targets("body_0"),
            period=frame_period,
            path_dims=(0, body_height, 0.0, 0.0),
            offset=base_offset + 1 - offset / 2,
            spread=0,
        )
        body_paths += follow_gait_path(
            targets=get_targets("body_1"),
            period=frame_period,
            path_dims=(0, body_height, 0.0, 0.0),
            offset=base_offset + offset / 2,
            spread=0,
        )
        # body_paths += animate_feet(targets=get_targets('tail'), period=frame_period,
        #    path_dims=(0.1, 0.4, 0.0, 0.0), offset=0, spread=0)
        body_paths += follow_gait_path(
            targets=get_targets("head"),
            period=frame_period,
            path_dims=(0, body_height * 0.5 * N(1, 0.05), 0.0, 0.0),
            offset=0,
            spread=0,
        )

    flap_height = U(0.3, 1)
    flap_speed_mult = 1  # uniform(0.7, 2)
    body_paths += follow_gait_path(
        targets=get_targets("wingtip"),
        period=int(frame_period / flap_speed_mult),
        path_dims=(0, flap_height, 0.0, flap_height),
        offset=base_offset + offset,
        spread=0,
    )

    for p in body_paths:
        if len(foot_paths):
            p.location.z = (
                1 - squash_gait_pct
            ) * p.location.z + squash_gait_pct * foot_paths[0].location.z
        p.parent = root

    all_paths = foot_paths + knee_paths + body_paths
    if motion:
        for p in all_paths:
            p.data.driver_add("eval_time").driver.expression = "frame"

    return all_paths

    Animate creature by moving its IK targets
    
infinigen/assets/objects/creatures/util/animation/run_cycle.py