Quickstart Guide
Welcome to DirectTrajOpt.jl! This guide will get you up and running in minutes.
What is DirectTrajOpt?
DirectTrajOpt.jl solves trajectory optimization problems - finding optimal control sequences that drive a dynamical system from an initial state to a goal state while minimizing a cost function.
Installation
First, install the package:
using Pkg
Pkg.add("DirectTrajOpt")You'll also need NamedTrajectories.jl for defining trajectories:
using DirectTrajOpt
using NamedTrajectories
using LinearAlgebra
using CairoMakieA Minimal Example
Let's solve a simple problem: drive a 2D system from [0, 0] to [1, 0] with minimal control effort.
Step 1: Define the Trajectory
A trajectory contains your states, controls, and time information:
N = 50 # number of time steps
traj = NamedTrajectory(
(
x = randn(2, N), # 2D state
u = randn(1, N), # 1D control
Δt = fill(0.1, N) # time step
);
timestep=:Δt,
controls=:u,
initial=(x = [0.0, 0.0],),
final=(x = [1.0, 0.0],),
bounds=(Δt = (0.05, 0.2), u = 1.0)
)N = 50, (x = 1:2, u = 3:3, → Δt = 4:4)Step 2: Define the Dynamics
Specify how your system evolves. For bilinear dynamics ẋ = (G₀ + u₁G₁) x:
G_drift = [-0.1 1.0; -1.0 -0.1] # drift term
G_drives = [[0.0 1.0; 1.0 0.0]] # control term
G = u -> G_drift + sum(u .* G_drives)
integrator = BilinearIntegrator(G, traj, :x, :u)BilinearIntegrator{Main.var"#2#3"}(Main.var"#2#3"(), [1, 2], [3], 4, 4, 2, 1)Step 3: Define the Objective
What do we want to minimize? Let's penalize control effort:
obj = QuadraticRegularizer(:u, traj, 1.0)Objective(L, ∇L, ∂²L, ∂²L_structure)Step 4: Create and Solve
Combine everything into a problem and solve:
prob = DirectTrajOptProblem(traj, obj, integrator)
solve!(prob; max_iter=100, verbose=false)This is Ipopt version 3.14.19, running with linear solver MUMPS 5.8.1.
Number of nonzeros in equality constraint Jacobian...: 484
Number of nonzeros in inequality constraint Jacobian.: 0
Number of nonzeros in Lagrangian Hessian.............: 539
Total number of variables............................: 196
variables with only lower bounds: 0
variables with lower and upper bounds: 100
variables with only upper bounds: 0
Total number of equality constraints.................: 98
Total number of inequality constraints...............: 0
inequality constraints with only lower bounds: 0
inequality constraints with lower and upper bounds: 0
inequality constraints with only upper bounds: 0
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
0 1.3671066e-01 5.05e+00 8.23e-02 0.0 0.00e+00 - 0.00e+00 0.00e+00 0
1 1.6665787e-01 1.33e-01 8.98e-01 -1.4 3.61e+00 - 9.80e-01 1.00e+00h 1
2 9.5249007e-02 7.48e-02 1.12e+00 -1.4 3.06e+00 - 3.75e-01 6.30e-01f 1
3 1.1831689e-01 4.50e-02 7.61e-01 -1.8 3.30e+00 - 3.45e-01 3.99e-01h 1
4 1.4049129e-01 3.84e-02 1.04e+00 -1.2 9.04e-01 0.0 6.47e-01 1.49e-01h 1
5 2.1864453e-01 1.98e-02 7.43e-01 -2.2 1.57e+00 - 4.59e-01 4.82e-01h 1
6 2.5959686e-01 1.52e-02 6.30e-01 -2.9 4.83e+00 - 1.93e-01 2.35e-01h 1
7 3.1610254e-01 1.19e-02 4.85e-01 -2.2 1.64e+00 - 2.73e-01 2.22e-01h 1
8 3.7276026e-01 1.00e-02 8.04e-01 -1.4 6.37e-01 -0.5 6.14e-01 1.62e-01h 1
9 4.5609188e-01 8.16e-03 3.24e+00 -1.0 4.12e+00 -1.0 6.88e-01 1.96e-01h 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
10 4.8587229e-01 8.07e-03 8.59e+00 -0.8 3.72e+00 - 8.66e-01 7.15e-02h 1
11 6.6762544e-01 5.10e-03 4.95e+01 -0.9 1.75e+00 - 1.00e+00 3.74e-01h 1
12 7.2831317e-01 4.69e-03 1.29e+02 -0.4 6.09e+00 - 2.56e-01 8.07e-02h 1
13 7.5251482e-01 4.65e-03 1.06e+03 0.6 1.42e+01 - 9.75e-01 7.90e-03h 1
14 7.9202003e-01 4.45e-03 1.53e+04 1.4 3.80e+00 - 1.00e+00 4.18e-02h 1
15 8.1772964e-01 4.32e-03 2.49e+05 2.1 7.75e+00 - 1.00e+00 2.91e-02h 1
16 8.3737418e-01 4.28e-03 5.41e+06 2.7 9.56e+00 - 1.00e+00 1.11e-02h 1
17 8.5432766e-01 4.20e-03 3.44e+07 2.7 9.70e+00 - 2.17e-01 1.82e-02h 1
18 8.6557694e-01 4.16e-03 3.96e+07 -2.0 1.04e+01 - 1.03e-02 9.99e-03h 1
19 8.7794597e-01 4.15e-03 5.48e+07 2.7 4.20e+02 - 1.56e-04 1.98e-04h 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
20r 8.7794597e-01 4.15e-03 9.62e+02 2.7 0.00e+00 - 0.00e+00 4.29e-07R 4
21r 8.7793918e-01 3.09e-03 1.02e+01 -3.5 5.41e-01 - 9.89e-01 9.87e-01f 1
22 8.8103032e-01 3.07e-03 1.02e+01 -4.0 4.26e-01 - 5.94e-02 5.37e-03h 1
23 8.9996319e-01 3.05e-03 5.31e+01 -0.9 1.83e+01 - 4.19e-03 6.85e-03f 1
24 9.1523305e-01 3.04e-03 1.73e+02 -1.3 1.60e+01 - 2.70e-02 5.44e-03h 1
25 9.2396982e-01 3.03e-03 2.48e+03 -2.0 1.53e+02 - 7.28e-03 2.16e-03h 1
26 9.3949895e-01 3.03e-03 1.37e+05 0.4 3.18e+02 - 1.00e+00 1.66e-03f 1
27 9.4007252e-01 3.02e-03 3.34e+08 1.1 1.54e+01 - 1.00e+00 2.79e-04h 1
28 9.4722088e-01 1.40e-03 3.26e+06 2.7 1.83e+00 - 9.90e-01 5.66e-01f 1
29 9.4743226e-01 1.40e-03 6.99e+08 2.7 3.77e+01 - 5.25e-02 9.15e-05h 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
30r 9.4743226e-01 1.40e-03 9.97e+02 2.7 0.00e+00 - 0.00e+00 4.66e-07R 9
31r 9.4742734e-01 1.70e-03 1.02e+01 -3.5 5.39e-01 - 9.90e-01 9.88e-01f 1
32r 9.4726387e-01 1.20e-03 6.61e+00 -4.0 1.95e-02 - 9.69e-01 9.02e-01f 1
33 9.4732486e-01 1.20e-03 1.48e+04 -1.1 8.83e-02 - 9.99e-01 1.36e-04h 1
34 9.4097932e-01 1.22e-03 2.18e+01 -1.3 6.36e-01 - 1.00e+00 1.00e+00f 1
35 9.4118311e-01 1.22e-03 4.73e+06 -0.5 2.49e+00 - 1.00e+00 2.31e-04h 1
36 9.4119085e-01 1.22e-03 7.46e+10 -0.1 6.86e-01 - 1.00e+00 6.28e-05h 1
37 9.4085399e-01 3.71e-01 7.65e+10 -0.1 2.27e+00 - 1.78e-01 1.78e-01s 20
38 9.4086223e-01 3.71e-01 2.59e+08 -0.8 3.33e-03 10.9 1.00e+00 1.00e+00s 22
39r 9.4086223e-01 3.71e-01 1.00e+03 -0.4 0.00e+00 11.3 0.00e+00 4.77e-07R 22
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
40r 9.4046082e-01 9.95e-02 9.67e+02 1.1 1.80e+02 - 1.47e-01 1.52e-03f 1
41 9.4054066e-01 9.94e-02 5.20e+03 -1.5 3.85e-01 - 6.50e-01 1.58e-04h 1
42 9.4065351e-01 9.94e-02 1.99e+07 -1.5 4.07e-01 - 7.21e-01 1.87e-04h 1
43r 9.4065351e-01 9.94e-02 1.00e+03 -1.0 0.00e+00 - 0.00e+00 4.55e-07R 3
44r 9.4063390e-01 2.41e-02 9.43e+02 -0.2 9.06e+01 - 9.39e-01 1.21e-03f 1
45r 9.4063390e-01 2.41e-02 9.99e+02 -1.5 0.00e+00 - 0.00e+00 2.70e-07R 6
46r 8.4489168e-01 8.49e-03 9.42e+02 0.8 2.02e+01 - 1.00e+00 1.56e-03f 1
47 8.9770884e-01 7.68e-03 8.45e+00 -1.5 2.38e-01 - 7.12e-01 1.02e-01h 1
48 9.2272857e-01 7.39e-03 7.30e+01 -1.5 1.23e+00 - 4.13e-01 3.70e-02h 1
49 9.3993317e-01 7.25e-03 1.56e+03 -1.5 5.02e-01 - 3.95e-01 1.93e-02h 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
50 9.4063084e-01 7.25e-03 1.15e+06 -1.5 1.68e+00 - 5.84e-01 7.73e-04h 1
51 9.4067767e-01 7.25e-03 1.90e+10 -1.5 8.58e-01 - 1.00e+00 6.00e-05h 1
52r 9.4067767e-01 7.25e-03 1.00e+03 -1.5 0.00e+00 - 0.00e+00 4.96e-07R 20
53r 9.4058920e-01 2.11e-03 3.06e+02 0.1 4.46e+00 - 9.91e-01 5.02e-03f 1
54 9.4061227e-01 2.11e-03 3.42e+04 -1.0 1.08e-01 - 1.00e+00 5.84e-05h 1
55 9.4066115e-01 2.11e-03 2.72e+08 -1.2 5.35e-01 - 5.46e-01 6.81e-05h 1
56r 9.4066115e-01 2.11e-03 1.00e+03 -1.2 0.00e+00 - 0.00e+00 3.01e-07R 16
57r 9.3989382e-01 9.12e-04 4.03e+01 -0.0 1.15e+00 - 9.90e-01 5.26e-02f 1
58 9.4005877e-01 9.12e-04 4.70e+03 -0.9 1.13e-01 - 9.98e-01 4.22e-04h 1
59 9.4043430e-01 9.11e-04 9.06e+06 -0.6 5.32e-01 - 1.00e+00 5.14e-04h 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
60r 9.4043430e-01 9.11e-04 1.00e+03 1.8 0.00e+00 - 0.00e+00 3.58e-07R 5
61r 9.2429815e-01 1.49e-03 9.30e+00 0.2 6.90e-02 - 9.91e-01 1.00e+00f 1
62r 9.1035966e-01 1.36e-03 1.31e+02 -1.5 1.75e-02 - 9.95e-01 7.07e-01f 1
63r 9.3373456e-01 1.46e-03 3.18e+02 -4.0 3.53e-02 - 8.71e-01 4.60e-01f 1
64r 7.7173779e-01 7.79e-03 4.08e+01 -1.4 4.82e-01 - 9.02e-01 9.24e-01f 1
65r 8.0923154e-01 1.13e-02 4.90e+01 -1.6 3.82e-01 - 1.00e+00 5.04e-01f 1
66r 8.9132251e-01 1.19e-02 1.58e-01 -2.3 1.81e-01 - 1.00e+00 9.90e-01f 1
67r 9.2094218e-01 1.25e-02 2.75e-01 -3.3 6.65e-02 - 9.99e-01 1.00e+00f 1
68r 9.2570027e-01 1.25e-02 5.10e-01 -4.0 3.21e-02 - 1.00e+00 1.00e+00f 1
69r 9.2585720e-01 1.25e-02 2.51e-02 -4.0 2.15e-02 - 1.00e+00 1.00e+00h 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
70r 9.2607961e-01 1.25e-02 2.02e-03 -4.0 1.65e-02 - 1.00e+00 1.00e+00h 1
71r 9.2609906e-01 1.25e-02 2.55e-05 -4.0 1.29e-03 - 1.00e+00 1.00e+00h 1
Number of Iterations....: 71
(scaled) (unscaled)
Objective...............: 9.2609920239966959e-01 9.2609920239966959e-01
Dual infeasibility......: 1.9996498124209516e-01 1.9996498124209516e-01
Constraint violation....: 1.2450478196233175e-02 1.2450478196233175e-02
Variable bound violation: 0.0000000000000000e+00 0.0000000000000000e+00
Complementarity.........: 1.0000000075047487e-04 1.0000000075047487e-04
Overall NLP error.......: 1.9996498124209516e-01 1.9996498124209516e-01
Number of objective function evaluations = 203
Number of objective gradient evaluations = 61
Number of equality constraint evaluations = 203
Number of inequality constraint evaluations = 0
Number of equality constraint Jacobian evaluations = 81
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations = 72
Total seconds in IPOPT = 7.644
EXIT: Converged to a point of local infeasibility. Problem may be infeasible.Step 5: Access the Solution
Let's look at the results.
plot(prob.trajectory)
The optimized trajectory is stored in prob.trajectory:
println("Final state: ", prob.trajectory.x[:, end])
println("Control norm: ", norm(prob.trajectory.u))Final state: [1.0, 0.0]
Control norm: 6.844892533463705What You Can Do
- Multiple objectives: Combine regularization, minimum time, terminal costs
- Flexible dynamics: Linear, bilinear, time-dependent systems
- Add constraints: Bounds, path constraints, custom nonlinear constraints
- Smooth controls: Penalize derivatives for smooth, implementable controls
- Free time: Optimize trajectory duration
This page was generated using Literate.jl.