Skip to content

Commit 5c90f09

Browse files
minor fixes + basic directions
1 parent 98805bc commit 5c90f09

File tree

10 files changed

+205
-74
lines changed

10 files changed

+205
-74
lines changed

src/Core/axes.jl

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ Add a new axes node to `frames`.
1717
[`add_axes_fixedoffset!`](@ref) and [`add_axes_root!`](@ref).
1818
"""
1919
function add_axes!(
20-
frames::FrameSystem{O,N}, name::Symbol, id::Int,
21-
funs::FrameAxesFunctions{O,N}=FrameAxesFunctions{O,N}(),
20+
frames::FrameSystem{O,T}, name::Symbol, id::Int,
21+
funs::FrameAxesFunctions{O,T}=FrameAxesFunctions{O,T}(),
2222
parentid=nothing
23-
) where {O,N<:Number}
23+
) where {O,T<:Number}
2424

2525
if has_axes(frames, id)
2626
# Check if a set of axes with the same ID is already registered within
@@ -64,7 +64,7 @@ function add_axes!(
6464

6565

6666
# Create point
67-
node = FrameAxesNode{O,N}(name, id, parentid, funs)
67+
node = FrameAxesNode{O,T}(name, id, parentid, funs)
6868

6969
# Insert new point in the graph
7070
add_axes!(frames, node)
@@ -86,10 +86,10 @@ represented by `dcm`, a Direction Cosine Matrix (DCM).
8686
See also [`add_axes!`](@ref).
8787
"""
8888
function add_axes_fixedoffset!(
89-
frames::FrameSystem{O,N}, name::Symbol, id::Int, parent, dcm::DCM{N}
90-
) where {O,N}
89+
frames::FrameSystem{O,T}, name::Symbol, id::Int, parent, dcm::DCM{T}
90+
) where {O,T}
9191

92-
funs = FrameAxesFunctions{O,N}(t -> Rotation{O}(dcm))
92+
funs = FrameAxesFunctions{O,T}(t -> Rotation{O}(dcm))
9393
add_axes!(frames, name, id, funs, axes_id(frames, parent))
9494
end
9595

@@ -107,9 +107,9 @@ despite the rotation depends on time).
107107
See also [`add_axes!`](@ref).
108108
"""
109109
function add_axes_projected!(
110-
frames::FrameSystem{O,N}, name::Symbol, id::Int, parent, fun::Function
111-
) where {O,N}
112-
funs = FrameAxesFunctions{O,N}(t -> Rotation{O}(fun(t)))
110+
frames::FrameSystem{O,T}, name::Symbol, id::Int, parent, fun::Function
111+
) where {O,T}
112+
funs = FrameAxesFunctions{O,T}(t -> Rotation{O}(fun(t)))
113113
add_axes!(frames, name, id, funs, axes_id(frames, parent))
114114
end
115115

@@ -134,17 +134,17 @@ If `δfun`, `δ²fun` or `δ³fun` are not provided, they are computed via autom
134134
function does not perform any checks on the output types.
135135
"""
136136
function add_axes_rotating!(
137-
frames::FrameSystem{O,N}, name::Symbol, id::Int, parent, fun,
137+
frames::FrameSystem{O,T}, name::Symbol, id::Int, parent, fun,
138138
δfun=nothing, δ²fun=nothing, δ³fun=nothing,
139-
) where {O,N}
139+
) where {O,T}
140140

141141
for (order, fcn) in enumerate([δfun, δ²fun, δ³fun])
142142
if (O < order + 1 && !isnothing(fcn))
143143
@warn "ignoring $fcn, frame system order is less than $(order+1)"
144144
end
145145
end
146146

