opensim-core
opensim-core copied to clipboard
Instabilities in CMC
This is a followup from issue #3183. I could remove a number of causes and simplified the model considerably, but althought CMC starts ok, after 0.5 seconds the arms start to oscillate wildly until it fails at a later point.
The root cause of my previous issue was that I had CMC Tasks for all joints, also those in the kinematic loop. I since then learned that only ONE is needed/required because that one already determines the others in the loop and it somehow interferes with CMC. Shouldn't there be something in the documentation about this?
Also removing the leg, including the weldconstraint, did not solve anything. After minimizing the model as much as possible I am left with a model with only 3 real joints and no constraints at all, but the problem still occurs.

Only the moving seat, the back and a single upper arm remain. The video shows the violent movement of the arm at the end.
The plot below shows the trajectory (IK results) and the CMC result. The vertical line in the plot is where CMC fails. That is probably due to the rapid change of the trajectory there. I will leave that for later, assuming that the wild behaviour just before that has nothing to do with this.
The important question is, why the violent behavior (starting at 0.7 seconds) while the prescribed trajectory is still very smooth. A regular PD controller should be able to cope with that. I already played with PD values and the weight of the upper arm, this changes nothing. Also the forces for the actuators are well below there maximum.

Note that only the arm the instability, but not the seat. I also observed that in all other tests that I did. If however I fix the seat to ground, the instabilities go away, so that is a hint maybe. What can I do now? Is there something wrong in CMC?
Please find the model, trajectory and everything in the zip-file Test3.zip
I made the trajectory a bit smoother, and now it fails later. Looking at the plot below we can see that more sudden movements of the joints have no influence on the instabilities at all. There seems to be no control at all!

