API  4.5
For C++ developers
exampleEMGTracking.py

This is an example that uses the MocoInverse tool and EMG data to create an EMG-driven simulation of walking. This example is used in hands-on workshops, and accordingly has blanks that users must fill in. See exampleSquatToStand_answers.m for a completed version.

1 import opensim as osim
2 import exampleEMGTracking_helpers as helpers
3 import os
4 import numpy as np
5 
6 
9 
10 # Part 1a: Load a 19 degree-of-freedom model with 18 lower-limb,
11 # sagittal-plane muscles and a torque-actuated torso. This includes a set of
12 # ground reaction forces applied to the model via ExternalLoads, which is
13 # necessary for the muscle redundancy problem. See the function definition
14 # at the bottom of this file to see how the model is loaded and constructed.
15 model = helpers.getWalkingModel()
16 
17 # Part 1b: Create the MocoInverse tool and set the Model.
18 
19 
20 # Part 1c: Create a TableProcessor using the coordinates file from inverse
21 # kinematics.
22 
23 
24 # Part 1d: Set the kinematics reference for MocoInverse using the
25 # TableProcessor we just created.
26 
27 
28 # Part 1e: Provide the solver settings: initial and final time, the mesh
29 # interval, and the constraint and convergence tolerances.
30 inverse.set_initial_time( )
31 inverse.set_final_time( )
32 inverse.set_mesh_interval( )
33 inverse.set_constraint_tolerance( )
34 inverse.set_convergence_tolerance( )
35 
36 if not os.path.isfile('effortSolution.sto'):
37  # Part 1f: Solve the problem!
38 
39 
40 
45 emgReference = osim.TimeSeriesTable('emg.sto')
46 helpers.compareSolutionToEMG(emgReference, 'effortSolution.sto')
47 
48 
51 
52 # Part 3a: Call initialize() to get access to the MocoStudy contained within
53 # the MocoInverse instance. This will allow us to make additional
54 # modifications to the problem not provided by MocoInverse.
55 
56 
57 # Part 3b: Create a MocoControlTrackingGoal, set its weight, and provide
58 # the EMG data as the tracking reference. We also need to specify the
59 # reference labels for the four muscles whose EMG we will track.
60 tracking =
61 tracking.setWeight( )
62 tracking.setReference( )
63 tracking.setReferenceLabel('/forceset/gasmed_l', 'gastrocnemius')
64 tracking.setReferenceLabel('/forceset/tibant_l', 'tibialis_anterior')
65 tracking.setReferenceLabel('/forceset/bfsh_l', 'biceps_femoris')
66 tracking.setReferenceLabel( )
67 
68 # Part 3c: The EMG signals in the tracking are all normalized to have
69 # a maximum value of 1, but the magnitudes of the excitations from the
70 # effort minimization solution suggest that these signals should be
71 # rescaled. Use addScaleFactor() to add a MocoParameter to the problem that
72 # will scale the reference data for the muscles in the tracking cost.
73 tracking.addScaleFactor('gastroc_factor', '/forceset/gasmed_l', [0.01, 1.0])
74 tracking.addScaleFactor('tibant_factor', '/forceset/tibant_l', [0.01, 1.0])
75 tracking.addScaleFactor('bifem_factor', '/forceset/bfsh_l', [0.01, 1.0])
76 tracking.addScaleFactor( )
77 
78 # Part 3d: Add the tracking goal to the problem.
79 
80 
81 # Part 3e: Update the MocoCasADiSolver with the updated MocoProblem using
82 # resetProblem().
83 solver = osim.MocoCasADiSolver.safeDownCast(study.updSolver())
84 solver.resetProblem(problem)
85 
86 # Part 3f: Tell MocoCasADiSolver that the MocoParameters we added to the
87 # problem via addScaleFactor() above do not require initSystem() calls on
88 # the model. This provides a large speed-up.
89 
90 
91 if not os.path.isfile('trackingSolution.sto'):
92  # Part 3g: Solve the problem!
93 
94 
95 
96 # Part 3h: Get the values of the optimized scale factors.
97 trackingSolution = osim.MocoTrajectory('trackingSolution.sto')
98 gastroc_factor = trackingSolution.getParameter('gastroc_factor')
99 tibant_factor = trackingSolution.getParameter('tibant_factor')
100 bifem_factor = trackingSolution.getParameter('bifem_factor')
101 gluteus_factor =
102 
103 
105 print('\nOptimized scale factor values:')
106 print('------------------------------')
107 print('gastrocnemius = ' + str(gastroc_factor))
108 print('tibialis anterior = ' + str(tibant_factor))
109 print('biceps femoris short head = ' + str(bifem_factor))
110 print('gluteus = ' + str(gluteus_factor))
111 
112 # Part 4b: Re-scale the reference data using the optimized scale factors.
113 gastroc = emgReference.updDependentColumn('gastrocnemius')
114 tibant = emgReference.updDependentColumn('tibialis_anterior')
115 bifem = emgReference.updDependentColumn('biceps_femoris')
116 gluteus = emgReference.updDependentColumn('gluteus')
117 for t in np.arange(emgReference.getNumRows()):
118  t = int(t) # Convert to Python built-in int type for indexing
119  gastroc[t] = gastroc_factor * gastroc[t]
120  tibant[t] = tibant_factor * tibant[t]
121  bifem[t] = bifem_factor * bifem[t]
122  gluteus[t] = gluteus_factor * gluteus[t]
123 
124 # Part 4c: Generate the plots. Compare results to the effort minimization
125 # solution.
126 helpers.compareSolutionToEMG(emgReference, 'effortSolution.sto',
127  'trackingSolution.sto')
128