147-
funs = FrameAxesFunctions{O,N}(
147+
funs = FrameAxesFunctions{O,T}(
148148
t -> Rotation{O}(fun(t)),
149149

150150
# First derivative

src/Core/directions.jl

Lines changed: 10 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,4 @@
11

2-
"""
3-
add_direction!(frames, name::Symbol, axesid, funs)
4-
5-
Add a new direction node to `frames`.
6-
7-
### Inputs
8-
- `frames` -- Target frame system
9-
- `name` -- Direction name, must be unique within `frames`
10-
- `axesid` -- ID of the axes the direction is expressed in
11-
- `funs` -- `DirectionFunctions` object storing the functions to compute the direction and,
12-
eventually, its time derivatives. It must match the type and order of `frames`.
13-
"""
14-
function add_direction!(
15-
frames::FrameSystem{O,N}, name::Symbol, axesid::Int, funs::DirectionFunctions{O,N}
16-
) where {O,N<:Number}
17-
if name in directions(frames)
18-
throw(
19-
ArgumentError(
20-
"A direction with name $name is already registered in the input frame system.",
21-
),
22-
)
23-
end
24-
25-
dir = Direction{O,N}(name, length(directions(frames)) + 1, axesid, funs)
26-
push!(directions(frames), Pair(name, dir))
27-
nothing
28-
end
29-
302
"""
313
add_direction!(frames, name::Symbol, axes, fun, δfun=nothing, δ²fun=nothing, δ³fun=nothing)
324
@@ -47,7 +19,7 @@ If `δfun`, `δ²fun` or `δ³fun` are not provided, they are computed via autom
4719
function does not perform any checks on the output types.
4820
"""
4921
function add_direction!(
50-
frames::FrameSystem{O,N}, name::Symbol, ax, fun::Function,
22+
frames::FrameSystem{O,N}, name::Symbol, axes, fun::Function,
5123
δfun=nothing, δ²fun=nothing, δ³fun=nothing
5224
) where {O,N}
5325

@@ -58,7 +30,7 @@ function add_direction!(
5830
end
5931

6032
funs = DirectionFunctions{O,N}(
61-
t -> Translation{O}fun(t),
33+
t -> Translation{O}(fun(t)),
6234

6335
# First derivative
6436
if isnothing(δfun)
@@ -86,18 +58,22 @@ function add_direction!(
8658
if isnothing(δ²fun)
8759
(
8860
if isnothing(δfun)
89-
t -> Translation{O}(vcat(fun(t), (fun, t), (fun, t), (fun, t)))
61+
t -> Direction{O}(vcat(fun(t), (fun, t), (fun, t), (fun, t)))
9062
else
91-
t -> Translation{O}(vcat(δfun(t), (fun, t), (fun, t)))
63+
t -> Direction{O}(vcat(δfun(t), (fun, t), (fun, t)))
9264
end
9365
)
9466
else
95-
t -> Translation{O}(vcat(δ²fun(t), (fun, t)))
67+
t -> Direction{O}(vcat(δ²fun(t), (fun, t)))
9668
end
9769
)
9870
else
9971
t -> Translation{O}(δ³fun(t))
10072
end,
10173
)
102-
return add_direction!(frames, name, axes_id(frames, ax), funs)
74+
75+
axid = axes_id(frames, axes)
76+
dir = DirectionDefinition{O,N}(name, length(directions(frames)) + 1, axid, funs)
77+
push!(directions(frames), Pair(name, dir))
78+
nothing
10379
end

src/Core/graph.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ end
88
FrameSystem{O, T, S}
99
1010
A `FrameSystem` instance manages a collection of user-defined `FramePointNode`,
11-
`FrameAxesNode` and `Direction` objects, enabling computation of arbitrary transformations
11+
`FrameAxesNode` and `DirectionDefinition` objects, enabling computation of arbitrary transformations
1212
between them. It is created by specifying the maximum transformation order `O`, the outputs
1313
datatype `T` and an `AbstractTimeScale` instance `S`.
1414
@@ -28,7 +28,7 @@ The parameter `S` can be dropped, in case the default (`BarycentricDynamicalTime
2828
struct FrameSystem{O,T<:Number,S<:AbstractTimeScale}
2929
points::AliasGraph{PointsGraph{O,T},Dict{Symbol,Int}}
3030
axes::AliasGraph{AxesGraph{O,T},Dict{Symbol,Int}}
31-
dir::Dict{Symbol,Direction{O,T}}
31+
dir::Dict{Symbol,DirectionDefinition{O,T}}
3232
end
3333

3434
function FrameSystem{O,T,S}() where {O,T,S}

src/Core/nodes.jl

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ const AxesGraph{O,T} = MappedNodeGraph{FrameAxesNode{O,T},SimpleGraph{Int}}
243243
const DirectionFunctions{O,T} = FramePointFunctions{O,T}
244244

245245
"""
246-
Direction{O, T}
246+
DirectionDefinition{O, T}
247247
248248
Define a new direction.
249249
@@ -252,18 +252,15 @@ Define a new direction.
252252
- `id` -- direction ID
253253
- `f` -- `DirectionFunctions` container
254254
"""
255-
struct Direction{O,T}
255+
struct DirectionDefinition{O,T}
256256
name::Symbol
257257
id::Int
258+
axesid::Int
258259

259260
# internals
260261
f::DirectionFunctions{O,T}
261262
end
262263

263-
function Direction{O,T}(name::Symbol, id::Int, dfun::DirectionFunctions{O,T}) where {O,T}
264-
return Direction{O,T}(name, id, dfun)
265-
end
266-
267-
function Base.show(io::IO, d::Direction{O,T}) where {O,T}
268-
return println(io, "Direction{$O, $T}(name=$(d.name), id=$(d.id))")
264+
function Base.show(io::IO, d::DirectionDefinition{O,T}) where {O,T}
265+
return println(io, "DirectionDefinition{$O, $T}(name=$(d.name), id=$(d.id), axesid=$(d.axesid))")
269266
end

src/Core/points.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,17 +138,17 @@ If `δfun`, `δ²fun` or `δ³fun` are not provided, they are computed with auto
138138
dimensions.
139139
"""
140140
function add_point_dynamical!(
141-
frames::FrameSystem{O,N}, name::Symbol, id::Int, parent, ax, fun,
141+
frames::FrameSystem{O,T}, name::Symbol, id::Int, parent, ax, fun,
142142
δfun=nothing, δ²fun=nothing, δ³fun=nothing
143-
) where {O,N}
143+
) where {O,T}
144144

145145
for (order, fcn) in enumerate([δfun, δ²fun, δ³fun])
146146
if (O < order + 1 && !isnothing(fcn))
147147
@warn "ignoring $fcn, frame system order is less than $(order+1)"
148148
end
149149
end
150150

151-
funs = FramePointFunctions{O,N}(
151+
funs = FramePointFunctions{O,T}(
152152
t -> Translation{O}(fun(t)),
153153

154154
# First derivative

src/Core/transform.jl

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ for (order, axfun, _axfun, pfun, _pfun, _pfwd, _pbwd, dfun) in zip(
153153
an observing point, in a given set of axes, at the desired time `t` expressed in
154154
seconds since `J2000`.
155155
"""
156-
function ($pfun)(fr::FrameSystem{O,N}, from, to, ax, t::Number) where {O,N}
156+
function ($pfun)(fr::FrameSystem{O,T}, from, to, ax, t::Number) where {O,T}
157157
if O < $order
158158
throw(
159159
ErrorException(
@@ -167,7 +167,7 @@ for (order, axfun, _axfun, pfun, _pfun, _pfwd, _pbwd, dfun) in zip(
167167
toid = point_id(fr, to)
168168
axid = axes_id(fr, ax)
169169

170-
fromid == toid && return @SVector zeros(N, 3 * $order)
170+
fromid == toid && return @SVector zeros(T, 3 * $order)
171171

172172
# Check to ensure that the two points are registerd
173173
for id in (fromid, toid)
@@ -266,4 +266,66 @@ for (order, axfun, _axfun, pfun, _pfun, _pfwd, _pbwd, dfun) in zip(
266266
end
267267

268268
end
269+
270+
# --------------------------------------------------------------------------------------
271+
# Directions transformations
272+
# --------------------------------------------------------------------------------------
273+
274+
@eval begin
275+
276+
"""
277+
$($dfun)(frames::FrameSystem, name::Symbol, axes, ep::Epoch)
278+
279+
Compute the direction vector `name` of order $(3*$order) at epoch `ep` expressed in
280+
the `axes` frame.
281+
282+
Requires a frame system of order ≥ $($order).
283+
"""
284+
@inline function ($dfun)(
285+
frames::FrameSystem{<:Any,<:Any,S}, name::Symbol, axes, ep::Epoch{S}
286+
) where {S}
287+
return $(dfun)(frames, name, axes, j2000s(ep))
288+
end
289+
290+
"""
291+
$($dfun)(frames::FrameSystem, name::Symbol, axes, t::Number)
292+
293+
Compute the direction vector `name` of order $(3*$order) at epoch `t`, where `t` is
294+
expressed in seconds since `J2000`.
295+
296+
Requires a frame system of order ≥ $($order).
297+
"""
298+
function ($dfun)(frames::FrameSystem{O,N}, name::Symbol, axes, t::Number) where {O,N}
299+
if O < $order
300+
throw(
301+
ErrorException(
302+
"Insufficient frame system order: " *
303+
"transformation requires at least order $($order).",
304+
),
305+
)
306+
end
307+
308+
if !has_direction(frames, name)
309+
throw(
310+
ErrorException(
311+
"No direction with name $(name) registered in the frame system."
312+
)
313+
)
314+
end
315+
316+
node = directions(frames)[name]
317+
stv = Translation{$order}(node.f[$order](t))
318+
319+
thisaxid = node.axesid
320+
axid = axes_id(frames, axes)
321+
if thisaxid != axid
322+
stv = ($axfun)(frames, thisaxid, axid, t) * stv
323+
end
324+
325+
D = 3 * $order
326+
return @views SVector(stv)[1:D]
327+
end
328+
329+
end
330+
269331
end

src/Definitions/directions.jl

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
2+
"""
3+
add_direction_position!(frames, name::Symbol, origin, target, axes)
4+
5+
Add a direction based on the position vector from `origin` to `target` in the specified `axes`.
6+
"""
7+
function add_direction_position!(
8+
frames::FrameSystem{O,T}, name::Symbol, from, to, axes
9+
) where {O,T}
10+
11+
fromid, toid = point_id(frames, from), point_id(frames, to)
12+
axid = axes_id(frames, axes)
13+
14+
for id in (fromid, toid)
15+
!has_point(frames, id) && throw(
16+
ArgumentError(
17+
"no points with id $id registered in the given frame system."
18+
)
19+
)
20+
end
21+
22+
!has_axes(frames, axid) && throw(
23+
ArgumentError(
24+
"no axes with id $axes registered in the given frame system"
25+
)
26+
)
27+
28+
fun = t -> unitvec(vector3(frames, fromid, toid, axid, t))
29+
return add_direction!(frames, name, axid, fun)
30+
end
31+
32+
"""
33+
add_direction_velocity!(frames, name::Symbol, origin, target, axes)
34+
35+
Add a direction based on the velocity vector from `origin` to `target` in the specified `axes`.
36+
"""
37+
function add_direction_velocity!(
38+
frames::FrameSystem{O,T}, name::Symbol, from, to, axes
39+
) where {O,T}
40+
41+
fid, tid = point_id(frames, from), point_id(frames, to)
42+
axid = axes_id(frames, axes)
43+
44+
for id in (fid, tid)
45+
!has_point(frames, id) && throw(
46+
ArgumentError(
47+
"no points with id $id registered in the given frame system."
48+
)
49+
)
50+
end
51+
52+
!has_axes(frames, axid) && throw(
53+
ArgumentError(
54+
"no axes with name $axes registered in the given frame system"
55+
)
56+
)
57+
58+
fun = t -> @views(unitvec(vector6(frames, fid, tid, axid, t)[4:end]))
59+
return add_direction!(frames, name, axid, fun)
60+
end
61+
62+
"""
63+
add_direction_orthogonal!(frames, name::Symbol, dir1, dir2)
64+
65+
Add a direction as the cross product between two existing directions (i.e. `dir1` and `dir2`).
66+
"""
67+
function add_direction_orthogonal!(
68+
frames::FrameSystem{O,T}, name::Symbol, dir1::Symbol, dir2::Symbol, axes
69+
) where {O,T}
70+
71+
for d in (dir1, dir2)
72+
if !(d in keys(directions(frames)))
73+
throw(
74+
ArgumentError(
75+
"no direction with name $d registered in the given frame system"
76+
)
77+
)
78+
end
79+
end
80+
81+
axid = axes_id(frames, axes)
82+
!has_axes(frames, axid) && throw(
83+
ArgumentError(
84+
"no axes with name $axes registered in the given frame system"
85+
)
86+
)
87+
88+
fun = t -> unitvec(cross3(direction3(frames, dir1, axid, t), direction3(frames, dir2, axid, t)))
89+
return add_direction!(frames, name, axid, fun)
90+
end

0 commit comments

Comments
 (0)