1

我试图使用德雷克工具箱编写最少时间的控制代码。但是中间,我看不懂错误信息:(请忽略括号中发生的事情,我只是不知道提交帖子需要多少细节,上帝!)

'''python
from pydrake.all import MathematicalProgram, Solve import numpy as np

def g(x):
    if abs(x)<1e-7:
        return 0.
    else:
        return 1.

mp = MathematicalProgram()

state_initial = np.asarray([1., 0])
position_goal = np.asarray([0,  0])

N=100
dt=0.01
u_over_time=mp.NewContinuousVariables(1,"u_0")
states_over_time = np.asarray([state_initial])
for k in range(1,N):
    u = mp.NewContinuousVariables(1, "u_%d" % k)
    state =mp.NewContinuousVariables(2,"state_%d" % k)
    u_over_time = np.vstack((u_over_time, u))
    states_over_time = np.vstack((states_over_time,state))

print "Number of decision vars", mp.num_vars()
for i in range(N-1):
    state_next0 = states_over_time[i,0]+  dt*states_over_time[i,1]
    state_next1 = states_over_time[i,1]+  dt*u_over_time[i]
    mp.AddLinearConstraint(states_over_time[i+1,0]>=state_next0)
    mp.AddLinearConstraint(states_over_time[i+1,1]>=state_next1)
    mp.AddLinearConstraint(states_over_time[i+1,0]<=state_next0)
    mp.AddLinearConstraint(states_over_time[i+1,1]<=state_next1)
    mp.AddLinearConstraint(u_over_time[i]<=1.)
    mp.AddLinearConstraint(u_over_time[i]>=-1.)

And the error info is :
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-2-be1aa565be42> in <module>()
     29     state_next1 = states_over_time[i,1]+  dt*u_over_time[i]
     30     mp.AddLinearConstraint(states_over_time[i+1,0]>=state_next0)
---> 31     mp.AddLinearConstraint(states_over_time[i+1,1]>=state_next1)
     32     mp.AddLinearConstraint(states_over_time[i+1,0]<=state_next0)
     33     mp.AddLinearConstraint(states_over_time[i+1,1]<=state_next1)

RuntimeError: You should not call `__bool__` / `__nonzero__` on `Formula`. If you are trying to make a map with `Variable`, `Expression`, or `Polynomial` as keys (and then access the map in Python), please use pydrake.common.containers.EqualToDict`.

May I know what's happening here? Thanks

----------------update line-----------------
I modified the code as you told me. Now the code now becomes:

'''python
    from pydrake.all import MathematicalProgram, Solve
    import numpy as np

    def g(x):
        if abs(x)<1e-7:
            return 0.
        else:
            return 1.

    mp = MathematicalProgram()

    state_initial = np.asarray([1., 0])
    position_goal = np.asarray([0,  0])

    N=100
    dt=0.01
    u_over_time=mp.NewContinuousVariables(1,"u_0")
    states_over_time = np.asarray([state_initial])
    for k in range(1,N):
        u = mp.NewContinuousVariables(1, "u_%d" % k)
        state =mp.NewContinuousVariables(2,"state_%d" % k)
        u_over_time = np.vstack((u_over_time, u))
        states_over_time = np.vstack((states_over_time,state))

    print "Number of decision vars", mp.num_vars()
    for i in range(N-1):
        state_next0 = states_over_time[i,0]+  dt*states_over_time[i,1]
        state_next1 = states_over_time[i,1]+  dt*u_over_time[i,0]
        mp.AddLinearConstraint(states_over_time[i+1,0]>=state_next0[0])
        mp.AddLinearConstraint(states_over_time[i+1,1]>=state_next1[0])
        mp.AddLinearConstraint(states_over_time[i+1,0]<=state_next0[0])
        mp.AddLinearConstraint(states_over_time[i+1,1]<=state_next1[0])
        mp.AddLinearConstraint(u_over_time[i,0]<=1.)
        mp.AddLinearConstraint(u_over_time[i,0]>=-1.)
