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 new NT
  • Loading branch information
Andy Goldschmidt committed Jun 13, 2025
commit 1ffee19142241af65de7f598e4eae2f590cd170e
67 changes: 34 additions & 33 deletions src/constraints/linear_constraints.jl
Original file line number Diff line number Diff line change
Expand Up @@ -216,36 +216,37 @@ function TimeStepsAllEqualConstraint(
return AllEqualConstraint(indices, bar_index, label)
end

struct L1SlackConstraint <: AbstractLinearConstraint
x_indices::Vector{Int}
s1_indices::Vector{Int}
s2_indices::Vector{Int}
label::String
end

function L1SlackConstraint(
name::Symbol,
traj::NamedTrajectory;
indices=1:traj.dims[name],
ts=(name ∈ keys(traj.initial) ? 2 : 1):(name ∈ keys(traj.final) ? traj.T-1 : traj.T),
label="L1 slack constraint on $name[$(indices)]"
)
@assert all(i ∈ 1:traj.dims[name] for i ∈ indices)

s1_name = Symbol("s1_$name")
s2_name = Symbol("s2_$name")

add_component!(traj, s1_name, rand(length(indices), traj.T))
add_component!(traj, s2_name, rand(length(indices), traj.T))

x_indices = stack(slice(t, traj.components[name][indices], traj.dim) for t ∈ ts)
s1_indices = stack(slice(t, traj.components[s1_name], traj.dim) for t ∈ ts)
s2_indices = stack(slice(t, traj.components[s2_name], traj.dim) for t ∈ ts)

return L1SlackConstraint(
x_indices,
s1_indices,
s2_indices,
label
)
end
# TODO: Doesn't work with parametric trajectory
# struct L1SlackConstraint <: AbstractLinearConstraint
# x_indices::Vector{Int}
# s1_indices::Vector{Int}
# s2_indices::Vector{Int}
# label::String
# end

# function L1SlackConstraint(
# name::Symbol,
# traj::NamedTrajectory;
# indices=1:traj.dims[name],
# ts=(name ∈ keys(traj.initial) ? 2 : 1):(name ∈ keys(traj.final) ? traj.T-1 : traj.T),
# label="L1 slack constraint on $name[$(indices)]"
# )
# @assert all(i ∈ 1:traj.dims[name] for i ∈ indices)

# s1_name = Symbol("s1_$name")
# s2_name = Symbol("s2_$name")

# add_component!(traj, s1_name, rand(length(indices), traj.T))
# add_component!(traj, s2_name, rand(length(indices), traj.T))

# x_indices = stack(slice(t, traj.components[name][indices], traj.dim) for t ∈ ts)
# s1_indices = stack(slice(t, traj.components[s1_name], traj.dim) for t ∈ ts)
# s2_indices = stack(slice(t, traj.components[s2_name], traj.dim) for t ∈ ts)

# return L1SlackConstraint(
# x_indices,
# s1_indices,
# s2_indices,
# label
# )
# end
26 changes: 13 additions & 13 deletions src/constraints/nonlinear_global_constraints.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,44 +22,44 @@ struct NonlinearGlobalConstraint <: AbstractNonlinearConstraint
equality::Bool=true,
)
global_comps = vcat([traj.global_components[name] for name in global_names]...)
local_comps = global_comps .- traj.dim * traj.T
offset_global_comps = global_comps .+ traj.dim * traj.T

g_eval = g(vec(traj)[global_comps])
g_eval = g(vec(traj)[offset_global_comps])
@assert g_eval isa AbstractVector{Float64}
g_dim = length(g_eval)

@views function g!(δ::AbstractVector, Z⃗::AbstractVector)
δ[:] = g(Z⃗[global_comps])
δ[:] = g(Z⃗[offset_global_comps])
return nothing
end

@views function ∂g!(∂g::AbstractMatrix, Z⃗::AbstractVector)
ForwardDiff.jacobian!(
∂g,
x -> g(x),
Z⃗[global_comps]
Z⃗[offset_global_comps]
)
end

