Standing Balance
About
This tutorial demonstrates how to use a ReflexController to perform a standing balance test.Balance Control
- Open the scenario
Tutorials/Tutorial 3a - 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.
Reflex Balance Controller
- Open the file
Tutorials/data/ControllerReflexBalance.scone
In this file, you will find a controller of type ReflexController:
# Some predefined variables we use later on $L0 = ~0.5 $KL = ~1 $KP = 0~0.1 $KV = 0~0.1 $VDELAY = 0.1 $OFS = [ 0 0.5 0 ] $DIR = [ 1 0 0 ] ReflexController { name = Balance symmetric = 1 # Muscle length reflexes MuscleReflex { target = iliopsoas L0 = $L0 KL = $KL delay = 0.010 } MuscleReflex { target = glut_max L0 = $L0 KL = $KL delay = 0.010 } MuscleReflex { target = rect_fem L0 = $L0 KL = $KL delay = 0.010 } MuscleReflex { target = hamstrings L0 = $L0 KL = $KL delay = 0.010 } MuscleReflex { target = vasti L0 = $L0 KL = $KL delay = 0.020 } MuscleReflex { target = gastroc L0 = $L0 KL = $KL delay = 0.020 } MuscleReflex { target = soleus L0 = $L0 KL = $KL delay = 0.035 } MuscleReflex { target = tib_ant L0 = $L0 KL = $KL delay = 0.035 } # Vestibular reflexes BodyPointReflex { target = iliopsoas source = torso KP = $KP KV = $KV delay = $VDELAY offset = $OFS direction = $DIR } BodyPointReflex { target = rect_fem source = torso KP = $KP KV = $KV delay = $VDELAY offset = $OFS direction = $DIR } BodyPointReflex { target = vasti source = torso KP = $KP KV = $KV delay = $VDELAY offset = $OFS direction = $DIR } BodyPointReflex { target = tib_ant source = torso KP = $KP KV = $KV delay = $VDELAY offset = $OFS direction = $DIR } BodyPointReflex { target = glut_max source = torso KP = $KP KV = $KV delay = $VDELAY offset = $OFS direction = $DIR } BodyPointReflex { target = hamstrings source = torso KP = $KP KV = $KV delay = $VDELAY offset = $OFS direction = $DIR } BodyPointReflex { target = gastroc source = torso KP = $KP KV = $KV delay = $VDELAY offset = $OFS direction = $DIR } BodyPointReflex { target = soleus source = torso KP = $KP KV = $KV delay = $VDELAY offset = $OFS direction = $DIR } }
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 proprioceptive reflexes, and BodyPointReflex to simulate vestibular reflexes.
In the Parameters window, you can see all the optimization parameters defined by this controller. These include the muscle length reflex gains and offsets defined in MuscleReflex (ending with .KL
and .L0
), as well as the parameters from the BodyPointReflex (ending with .KP
and .KD
).
Balance Objective
Finally, we define the objective function 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 RL
in the filter box:
Adding 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:
- Open the file
Tutorial 3b - Motor Noise Balance.scone
You will find that the controller has been adjusted to add include motor noise, using a NoiseController.
# 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 } }
- Optimize the scenario by pressing
Ctrl + F5
Now, compare the results to the previous optimization. You'll find quite a difference in both the muscle excitation patterns, as well as in the resulting balance strategy!