Controlling seems to work the first 0.7 seconds because the upper arm is being held in the correct position while being pulled on by gravity. But after that everything is wrong! Does it has to do with using the balljoint?
Here the used trajectory: trajectory.zip
I'm hoping I am doing something wrong, but I am afraid there is something wrong with CMC.
I really need to solve this problem! I now studied the CMC sources hoping to find something. As the name implies, CMC is about muscles, but my model does not have muscles. So maybe that is part of the problem? Maybe there is a hidden assumption that there should be muscles (for CMC), but I can't find it. I do not use muscles because I first want to get the "boat" part working. Also, a lot of interesting experiments already can be done without muscles, only a simple human model.
I mostly understand the CMC code, but questions remain. Below are 2 fragments of the debug output, one step (call to computeControls) in the beginning and one at the end shortly before the simulation fails because the force exceeds the maximum of -10000 of constraints are not met.
What I see (as in the video) is that towards the end "seatpos" (index 0) behaves properly with small errors and "uarmleft_up" (index 4) totally gets out of control. Interestingly the force of the seatpos actuator increases all the time, until the force becomes to high. At the same time the force of uarmleft_up remains within bounds. I also added some extra debug output in the ipopt code, and find that ipopt always (until the very last step) can solve the problem "easily", only a few calls to objectFunction and gradientFunction. So the question is, if ipopt is working fine, why isn't the model tracking the intended target?
I have to say that I don't quite follow how SO works when there are no muscles, and consequently no overspecification as normally with muscles. There is nothing to optimize now. Am I right? It seems that SO now only is used to find the force with the desired accelleration. I would assume that in this case the PD calculated value (g^dotdot) could directly go to the actuator (so skip the SO step), this is how a normal PD controller (for say a motor) would work. It is therefore strange that when you compare the desired acceleration with the desired force that the signs of each index are not all the same.
E.g.
Desired acceleration: 1.70604 -25.6589 51.2406 7.39935 -533.187
Desired actuator forces: 79.3705 -2885.36 63.8819 -20.5156 -613.101
Note the 4th value.
Now the fragments, here one from the beginning of CMC:
[info] CMC::computeControls, t = 0.024
[info] -- step size = 0.00200000, target time = 0.026
[info] ------------------------------
[info] CMC::computeControls, summary:
[info] ------------------------------
[info] -- Q = ~[-0.681794 0.119735 0.932523 0.297034 -0.410917 0]
[info] -- U = ~[0.145216 0.0700822 -0.508073 0.201104 -0.223761]
[info] -- Z = ~[]
[info] -- Qdesired = -0.681808 0.119893 0.931561 0.298824 -0.411353
[info] -- Udesired = 0.131129 0.0631776 -0.650905 0.259196 -0.275546
[info] -- Qcorrection = 1.45573e-05 -0.000157372 0.000962335 -0.0017902 0.000435893
[info] -- Ucorrection = 0.0140866 0.00690459 0.142832 -0.0580919 0.0517845
[info] ------------------------------
[info]
[info] Errors at time 0.024:
[warning] Task 'seatpos': pErr = -1.45573e-05, vErr = -0.0206984.
[info]
[warning] Task 'lbackangle': pErr = 0.000157372, vErr = -0.0697776.
[info]
[warning] Task 'uarmleft_out': pErr = -0.000962335, vErr = -0.0777996.
[info]
[warning] Task 'uarmleft_trn': pErr = 0.00179020, vErr = 0.0435713.
[info]
[warning] Task 'uarmleft_up': pErr = -0.000435893, vErr = 0.0597497.
[info]
[info] xmin: -10000 -10000 -10000 -10000 -10000
[info] xmax: 10000 10000 10000 10000 10000
[info]
[info] tiReal = 0.024, tfReal = 0.026
[info] Min forces: -10000 -10000 -10000 -10000 -10000
[info] Max forces: 10000 10000 10000 10000 10000
[info]
[info] Desired actuator forces: -375.37 -186.947 130.424 -33.1976 85.436
[info]
[info] CMC::computeControls, root solve (tFinal = 0.026):
[info] -- _tf 0.026, controls = -375.37 -186.947 130.424 -33.1976 85.436
[info]
And here the last one before the fail, also solved "directly" with ipopt:
[info] CMC::computeControls, t = 1.246
[info] -- step size = 0.00200000, target time = 1.248
[info] ------------------------------
[info] CMC::computeControls, summary:
[info] ------------------------------
[info] -- Q = ~[0.0389963 -0.61728 -3.36024 0.0875875 30.1418 0]
[info] -- U = ~[0.263858 0.140136 17.0289 11.4251 -126.686]
[info] -- Z = ~[]
[info] -- Qdesired = 0.0393825 -0.626035 0.594185 2.70792 -0.799471
[info] -- Udesired = -0.0176966 -0.033201 -1.31799 -1.61323 0.244807
[info] -- Qcorrection = -0.000386184 0.00875503 -3.95442 -2.62033 30.9413
[info] -- Ucorrection = 0.281555 0.173337 18.3469 13.0384 -126.931
[info] ------------------------------
[info]
[info] Errors at time 1.246:
[warning] Task 'seatpos': pErr = 0.000386184, vErr = -0.271732.
[info]
[warning] Task 'lbackangle': pErr = -0.00875503, vErr = -0.192049.
[info]
[warning] Task 'uarmleft_out': pErr = 3.95442, vErr = -18.3157.
[info]
[warning] Task 'uarmleft_trn': pErr = 2.62033, vErr = -13.0079.
[info]
[warning] Task 'uarmleft_up': pErr = -30.9413, vErr = 126.94.
[info]
[info] xmin: -10000 -10000 -10000 -10000 -10000
[info] xmax: 10000 10000 10000 10000 10000
[info]
[info] tiReal = 1.246, tfReal = 1.248
[info] Min forces: -10000 -10000 -10000 -10000 -10000
[info] Max forces: 10000 10000 10000 10000 10000
[info]
[info] Desired actuator forces: -5009.12 418.817 32.6027 -33.0359 -596.353
[info]
[info] CMC::computeControls, root solve (tFinal = 1.248):
[info] -- _tf 1.248, controls = -5009.12 418.817 32.6027 -33.0359 -596.353
[info]
The very last step starts ok, but in the optimizer it fails to find a solution: There are a lot of calls to the constraint and objective function, here a few lines from my debug:
Constraint function
x = ~[-10000 4691.55 -50.141 -51.0856 -598.206]
constraintEqn = ~[4.04375 26.044 -4.50932 -2.97313 -26.5244]
......
Constraint function
x = ~[-10000 4691.55 -50.141 -51.0856 -598.206]
constraintEqn = ~[4.04375 26.044 -4.50932 -2.97313 -26.5244]
Note that the first x is at the limit and that the constraints a not met. All the previous steps end with the constrains met, e.g. the step directy before the last one has
constraintEqn = ~[-2.84217e-14 2.84217e-14 0 7.10543e-15 1.13687e-13]
Because the SO step seems to be working perfectly the first second, I only can conclude that there is something wrong here, hence the issue. I really would appreciate some help here! Regards, Sietse
Still hoping for a reaction here. After reading the Thelen2006 article I think I understand the code in CMC.cpp and I think it should work with models without any muscles. I think I have simplified the situation some more. I now have 2 trajectories of which one works PERFECTLY and the other FAILS. What is wrong here? Both trajectories do NOT move the model at all, this means that all values in each row of the .mot file are the same, apart from the timestamp.
The FIRST file starts with
0 -0.68472377 6.85933357 53.53680602 17.1 -23.4576508
and after that only the first (time) column changes. Note that 17.1 is for the "roll" joint of the ball joint, to make the upper arm turn, hence uarmleft_trn.
There are 7 seconds of data in each .mot file.
Using this as input for CMC makes it work perfectly. Looking at the controls in each step we see that they hardly change at all as we would expect, always something like
'
[info] -- controls = -1.45994e-06 -48.8001 1.50523 3.3732 -4.08445
'
The SECOND .mot file is only slightly different: all values 17.1 are replaced with 117.1.
But now, after 6 seconds the SO optimization fails because the controls exceeds the maximum of 10000!
The controls start as above, but after about 3 seconds it starts to oscillate with ever increasing values.
At the end the controls are as follows:
[info] -- controls = 9986.79 -7209.87 67.6948 7.42411 -621.063
In the beginning of the oscillation there is nothing visible, but at the end the arm starts to oscillate.
This file (trajectory.zip) contains this second trajectory.
The only thing I can conclude is that there is something wrong in CMC!
Please help! Sietse.
PS: From all the experiments that I have done with different trajectories it seems that the joint that turns the upper-arm is the most vulnerable to instabilities. So maybe it has something to do with using a ball joint?
PS2: I also did another experiment. Because there are no muscles in my model I removed the SO from computeControls. After playing around with PD values it mostly worked, but the same type of instabilities arose. So maybe the problem is not in the SO step at all.
I simplified the model further, it now only consists of 2 bodies, a pin-joint (below) and a ball-joint (at the top). The behavior still is the same as before! If I change the pin-joint into a weld-joint there are no instabilities.
I created a trajectory where the position is held fixed all the times apart from a small step in one of the joints in the ball. This only for 3 degrees and only from 0.5 to 0.6 seconds. The step is followed, but the instabilities start immediately after that
This is the behavior with that trajectory.
Here the simplified model and the trajectory: Test4.zip
I also asked this on the forum, but no response there either regrettably.
I more and more think that the optimization strategy for the fast target is not good for this kind of model. The fact that the actual position is not taken into account seems to be the problem. See my message "CMC does not work with some muscle/no-muscle models" on the forum on March 9-th. for more on this.
But before I try to create this new optimization strategy in OpenSim I really need some feedback from someone who is knowledgeable of the ins and outs of CMC!
Thanks in advance, Sietse
To clarify the problem a little bit better here a plot of the intended trajectory, the actual result and a closeup of this result. The trajectory only has a little disturbance in uarmleft_trn. In the actual result, Run_away, the instability can be seen. In the detail you can see that the disturbance is followed not very well, the changes are more in the other 2 ball joint actuators. But after this the instability begins. Without the disturbance in the beginning the instability will start after about 6 seconds anyway.