# global subspace
jacobian_structure = spzeros(g_dim, traj.global_dim)
jacobian_structure[:, local_comps] .= 1.0
jacobian_structure[:, global_comps] .= 1.0

@views function μ∂²g!(
μ∂²g::AbstractMatrix,
Z⃗::AbstractVector,
μ::AbstractVector
)
ForwardDiff.hessian!(
μ∂²g[local_comps, local_comps],
μ∂²g[global_comps, global_comps],
x -> μ'g(x),
Z⃗[global_comps]
Z⃗[offset_global_comps]
)
end

# global subspace
hessian_structure = spzeros(traj.global_dim, traj.global_dim)
hessian_structure[local_comps, local_comps] .= 1.0
hessian_structure[global_comps, global_comps] .= 1.0

return new(
g!,
Expand Down Expand Up @@ -136,14 +136,14 @@ struct NonlinearGlobalKnotPointConstraint <: AbstractNonlinearConstraint

x_comps = vcat([traj.components[name] for name in names]...)
global_comps = vcat([traj.global_components[name] for name in global_names]...)
local_comps = global_comps .- traj.dim * traj.T
offset_global_comps = global_comps .+ traj.dim * traj.T

# (Rebased) global data is appended to the knot point
xg_comps = vcat([x_comps, traj.dim .+ local_comps]...)
# append global data to the knot point
xg_comps = vcat([x_comps, global_comps .+ traj.dim]...)
z_dim = traj.dim + traj.global_dim

# Each slice indexes into Z⃗
xg_slices = [vcat([slice(t, x_comps, traj.dim), global_comps]...) for t in times]
# append global data to the trajectory (each slice indexes into Z⃗)
xg_slices = [vcat([slice(t, x_comps, traj.dim), offset_global_comps]...) for t in times]

Z⃗ = vec(traj)
@assert g(Z⃗[xg_slices[1]], params[1]) isa AbstractVector{Float64}
Expand Down
3 changes: 1 addition & 2 deletions src/integrators/time_dependent_bilinear_integrator.jl
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,7 @@ end
@testitem "testing zoh TimeDependentBilinearIntegrator" begin
include("../../test/test_utils.jl")

G, traj = bilinear_dynamics_and_trajectory()
add_component!(traj, :t, get_times(traj))
G, traj = bilinear_dynamics_and_trajectory(time=true)

# zero order hold
B = TimeDependentBilinearIntegrator((a, t) -> G(a), traj, :x, :u, :t)
Expand Down
4 changes: 2 additions & 2 deletions src/objectives/global_objectives.jl
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ function GlobalObjective(
Q::Float64=1.0
)
Z_dim = traj.dim * traj.T + traj.global_dim
g_comps = vcat([traj.global_components[name] for name in global_names]...)
g_comps = vcat([traj.dim * traj.T .+ traj.global_components[name] for name in global_names]...)

L(Z⃗::AbstractVector{<:Real}) = Q * ℓ(Z⃗[g_comps])

Expand Down Expand Up @@ -76,7 +76,7 @@ function GlobalKnotPointObjective(

Z_dim = traj.dim * traj.T + traj.global_dim
x_comps = vcat([traj.components[name] for name in names]...)
g_comps = vcat([traj.global_components[name] for name in global_names]...)
g_comps = vcat([traj.dim * traj.T .+ traj.global_components[name] for name in global_names]...)

xg_slices = [vcat([slice(t, x_comps, traj.dim), g_comps]...) for t in times]

Expand Down
5 changes: 5 additions & 0 deletions test/test_utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ function bilinear_dynamics_and_trajectory(;
Δt = 0.1,
u_bound = 0.1,
ω = 0.1,
time=false
)
Gx = sparse(Float64[
0 0 0 1;
Expand Down Expand Up @@ -182,5 +183,9 @@ function bilinear_dynamics_and_trajectory(;
)
)

if time
traj = add_component(traj, :t, get_times(traj))
end

return G, traj
end
Loading