@@ -6,6 +6,7 @@ addOption(prob, k, v::Float64) = Ipopt.AddIpoptNumOption(prob, k, v)
66 solve_with_ipopt(problem, robot;
77 initial_guess=Float64[],
88 use_inv_dyn=false,
9+ minimise_velocities=false,
910 minimise_torques=false,
1011 user_options=Dict())
1112
@@ -16,6 +17,7 @@ Further options can be set using the keyword arguments. See [Solver Interfaces](
1617# Keyword arguments
1718- `initial_guess::Vector{Float64}=Float64[]`: the starting point for the solver.
1819- `use_inv_dyn::Bool=false`: if true, enables the use of inverse dynamics instead of forward dynamics.
20+ - `minimise_velocities::Bool=false`: if true, activates a cost function to minimize the joint velocities.
1921- `minimise_torques::Bool=false`: if true, activates a cost function to minimize the joint torques.
2022- `user_options::Dict=Dict()`: the user options for Ipopt.
2123
@@ -24,6 +26,7 @@ See also: [`solve_with_knitro`](@ref)
2426function solve_with_ipopt (problem:: Problem , robot:: Robot ;
2527 initial_guess:: Vector{Float64} = Float64[],
2628 use_inv_dyn:: Bool = false ,
29+ minimise_velocities:: Bool = false ,
2730 minimise_torques:: Bool = false ,
2831 user_options:: Dict = Dict (" hessian_approximation" => " limited-memory" ))
2932 # # # # # # # # # # # # # # # #
@@ -275,28 +278,41 @@ function solve_with_ipopt(problem::Problem, robot::Robot;
275278 # Objective #
276279 # # # # # # #
277280
278- function eval_f (x)
279- return 0
280- end
281+ eval_f (x) = 0 # Callback function for evaluating objective function
282+ eval_grad_f (x, grad_f) = grad_f[:] = zeros (n) # Callback function for evaluating gradient of objective function
283+
284+ if minimise_velocities
285+ offset_velocities = robot. n_q + 1 # indice of the first velocity value within a knot point
286+ indexVars = vcat ([range ((i - 1 ) * nₓ + offset_velocities, length= robot. n_v)
287+ for i = 1 : problem. num_knots]. .. )
288+ coefs = fill (1 / problem. num_knots, robot. n_v * problem. num_knots)
289+ @assert length (indexVars) == length (coefs)
290+
291+ eval_f = function (x)
292+ return sum (coefs .* x[indexVars] .* x[indexVars])
293+ end
281294
282- function eval_grad_f (x, grad_f)
283- grad_f[:] = zeros (n)
295+ eval_grad_f = function (x, grad_f)
296+ grad_f[:] = zeros (n)
297+ @. grad_f[indexVars] = coefs * 2 * x[indexVars]
298+ end
284299 end
285300
286301 if minimise_torques
287- ind_τ = hcat ([range (1 + (i * nₓ) + robot. n_q + robot. n_v, length= robot. n_τ)
288- for i = (1 : problem. num_knots - 1 ) .- 1 ]. .. )
289- indexVars, coefs = vec (ind_τ), fill (1 / (problem. num_knots - 1 ), n3)
302+ offset_torques = robot. n_q + robot. n_v + 1 # indice of the first torque value within a knot point
303+ num_knots_with_torque = problem. num_knots - 1
304+ indexVars = vcat ([range ((i - 1 ) * nₓ + offset_torques, length= robot. n_τ)
305+ for i = 1 : num_knots_with_torque]. .. )
306+ coefs = fill (1 / num_knots_with_torque, robot. n_τ * num_knots_with_torque)
290307 @assert length (indexVars) == length (coefs)
291308
292- eval_f = function (x)
293- # Minimize τ, i.e., the necessary joint torques.
309+ eval_f = function (x)
294310 return sum (coefs .* x[indexVars] .* x[indexVars])
295311 end
296312
297- eval_grad_f = function (x, grad_f)
313+ eval_grad_f = function (x, grad_f)
298314 grad_f[:] = zeros (n)
299- grad_f[indexVars] . = coefs .* 2 x [indexVars]
315+ @. grad_f[indexVars] = coefs * 2 * x [indexVars]
300316 end
301317 end
302318
0 commit comments