-
Notifications
You must be signed in to change notification settings - Fork 327
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding SynergyController
#3796
Adding SynergyController
#3796
Conversation
…misordered table states
@aymanhab or @carmichaelong, do either of you have bandwidth for a review? @AlbertoCasasOrtiz, if you're interested in learning more about opensim-core, tagging along as a second reviewer here would be a good place to start! |
I've made a few updates: added Python and Matlab versions of the new example, and changes to the bindings to support these examples (and |
@carmichaelong @AlbertoCasasOrtiz I made a few small changes, but this is now ready for review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @nickbianco, I left some comments throughout and had two higher level comments:
- It looks like users only interact with
SynergyVector
by passing in and usingSimTK::Vector
orSimTK:Matrix
and don't use the names (though I may have missed a use case somewhere). What's the rationale for adding theSynergyVector
class, since it looks like the controller deal with indexing for users? - Did you consider adding the synergy examples as different files (even within the same example folders)?
Reviewed 12 of 15 files at r1, 7 of 10 files at r2, 4 of 5 files at r3, 3 of 3 files at r4, 1 of 1 files at r5.
Reviewable status: all files reviewed (commit messages unreviewed), 7 unresolved discussions (waiting on @AlbertoCasasOrtiz and @nickbianco)
Bindings/Java/Matlab/examples/Moco/example3DWalking/exampleMocoInverse.m
line 275 at r4 (raw file):
[Wr, Hr] = nnmf(Ar, numSynergies); % Scale W and H assuming that the elements of H are all 0.5.
could be helpful for users to give them a better sense of what the scaling is trying to do (on a high level), either in the comment block just above for SynergyController, or right here
Bindings/Java/Matlab/examples/Moco/example3DWalking/exampleMocoInverse.m
line 275 at r4 (raw file):
[Wr, Hr] = nnmf(Ar, numSynergies); % Scale W and H assuming that the elements of H are all 0.5.
how different is scaling after performing nnmf, rather than scaling within each loop of nnmf (as in the function in CommonUtilities.cpp
?
Bindings/Python/examples/Moco/example3DWalking/exampleMocoInverse.py
line 249 at r4 (raw file):
Hr = nmf.components_ # Scale W and H assuming that the elements of H are all 0.5.
same comment as in matlab example
OpenSim/Common/CommonUtilities.cpp
line 255 at r4 (raw file):
} } for (int i = 0; i < H0.nrow(); ++i) {
based on the paper for alternating least squares (and subsequent code), does H0
need to be initialized systematically randomly (or just be a matrix of the correct size with arbitrary values)?
OpenSim/Common/CommonUtilities.cpp
line 298 at r4 (raw file):
// Compute error using the Frobenius norm. error = A - W * H; normError = std::sqrt(error.scalarNormSqr()) /
interesting way to normalize this error and makes sense. is this a typical way to do so? i didn't see it in the cited paper
OpenSim/Common/CommonUtilities.cpp
line 318 at r4 (raw file):
normError0 = normError; W0 = W; H0 = H;
actually, i think H0
could be removed all together?
OpenSim/Moco/MocoProblemRep.cpp
line 49 at r5 (raw file):
// Mute non-critical Logger output. Logger::Level origLoggerLevel = Logger::getLevel(); Logger::setLevel(Logger::Level::Warn);
is there any reason a developer (or advanced user) may want to see these, or is it all actually clutter for common users?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @carmichaelong.
- The helper class
SynergyVector
is mainly to make the XML more readable. If I instead used made thesynergy_vectors
property a list ofSimTK::Vector
, in XML, all the synergy vector weights get concatenated into one long vector. Using theSynergyVector
type as an intermediate class breaks up each synergy vector into a readable XML component. - I did, but since the synergy example uses the solution from the first sub-example in
exampleMocoInverse
, I think it makes sense to keep them in the same file.
Reviewable status: 22 of 27 files reviewed, 7 unresolved discussions (waiting on @AlbertoCasasOrtiz and @carmichaelong)
Bindings/Java/Matlab/examples/Moco/example3DWalking/exampleMocoInverse.m
line 275 at r4 (raw file):
Previously, carmichaelong wrote…
could be helpful for users to give them a better sense of what the scaling is trying to do (on a high level), either in the comment block just above for SynergyController, or right here
Updated the comment.
Bindings/Java/Matlab/examples/Moco/example3DWalking/exampleMocoInverse.m
line 275 at r4 (raw file):
Previously, carmichaelong wrote…
how different is scaling after performing nnmf, rather than scaling within each loop of nnmf (as in the function in
CommonUtilities.cpp
?
I don't think it really matters much. All three examples will give slightly different synergy vectors and weights, but I think that's fine. These aren't supposed to be rigorous examples for extracting synergies, just a demo of the new controller.
Bindings/Python/examples/Moco/example3DWalking/exampleMocoInverse.py
line 249 at r4 (raw file):
Previously, carmichaelong wrote…
same comment as in matlab example
Done.
OpenSim/Common/CommonUtilities.cpp
line 255 at r4 (raw file):
Previously, carmichaelong wrote…
based on the paper for alternating least squares (and subsequent code), does
H0
need to be initialized systematically randomly (or just be a matrix of the correct size with arbitrary values)?
I've removed H0
based on your other comment.
OpenSim/Common/CommonUtilities.cpp
line 298 at r4 (raw file):
Previously, carmichaelong wrote…
interesting way to normalize this error and makes sense. is this a typical way to do so? i didn't see it in the cited paper
I did this based on a recommendation from B.J. It's just a way to scale synergy weights and excitations into "reasonable" ranges.
OpenSim/Common/CommonUtilities.cpp
line 318 at r4 (raw file):
Previously, carmichaelong wrote…
actually, i think
H0
could be removed all together?
Ah yes, it is totally unused!
OpenSim/Moco/MocoProblemRep.cpp
line 49 at r5 (raw file):
Previously, carmichaelong wrote…
is there any reason a developer (or advanced user) may want to see these, or is it all actually clutter for common users?
I've removed these changes. The InputController
changes add some clutter because until the ControlDistributor
is connected to the model's InputController
s, the controller will print a message saying that the controller will be ignored. I'd like to keep this message for the component in general, but I also don't want to confuse users in Moco. But I also don't necessarily want to ignore all print outs in MocoProblemRep
either.
For now I think we keep them, I can patch in a better solution later, maybe after some user feedback.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All of the responses throughout sound good to me, thanks for all the explanations/clarifications!
Reviewed 6 of 6 files at r6, all commit messages.
Reviewable status:complete! all files reviewed, all discussions resolved (waiting on @AlbertoCasasOrtiz)
Thanks @carmichaelong! |
The failing tests on the Windows2022 are unrelated, so I'm merging. Thanks @carmichaelong and @AlbertoCasasOrtiz! |
Fixes issue #3677
Brief summary of changes
Adds
SynergyController
, a controller that computes controls for a model based on a linear combination of a set of Input control signals and a set of synergy vectors. These changes also include a new utility function for performing basic non-negative matrix factorization, and a sub-example inexampleMocoInverse
demostrating how to useSynergyController
with Moco.Other changes include:
CommonUtilities
function for performing basic non-negative factorization, to support the new example.report.py
andosimMocoTrajectoryReport.m
for plotting Input controls.MocoTrajectory
where thegetValuesTrajectory
,getSpeedsTrajectory
, etc., functions were returning the incorrect matrices if the trajectory was not organized a specific way.getInputControl()
).Testing I've completed
testMocoControllers.cpp
was refactored to useSynergyController.cpp
in favor of the customTriplePendulumController
class. Added unit tests specificSynergyController
.Looking for feedback on...
CHANGELOG.md (choose one)
[perf-win]
Performance analysis
Platform: Windows, self-hosted runner
This change is