2016-10-10 34 views
0

我正在尝试迁移Ipopt源代码tarball中的振幅车问题作为示例。我遇到了结束条件问题(在最终迭代中达到零速的地方)和成本函数(最小化最终时间)。重新构造AMPL车示例

有人可以帮我修改以下模型吗?

# min tf 
# dx/dt = 0 
# dv/dt = a - R*v^2 
# x(0) = 0; x(tf) = 100 
# v(0) = 0; v(tf) = 0 
# -3 <= a <= 1 (a is the control variable) 

#!Python3.5 
from pyomo.environ import * 
from pyomo.dae import * 

N = 20; 
T = 10; 
L = 100; 

m = ConcreteModel() 

# Parameters 
m.R = Param(initialize=0.001) 

# Variables 
def x_init(m, i): 
    return i*L/N 

m.t = ContinuousSet(bounds=(0,1000)) 
m.x = Var(m.t, bounds=(0,None), initialize=x_init) 
m.v = Var(m.t, bounds=(0,None), initialize=L/T) 
m.a = Var(m.t, bounds=(-3.0,1.0), initialize=0) 

# Derivatives 
m.dxdt = DerivativeVar(m.x, wrt=m.t) 
m.dvdt = DerivativeVar(m.v, wrt=m.t) 

# Objetives 
m.obj = Objective(expr=m.t[N]) 

# DAE 
def _ode1(m, i): 
    if i==0: 
     return Constraint.Skip 
    return m.dxdt[i] == m.v[i] 
m.ode1 = Constraint(m.t, rule=_ode1) 

def _ode2(m, i): 
    if i==0: 
     return Constraint.Skip 
    return m.dvdt[i] == m.a[i] - m.R*m.v[i]**2 
m.ode2 = Constraint(m.t, rule=_ode2) 

# Constraints 
def _init(m): 
    yield m.x[0] == 0 
    yield m.v[0] == 0 
    yield ConstraintList.End 
m.init = ConstraintList(rule=_init) 

''' 
def _end(m, i): 
    if i==N: 
     return m.x[i] == L amd m.v[i] == 0 
    return Constraint.Skip 
m.end = ConstraintList(rule=_end) 
''' 

# Discretize 
discretizer = TransformationFactory('dae.finite_difference') 
discretizer.apply_to(m, nfe=N, wrt=m.t, scheme='BACKWARD') 

# Solve 
solver = SolverFactory('ipopt', executable='C:\\EXTERNOS\\COIN-OR\\win32-msvc12\\bin\\ipopt') 
results = solver.solve(m, tee=True) 
+0

欢迎来到Stack Overflow!请参阅[问]和[mcve]。 – Mat

回答

1

目前,Pyomo中的ContinuousSet必须是有界的。这意味着为了解决使用此工具的最小时间最优控制问题,必须重新构造问题以从连续集中移除时间缩放。另外,你必须引入一个额外的变量来表示最后的时间。我已向Pyomo github repository添加了一个示例,说明如何解决您的问题。

+0

太棒了!这与放大的方式是一样的,使用一个自变量来表示时间。相同的概念,但语法真的不同,非常感谢! – Pablo