Standing High Jump

About

This tutorial demonstrates how to use feed-forward control to perform a standing high jump task. It shows how to use different types of functions for feed-forward control, as well as the how to setup the objective function.

Piece-Wise Constant Control

  • Click on File → Open…, and open Tutorials/Tutorial 2a - Standing High Jump.scone

In the editor, you'll see a section called 'Controller', with the following code:

# Controller for the Model
FeedForwardController {
	symmetric = 1
 
	# Function for feed-forward pattern
	PieceWiseConstant {
		control_points = 2
		control_point_y = 0.3~0.01<0,1> # Initial y value of control points
		control_point_dt = 0.2~0.01<0,1> # initial delta time between control points
	}
}

The FeedForwardController is the type of controller, and the Function defines the type of function. In this case, we define a PieceWiseConstantFunction function with two control points, and a variable time between control points. The values after control_point_y and control_point_dt define parameters to be optimized, and have the following format:

mean~standard deviation<minimum, maximum>

  • To start the optimization, click on Scenario → Optimize Scenario

If you do not wish to optimize a parameter, for instance if you wish to use a piece-wise function with a fixed time interval of 0.1 seconds, simply change control_point_dt to:

control_point_dt = 0.1 # this parameter is no longer optimized

Polynomial Control

Instead of using a PieceWiseConstantFunction function, it is also possible to use a PieceWiseLinearFunction function or a Polynomial, simply by changing the type of the function.

Keywords in SCONE are case sensitive.

To use a polynomial to define the muscle excitation signal for each muscle, change the code into the following (see also Tutorials/Tutorial 2b - Standing High Jump - Polynomial.scone):

# Controller for the Model
FeedForwardController {
	symmetric = 1
 
	# 2nd degree polynomial ax^2 + bx + c
	Polynomial {
		degree = 2
		coefficient0 = 0.3~0.01<0,1> # initial value for c
		coefficient1 = 0~0.1<-10,10> # initial value for b
		coefficient2 = 0~0.1<-10,10> # initial value for a
	}
}

Jumping with a Straight Upper Body

If you have run the optimization for a while, you will notice that the model has a tendency to lean backwards during the jump. The reason for this is that our optimization objective only cares about how high it jumps, not about the pose of its upper body.

The objective function is defined by the Objective and Measure tags. The objective type is a SimulationObjective, which is used for objective functions that are the result of a simulation. Inside the Objective you'll find the Measure that defines the fitness function of the objective.

By default, JumpMeasure measures the maximum height of the Center of Mass (COM) of the model. We can add an additional term to also take into account the orientation of the upper body (see also Tutorial 2c - Standing High Jump - Straight Pose):

# Composite measure for straight pose jumping
CompositeMeasure {
 
	# Fitness measure for jumping
	JumpMeasure {
		termination_height = 0.75
		prepare_time = 0.2
	}
 
	# Penalize backwards leaning pose
	DofMeasure {
		dof = pelvis_tilt
		position { min = -45 max = 0 abs_penalty = -10 }
	}
}

What we've done here is changed the measure type to CompositeMeasure, and combine our JumpMeasure with an additional DofMeasure. The latter applies a penalty when a specific Degree of Freedom (DOF) is outside a specific range. In this case, we define the valid range to be between -45 and 0 degrees, and apply a penalty of -10 per degree at which the pelvis_tilt is outside this range.

Setting the initial parameters

Since we don't want to redo our entire optimization, we jump-start the optimization by initializing the parameters using the result of an earlier optimization. This is accomplished with the following line:

init_file = data/StandingHighJumpFC2.par # use previous result
  • Run the scenario by pressing Ctrl + T

You will notice that the simulation is already jumping, because the parameters from the previous optimization were taken.

  • Start the optimization through Scenario → Optimize Scenario

As you can see, the initial fitness of the optimization is a lot higher than when starting from scratch. As the simulation progresses, you'll see the upper body staying more straight during the jump.

In order to make the optimization run as fast as possible, keep as few optimizations running as possible. Any optimization can be terminated by clicking on the little 'x' in the upper right corner of the optimization window.

Jumping with Knees Up

By default, JumpMeasure tracks the height of the COM of the model. However, it can also be changed to measure the maximum height of a point of a specific body part. For instance, we can measure knee height by inserting the following tag (see Tutorial 2d - Standing High Jump - Knees Up):

body = tibia_r

Note that, since our controller is symmetric, it doesn't matter which side of a body part we choose. In addition to changing the target, we will also add some control points to accommodate for the more complex activation pattern required for this type of jump:

control_points = 4

The init_file will still be used to initialize the first two control points from the earlier jump, but the last two will be optimized from scratch.

  • Start the optimization by pressing ``Ctrl + F5``

After clicking on one of the results, analyze the activation patterns in the Analysis tool, to find out what jumping strategies are found by the optimizer. You might notice that the optimization of this scenario does not progress as fast as the initial one. Apparently, optimizing knee height is more complex than optimizing the COM position!

  • by tgeijten