Improve the speed of SNOPT solver for MPC trajectory optimization.

huangapple go评论74阅读模式
英文:

Improve the speed of SNOPT solver for MPC trajectory optimization

问题

I am using pydrake SNOPT to solve a trajectory optimization problem for multi-step walking with a linear inverted pendulum model.
2步轨迹需要0.6秒来解决。需要实时MPC来加速。
我已经尝试了几种方法来提高速度。

  1. 放宽容差似乎没有帮助。
  2. 解决()花了0.2秒。检查snopt.out,我发现在第一个主要迭代之前完成了600次(主要和次要)迭代和300次QP次要迭代。这是否表明热启动可以将时间减半?Drake是否支持SNOPT的热启动?
  3. 一个特定的约束被评估了500次,并且占据了总解决时间的60%。这是一个非线性的Python函数。我可以通过在Cython或纯C中实现它来改进吗?是否有任何资源展示了如何做到这一点,以及Py2C可能提供多少改进?
    请告诉我是否有什么我可能忽视的东西,特别是在snopt.out文件中。
英文:

I am using pydrake SNOPT to solve a trajectory optimization problem for multi-step walking with linear inverted pendulum model.
The 2-step trajectory takes 0.6s to solve. A speed-up is needed for real-time MPC.

I have tried several ways to improve the speed.

  1. Relaxing the tolerance didn't seems to help.
self.mp.SetSolverOption(SnoptSolver().solver_id(), "Major feasibility tolerance", 1e-4)
self.mp.SetSolverOption(SnoptSolver().solver_id(), "Minor feasibility tolerance", 1e-4)
  1. The solve() took 0.2s. Inspecting the snopt.out, I found 600 iterations (major and minor) are completed and 300 QP minor iterations are completed before the first major iteration. Is that an indication that a warm start can help cut down the time by half? Does Drake support warm start for SNOPT? This post says no.
  2. One particular constraint is evaluated 500 times and takes 60% of the total solving time. It is a nonlinear Python function. Can I improve it by implementing in Cython or pure C? Are there any resources that show how to do this and how much improvement the Py2C might provide?

Please let me know if there's anything that I might have overlooked. Especially in the snopt.out file.

 SNMEMA EXIT 100 -- finished successfully
 SNMEMA INFO 104 -- memory requirements estimated

答案1

得分: 1

感谢您的问题!

对于热启动,目前我们可以通过传递一个初始猜测来热启动原始变量。以下是伪代码

prog.SetInitialGuess(vars, vals)
result = mp.Solve(prog)

在SNOPT的前几个主要迭代中,通常需要很长时间。

> 我可以通过使用Cython或纯C来改进吗?

是的,我强烈建议您将约束编写成C++,然后从Python绑定中调用它(抱歉,我不熟悉Cython方法)。如果您的约束评估在Python代码中,那么SNOPT将首先调用C++回调,然后再调用Python函数。跨语言的这种间接调用可能会很慢。我的同事可能知道比编写C++约束并创建Python绑定更好的方法。

英文:

Thanks for the question!

For the warm-start, currently we can warm start the primal variable, by passing an initial guess. Here is a pseudo-code

prog.SetInitialGuess(vars, vals)
result = mp.Solve(prog)

The first few major iterations in SNOPT usually takes a lot of time.

> Can I improve it by implementing in Cython or pure C?

Yes, I strongly suggest to write your constraint in C++ and then call it from the python binding (Sorry I am not familiar with Cython approach). If your constraint evaluation is in python code, then SNOPT will first call the C++ callback, which then calls the python function. This indirect call across languages can be slow. My colleagues might know a better approach rather than writing a C++ constraint and create the python binding.

huangapple
  • 本文由 发表于 2023年4月20日 02:18:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/76057695.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定