ligament boundary conditions

OpenSim Moco is a software toolkit to solve optimal control problems with musculoskeletal models defined in OpenSim using the direct collocation method.
POST REPLY
User avatar
Hojin Song
Posts: 75
Joined: Wed Jul 08, 2020 9:46 am

ligament boundary conditions

Post by Hojin Song » Sun Feb 18, 2024 9:18 pm

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

User avatar
Ross Miller
Posts: 375
Joined: Tue Sep 22, 2009 2:02 pm

Re: ligament boundary conditions

Post by Ross Miller » Mon Feb 19, 2024 8:04 am

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

User avatar
Pasha van Bijlert
Posts: 227
Joined: Sun May 10, 2020 3:15 am

Re: ligament boundary conditions

Post by Pasha van Bijlert » Tue Feb 20, 2024 5:34 am

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

User avatar
Nicholas Bianco
Posts: 1044
Joined: Thu Oct 04, 2012 8:09 pm

Re: ligament boundary conditions

Post by Nicholas Bianco » Tue Feb 20, 2024 4:50 pm

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

User avatar
Hojin Song
Posts: 75
Joined: Wed Jul 08, 2020 9:46 am

Re: ligament boundary conditions

Post by Hojin Song » Wed Feb 21, 2024 7:17 pm

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
error.PNG (22.68 KiB) Viewed 13645 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

User avatar
Nicholas Bianco
Posts: 1044
Joined: Thu Oct 04, 2012 8:09 pm

Re: ligament boundary conditions

Post by Nicholas Bianco » Thu Feb 22, 2024 11:28 am

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

User avatar
Hojin Song
Posts: 75
Joined: Wed Jul 08, 2020 9:46 am

Re: ligament boundary conditions

Post by Hojin Song » Fri Feb 23, 2024 12:40 am

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
err1.PNG (14.38 KiB) Viewed 13624 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
Last edited by Hojin Song on Mon Feb 26, 2024 10:13 pm, edited 2 times in total.

User avatar
Nicholas Bianco
Posts: 1044
Joined: Thu Oct 04, 2012 8:09 pm

Re: ligament boundary conditions

Post by Nicholas Bianco » Fri Feb 23, 2024 10:49 am

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

User avatar
Hojin Song
Posts: 75
Joined: Wed Jul 08, 2020 9:46 am

Re: ligament boundary conditions

Post by Hojin Song » Mon Feb 26, 2024 9:49 pm

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

POST REPLY