The model and trajectory can be found in the zip-file from the previous message. Looking at the situation at about 1.7 seconds the situation is as follows.
` [info] CMC::computeControls, root solve (tFinal = 1.7): [info] -- controls = 1.7 [info] [info] CMC::computeControls, t = 1.7 [info] -- step size = 0.00200000, target time = 1.70200 [info] ------------------------------ [info] CMC::computeControls, summary: [info] ------------------------------ [info] -- Q = ~[0.140326 0.183636 3.3165 -27.1329 0] [info] -- U = ~[-1.16965 4.20952 -5.7145 110.305] [info] -- Z = ~[] [info] -- Qdesired = 0.119718 0.934394 2.04204 -0.409413 [info] -- Udesired = 4.73686e-28 3.74167e-27 1.5158e-26 7.57898e-27 [info] -- Qcorrection = 0.0206076 -0.750757 1.27446 -26.7235 [info] -- Ucorrection = -1.16965 4.20952 -5.7145 110.305 [info] ------------------------------ [info] [info] Errors at time 1.7: [warning] Task 'lbackangle': pErr = -0.0206076, vErr = 1.16965. [info] [warning] Task 'uarmleft_out': pErr = 0.750757, vErr = -4.20952. [info] [warning] Task 'uarmleft_trn': pErr = -1.27446, vErr = 5.7145. [info] [warning] Task 'uarmleft_up': pErr = 26.7235, vErr = -110.305. [info] ......... [info] [info] Desired actuator forces: 2382.42 -40.7849 39.8364 525.41 [info]
` Both pErr and vErr are very large and increasing with each step for 'uarmleft_up'. But the optimization still succeeds while driving q away(!) from the value in the trajectory!
Again, please help! Sietse
Because I somehow think that not using muscles is the problem here I changed the CoordinateActuator in the
lower PinJoint into 2 muscles.
But it does not make any difference in the behavior, the balljoint becomes unstable just the same!
I don't know what to do next. Where can I turn to for help with CMC? Sietse