loco-3d / crocoddyl

Crocoddyl is an optimal control library for robot control under contact sequence. Its solver is based on various efficient Differential Dynamic Programming (DDP)-like algorithms
BSD 3-Clause "New" or "Revised" License
808 stars 166 forks source link

Code generated DDP with free flyer model in contact gives random result #917

Open edantec opened 3 years ago

edantec commented 3 years ago

I am trying to produce a code generated DDP object with the Talos model in contact and a very simple cost function composed of a state regularization and control regularization. This simple cost function is sufficient to stabilize Talos on its feet so I'm expecting the code generation to behave the same way.

However when executing one iteration of the DDP over a random guess, the result is completely random (cost decrease, gradient, etc... all random) and not at all repeatable. The derivatives of the code generated action model have been compared to the derivatives of the classical action model, and are the same, so the error doesn't come from that.

An example of how I build my DDP object is presented here: https://gitlab.laas.fr/proyan/mpc_controller/-/blob/master/src/hand_tracking_problem_full_codegen.cpp

cmastalli commented 3 years ago

However when executing one iteration of the DDP over a random guess, the result is completely random (cost decrease, gradient, etc... all random) and not at all repeatable.

This is not clear. If you have a random guess, then the solver iterations will be different between them, right?

You also need to be aware that the DDP solver is much unstable than the FDDP solver. It means, it requires a "better" initial guess.

An example of how I build my DDP object is presented here: https://gitlab.laas.fr/proyan/mpc_controller/-/blob/master/src/hand_tracking_problem_full_codegen.cpp

This code is closed source, if you wanted me to have a look then you need to give me the reading rights :)

cmastalli commented 3 years ago

Have you played with the benchmark code? Perhaps, you can reproduce your issue there.

edantec commented 3 years ago

What I meant by random guess is that for a fixed (random) guess, two repetitions of a ddp.solve won't give the same decrease in cost as it is expected with classically generated DDP. Rohan will give you the reading rights asap.

cmastalli commented 3 years ago

What I meant by random guess is that for a fixed (random) guess, two repetitions of a ddp.solve won't give the same decrease in cost as it is expected with classically generated DDP.

Thanks for the clarification.

Have you observed this issue in other solvers? Could you quickly try with FDDP and BoxFDDP?

edantec commented 3 years ago

I have the same issue with DDP, FDDP, and BoxFDDP.

edantec commented 3 years ago

Here is an example of how I write my code generated problem. https://github.com/edantec/crocoddyl/blob/benchmark/benchmark/talos_cppad.cpp

However I couldn't make this branch compile on my machine due to an error of type undefined reference to symbol 'dlclose@@GLIBC_2.2.5 error adding symbols: DSO missing from command line'

proyan commented 3 years ago

You need to link CMAKE_DL_LIBS in the benchmark. See the file benchmarks/CMakelists.txt for reference

edantec commented 3 years ago

I have added talos_cppad.cpp in SET(${PROJECT_NAME}_CODEGEN_BENCHMARK ) inside benchmarks/CMakelists.txt but still the same error. On closer analysis, one iteration of code-generated ddp.solve produces derivatives of the cost and dynamics (Lxx, Fx, etc...) equal to zero for completely random knots (usually 3 or 5). I've tracked the error until this line: https://github.com/edantec/crocoddyl/blob/b58ef3d7f661f0bd2f36bb5d55491fc8cad3bc06/include/crocoddyl/core/optctrl/shooting.hxx#L181 where calcDiff produces here derivatives equal to 0 for Lxx, Fx, and so, for some random knots

cmastalli commented 3 years ago

Is there any update regarding this topic?

edantec commented 3 years ago

Yes there is. I've simplified the problem to consider the 4 DoF Talos arm without contact and I have the same randomness issue. I could backtrack the error until: https://github.com/edantec/crocoddyl/blob/2d62f18b06c233133f45062918f99385b6fd8438/include/crocoddyl/core/codegen/action-base.hpp#L212 After this line d->calcDiffout contains some Fx, Lxx... equal to 0, a visibly complete random phenomenon. I didn't go further than that.

proyan commented 3 years ago

Sorry @edantec, but I have not yet worked on your issue.

Code-gen bugs take time to solve. And unfortunately, I haven't found the courage to plunge in your implementation. I may come around to it, but I can't give you any timeline for my support.

edantec commented 3 years ago

Just for illustration, I've written a simple example highlighting the problem here on a side branch: https://github.com/edantec/crocoddyl/blob/benchmark/benchmark/talos_cppad.cpp When I execute this benchmark several time, the computed cost for classical DDP remains the same whereas CG DDP cost is random.

cmastalli commented 3 years ago

You are sharing the same CG model across all the running models: https://github.com/edantec/crocoddyl/blob/benchmark/benchmark/talos_cppad.cpp#L129

Despite that I am not sure if this is the issue source, could you create a single CG per node?

edantec commented 3 years ago

I've created one single CG per node: https://github.com/edantec/crocoddyl/blob/9fd6dbe2d87a8327efd7cc1441134c48e273b741/benchmark/talos_cppad.cpp#L176 Now the result of codegen ddp is no more random, but it is still different from the result of classical DDP. This is a progress, but something is still off.

cmastalli commented 9 months ago

@edantec -- I wonder if this issue still occurs in the latest version of Crocoddyl. For instance, I have made a few fixes that could have sorted out this, e.g., https://github.com/loco-3d/crocoddyl/pull/1165.

Could you try this again? If the results are different, then please share logs of both cases: with and without codegen.