Skip to content

Commit b304811

Browse files
committed
Update cone methods
1 parent 1816188 commit b304811

File tree

6 files changed

+320
-167
lines changed

6 files changed

+320
-167
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ DocStringExtensions = "0.8"
2020
FiniteDiff = "2"
2121
ForwardDiff = "0.10"
2222
MathOptInterface = "0.9"
23-
RobotZoo = "0.3"
2423
RobotDynamics = "0.4"
24+
RobotZoo = "0.3"
2525
Rotations = "~1.0"
2626
StaticArrays = "1"
2727
UnsafeArrays = "1"

src/TrajectoryOptimization.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ include("quadratic_costs.jl")
8080
include("lie_costs.jl")
8181
include("objective.jl")
8282

83+
include("cones.jl")
8384
include("abstract_constraint.jl")
8485
include("constraints.jl")
8586
include("dynamics_constraints.jl")

src/abstract_constraint.jl

Lines changed: 0 additions & 166 deletions
Original file line numberDiff line numberDiff line change
@@ -1,171 +1,5 @@
11
import RobotDynamics: jacobian!
22

3-
4-
""""
5-
Specifies whether the constraint is an equality or inequality constraint.
6-
Valid subtypes are `Equality`, `Inequality` ⟺ `NegativeOrthant`, and `SecondOrderCone`.
7-
8-
The sense of a constraint can be queried using `sense(::AbstractConstraint)`
9-
10-
If `sense(con) <: Conic` (i.e. not `Equality`), then the following operations are supported:
11-
* `Base.in(::Conic, x::StaticVector)`. i.e. `x ∈ cone`
12-
* `projection(::Conic, x::StaticVector)`
13-
* `∇projection(::Conic, J, x::StaticVector)`
14-
* `∇²projection(::Conic, J, x::StaticVector, b::StaticVector)`
15-
"""
16-
abstract type ConstraintSense end
17-
abstract type Conic <: ConstraintSense end
18-
19-
"""
20-
Equality constraints of the form ``g(x) = 0`.
21-
Type singleton, so it is created with `Equality()`.
22-
"""
23-
struct Equality <: ConstraintSense end
24-
"""
25-
Inequality constraints of the form ``h(x) \\leq 0``.
26-
Type singleton, so it is created with `Inequality()`.
27-
Equivalent to `NegativeOrthant`.
28-
"""
29-
struct NegativeOrthant <: Conic end
30-
const Inequality = NegativeOrthant
31-
32-
struct PositiveOrthant <: Conic end
33-
34-
"""
35-
The second-order cone is defined as
36-
``\\|x\\| \\leq t``
37-
where ``x`` and ``t`` are both part of the cone.
38-
TrajectoryOptimization assumes the scalar part ``t`` is
39-
the last element in the vector.
40-
"""
41-
struct SecondOrderCone <: Conic end
42-
43-
dualcone(::NegativeOrthant) = NegativeOrthant()
44-
dualcone(::PositiveOrthant) = PositiveOrthant()
45-
dualcone(::SecondOrderCone) = SecondOrderCone()
46-
47-
projection(::NegativeOrthant, x) = min.(0, x)
48-
projection(::PositiveOrthant, x) = max.(0, x)
49-
50-
function projection(::SecondOrderCone, x::StaticVector)
51-
# assumes x is stacked [v; s] such that ||v||₂ ≤ s
52-
s = x[end]
53-
v = pop(x)
54-
a = norm(v)
55-
if a <= -s # below the cone
56-
return zero(x)
57-
elseif a <= s # in the cone
58-
return x
59-
elseif a >= abs(s) # outside the cone
60-
return 0.5 * (1 + s/a) * push(v, a)
61-
else
62-
throw(ErrorException("Invalid second-order cone projection"))
63-
end
64-
end
65-
66-
function ∇projection!(::SecondOrderCone, J, x::StaticVector{n}) where n
67-
s = x[end]
68-
v = pop(x)
69-
a = norm(v)
70-
if a <= -s # below cone
71-
J .*= 0
72-
elseif a <= s # in cone
73-
J .*= 0
74-
for i = 1:n
75-
J[i,i] = 1.0
76-
end
77-
elseif a >= abs(s) # outside cone
78-
# scalar
79-
b = 0.5 * (1 + s/a)
80-
dbdv = -0.5*s/a^3 * v
81-
dbds = 0.5 / a
82-
83-
# dvdv = dbdv * v' + b * oneunit(SMatrix{n-1,n-1,T})
84-
for i = 1:n-1, j = 1:n-1
85-
J[i,j] = dbdv[i] * v[j]
86-
if i == j
87-
J[i,j] += b
88-
end
89-
end
90-
91-
# dvds
92-
J[1:n-1,n] .= dbds * v
93-
94-
# ds
95-
dsdv = dbdv * a + b * v / a
96-
dsds = dbds * a
97-
ds = push(dsdv, dsds)
98-
J[n,:] .= ds
99-
else
100-
throw(ErrorException("Invalid second-order cone projection"))
101-
end
102-
return J
103-
end
104-
105-
function Base.in(x, ::SecondOrderCone)
106-
s = x[end]
107-
v = pop(x)
108-
a = norm(v)
109-
return a <= s
110-
end
111-
112-
function cone_status(::SecondOrderCone, x)
113-
s = x[end]
114-
v = pop(x)
115-
a = norm(v)
116-
if a <= -s
117-
return :below
118-
elseif a <= s
119-
return :in
120-
elseif a > abs(s)
121-
return :outside
122-
else
123-
return :invalid
124-
end
125-
end
126-
127-
function ∇²projection!(::SecondOrderCone, hess, x::StaticVector, b::StaticVector)
128-
n = length(x)
129-
s = x[end]
130-
v = pop(x)
131-
bs = b[end]
132-
bv = pop(b)
133-
a = norm(v)
134-
135-
if a <= -s
136-
return hess .= 0
137-
elseif a <= s
138-
return hess .= 0
139-
elseif a > abs(s)
140-
dvdv = -s/norm(v)^2/norm(v)*(I - (v*v')/(v'v))*bv*v' +
141-
s/norm(v)*((v*(v'bv))/(v'v)^2 * 2v' - (I*(v'bv) + v*bv')/(v'v)) +
142-
bs/norm(v)*(I - (v*v')/(v'v))
143-
dvds = 1/norm(v)*(I - (v*v')/(v'v))*bv;
144-
dsdv = bv'/norm(v) - v'bv/norm(v)^3*v'
145-
dsds = 0
146-
hess[1:n-1,1:n-1] .= dvdv*0.5
147-
hess[1:n-1,n] .= dvds*0.5
148-
hess[n:n,1:n-1] .= dsdv*0.5
149-
hess[n,n] = 0
150-
return hess
151-
# return 0.5*[dvdv dvds; dsdv dsds]
152-
else
153-
throw(ErrorException("Invalid second-order cone projection"))
154-
end
155-
end
156-
157-
function ∇projection!(::NegativeOrthant, J, x::StaticVector{n}) where n
158-
for i = 1:n
159-
J[i,i] = x <= 0 ? 1 : 0
160-
end
161-
end
162-
163-
function ∇²projection!(::NegativeOrthant, hess, x::StaticVector, b::StaticVector)
164-
hess .= 0
165-
end
166-
167-
Base.in(::NegativeOrthant, x::StaticVector) = all(x->x<=0, x)
168-
1693
"""
1704
AbstractConstraint
1715

0 commit comments

Comments
 (0)