opensim-org / opensim-core

SimTK OpenSim C++ libraries and command-line applications, and Java/Python wrapping.
https://opensim.stanford.edu
Apache License 2.0
783 stars 316 forks source link

CMC tool with slow target does not work properly #3127

Closed SietseAchterop closed 2 years ago

SietseAchterop commented 2 years ago

I already asked this on the forum. But in the end I cannot think of anything else then that there is something wrong here. The problem is that when using CMC my model behaves violently and clearly non-physical. There are no errors or warnings. The zipfile contains all data including a video, opensim_video.webm, that shows the behavior.

CMC_error.zip

The model Bootbaan.osim is made as simple as possible, created from bootbaan_ERROR.py. The motion trajectory.mot is created using python and the IK-tool from trajectory.py. It is a motion created for the complete model, but that doesn't make any difference, the motion is as expected as seen in the IK-tool and trajectory.mot.

There is nothing special about the model. Only one kinematic loop and a contact force (ElasticFoundationForce) between the model and ground. If I remove the upperarm and shoulderjoint from the model then everything works as expected!

More complicated models even start in a completely wrong posture (with weldconstraints violated) in the first instant after 0.02 second. These models, after 5 to 10 seconds in simulation time, get stuck in the computation and never finish.

Am I doing something wrong or is there an error in CMC? Thanks in advance. Sietse

.

nickbianco commented 2 years ago

Hi @SietseAchterop, other users have historically had issues getting simulations to work when using the slow target in CMC. Is the fast target not appropriate/working for your simulations? Although, my guess is that CMC is having trouble tracking your motion due to the contact between the boat and the ground.

What is the purpose of this contact force in your model? You could replace the existing 2-DOF ground-to-bound joint with a 1-DOF slider joint; this should be more stable in CMC. Based on the trajectory you've included, the vertical motion might not be as important for this model anyway. If resistance with the ground (water?) is important for the simulation, you could add a force in the direction of the slider joint to model it.

If all else fails with CMC, you might consider using MocoInverse, a tool based on the new OpenSim Moco package for solving "inverse" simulations.

SietseAchterop commented 2 years ago

Thank you very much for the response! Yes, challenging indeed. This response is a bit long, please bear with me.

Here a bit of context. The overall goal of this project, this in collaboration with the Human Movement Sciences department at our university, is to simulate a full body musculoskeletal model on a boat in water. This is done to better learn about rowing technique (e.g. when to use the legs, back and arms in a stroke) and about rigging (e.g. where to position the oar-locks and configuration of the oars). All to achieve faster speeds given a rower.

What I want (with respect to contacts) is the following:

  1. Using friction to model propelling a boot though water. I now use ElasticFoundationForce between a halfplane and a meshbox (the boat). Is there a better way to do this using CMC?
  2. Also modelling the blade in the water using friction. This is more complicated, and not used now, but I mention it for completeness: I created a customforce in Simbody, called BladeForce, it is a simple derivative of ElasticFoundationForce. The friction now depends upon the direction of how the blade "pushes through the water". When the direction is in line with the oar then there is very little friction, and when the direction is perpendicular to that there is a lot of friction. This works fine, but I am not using this at the moment.

I forgot to mention that in the calculated trajectory the boat does not move. The whole idea is that we want determine the speed of the boat. That is the reason I am using CMC. The configuration is such that there are no CMC-Tasks for both boat joints. (This was not yet the case in the earlier zip-file, but the problem is the same.)

Now to your response.
I used 2 DOF for the boat because I thought that this would let the boat "settle better in the water" for the friction to work better. But fixating the up/down direction, effectively reducing to a slider joint, didn't make much difference.

I simplified the model even further, but the problem remains.

  1. Changed the boatJoint into a WeldJoint. Same problem.

  2. After that the contacts and force could be removed. Same problem. So the contact forces are not the problem.

  3. Finally I removed the constraint in the lower leg. Same problem. First the arm goes wild and then also the seat- and other -joints do the same. So the loop constraint isn't the problem either.

I wonder, is the problem in Simbody or in the CMC-part. For completeness here the new model and CMC-tasks file: CMC_simplest.zip

Note that I currently, for simplicity, do not use muscles in my model. Is that part of the problem? I mean, most models do use muscles. Am I correct in assuming that for SO there is no optimization needed/possible because the is no redundancy like with muscles? (Side-remark: in the documentation in CMC/slow target there is mention of "weighted sum of squared actuator controls", but the weight-factors are NOT there in the expression for J!)

