Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
d7d970a
Duration Constraint
BBhattacharyya1729 Apr 21, 2025
f4513fd
Merge remote-tracking branch 'upstream/main'
BBhattacharyya1729 May 1, 2025
b9981a7
free phases
andgoldschmidt May 3, 2025
acf0de1
intro global constraints / objectives, constraints to use global dim …
andgoldschmidt May 5, 2025
55e0a8b
Added Pairwise
BBhattacharyya1729 May 6, 2025
66f6941
clean
andgoldschmidt May 7, 2025
3d9e65a
Merge branch 'main' of github.com:harmoniqs/DirectTrajOpt.jl into fea…
andgoldschmidt May 7, 2025
aec79a7
Merge branch 'main' of github.com:harmoniqs/DirectTrajOpt.jl into fea…
andgoldschmidt May 7, 2025
8d936fe
refactor to separate pure knot point from global mixed
andgoldschmidt May 9, 2025
5c009eb
check overlapping constraint for zero reset
andgoldschmidt May 10, 2025
da8a5be
add reset for global nonlinear constraint
andgoldschmidt May 10, 2025
b2deb0f
min time obj free time only
andgoldschmidt May 19, 2025
6f9db34
added duration and symmetry consraints
BBhattacharyya1729 May 28, 2025
dcc5643
Update regularizers.jl
BBhattacharyya1729 May 28, 2025
ef4657a
Merge branch 'harmoniqs:main' into Feature/DurationSymmetry
BBhattacharyya1729 May 28, 2025
dd18f16
Merge branch 'main' into feature/free-phases
andgoldschmidt Jun 4, 2025
d7781ab
update global data
andgoldschmidt Jun 5, 2025
5911dc1
refactor NT concrete
Jun 7, 2025
1ffee19
update for new NT
Jun 13, 2025
c0213ea
added tests for symmetry and duration constraints
BBhattacharyya1729 Jun 16, 2025
9b6f1e7
Fixed duration/symmetry constraint tests
BBhattacharyya1729 Jun 16, 2025
1b07173
update for parametric NT, test global obj and constraints
andgoldschmidt Jun 17, 2025
e9623fb
Merge remote-tracking branch 'bikrant/Feature/DurationSymmetry' into …
andgoldschmidt Jun 18, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
update for parametric NT, test global obj and constraints
  • Loading branch information
andgoldschmidt committed Jun 17, 2025
commit 1b07173786427d475d2ec9c7129229d4b5adece6
4 changes: 2 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "DirectTrajOpt"
uuid = "c823fa1f-8872-4af5-b810-2b9b72bbbf56"
authors = ["Aaron Trowbridge <[email protected]> and contributors"]
version = "0.2.7"
version = "0.3.0"

