Healthy Gait
About
This tutorial shows how to optimize gait controllers, based on the model by [Geyer & Herr 2010].- Open the scenario
Tutorials/Tutorial 4a - Gait
As you can see, the scone file is fairly short and doesn't contain a Controller or a Measure. However, there is a section in the middle that says:
# Controller for gait, based on [Geyer & Herr 2010] << data/ControllerGH2010.scone >> # Measure for gait << data/MeasureGait10.scone >>
What this means is, we have moved the controller and measure code to different files, in order to keep things tidy. Before we look into any details, start the optimization (this will take a while).
- Click
Scenario → Optimize Scenario
or pressCtrl + F5
Controller [Geyer & Herr 2010]
The actual Controller is inside the file Tutorials/data/ControllerGH2010.scone
, which implements the controller defined by [Geyer & Herr 2010]:
# Gait controller adapted from [Geyer & Herr 2010] by Thomas Geijtenbeek GaitStateController { signature_postfix = "GH2010v8" stance_load_threshold = ~0.1<0.001,1> leg_load_sensor_delay = 0 symmetric = 1 ConditionalControllers { # TA stretch reflexes [Geyer & Herr 2010] ConditionalController { states = "EarlyStance LateStance Liftoff Swing Landing" ReflexController { MuscleReflex { target = tib_ant delay = 0.020 KL = ~1.1<-10,10> L0 = ~0.71<0,2> } MuscleReflex { target = tib_ant source = soleus delay = 0.020 KF = ~-0.3<-10,10> } } } # GAS and SOL F+ reflexes [Geyer & Herr 2010] ConditionalController { states = "EarlyStance LateStance Liftoff" ReflexController { MuscleReflex { target = soleus delay = 0.020 KF = ~1.2<-10,10> } MuscleReflex { target = gastroc delay = 0.020 KF = ~1.1<-10,10> } } } # Stance reflexes ConditionalController { states = "EarlyStance LateStance" ReflexController { Reflexes { # F+ VAS ConditionalMuscleReflex { target = vasti delay = 0.010 KF = ~1.15<-10,10> # G_VAS C0 = ~0.09<-1,1> # S_0,VAS dof = knee_angle pos_max = ~-0.175<-1,0> } # Root stability DofReflex { target = hamstrings source = pelvis_tilt delay = 0.005 KP = ~1.91<-10,10> # k_p KV = ~0.25<-10,10> # k_d P0 = -0.105 # theta_ref, not optimized because of C0 C0 = ~0.05<-1,1> # S_0,BAL } DofReflex { target = glut_max source = pelvis_tilt delay = 0.005 KP = ~1.91<-10,10> # k_p KV = ~0.25<-10,10> # k_d P0 = -0.105 # theta_ref, not optimized because of C0 C0 = ~0.05<-1,1> # S_0,BAL } DofReflex { target = iliopsoas source = pelvis_tilt delay = 0.005 KP = ~-1.91<-10,10> # -k_p KV = ~-0.25<-10,10> # -k_d P0 = -0.105 # theta_ref, not optimized because of C0 C0 = ~0.05<-1,1> # S_0,BAL } } } } # Double support reflexes ConditionalController { states = "Liftoff" ReflexController { MuscleReflex { target = iliopsoas delay = 0.005 C0 = ~0.25<-1,1> # DELTA_S } MuscleReflex { target = glut_max delay = 0.005 C0 = ~-0.25<-1,1> # DELTA_S } } } # Swing reflexes ConditionalController { states = "Swing Landing" ReflexController { # HFL excitation [Geyer & Herr 2010] MuscleReflex { target = iliopsoas delay = 0.005 KL = ~0.35<-10,10> # G_HFL L0 = ~0.6<0,2> # l_off_HFL } DofReflex { target = iliopsoas source = pelvis_tilt delay = 0.005 KP = ~1.15<-10,10> # k_lean KV = ~0.25<-10,10> # not in [GH2010] P0 = ~-0.105<-1,1> # theta_ref } # late-swing HFL inhibition [Geyer & Herr 2010] MuscleReflex { target = iliopsoas source = hamstrings delay = 0.005 KL = ~-4.0<-10,10> L0 = ~0.85<0,2> } # late-swing HAM and GLU reflexes [Geyer & Herr 2010] MuscleReflex { target = hamstrings delay = 0.005 KF = ~0.65<-10,10> } MuscleReflex { target = glut_max delay = 0.005 KF = ~0.4<-10,10> } } } } }
Gait at Different Speeds
- Open the file
Tutorials/Tutorial 4b - Gait at Different Speeds.scone
To optimize gait for different target speeds, we can simply change the optimization criterion. In this case, we define the optimization criterion in the file Tutorials/data/MeasureGait15.scone
:
# Measure for gait, minimum speed = 1.5 m/s CompositeMeasure { GaitMeasure { name = Gait weight = 100 threshold = 0.05 termination_height = 0.85 min_velocity = 1.5 } EffortMeasure { name = Effort weight = 0.1 measure_type = Wang2012 use_cost_of_transport = 1 } CompositeMeasure { name = DofLimits symmetric = 1 DofMeasure { weight = 0.1 dof = ankle_angle position { min = -60 max = 60 squared_penalty = 1 } } DofMeasure { weight = 0.01 threshold = 5 dof = knee_angle force { min = 0 max = 0 abs_penalty = 1 } } } }
The target speed is set by the min_velocity
tag in the GaitMeasure section. In addition, and EffortMeasure is used to minimize cost of transport, and DofMeasure is used to prevent knee and ankle hyper-extension.
Perturbed Gait
- Open the file
Tutorials/Tutorial 4c - Perturbed Gait.scone
Here you will see that we use a CompositeController that consists of our Geyer and Herr controller, in combination with a couple of PerturbationController entries:
CompositeController { # Controller for gait, based on [Geyer & Herr 2010] << data/ControllerGH2010.scone >> # Perturbation backwards every 4 seconds PerturbationController { start_time = 3 duration = 0.2 interval = 4 force = [ -100 0 0 ] body = pelvis position_offset = [ -0.15 0.35 0 ] } # Perturbation forwards every other 4 seconds PerturbationController { start_time = 5 duration = 0.2 interval = 4 force = [ 100 0 0 ] body = pelvis position_offset = [ -0.15 0.35 0 ] } }
Note that inside SCONE, a PerturbationController is a controller just like anything else, even though it does not work on internal actuators. A SCONE Controller is simply any entity that can generate actuator inputs in the simulation.
- Test the optimization by pressing
Ctrl + T
You'll see that, once the first perturbation kicks in, the model falls over immediately. The control parameters of the model have not yet been optimized to be robust against external perturbations.
- Start the optimization with
Ctrl + F5
After a while, you'll find that the gait controller will become more robust against perturbations. Note that we have increased the simulation time 30 seconds: can you think of a reason why?
Walking on Ice
To simulate walking on ice, we need to adjust the friction defined in the contact force. For this tutorial, we have created a separate model in which we have done exactly that (see Tutorials/data/Human0914Ice.osim
):
<HuntCrossleyForce name="foot_r"> <!--Flag indicating whether the force is disabled or not. Disabled means that the force is not active in subsequent dynamics realizations.--> <isDisabled>false</isDisabled> <!--Material properties.--> <HuntCrossleyForce::ContactParametersSet name="contact_parameters"> <objects> <HuntCrossleyForce::ContactParameters> <!--Names of geometry objects affected by these parameters.--> <geometry>platform r_heel r_toe</geometry> <stiffness>2e6</stiffness> <dissipation>1</dissipation> <static_friction>0.15</static_friction> <dynamic_friction>0.15</dynamic_friction> <viscous_friction>0.15</viscous_friction> </HuntCrossleyForce::ContactParameters> </objects> <groups /> </HuntCrossleyForce::ContactParametersSet> <!--Slip velocity (creep) at which peak static friction occurs.--> <transition_velocity>0.1</transition_velocity> </HuntCrossleyForce>
The tags to look for are called static_friction
and dynamic_friction
.
- Open the file
Tutorials/Tutorial 4d - Walking on Ice
In our SCONE scenario, we simply assign the new model file:
model_file = data/Human0914Ice.osim
We also change the objective function to allow for a lower minimum velocity:
<< data/MeasureGait05.scone >>
- Optimize the scenario with the modified OpenSim model (
Ctrl + F5
)
Eventually, this will produce a controller that is robust against walking on ice. Be sure to check the intermediate results in the Optimization Results
panel!