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.
- Evaluate the scenario by pressing
Ctrl + E
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 entries, 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 vestibular reflexes.
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 } }