'''

And the error info is:
TypeError                                 Traceback (most recent call last)
<ipython-input-7-82e68c2ebfaa> in <module>()
     27     state_next0 = states_over_time[i,0]+  dt*states_over_time[i,1]
     28     state_next1 = states_over_time[i,1]+  dt*u_over_time[i,0]
---> 29     mp.AddLinearConstraint(states_over_time[i+1,0]>=state_next0[0])
     30     mp.AddLinearConstraint(states_over_time[i+1,1]>=state_next1[0])
     31     mp.AddLinearConstraint(states_over_time[i+1,0]<=state_next0[0])

TypeError: 'float' object has no attribute '__getitem__'

What's the problem this time? Thanks.

(Btw, one of my complain is that, the error info always not that effective to give the hint of where the problem is...)

-----------------update 2nd time line--------------------
Now a similar problem happened to the g(x), the code:
'''
    from pydrake.all import MathematicalProgram, Solve
    import numpy as np

    def g(x):
        print 'x=',x
        print 'x[0]=',x[0]
        if x[0]*x[0]+x[1]*x[1]<1e-7: # x.dot(x)
            return 0.
        else:
            return 1.

    mp = MathematicalProgram()

    state_initial = np.asarray([1., 0])
    #position_goal = np.asarray([0,  0]) # already in g(x)

    N=100
    dt=0.01
    u_over_time=mp.NewContinuousVariables(1,"u_0")
    states_over_time = np.asarray([state_initial])
    for k in range(1,N):
        u = mp.NewContinuousVariables(1, "u_%d" % k)
        state =mp.NewContinuousVariables(2,"state_%d" % k)
        u_over_time = np.vstack((u_over_time, u))
        states_over_time = np.vstack((states_over_time,state))

    print "Number of decision vars", mp.num_vars()
    for i in range(N-1):
        state_next0 = states_over_time[i,0]+  dt*states_over_time[i,1]
        state_next1 = states_over_time[i,1]+  dt*u_over_time[i,0]
        mp.AddLinearConstraint(states_over_time[i+1,0]>=state_next0)
        mp.AddLinearConstraint(states_over_time[i+1,1]>=state_next1)
        mp.AddLinearConstraint(states_over_time[i+1,0]<=state_next0)
        mp.AddLinearConstraint(states_over_time[i+1,1]<=state_next1)
        mp.AddLinearConstraint(u_over_time[i,0]<=1.)
        mp.AddLinearConstraint(u_over_time[i,0]>=-1.)
    reward=np.zeros((N,1))
    for i in range(N):
        reward[i]=g(states_over_time[i,:])

    mp.AddQuadraticCost(reward.dot(reward))
    result=Solve(mp)
'''
This time neither x or x[0] could solve the problem. the output info is :

Number of decision vars 298
x= [1.0 0.0]
x[0]= 1.0
x= [Variable('state_1(0)', Continuous) Variable('state_1(1)', Continuous)]
x[0]= state_1(0)

---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-8-08d1cd75397e> in <module>()
     37 reward=np.zeros((N,1))
     38 for i in range(N):
---> 39     reward[i]=g(states_over_time[i,:])
     40 
     41 mp.AddQuadraticCost(reward.dot(reward))

<ipython-input-8-08d1cd75397e> in g(x)
      5     print 'x=',x
      6     print 'x[0]=',x[0]
----> 7     if x[0]*x[0]+x[1]*x[1]<1e-7: # x.dot(x)
      8         return 0.
      9     else:

RuntimeError: You should not call `__bool__` / `__nonzero__` on `Formula`. If you are trying to make a map with `Variable`, `Expression`, or `Polynomial` as keys (and then access the map in Python), please use pydrake.common.containers.EqualToDict`.

What can I do this time? Thanks
Btw, you see in the code i print x or x[0] only once, but i got two different answer? funny, isn't it? why is this?

4

4 回答 4

1

state_next1不是符号表达式,它是符号表达式的numpy数组,所以你需要做state_next1[0]. 同样,您将需要更改u_over_time[i] <= 1u_over_time[i, 0] <= 1.

解决问题的另一种方法是state_next1使用u_overt_time[i, 0]而不是计算u_over_time[i]。修改后,代码中的for循环应该是

for i in range(N-1):
    state_next0 = states_over_time[i,0]+  dt*states_over_time[i,1]
    state_next1 = states_over_time[i,1]+  dt*u_over_time[i, 0]
    mp.AddLinearConstraint(states_over_time[i+1,0]>=state_next0)
    mp.AddLinearConstraint(states_over_time[i+1,1]>=state_next1)
    mp.AddLinearConstraint(states_over_time[i+1,0]<=state_next0)
    mp.AddLinearConstraint(states_over_time[i+1,1]<=state_next1)
    mp.AddLinearConstraint(u_over_time[i, 0]<=1.)
    mp.AddLinearConstraint(u_over_time[i, 0]>=-1.)

我改成你定义u_over_time[i]的地方。u_over_time[i, 0]state_next1

于 2019-12-15T19:25:55.150 回答
0

我用二分法写了一个答案,也是tedrake在课堂上推荐的。但我不喜欢这种方法。迭代次数太多。我只是把它放在这里,当我有一个混合整数代码时,我会回来。

上帝,我就是无法通过代码检查...我真的很讨厌stackoverflow的代码检查机制...

''' from pydrake.all import MathematicalProgram, Solve import numpy as np import matplotlib.pyplot as plt ''' def g(x): print 'x=',x print 'x[0]=',x[0] if x[0]*x[0]+x[1]*x[1]<1e-7: # x.dot(x) return 0. else: return 1. ''' #mp = MathematicalProgram()