I know that I am wrong here, because I have to set the weight considerable higher than 1, they are at 1000 or 10000, to make the model follow the trajectory properly. I don't really understand this.

In conclusion about my model and using slow target here: either I am doing something stupid or we are about to find an error in CMC. I hope it's the first, because then I can continue with my project!

I started off by using by using the default, fast target mode, but failed to get it to work in all but the simplest cases. I actually would like to use fast target, but how do I get a trajectory that does not make the optimisation fail directly? Opensim crashes in the very first call to _optimizer->optimize(fVector); in CMC.cpp, so when its calling into Simbody. The error Optimizer failed: Ipopt: Infeasible problem detected (status 2) ends with 3 possible causes, of which the last 2 are not applicable I think, but the first one? not all model degrees-of-freedom are actuated I, intensionally, do not actuate the boatJoint, but I also (now) do not give CMC the task to actuate it.

I tried to make the movement very slow, but that did not help much. From the error message I understand that the "Model cannot generate the forces necessary to achieve the target acceleration." Or does it has anything to do with how to get the model into the initial position. I also put the model in the correct initial position using the IK results, but that didn't make any difference. Using verbose printing I see that the initial error is very slow, e.g. [warning] Task 'seatpos': pErr = -1.16611e-06, vErr = 0.0. And the movement after that is very slow and gradual. So where are the large accelerations that are mentioned?

Thanks again, Sietse

nickbianco commented 2 years ago

Hi @SietseAchterop, thanks for the detailed response, this is very helpful.

The whole idea is that we want determine the speed of the boat. That is the reason I am using CMC.

If I'm understanding what you're trying to do, this could be a key issue with your approach. The primary use for CMC is to estimate muscle activity from a known motion, usually walking. CMC is not designed to predict or estimate unknown motions. Even if you prescribe a motion such that the boat doesn't move relative to the ground, if there's no actuator between the boat and the ground, CMC will likely fail (which is what you're seeing with the error not all model degrees-of-freedom are actuated). CMC won't work if you don't actuate all degrees-of-freedom (even if you intend to keep actuator forces very low at certain degrees-of-freedom).

So it seems like CMC might not fit your needs. It sounds like you want to solve a problem where you prescribed the motion of the "rower" in the boat and then predict how fast the boat moves. Moco might be a better tool for this scenario, since it allows you to solve problems where you track kinematics for certain DOFs and predict kinematics for other DOFs. You could use the model without the vertical motion (since it seems unnecessary) and include the BladeForce component you've made since you only really care about the friction force and not the vertical contact force (the vertical contact force won't matter anyway if you have no vertical motion).

I'll answer some of the other questions you had, just in case.

Note that I currently, for simplicity, do not use muscles in my model. Is that part of the problem?

Adding muscles to the model should make it more difficult to solve, not the other way around. So this shouldn't be the problem.

Am I correct in assuming that for SO there is no optimization needed/possible because the is no redundancy like with muscles?

StaticOptimization will always solve an optimization problem, even if there's no muscle redundancy present. You'll end up with a result that should be close to the inverse dynamics result if you're only using joint torques, but the optimization still needs to happen based on how the SO tool is designed.

(Side-remark: in the documentation in CMC/slow target there is mention of "weighted sum of squared actuator controls", but the weight-factors are NOT there in the expression for J!)

Looking at the documentation, the full sentence reads "weighted sum of squared actuator controls plus the sum of desired acceleration errors", which I think is referring to the weight on the slow target term, not to individual weights on the actuator controls. This could be written more clearly.

I know that I am wrong here, because I have to set the weight considerable higher than 1, they are at 1000 or 10000, to make the model follow the trajectory properly.

I don't think you're necessarily wrong here. Depending on how large the actuator control values are, you might need larger weights on the slow target term for the optimizer to show preference to it in the cost function.

In conclusion about my model and using slow target here: either I am doing something stupid or we are about to find an error in CMC. I hope it's the first, because then I can continue with my project!

I don't think either is the case here! CMC can be frustrating to work with in many cases, and this is one of the reasons why we built Moco. Moco allows much more flexibility to solve custom optimization problems (like this one) when CMC and SO are not sufficient.

SietseAchterop commented 2 years ago

Thanks! This helps! I will look into Moco. I did use the vertical motion of the blade to be able to perform the recover-phase of the rowing-cycle where the blade is to be transported to the beginning of the next stroke. The blade then should have no friction.

Thanks again. The issue can be closed I think.

nickbianco commented 2 years ago

Glad this was helpful! Hopefully Moco works for your problem, but let us know if you run into any problems again.