Support variable time with `create_objective_function()`
We now have variable time step support but it will not work with the current create_objective_function().
Would it make sense to give an example how for form the obj_grad function for the cases
- you only want to minimize h_opty
- you want to minimize $\int (fx^2 + fy^2 + hopy) \ dt$ ? I am never 100% sure I do it right, and then if opty does not give a reasonable result I wonder whether my obj_grad is wrong or some other mistake.
I think the examples are more like $\int dt$ (minimize time) or $w_1\int F^2 dt + w_2\int dt$ (minimize force and time with weights). The integrals should never have 'h' in them, only time. create_objective_function()'s job is to convert integrals in continuous time to their discrete versions.
The simplest would be to use something like the following:
def lambdify_function(expr, multiplication_array, take_sum):
if take_sum:
def integration_function(x):
return np.sum(x * multiplication_array)
else:
def integration_function(x):
return x * multiplication_array
return sm.lambdify(
(states, inputs, params), expr,
modules=[{int_placeholder.name: integration_function}, "numpy"],
cse=True)
...
def multiply_integrals(expr, value):
if not expr.args:
return expr
if isinstance(expr, sm.Integral):
return value * expr
return expr.func(*(multiply_integrals(arg, value) for arg in expr.args))
objective = multiply_integrals(objective, node_time_interval)
I think the examples are more like ∫dt (minimize time) or w1∫F2dt+w2∫dt (minimize force and time with weights). The integrals should never have 'h' in them, only time.
create_objective_function()'s job is to convert integrals in continuous time to their discrete versions.
Of course STUPID of my part to put h in the integral!