state_initial = np.asarray([1., 0])
#position_goal = np.asarray([0,  0]) # already in g(x)

#N=201
dt=0.01
upper=1000; lower=1;
N=upper
while upper-lower>1:
    print '---------------------'
    print 'N=',N
    mp = MathematicalProgram()
    u_over_time=mp.NewContinuousVariables(1,"u_0")
    states_over_time = mp.NewContinuousVariables(2,"state intial")
    mp.AddLinearConstraint(states_over_time[0]==np.asarray([state_initial[0]]))
    mp.AddLinearConstraint(states_over_time[1]==np.asarray([state_initial[1]]))
    #states_over_time = np.asarray([state_initial])
    for k in range(1,N):
        u = mp.NewContinuousVariables(1, "u_%d" % k)
        state =mp.NewContinuousVariables(2,"state_%d" % k)
        u_over_time = np.vstack((u_over_time, u))
        states_over_time = np.vstack((states_over_time,state))

    print "Number of decision vars", mp.num_vars()
    for i in range(N-1):
        state_next0 = states_over_time[i,0]+  dt*states_over_time[i,1]
        state_next1 = states_over_time[i,1]+  dt*u_over_time[i,0]
        mp.AddLinearConstraint(states_over_time[i+1,0]>=state_next0)
        mp.AddLinearConstraint(states_over_time[i+1,1]>=state_next1)
        mp.AddLinearConstraint(states_over_time[i+1,0]<=state_next0)
        mp.AddLinearConstraint(states_over_time[i+1,1]<=state_next1)
        mp.AddLinearConstraint(u_over_time[i,0]<=1.)
        mp.AddLinearConstraint(u_over_time[i,0]>=-1.)
    '''
    reward=np.zeros((N,1))
    for i in range(N):
        reward[i]=g(states_over_time[i,:])
    '''
    mp.AddLinearConstraint(states_over_time[-1,0]<=1e-7)
    mp.AddLinearConstraint(states_over_time[-1,1]<=1e-7)
    mp.AddLinearConstraint(states_over_time[-1,0]>=1e-7)
    mp.AddLinearConstraint(states_over_time[-1,1]>=1e-7)
    #mp.AddQuadraticCost(reward.dot(reward))

    result=Solve(mp)
    print result.is_success()
    if result.is_success():
        upper=N
    else:
        lower=N
    N=lower+int((upper-lower)/2.0)
N=upper
#print result.is_success()
print 'least time=',dt*N
u_over_time=result.GetSolution(u_over_time)
states_over_time=result.GetSolution(states_over_time)
#print 'u=',u_over_time
#print 'last state=',states_over_time[-1,:]

