首页 > 解决方案 > SNOPT 上的退出条件 41

问题描述

我正在尝试使用 SNOPT 进行优化。

现在,当我运行它时,我一直得到退出条件 41。

我在求解器中添加了以下参数:

prog.SetSolverOption(solver.solver_id(),"Function Precision","1e-6")
prog.SetSolverOption(solver.solver_id(),"Major Optimality Tolerance","1e-3")
prog.SetSolverOption(solver.solver_id(),"Superbasics limit","600")
#print("Trying to Solve")
result = solver.Solve(prog)
print(result.is_success())

但我仍然心满意足地得到相同的退出条件。

该错误似乎来自我正在使用的插值函数。(当我删除它时,我不再收到错误)。

t, c, k = interpolate.splrep(sref, kapparef, s=0, k=3)

kappafnc = interpolate.BSpline(t, c, k, extrapolate=False)

这是我认为我确定导致问题的功能:

  def car_continous_dynamics(self, state, force, steering):
        beta = steering
        s = state[0]
        #print(s)
        n = state[1]
        alpha = state[2]
        v = state[3]
        #State = s, n, alpha , v
        #s= distance along the track, n = perpendicular distance along the track
        #alpha = velocity angle relative to the track
        #v= magnitude of the velocity of the car

        s_val = 0
        if s.value() >0:
          s_val = s.value()
          
        
        Cm1 = 0.28
        Cm2 = 0.05
        Cr0 = 0.011
        Cr2 = 0.006
        m = 0.043
        phi_dot = v*beta*15.5
        Fxd = (Cm1 - Cm2 * v) * force - Cr2 * v * v - Cr0 *tanh(5 * v)
        s_dot = v*cos(alpha+.5*beta)/(1)##-n*self.kappafunc(s_val))
        n_dot= v*sin(alpha+.5*beta)
        alpha_dot = phi_dot #-s_dot*self.kappafunc(s_val)
        v_dot=Fxd/m*cos(beta*.5)

        # concatenate velocity and acceleration
        #print(s_dot)
        #print(n_dot)
        #print(alpha_dot)
        #print(v_dot)
        state_dot = np.array((s_dot,n_dot,alpha_dot,v_dot))
        #print("State dot")

        #print(state_dot.dtype.name)
        #print(state_dot)
        #print(state_dot)
        return state_dot
``

标签: drake

解决方案


在 SNOPT 中调试 INFO 41 通常具有挑战性,它通常是由一些糟糕的梯度引起的(但也可能是由于问题很难优化)。

您应该检查您的渐变是否表现良好。我看你有

s_val = 0
if s.value() >0:
    s_val = s.value()

有两个潜在问题

  1. s携带梯度(您可以检查s.derivatives(),它具有非零梯度),但是当您计算 时s_val,这是一个float没有梯度的对象。因此,您会丢失梯度信息。
  2. s_val在 0 处不可微。

我会在你的函数中使用s而不是s_val(没有分支if s.value() > 0)。s>=0并且还添加一个约束

prog.AddBoundingBoxConstraint(0, np.inf, s)

有了这个边界框约束,SNOPT 保证在每次迭代中,is 的值总是非负的。


推荐阅读