Standing Balance

About

This tutorial demonstrates how to use a ReflexController to perform a standing balance test.
  • Open the scenario Tutorials/Tutorial 3a - Standing Balance.scone

You may notice that the file is pretty short, but that it does contain the following lines:

# Controller for reflex based balance (different file)
<< data/ControllerReflexBalance.scone >>
 
# Measure for standing balance (different file)
<< data/MeasureBalance.scone >>

What happens here is that both the controller and the measure are defined in another file. This is great for reusing algorithms, and also makes the main file a little cleaner.

  • Test the scenario by pressing Ctrl + T

You'll that with the initial parameter settings, the human model falls pretty quickly.

  • Optimize the scenario by pressing Ctrl + F5

While SCONE is optimizing the scenario in the background, we can have a close look at what's going on.

  • Open the file Tutorials/data/ControllerReflexBalance.scone

In this file, you will find a controller of type ReflexController:

Controller {
	type = ReflexController
	symmetric = 1
 
	# Muscle length reflexes
	MuscleReflex { target = iliopsoas L0 = ~0.5 KL = ~1 delay = 0.010 }
	MuscleReflex { target = glut_max L0 = ~0.5 KL = ~1 delay = 0.010 }
	MuscleReflex { target = rect_fem L0 = ~0.5 KL = ~1 delay = 0.010 }
	MuscleReflex { target = hamstrings L0 = ~0.5 KL = ~1 delay = 0.010 }
	MuscleReflex { target = vasti L0 = ~0.5 KL = ~1 delay = 0.020 }
	MuscleReflex { target = gastroc L0 = ~0.5 KL = ~1 delay = 0.020 }
	MuscleReflex { target = soleus L0 = ~0.5 KL = ~1 delay = 0.035 }
	MuscleReflex { target = tib_ant L0 = ~0.5 KL = ~1 delay = 0.035 }
 
	# Vestibular reflexes
	BodyPointReflex { target = iliopsoas source = torso
		KP = 0~0.1 KV = 0~0.1 delay = 0.1 offset = [ 0 0.5 0 ] direction = [ 1 0 0 ] }
	BodyPointReflex { target = rect_fem source = torso
		KP = 0~0.1 KV = 0~0.1 delay = 0.1 offset = [ 0 0.5 0 ] direction = [ 1 0 0 ] }
	BodyPointReflex { target = vasti source = torso 
		KP = 0~0.1 KV = 0~0.1 delay = 0.1 offset = [ 0 0.5 0 ] direction = [ 1 0 0 ] }
	BodyPointReflex { target = tib_ant source = torso 
		KP = 0~0.1 KV = 0~0.1 delay = 0.1 offset = [ 0 0.5 0 ] direction = [ 1 0 0 ] }
	BodyPointReflex { target = glut_max source = torso 
		KP = 0~0.1 KV = 0~0.1 delay = 0.1 offset = [ 0 0.5 0 ] direction = [ 1 0 0 ] }
	BodyPointReflex { target = hamstrings source = torso 
		KP = 0~0.1 KV = 0~0.1 delay = 0.1 offset = [ 0 0.5 0 ] direction = [ 1 0 0 ] }
	BodyPointReflex { target = gastroc source = torso 
		KP = 0~0.1 KV = 0~0.1 delay = 0.1 offset = [ 0 0.5 0 ] direction = [ 1 0 0 ] }
	BodyPointReflex { target = soleus source = torso 
		KP = 0~0.1 KV = 0~0.1 delay = 0.1 offset = [ 0 0.5 0 ] direction = [ 1 0 0 ] }
}

Controllers of type ReflexController contain one or more Reflex entrym each of which defines a reflex arc, with a specific gains, offsets and delay. In our example, we use MuscleReflex to simulate proprioceptic reflexes, and BodyPointReflex to simulate vestibulair reflexes. Both gains and offsets are initialized using our global variables – this makes it easy to experiment with different initial values.

Finally, we define our fitness in the file Tutorials/data/MeasureBalance.scone.

  • Open the file Tutorials/data/MeasureBalance.scone

You will find a CompositeMeasure that contains terms for not falling, minimizing effort and penalizing locked knees:

# Measure for standing balance
CompositeMeasure {
	# Penalize falling
	BalanceMeasure {
		termination_height = 0.8
		weight = 100
	}
 
	# Minimize effort
	EffortMeasure {
		name = Effort
		weight = 0.01
		measure_type = Wang2012
	}
 
	# Penalize locked knees
	DofMeasure {
		dof = knee_angle_r
		position { min = -30 max = 0 abs_penalty = 10 }
	}
}

Our measure combines a BalanceMeasure to detect falling and an EffortMeasure to minimize energy. In addition, we use DofMeasure to penalize upper body sway and locked knees.

Analyzing the Results

After a while, you'll notice that the optimization results get better. In this case, we are penalizing falling, which means a lower value indicates a better result.

  • Check the results by clicking on the most recent item in Optimization Results

After playing back the results, it's possible to analyze the contribution of each of the feedback paths using the analysis tool. They can be best found by typing a capital 'R' in the filter box:

Standing Balance with Motor Noise

When optimizing balance, you might notice that the results aren't entirely realistic. One way to improve this is to add motor noise (see also Tutorial 3b - Standing Balance - Motor Noise):

# CompositeController with multiple sub-controllers
CompositeController {
	# Controller for reflex based balance (different file)
	<< data/ControllerReflexBalance.scone >>
 
	# Motor noise controller
	NoiseController {
		base_noise = 0.01
		proportional_noise = 0.1
	}
}
  • by tgeijten