fig, ax = plt.subplots(2, 1)
plt.subplot(2, 1, 1);plt.plot(np.arange(dt, dt*N, dt),u_over_time);
plt.legend(["u against t"])
plt.subplot(2, 1, 2);plt.plot(states_over_time[:,0],states_over_time[:,1]);
plt.legend(["phase portrait"])

'''

于 2019-12-21T03:24:42.383 回答
0

这是一段不会引发语法错误的代码

    from pydrake.all import MathematicalProgram, Solve
    import numpy as np

    def g(x):
        x_squared_norm = np.power(x.reshape((2, -1)), 2)
        return np.sum(x_squared_norm > 1e-7)

    mp = MathematicalProgram()

    state_initial = np.asarray([1., 0])
    #position_goal = np.asarray([0,  0]) # already in g(x)

    N=100
    dt=0.01
    u_over_time=mp.NewContinuousVariables(1,"u_0")
    states_over_time = np.asarray([state_initial])
    for k in range(1,N):
        u = mp.NewContinuousVariables(1, "u_%d" % k)
        state =mp.NewContinuousVariables(2,"state_%d" % k)
        u_over_time = np.vstack((u_over_time, u))
        states_over_time = np.vstack((states_over_time,state))

    print "Number of decision vars", mp.num_vars()
    for i in range(N-1):
        state_next0 = states_over_time[i,0]+  dt*states_over_time[i,1]
        state_next1 = states_over_time[i,1]+  dt*u_over_time[i,0]
        mp.AddLinearConstraint(states_over_time[i+1,0]>=state_next0)
        mp.AddLinearConstraint(states_over_time[i+1,1]>=state_next1)
        mp.AddLinearConstraint(states_over_time[i+1,0]<=state_next0)
        mp.AddLinearConstraint(states_over_time[i+1,1]<=state_next1)
        mp.AddLinearConstraint(u_over_time[i,0]<=1.)
        mp.AddLinearConstraint(u_over_time[i,0]>=-1.)
    mp.AddCost(g, vars=states_over_time[1:,:].reshape((1, -1)).squeeze())
    result=Solve(mp)

请注意,我更改了 , 的定义g并调用mp.AddCostmp.AddQuadraticCost. mp.AddQuadraticCost期望二次符号表达式。您的代码中的表达式不是二次的(它if在成本中有一个语句,并且二次成本不允许if语句。)。

这段代码应该可以正常运行,但不知道能不能找到解决办法。同样,这个成本是不可微的,所以任何基于梯度的非线性求解器都会遇到麻烦。

如果实在不想将问题求解为非线性优化问题,可以考虑将问题重新表述为混合整数程序。也就是说,您的成本是一堆二进制变量的总和b[i]b[i] = 1 if |x[i, 0]| > epsilon or |x[i, 1]| > epsilon; otherwise b[i] = 0您可以将其表述为混合整数线性约束。

于 2019-12-19T17:39:50.023 回答
0

行中抛出的错误

if x[0]*x[0]+x[1]*x[1]<1e-7: # x.dot(x)
    return 0.

是因为你用 打了电话AddQuadraticCost,但你的成本不是二次的。Drake 尝试将符号表达式解析为二次表达式,但失败了。具体来说,当您检查表达式 x[0] * x[0] + x[1] * x[1] < 1e-7 时,Drake 会失败。没有二次成本可以有这种类型的“if”语句。

你的成本的数学公式是什么?您是否真的要按照g(x)函数中定义的方式施加成本,即如果 x'*x < 1e-7,则 g(x) = 0,否则 g(x) = 1?这是一个非常糟糕的成本(它几乎无处不在,但在原点附近有从 1 到 0 的离散跳跃)。

由于您想解决最少时间的最优控制问题,我建议您更改您的公式,并dt在您的问题中设置一个决策变量。即你将有动态约束

x[n+1] = x[n] + f(x[n], u[n]) * dt[n]

最终状态约束

x[N] = x_desired

初始状态约束

x[0] = x_initial

你的成本函数是最小化时间

min sum_i dt[i]

然后你将有平滑的成本和约束。

于 2019-12-17T16:52:29.000 回答