I did not have any problems with the 2D walking examples, but this 3D example does not seem to work for me.
The torque-driven marker tracking example finishes in about 650 iterations with an objective value of 99.821. IPOPT says the problem is solved. But I don't think this is a valid solution. The visualizer window shows a random swarm of moving markers and nothing else. The plots do not look good either. I have not tried the muscle-driven state tracking yet.
Any clues what might be happening, or how to troubleshoot?
This is with OpenSim 4.3 and Matlab 2021a.
I have attached the visualizer window, the beginning of the plots and also my Windows path in case that is an issue.
Ton van den Bogert
exampleMocoTrack (Matlab)
- Nicholas Bianco
- Posts: 1056
- Joined: Thu Oct 04, 2012 8:09 pm
Re: exampleMocoTrack (Matlab)
Hi Ton,
Yes, that definitely looks wrong. There have been other posts about the marker tracking examples and there is a GitHub issue for it: https://github.com/opensim-org/opensim-core/issues/3094.
I'll try to investigate this soon so we can include a fix for the next release.
Best,
Nick
Yes, that definitely looks wrong. There have been other posts about the marker tracking examples and there is a GitHub issue for it: https://github.com/opensim-org/opensim-core/issues/3094.
I'll try to investigate this soon so we can include a fix for the next release.
Best,
Nick
- Nicholas Bianco
- Posts: 1056
- Joined: Thu Oct 04, 2012 8:09 pm
Re: exampleMocoTrack (Matlab)
Hi Ton,
I've figured out what is causing this issue. In the marker tracking example, the reference marker data is set using "track.setMarkersReferenceFromTRC('marker_trajectories.trc')". This method takes the marker file as the main argument (shown), and optionally you can provide a second argument to customize the low-pass filter frequency (which is 6 Hz by default). The filtering was causing the problem; when I remove it from the problem by using "track.setMarkersReference()" instead, the problem solves as expected.
Here's how to do that (in Matlab):
Let me know if that works for you.
Best,
Nick
I've figured out what is causing this issue. In the marker tracking example, the reference marker data is set using "track.setMarkersReferenceFromTRC('marker_trajectories.trc')". This method takes the marker file as the main argument (shown), and optionally you can provide a second argument to customize the low-pass filter frequency (which is 6 Hz by default). The filtering was causing the problem; when I remove it from the problem by using "track.setMarkersReference()" instead, the problem solves as expected.
Here's how to do that (in Matlab):
Code: Select all
markers = TimeSeriesTableVec3('marker_trajectories.trc');
tableProcessor = TableProcessor(markers.flatten());
track.setMarkersReference(tableProcessor);
Let me know if that works for you.
Best,
Nick
- Ton van den Bogert
- Posts: 167
- Joined: Thu Apr 27, 2006 11:37 am
Re: exampleMocoTrack (Matlab)
It took me a while to get back to this, but Nick's suggestion worked. Thanks, Nick!
I tried the example in OpenSim 4.4 and it still needs this same fix to work correctly.
When the solution was visualized, there were markers but no bones. I assumed that the visualizer would look in the main OpenSim Geometry folder, but that is not the case (at least on my installation).
The fix for this is mentioned in the Matlab API documentation: ModelVisualizer.addDirToGeometrySearchPaths(path). I did this before the solve and visualize and that worked.
Then all bones showed up except four: left and right tibia and femur. The .osim file does not have the correct VTP file names for those. Change r_femur.vtp to femur_r.vtp etc.
A few other things that I noticed, not critical but somewhat annoying:
I tried the example in OpenSim 4.4 and it still needs this same fix to work correctly.
When the solution was visualized, there were markers but no bones. I assumed that the visualizer would look in the main OpenSim Geometry folder, but that is not the case (at least on my installation).
The fix for this is mentioned in the Matlab API documentation: ModelVisualizer.addDirToGeometrySearchPaths(path). I did this before the solve and visualize and that worked.
Then all bones showed up except four: left and right tibia and femur. The .osim file does not have the correct VTP file names for those. Change r_femur.vtp to femur_r.vtp etc.
A few other things that I noticed, not critical but somewhat annoying:
- When I delete the "delete_this" file to stop the optimization, it throws an exception about the trajectory being sealed. The exception happens inside MocoTrack_solveAndVisualize(Native Method) so I never have a chance to unseal it. It would be nice, for testing, to stop the optimization prematurely and see the result. I remember this working correctly before, maybe in 4.3.
- On my computer, osimMocoTrajectoryReport generates a PostScript file, and the "open" function then opens this as text in the Matlab editor, which is not useful. I can open PS files, so not a big deal but I think the user needs more information. I looked at osimMocoTrajectoryReport.m and figured out that I need to install ps2dpf to make this work correctly.
- Nicholas Bianco
- Posts: 1056
- Joined: Thu Oct 04, 2012 8:09 pm
Re: exampleMocoTrack (Matlab)
Hi Ton, glad it worked!
The issue was actually related to the marker millimeters-to-meters units conversion that was happening inside of setMarkersReferenceFromTRC(); the MarkersReference class already handles this conversion (if needed), so we were converting twice by accident.
Best,
Nick
The issue was actually related to the marker millimeters-to-meters units conversion that was happening inside of setMarkersReferenceFromTRC(); the MarkersReference class already handles this conversion (if needed), so we were converting twice by accident.
If you get the MocoStudy directly using MocoTrack::initialize(), you can call unseal():When I delete the "delete_this" file to stop the optimization, it throws an exception about the trajectory being sealed. The exception happens inside MocoTrack_solveAndVisualize(Native Method) so I never have a chance to unseal it. It would be nice, for testing, to stop the optimization prematurely and see the result. I remember this working correctly before, maybe in 4.3.
Code: Select all
track = MocoTrack();
% your MocoTrack problem settings here
% solve and unseal
study = track.initialize();
solutionSealed = study.solve();
solution = solutionSealed.unseal();
% visualize
study.visualize(solution);
That reporting script could definitely be improved. Glad you found a temporary fix for the PS conversion. (FYI, if you don't mind switching to Python, there's there much better 'report.py' tool for auto-generating a report from your MocoSolutions. You could even keep your existing Matlab workflow and write a quick Python script just for reporting to use this tool.)On my computer, osimMocoTrajectoryReport generates a PostScript file, and the "open" function then opens this as text in the Matlab editor, which is not useful. I can open PS files, so not a big deal but I think the user needs more information. I looked at osimMocoTrajectoryReport.m and figured out that I need to install ps2dpf to make this work correctly.
Best,
Nick
- Ton van den Bogert
- Posts: 167
- Joined: Thu Apr 27, 2006 11:37 am
Re: exampleMocoTrack (Matlab)
Thanks, Nick.
Your suggestions worked. It makes some sense that solveAndVisualize fails to visualize when the solution is sealed. There was already a comment in the code that suggested using track.solve to skip the visualization, and that allowed me to unseal before saving and plotting the results.
I am curious though, to visualize the unsealed solution, why is track.initialize needed to create a study? track.solve and study.solve seem to work identically. So I tried track.visualize and that was not a valid method for the MocoTrack class. Trying to develop some intuition... Don't know if I could have learned about track.initialize if you had not told me.
It might be more clear if "solve" was not allowed in MocoTrack and/or the example code already used study = track.initialize and study.solve. Then I would look up initialize in the MocoTrack documentation, learn that it produces a MocoStudy and find the solve and visualize methods in MocoStudy.
It is still hard for me to go beyond the example code, but definitely becoming more familiar with the API documentation.
Ton
Your suggestions worked. It makes some sense that solveAndVisualize fails to visualize when the solution is sealed. There was already a comment in the code that suggested using track.solve to skip the visualization, and that allowed me to unseal before saving and plotting the results.
I am curious though, to visualize the unsealed solution, why is track.initialize needed to create a study? track.solve and study.solve seem to work identically. So I tried track.visualize and that was not a valid method for the MocoTrack class. Trying to develop some intuition... Don't know if I could have learned about track.initialize if you had not told me.
It might be more clear if "solve" was not allowed in MocoTrack and/or the example code already used study = track.initialize and study.solve. Then I would look up initialize in the MocoTrack documentation, learn that it produces a MocoStudy and find the solve and visualize methods in MocoStudy.
It is still hard for me to go beyond the example code, but definitely becoming more familiar with the API documentation.
Ton
- Nicholas Bianco
- Posts: 1056
- Joined: Thu Oct 04, 2012 8:09 pm
Re: exampleMocoTrack (Matlab)
Hi Ton,
Within MocoTrack, solveAndVisualize() makes the (equivalent to the) following calls:
Only MocoStudy has the visualize() method, so if you need to make any changes in between these methods (i.e., unseal()), you need to call initialize() first. MocoTrack is basically a convenience class for creating a MocoStudy which it manages internally. The initialize() method gives you access to this MocoStudy if you wish to make further changes to it beyond what MocoTrack offers. This interface can be a bit clunky at times though, and I'd like to improve it eventually, but I haven't figured out exactly how I want to do that yet.
Hopefully that helps!
-Nick
Within MocoTrack, solveAndVisualize() makes the (equivalent to the) following calls:
Code: Select all
MocoStudy study = track.initalize();
MocoSolution solution = study.solve();
study.visualize(solution);
Hopefully that helps!
-Nick