This is an example using the MocoInverse tool with a complex model to prescribe walking. This example also shows how to track electromyography data.
32 import opensim
as osim
34 def solveMocoInverse():
37 inverse = osim.MocoInverse()
43 modelProcessor = osim.ModelProcessor(
'subject_walk_scaled.osim')
44 modelProcessor.append(osim.ModOpAddExternalLoads(
'grf_walk.xml'))
45 modelProcessor.append(osim.ModOpIgnoreTendonCompliance())
46 modelProcessor.append(osim.ModOpReplaceMusclesWithDeGrooteFregly2016())
48 modelProcessor.append(osim.ModOpIgnorePassiveFiberForcesDGF())
50 modelProcessor.append(osim.ModOpScaleActiveFiberForceCurveWidthDGF(1.5))
56 modelProcessor.append(osim.ModOpReplacePathsWithFunctionBasedPaths(
57 "subject_walk_scaled_FunctionBasedPathSet.xml"))
58 modelProcessor.append(osim.ModOpAddReserves(1.0))
59 inverse.setModel(modelProcessor)
66 inverse.setKinematics(osim.TableProcessor(
'coordinates.sto'))
69 inverse.set_initial_time(0.48)
70 inverse.set_final_time(1.61)
71 inverse.set_mesh_interval(0.02)
75 inverse.set_kinematics_allow_extra_columns(
True)
78 solution = inverse.solve()
79 solution.getMocoSolution().write(
'example3DWalking_MocoInverse_solution.sto')
82 model = modelProcessor.process()
83 report = osim.report.Report(model,
84 'example3DWalking_MocoInverse_solution.sto',
89 def solveMocoInverseWithEMG():
92 inverse = osim.MocoInverse()
93 modelProcessor = osim.ModelProcessor(
'subject_walk_scaled.osim')
94 modelProcessor.append(osim.ModOpAddExternalLoads(
'grf_walk.xml'))
95 modelProcessor.append(osim.ModOpIgnoreTendonCompliance())
96 modelProcessor.append(osim.ModOpReplaceMusclesWithDeGrooteFregly2016())
97 modelProcessor.append(osim.ModOpIgnorePassiveFiberForcesDGF())
98 modelProcessor.append(osim.ModOpScaleActiveFiberForceCurveWidthDGF(1.5))
99 modelProcessor.append(osim.ModOpReplacePathsWithFunctionBasedPaths(
100 "subject_walk_scaled_FunctionBasedPathSet.xml"))
101 modelProcessor.append(osim.ModOpAddReserves(1.0))
102 inverse.setModel(modelProcessor)
103 inverse.setKinematics(osim.TableProcessor(
'coordinates.sto'))
104 inverse.set_initial_time(0.48)
105 inverse.set_final_time(1.61)
106 inverse.set_mesh_interval(0.02)
107 inverse.set_kinematics_allow_extra_columns(
True)
109 study = inverse.initialize()
110 problem = study.updProblem()
113 emgTracking = osim.MocoControlTrackingGoal(
'emg_tracking')
114 emgTracking.setWeight(50.0)
117 controlsRef = osim.TimeSeriesTable(
'electromyography.sto')
121 soleus = controlsRef.updDependentColumn(
'soleus')
122 gasmed = controlsRef.updDependentColumn(
'gastrocnemius')
123 tibant = controlsRef.updDependentColumn(
'tibialis_anterior')
124 for t
in range(0, controlsRef.getNumRows()):
125 soleus[t] = 0.77 * soleus[t]
126 gasmed[t] = 0.87 * gasmed[t]
127 tibant[t] = 0.37 * tibant[t]
128 emgTracking.setReference(osim.TableProcessor(controlsRef))
130 emgTracking.setReferenceLabel(
'/forceset/soleus_r',
'soleus')
131 emgTracking.setReferenceLabel(
'/forceset/gasmed_r',
'gastrocnemius')
132 emgTracking.setReferenceLabel(
'/forceset/gaslat_r',
'gastrocnemius')
133 emgTracking.setReferenceLabel(
'/forceset/tibant_r',
'tibialis_anterior')
134 problem.addGoal(emgTracking)
137 solution = study.solve()
138 solution.write(
'example3DWalking_MocoInverseWithEMG_solution.sto')
141 controlsRef.removeColumn(
'medial_hamstrings')
142 controlsRef.removeColumn(
'biceps_femoris')
143 controlsRef.removeColumn(
'vastus_lateralis')
144 controlsRef.removeColumn(
'vastus_medius')
145 controlsRef.removeColumn(
'rectus_femoris')
146 controlsRef.removeColumn(
'gluteus_maximus')
147 controlsRef.removeColumn(
'gluteus_medius')
148 controlsRef.setColumnLabels([
'/forceset/soleus_r',
'/forceset/gasmed_r',
149 '/forceset/tibant_r'])
150 controlsRef.appendColumn(
'/forceset/gaslat_r', gasmed)
151 osim.STOFileAdapter.write(controlsRef,
'controls_reference.sto')
155 model = modelProcessor.process()
156 output =
'example3DWalking_MocoInverseWithEMG_report.pdf' 158 'controls_reference.sto',
159 'example3DWalking_MocoInverseWithEMG_solution.sto']
160 report = osim.report.Report(model,
161 'example3DWalking_MocoInverse_solution.sto',
162 output=output, bilateral=
True,
164 colors=[
'black',
'blue',
'red'])
172 def solveMocoInverseWithSynergies(numSynergies=5):
177 modelProcessor = osim.ModelProcessor(
'subject_walk_scaled.osim')
178 modelProcessor.append(osim.ModOpAddExternalLoads(
'grf_walk.xml'))
179 modelProcessor.append(osim.ModOpIgnoreTendonCompliance())
180 modelProcessor.append(osim.ModOpIgnoreActivationDynamics())
181 modelProcessor.append(osim.ModOpReplaceMusclesWithDeGrooteFregly2016())
182 modelProcessor.append(osim.ModOpIgnorePassiveFiberForcesDGF())
183 modelProcessor.append(osim.ModOpScaleActiveFiberForceCurveWidthDGF(1.5))
184 modelProcessor.append(osim.ModOpReplacePathsWithFunctionBasedPaths(
185 "subject_walk_scaled_FunctionBasedPathSet.xml"))
186 modelProcessor.append(osim.ModOpAddReserves(1.0))
187 model = modelProcessor.process()
191 prevSolution = osim.MocoTrajectory(
'example3DWalking_MocoInverse_solution.sto')
192 leftControlNames = list()
193 rightControlNames = list()
195 for actu
in model.getComponentsList():
196 if actu.getConcreteClassName().endswith(
'Muscle'):
197 name = actu.getName()
198 if name.endswith(
'_r'):
199 rightControlNames.append(actu.getAbsolutePathString())
200 elif name.endswith(
'_l'):
201 leftControlNames.append(actu.getAbsolutePathString())
203 controls = prevSolution.exportToControlsTable()
204 leftControls = osim.TimeSeriesTable(controls.getIndependentColumn())
205 rightControls = osim.TimeSeriesTable(controls.getIndependentColumn())
206 for name
in leftControlNames:
207 leftControls.appendColumn(name, controls.getDependentColumn(name))
208 for name
in rightControlNames:
209 rightControls.appendColumn(name, controls.getDependentColumn(name))
237 from sklearn.decomposition
import NMF
239 nmf = NMF(n_components=numSynergies, init=
'random', random_state=0)
241 Al = leftControls.getMatrix().to_numpy()
242 Wl = nmf.fit_transform(Al)
245 Ar = rightControls.getMatrix().to_numpy()
246 Wr = nmf.fit_transform(Ar)
252 scaleVec = 0.5*np.ones(Hl.shape[1])
253 for i
in range(numSynergies):
254 scale_l = np.linalg.norm(scaleVec) / np.linalg.norm(Hl[i, :])
258 scale_r = np.linalg.norm(scaleVec) / np.linalg.norm(Hr[i, :])
263 leftController = osim.SynergyController()
264 leftController.setName(
"synergy_controller_left_leg")
267 for name
in leftControlNames:
268 leftController.addActuator(
269 osim.Muscle.safeDownCast(model.getComponent(name)))
273 for i
in range(numSynergies):
274 synergyVector = osim.Vector(Hl.shape[1], 0.0)
275 for j
in range(Hl.shape[1]):
276 synergyVector.set(j, Hl[i, j])
277 leftController.addSynergyVector(synergyVector)
278 model.addController(leftController)
281 rightController = osim.SynergyController()
282 rightController.setName(
"synergy_controller_right_leg")
283 for name
in rightControlNames:
284 rightController.addActuator(
285 osim.Muscle.safeDownCast(model.getComponent(name)))
286 for i
in range(numSynergies):
287 synergyVector = osim.Vector(Hr.shape[1], 0.0)
288 for j
in range(Hr.shape[1]):
289 synergyVector.set(j, Hr[i, j])
290 rightController.addSynergyVector(synergyVector)
291 model.addController(rightController)
292 model.finalizeConnections()
296 inverse = osim.MocoInverse()
297 inverse.setName(
"example3DWalking_MocoInverseWithSynergies")
298 inverse.setModel(osim.ModelProcessor(model))
299 inverse.setKinematics(osim.TableProcessor(
'coordinates.sto'))
300 inverse.set_initial_time(0.48)
301 inverse.set_final_time(1.61)
302 inverse.set_mesh_interval(0.02)
303 inverse.set_kinematics_allow_extra_columns(
True)
311 study = inverse.initialize()
312 problem = study.updProblem()
318 effort = osim.MocoControlGoal.safeDownCast(
319 problem.updGoal(
"excitation_effort"))
320 for i
in range(numSynergies):
321 nameLeft = (f
'/controllerset/synergy_controller_left_leg' 322 f
'/synergy_excitation_{i}')
323 problem.setInputControlInfo(nameLeft, [0, 1.0])
324 effort.setWeightForControl(nameLeft, 10)
326 nameRight = (f
'/controllerset/synergy_controller_right_leg' 327 f
'/synergy_excitation_{i}')
328 problem.setInputControlInfo(nameRight, [0, 1.0])
329 effort.setWeightForControl(nameRight, 10)
332 solution = study.solve()
336 solution.generateControlsFromModelControllers(model)
340 coordinateValues = prevSolution.exportToValuesTable()
341 coordinateSpeeds = prevSolution.exportToSpeedsTable()
342 solution.insertStatesTrajectory(coordinateValues)
343 solution.insertStatesTrajectory(coordinateSpeeds)
346 solutionFile = (f
'example3DWalking_MocoInverseWith' 347 f
'{numSynergies}Synergies_solution.sto')
348 solution.write(solutionFile)
352 output = (f
'example3DWalking_MocoInverseWith' 353 f
'{numSynergies}Synergies_report.pdf')
354 ref_files = [
'example3DWalking_MocoInverse_solution.sto']
355 report = osim.report.Report(model, solutionFile,
356 output=output, bilateral=
True,
358 colors=[
'black',
'red'])
368 solveMocoInverseWithEMG()
374 solveMocoInverseWithSynergies(numSynergies)