[deps]
ExponentialAction = "e24c0720-ea99-47e8-929e-571b494574d3"
Expand Down Expand Up @@ -31,7 +31,7 @@ JLD2 = "0.5"
Libdl = "1.10, 1.11"
LinearAlgebra = "1.10, 1.11"
MathOptInterface = "1.40"
NamedTrajectories = "0.3"
NamedTrajectories = "0.4"
OrdinaryDiffEq = "6.97"
Reexport = "1.2"
SciMLBase = "2.86"
Expand Down
49 changes: 25 additions & 24 deletions src/constraints/linear_constraints.jl
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,6 @@ function EqualityConstraint(
return EqualityConstraint(name, ts, fill(val, traj.dims[name]), traj; label=label)
end



"""
GlobalEqualityConstraint(
name::Symbol,
Expand All @@ -82,20 +80,36 @@ function GlobalEqualityConstraint(
traj::NamedTrajectory;
label="equality constraint on global variable $name"
)
@assert name ∈ keys(traj.global_data)
@assert name ∈ traj.global_names
@assert length(val) == traj.global_dims[name]

indices = traj.global_components[name]
indices = traj.dim * traj.T .+ traj.global_components[name]
return EqualityConstraint(indices, val, label)
end

struct AllEqualConstraint <: AbstractLinearConstraint
indices::Vector{Int}
bar_index::Int
label::String
end

function TimeStepsAllEqualConstraint(
traj::NamedTrajectory;
label="timesteps all equal constraint"
)
@assert traj.timestep isa Symbol
indices = [index(k, traj.components[traj.timestep][1], traj.dim) for k ∈ 1:traj.T-1]
bar_index = index(traj.T, traj.components[traj.timestep][1], traj.dim)
return AllEqualConstraint(indices, bar_index, label)
end


###
### BoundsConstraint
###

# TODO: Refactor using `get_bounds_from_dims` from NamedTrajectories.jl

struct BoundsConstraint <: AbstractLinearConstraint
indices::Vector{Int}
bounds::Vector{Tuple{Float64, Float64}}
Expand Down Expand Up @@ -158,11 +172,11 @@ function GlobalBoundsConstraint(
traj::NamedTrajectory;
label="bounds constraint on global variable $name"
)
@assert name ∈ keys(traj.global_data)
@assert name ∈ traj.global_names
@assert length(bounds[1]) == length(bounds[2]) == traj.global_dims[name]
@assert all(bounds[1] .<= bounds[2])

indices = traj.global_components[name]
indices = traj.dim * traj.T .+ traj.global_components[name]

bounds = collect(zip(bounds...))

Expand All @@ -175,7 +189,7 @@ function GlobalBoundsConstraint(
traj::NamedTrajectory;
label="bounds constraint on global variable $name"
)
@assert name ∈ keys(traj.global_data)
@assert name ∈ traj.global_names
@assert length(bound) == traj.global_dims[name]
@assert all(bound .>= 0) "bound must be non-negative when only one bound is provided"

Expand All @@ -190,7 +204,7 @@ function GlobalBoundsConstraint(
traj::NamedTrajectory;
label="bounds constraint on global variable $name"
)
@assert name ∈ keys(traj.global_data)
@assert name ∈ traj.global_names
@assert bound >= 0 "bound must be non-negative when only one bound is provided"

bounds = (-fill(bound, traj.global_dims[name]), fill(bound, traj.global_dims[name]))
Expand All @@ -199,22 +213,9 @@ function GlobalBoundsConstraint(
end



struct AllEqualConstraint <: AbstractLinearConstraint
indices::Vector{Int}
bar_index::Int
label::String
end

function TimeStepsAllEqualConstraint(
traj::NamedTrajectory;
label="timesteps all equal constraint"
)
@assert traj.timestep isa Symbol
indices = [index(k, traj.components[traj.timestep][1], traj.dim) for k ∈ 1:traj.T-1]
bar_index = index(traj.T, traj.components[traj.timestep][1], traj.dim)
return AllEqualConstraint(indices, bar_index, label)
end
###
### L1SlackConstraint
###

# TODO: Doesn't work with parametric trajectory
# struct L1SlackConstraint <: AbstractLinearConstraint
Expand Down
29 changes: 16 additions & 13 deletions src/constraints/nonlinear_constraints.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ struct NonlinearKnotPointConstraint{F1, F2, F3} <: AbstractNonlinearConstraint
Create a NonlinearKnotPointConstraint object that represents a nonlinear constraint on a trajectory.

# Arguments
- `g::Function`: Function that defines the constraint. If `equality=false`, the constraint is `g(x) ≤ 0`.
- `g::Function`: Function over knot point variable(s) that defines the constraint, `g(x)`.
- `name::Symbol`: Name of the variable to be constrained.
- `traj::NamedTrajectory`: The trajectory on which the constraint is defined.

Expand All @@ -52,8 +52,9 @@ struct NonlinearKnotPointConstraint{F1, F2, F3} <: AbstractNonlinearConstraint
x_slices = [slice(t, x_comps, traj.dim) for t in times]

# inspect view of knot point data
@assert g(traj.datavec[x_slices[1]], params[1]) isa AbstractVector{Float64}
g_dim = length(g(traj.datavec[x_slices[1]], params[1]))
Z⃗ = vec(traj)
@assert g(Z⃗[x_slices[1]], params[1]) isa AbstractVector{Float64}
g_dim = length(g(Z⃗[x_slices[1]], params[1]))

@views function g!(δ::AbstractVector, Z⃗::AbstractVector)
for (i, x_slice) ∈ enumerate(x_slices)
Expand Down Expand Up @@ -172,7 +173,7 @@ end

# ============================================================================= #

@testitem "testing NonlinearConstraint" begin
@testitem "testing NonlinearKnotPointConstraint" begin

using TrajectoryIndexingUtils

Expand All @@ -182,31 +183,33 @@ end

g(a) = [norm(a) - 1.0]

g_dim = 1
times = 1:traj.T

NLC = NonlinearKnotPointConstraint(g, :u, traj; times=times, equality=false)
U_SLICE(k) = slice(k, traj.components[:u], traj.dim)

ĝ(Z⃗) = vcat([g(Z⃗[slice(k, traj.components[:u], traj.dim)]) for k ∈ times]...)
ĝ(Z⃗) = vcat([g(Z⃗[U_SLICE(k)]) for k ∈ times]...)

δ = zeros(length(times))
δ = zeros(g_dim * traj.T)

NLC.g!(δ, traj.datavec)
NLC.g!(δ, vec(traj))

@test δ ≈ ĝ(traj.datavec)
@test δ ≈ ĝ(vec(traj))

NLC.∂g!(NLC.∂gs, traj.datavec)
NLC.∂g!(NLC.∂gs, vec(traj))

∂g_full = Constraints.get_full_jacobian(NLC, traj)

∂g_autodiff = ForwardDiff.jacobian(ĝ, traj.datavec)
∂g_autodiff = ForwardDiff.jacobian(ĝ, vec(traj))

@test ∂g_full ≈ ∂g_autodiff

μ = randn(length(times))
μ = randn(g_dim * traj.T)

NLC.μ∂²g!(NLC.μ∂²gs, traj.datavec, μ)
NLC.μ∂²g!(NLC.μ∂²gs, vec(traj), μ)

hessian_autodiff = ForwardDiff.hessian(Z -> μ'ĝ(Z), traj.datavec)
hessian_autodiff = ForwardDiff.hessian(Z -> μ'ĝ(Z), vec(traj))

μ∂²g_full = Constraints.get_full_hessian(NLC, traj)

Expand Down
Loading
Loading