Page 1 of 1
ligament boundary conditions
Posted: Sun Feb 18, 2024 9:18 pm
by hojin95
Hi MOCO Experts,
I was wondering if there's a way to set boundary conditions for ligament properties? I'm hoping to give upper cap on either ligament's elongation or tension so the ligament won't go beyond the upper limit. It seems the ligament component in OpenSim doesn't have any boundary component. If a custom boundary condition is needed, would you let me know how or where can I find a reference to start with?
Best,
Hojin
Re: ligament boundary conditions
Posted: Mon Feb 19, 2024 8:04 am
by rosshm
Hi Hojin,
Ligament length isn't a control, state, or parameter, so I don't think it can be directly bounded.
You could bound the allowed ranges on the DOF spanned by the ligament to indirectly limit its length.
Ross
Re: ligament boundary conditions
Posted: Tue Feb 20, 2024 5:34 am
by pvb
HI all,
I've never used it, but could MocoOutputConstraint work here (
https://simtk.org/api_docs/opensim/api_ ... raint.html), assuming ligaments have an output "length" ?
Cheers,
Pasha
Re: ligament boundary conditions
Posted: Tue Feb 20, 2024 4:50 pm
by nbianco
Hi all,
MocoOutputConstraint isn't quite what you need: it's a path constraint that bounds a continuous output value across the trajectory. However,
MocoInitialOutputGoal and
MocoFinalOutputGoal, when used in "endpoint constraint" mode, could be used to this effect.
Best,
Nick
Re: ligament boundary conditions
Posted: Wed Feb 21, 2024 7:17 pm
by hojin95
Hi all,
Thank you all for your replies!
However, MocoInitialOutputGoal and MocoFinalOutputGoal, when used in "endpoint constraint" mode, could be used to this effect.
1) Nick, I'm just wondering if having both goals in endpoint constraint mode, will it gives maximum boundaries to ligaments throughout the movement or just at the initial and final pose?
2) In addition to the question above, I've tried to include MocoInitialOutputGoal in "endpoint constraint" mode, but it seems I can't set the boundary using MocoBounds. The codes below are things that I've tried:
Code: Select all
auto* ligCap = problem.addGoal<MocoInitialOutputGoal>("constraint");
ligCap->setMode("endpoint_constraint");
ligCap->setOutputPath("/forceset/cPT/geometrypath\|length");
auto conInfo = ligCap->updConstraintInfo();
conInfo.setBounds(MocoBounds(0, 1));
Code: Select all
auto ligCap = MocoInitialOutputGoal("constraint");
ligCap.setMode("endpoint_constraint");
ligCap.setOutputPath("/forceset/cPT/geometrypath\|length");
auto info = ligCap.updConstraintInfo();
info.setBounds(MocoBounds(0, 1));
problem.addGoal(ligCap);
Either way, I'm getting an error message at MocoBounds that says:
no suitable user-defined conversion from "OpenSim::MocoBounds" to "const std::vector<OpenSim::MocoBounds, std::allocator<OpenSim::MocoBounds>>" exists
Were there anything wrong in the code or we cannot set the boundaries when using MocoInitialOutputGoal?
![error.PNG](./download/file.php?id=7572&sid=830b801eb2d67aab965312513c9198fc)
- error.PNG (22.68 KiB) Viewed 3398 times
3) Moreover, it looks MocoOutputGoal also supports "endpoint constraint" mode. Can it achieve the same goal (giving an upper boundary to the ligament tension or length) throughout the entire movement?
Apologies for a long question
Best,
Hojin
Re: ligament boundary conditions
Posted: Thu Feb 22, 2024 11:28 am
by nbianco
Hi Hojin,
1) Apologies, you used the term "boundary" so my mind immediately went to the notion of a "boundary constraint" (or "endpoint constraint" as we call it in Moco) in an optimal control problem. After more carefully reading your post, I see that MocoOutputConstraint is really what you need, as it will apply a bounds across the whole trajectory via a path constraint.
2) MocoConstraintInfo expects a vector of MocoBounds (this is true for MocoOutputConstraint as well). If you only have one constraint (either path or endpoint), then it should be a vector of length one.
3) As I said above, MocoOutputConstraint is what you are looking for. (Since you asked: MocoOutputGoal in endpoint constraint mode will apply bounds to the intergral of the specified output.)
Best,
Nick
Re: ligament boundary conditions
Posted: Fri Feb 23, 2024 12:40 am
by hojin95
Hi NIck,
Thank you for letting me know that I should use MocoOutputConstraint.
Sadly, after trying using MocoOutputConstraint, I'm facing a new issue where the build was succeed but in the debug console, it was killed before starting Moco. The code that I used is as follows:
Code: Select all
ForceSet fset = model.getForceSet();
string ligName; double restLength; double maxLength;
for (int j = 0; j < fset.getSize(); ++j) {
const Ligament* ligament = dynamic_cast<Ligament*>(&fset.get(j));
ligName = ligament->getName();
restLength = ligament->get_resting_length();
maxLength = restLength * 1.1; // 10% strain
std::vector<MocoBounds> bound;
bound.push_back(MocoBounds(0, maxLength));
auto* ligcon = problem.addPathConstraint<MocoOutputConstraint>();
ligcon->setOutputPath("/forceset/" + ligName + "/geometrypath|length");
auto& coninfo = ligcon->updConstraintInfo();
coninfo.setBounds(bound);
};
and the error is:
![err1.PNG](./download/file.php?id=7581&sid=830b801eb2d67aab965312513c9198fc)
- err1.PNG (14.38 KiB) Viewed 3377 times
Alternately, I have tried adding the constraints one by one instead of using a for loop to see if the for loop was the problem. However, it returns the same error. The code I've used for this is:
Code: Select all
std::vector<double> ligmax = { 0.0539138, 0.0868513, 0.0683794, 0.058454,
0.0891373, 0.0911248, 0.0920834, 0.0458089, 0.0457561, 0.0461644,
0.0460183, 0.0448821, 0.0445418 };
std::vector<MocoBounds> bound_aLCL;
bound_aLCL.push_back(MocoBounds(0, ligmax[1]));
auto* ligcon_aLCL = problem.addPathConstraint<MocoOutputConstraint>();
ligcon_aLCL->setOutputPath("/forceset/aLCL/geometrypath\|length");
auto& coninfo_aLCL = ligcon_aLCL->updConstraintInfo();
coninfo_aLCL.setBounds(bound_aLCL);
std::vector<MocoBounds> bound_mLCL;
bound_mLCL.push_back(MocoBounds(0, ligmax[2]));
auto* ligcon_mLCL = problem.addPathConstraint<MocoOutputConstraint>();
ligcon_mLCL->setOutputPath("/forceset/mLCL/geometrypath\|length");
auto& coninfo_mLCL = ligcon_mLCL->updConstraintInfo();
coninfo_mLCL.setBounds(bound_mLCL);
*I've shorten the code to make this post short but there will be 6 MocoOutputConstraints in total.
Instead of having multiple MocoOutputConstraint, if I have only one, it looks working. I don't think this is true, but perhaps we cannot have multiple MocoOutputConstraint in one study? The aim of having these constraints is to give upper boundaries to every single ligament's length based on 10% maximum strain. Could you be able to point out what have done wrong in my approach?
Best,
Hojin
Re: ligament boundary conditions
Posted: Fri Feb 23, 2024 10:49 am
by nbianco
Hi Hojin,
Thanks for reporting this. Could you help me find the root issue?
Could you use the Visual Studio debugger to create a stack trace to where the failure occurs? Or alternatively, provide a standalone code snippet that reproduces the issue?
Thanks,
Nick
Re: ligament boundary conditions
Posted: Mon Feb 26, 2024 9:49 pm
by hojin95
Hi Nick,
I've found that this issue was due to not setting the name for each constraint. After naming each constraint, it worked. Thank you for the help
** In addition, unconverged solution using path constraints are not being saved. This reminds me of an older post regarding the similar issue (
viewtopicPhpbb.php?f=1815&t=14984&p=0&s ... be83a0dbf5). Just wondering whether this has been fixed in the newer version? (currently using v4.4)
Best,
Hojin