Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Non-symbolic inputs to a to_function when using Direct Collocation method #5

Open
loughlindd opened this issue Apr 21, 2021 · 0 comments

Comments

@loughlindd
Copy link

Dear Joris,
Thanks for the great job with the Rockit software.

I am generating a to_function for Optimal Control Problems, but have been faced with an issue : in the master example car_example_parametric, both states are sampled together, but in my case I wish to avoid this, in order to have separate to_function inputs for every state.
This does not cause any problem when using the Multiple Shooting method, but when using the Direct Collocation the to_function cannot be generated. It looks like the Collocation method assigns only one opti placeholder (per control interval) which is a vertcat of all the states. Therefore, when sampling the states individually they are expressed as : vertsplit(opti_x_1){0}, which is not symbolic and therefore cannot be used as a to_function input.

Is this a deliberate limitation to rockit, or do you believe there is a way to overcome this issue ?
Just in case, here is code generating the issue, by commenting/uncommenting lines 77-78.

Thanks for your help
Loughlin

#
#     This file is part of rockit.
#
#     rockit -- Rapid Optimal Control Kit
#     Copyright (C) 2019 MECO, KU Leuven. All rights reserved.
#
#     Rockit is free software; you can redistribute it and/or
#     modify it under the terms of the GNU Lesser General Public
#     License as published by the Free Software Foundation; either
#     version 3 of the License, or (at your option) any later version.
#
#     Rockit is distributed in the hope that it will be useful,
#     but WITHOUT ANY WARRANTY; without even the implied warranty of
#     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#     Lesser General Public License for more details.
#
#     You should have received a copy of the GNU Lesser General Public
#     License along with CasADi; if not, write to the Free Software
#     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
#
#

"""
Car accelerating on a linear track
====================================


"""

from rockit import *
from numpy import sin, pi
from casadi import vertcat
import numpy as np
import matplotlib.pyplot as plt

ocp = Ocp(T=FreeTime(1.0))

# Define constants
m = 500
c = 2
d = 1000

# Define states
p = ocp.state()
v = ocp.state()

# Defince controls
F = ocp.control()

# Specify ODE
ocp.set_der(p, v)
ocp.set_der(v, 1/m * (F - c * v**2))

# Lagrange objective
ocp.add_objective(ocp.T)

# Define parameters
F_max = ocp.parameter(grid='control')
p0 = ocp.parameter()

# Path constraints
ocp.subject_to(-F_max <= (F<= F_max))
ocp.subject_to(v >= 0)

# Initial constraints
ocp.subject_to(ocp.at_t0(p)==p0)
ocp.subject_to(ocp.at_t0(v)==0)

# End constraints
ocp.subject_to(ocp.at_tf(p)==d)
ocp.subject_to(ocp.at_tf(v)==0)

# Pick a solver
ocp.solver('ipopt')

# Choose a solution method
ocp.method(MultipleShooting(N=20,M=1,intg='rk')) #This works
# ocp.method(DirectCollocation(N=20,M=1,intg='rk')) #This does not work


# Set values for parameters
ocp.set_value(p0, 1)
ocp.set_value(F_max, 2500*np.ones(20))

# Translate problem to function
T = ocp.value(ocp.T)
p_state = ocp.sample(p,grid='control')[1]
v_state = ocp.sample(v,grid='control')[1]

controls = ocp.sample(F,grid='control-')[1]
test = ocp.to_function('test', [p0, ocp.sample(F_max,grid='control-')[1], T, p_state, v_state, controls], [ocp.sample(F,grid='control')[1], T, p_state, v_state, controls])

# Initial value
sol_T = 1.0
sol_p_state = 0
sol_v_state = 0

sol_controls = 0

# Solve problem for different values for parameters, initializing with previous solution
signal1, sol_T, sol_p_state1, sol_v_state1, sol_controls = test(0, 2500*np.ones(20), sol_T, sol_p_state, sol_v_state, sol_controls)
signal2, sol_T, sol_p_state2, sol_v_state2, sol_controls = test(0, 2500*np.ones(20), sol_T, sol_p_state1, sol_v_state1, sol_controls)
signal3, sol_T, sol_p_state3, sol_v_state3, sol_controls = test(0, 2000*np.ones(20), sol_T, sol_p_state2, sol_v_state2, sol_controls)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant