11# ## A Pluto.jl notebook ###
2- # v0.20.20
2+ # v0.20.21
33
44using Markdown
55using InteractiveUtils
2828 using PlutoUI
2929 using IntervalSets
3030 using RunwayLib. StaticArrays
31- import RunwayLib: compute_worst_case_fault_direction_and_slope
31+ import RunwayLib: compute_worst_case_fault_direction_and_slope, _uconvert
3232end
3333
3434# ╔═╡ 46af6473-88bf-49b9-8dc9-0a72e995f784
@@ -117,9 +117,6 @@ H0 = RunwayLib.compute_H(cam_pos, cam_rot, runway_corners)
117117# ╔═╡ 36e1df5f-9cf1-43d1-a2a4-9e63c56ae7c8
118118cycle (xs:: AbstractVector ) = xs[[eachindex (xs); first (eachindex (xs))]]
119119
120- # ╔═╡ 59a0ab1e-0360-4d24-9320-fb3966062b9d
121- aircraft_model = load (joinpath (" assets" , " A320NeoV2_lowpoly.stl" ));
122-
123120# ╔═╡ 120a3051-4909-4e65-a35d-82e76b706567
124121function setup_corner_selections (figpos)
125122 gl = GridLayout (figpos, tellwidth = false )
@@ -197,10 +194,9 @@ lines(-100:1:100, ø->integrity_root_objective(ø, (; alphaidx, fi_indices, H=H0
197194
198195# ╔═╡ 18ebe84e-5710-48b7-9849-130b5b55715c
199196function get_analytic_max_error (alphaidx, fi_indices, H, px_std)
200- @show alphaidx " FROM ANALYTIC"
201-
202- slope_g = RunwayLib. compute_worst_case_fault_direction_and_slope (alphaidx, fi_indices, H, noise_cov)[2 ] * m
203- g_wo_noise = RunwayLib. compute_worst_case_fault_direction_and_slope_wo_noise (alphaidx, fi_indices, H)[2 ] * m / px
197+ unit = (alphaidx <= 3 ? m : rad)
198+ slope_g = RunwayLib. compute_worst_case_fault_direction_and_slope (alphaidx, fi_indices, H, noise_cov)[2 ] * unit
199+ g_wo_noise = RunwayLib. compute_worst_case_fault_direction_and_slope_wo_noise (alphaidx, fi_indices, H)[2 ] * unit / px
204200
205201 # 2. Determine the Detection Threshold (T)
206202 # The monitor checks if SSE < T².
@@ -214,17 +210,23 @@ function get_analytic_max_error(alphaidx, fi_indices, H, px_std)
214210 sigma_val = px_std
215211 @assert isapprox (slope_g * sqrt (T_chisq), g_wo_noise * sigma_val * sqrt (T_chisq); rtol= 1e-4 )
216212 analytic_max_error = slope_g * sqrt (T_chisq)
213+ analytic_max_error
217214end
218215
219216# ╔═╡ 982214a6-fd01-4166-aefe-36f051067be2
220217md """
221218## Get experimental error function
222219"""
223220
221+ # ╔═╡ 99dc4716-4809-4581-9e62-08c95eba6885
222+ " Returns [roll, pitch, yaw] in degrees (unitful)."
223+ rpy (R:: RotZYX ) = uconvert .(°, reverse (params (R))* rad)
224+
225+ # ╔═╡ e7e2b951-391e-49e7-ab2b-58d5be1d22b3
226+ @assert all (rpy (RotZYX (roll= 10 °, pitch= 5 °, yaw= 1 °)) .== [10 °, 5 °, 1 °])
227+
224228# ╔═╡ 8a4de21a-acbc-4ce0-9315-6cc86376e3b1
225229function get_experimental_max_error (alphaidx, fi_indices, H, noisy_observations, cam_pose_est)
226- @show alphaidx
227- @show sum (H)
228230 experimental_max_error_tpl = map ([
229231 (0.0 , 100.0 ),
230232 (- 100.0 , 0.0 )
@@ -240,10 +242,11 @@ function get_experimental_max_error(alphaidx, fi_indices, H, noisy_observations,
240242 experimental_max_error = if alphaidx <= 3
241243 (cam_pose_est_faulty. pos - cam_pose_est. pos)[alphaidx]
242244 else
243- reverse ( params (cam_pose_est_faulty. rot) - params (cam_pose_est. rot))[alphaidx - 3 ]
245+ ( rpy (cam_pose_est_faulty. rot) - rpy (cam_pose_est. rot))[alphaidx - 3 ] .| > _uconvert (rad)
244246 end
245247 experimental_max_error
246248 end |> sort
249+ experimental_max_error_tpl
247250end
248251
249252# ╔═╡ a5214c33-0e64-4ac2-8484-ca03bbf660ad
324327 analytic_max_error_3 = slope_3 * sqrt (T_chisq_3)
325328 new_sigma_val = 2.0 * px
326329 @assert isapprox (analytic_max_error_3, slope_3_wo_noise * px_std * sqrt (T_chisq_3); rtol= 1e-4 )
327- @show slope_3_wo_noise * new_sigma_val * sqrt (T_chisq_3), slope_3_wo_noise * old_sigma_val * sqrt (T_chisq_3)
328-
330+
329331 # 2. Calculate Experimental Max Error
330332 search_params = (;
331333 alphaidx= target_alphaidx,
@@ -483,13 +485,19 @@ function do_computations(ui, ctx)
483485 noise_cov
484486 ). p_value > 0.05
485487
486- @info " HELLO"
487- on (alphaidx) do alphaidx
488- @info " WORLD"
489- @info " From the viz: $(alphaidx) "
490- end
491- analytic_worst_case = @lift get_analytic_max_error ($ alphaidx, $ fi_indices, $ H, ctx. px_std)
492- experimental_worst_case = @lift get_experimental_max_error ($ alphaidx, $ fi_indices, $ H, ctx. noisy_observations, $ cam_pose_est_noisy)
488+ # this is a tricky part. the result can either be of type meters, or of type radians.
489+ # however, when we create the `analytic_worst_case` observable, it tries to infer the type and drops the union,
490+ # leading to a silent error later.
491+ # We follow https://discourse.julialang.org/t/makie-observable-lift-functions/121202/6
492+ # and use `map!` to fix this.
493+ analytic_worst_case = Observable {Union{typeof(1.0m), typeof(1.0rad)}} ()
494+ map! (analytic_worst_case, alphaidx, fi_indices, H) do alphaidx_, fi_indices_, H_
495+ get_analytic_max_error (alphaidx_, fi_indices_, H_, ctx. px_std)
496+ end
497+ experimental_worst_case = Observable {Union{Vector{typeof(1.0m)}, Vector{typeof(1.0rad)}}} ()
498+ map! (experimental_worst_case, alphaidx, fi_indices, H, cam_pose_est_noisy) do alphaidx_, fi_indices_, H_, cam_pose_est_noisy_
499+ get_experimental_max_error (alphaidx_, fi_indices_, H_, ctx. noisy_observations, cam_pose_est_noisy_)
500+ end
493501
494502 return (; yobs_pts, yperturb_pts, yrand_pts, yfi_pts,
495503 perturbed_observations, cam_pose_est_pert,
499507
500508# 3. Visualization
501509function setup_plots (fig, ui, data, ctx)
502- (; aircraft_model, runway_corners, true_observations) = ctx
510+ (; runway_corners, true_observations) = ctx
511+ aircraft_model = load (joinpath (" assets" , " A320NeoV2_lowpoly.stl" ));
503512 colors = Makie. wong_colors ()
504513 c1, c4, c7 = colors[1 ], colors[4 ], colors[7 ]
505514
@@ -512,7 +521,8 @@ function setup_plots(fig, ui, data, ctx)
512521
513522 Label (pose_delta_layout[1 , 1 ], text= @lift (let
514523 diff = ($ (data. cam_pos_est_pert) - cam_pos_est)
515- s = repr (" text/plain" , round .([typeof (1.0 m)], diff; digits= 2 ))
524+ unit = (eltype (diff) <: Unitful.Length ? typeof (1.0 m) : typeof (1.0 °))
525+ s = repr (" text/plain" , round .(unit, diff; digits= 2 ))
516526 split (s, ' \n ' )[2 : end ] |> x-> join (x, ' \n ' )
517527 end ), halign= :right )
518528
@@ -524,21 +534,23 @@ function setup_plots(fig, ui, data, ctx)
524534 Label (pose_delta_layout[1 , 3 ], text= " =\n =\n =" , justification= :left )
525535
526536 Label (pose_delta_layout[1 , 4 ], text= @lift (let
527- diff = params ($ (data. cam_rot_est_pert)) - params ($ (data. cam_rot_est_noisy))
528- s = repr (" text/plain" , round .([typeof (1.0 °)], reverse ( rad2deg .( diff.* rad)) ; digits= 1 ))
537+ diff = rpy ($ (data. cam_rot_est_pert)) - rpy ($ (data. cam_rot_est_noisy))
538+ s = repr (" text/plain" , round .([typeof (1.0 °)], diff; digits= 1 ))
529539 split (s, ' \n ' )[2 : end ] |> x-> join (x, ' \n ' )
530540 end ), halign= :right )
531541
532542 # # Worst case
533543 worst_case_layout = GridLayout (pose_delta_layout[0 : 1 , 5 ])
534544 Label (worst_case_layout[1 ,1 ], text= " Analytic Worst Case" , font= :bold , halign= :left )
535- Label (worst_case_layout[2 ,1 ], text= @lift (let
536- worst_case_rnd = round (typeof (1.0 m), $ (data. analytic_worst_case); sigdigits= 2 )
537- string (0 m± worst_case_rnd)
538- end ), valign= :top , halign= :left )
545+ Label (worst_case_layout[2 ,1 ], text= @lift (let val = $ (data. analytic_worst_case)
546+ unit = (val isa Unitful. Length ? m : °)
547+ worst_case_rnd = round (unit, val; sigdigits= 2 )
548+ string (0 unit± worst_case_rnd)
549+ end ), valign= :top , halign= :left )
539550 Label (worst_case_layout[3 ,1 ], text= " Line Search Worst Case" , font= :bold , halign= :left )
540- Label (worst_case_layout[4 ,1 ], text= @lift (let
541- worst_case_tpl = round .(typeof (1.0 m), $ (data. experimental_worst_case); sigdigits= 2 )
551+ Label (worst_case_layout[4 ,1 ], text= @lift (let vals = $ (data. experimental_worst_case)
552+ unit = (first (vals) isa Unitful. Length ? m : °)
553+ worst_case_tpl = round .(unit, vals; sigdigits= 2 )
542554 string (worst_case_tpl[1 ] .. worst_case_tpl[2 ])
543555 end ), valign= :top , halign= :left )
544556 rowgap! (worst_case_layout, 0 )
@@ -589,11 +601,11 @@ function setup_plots(fig, ui, data, ctx)
589601 on (_ -> reset_limits! (ax), data. yrand_pts)
590602 on (_ -> reset_limits! (ax), data. yfi_pts)
591603end
592- context = (; true_observations, noisy_observations, runway_corners, cam_pos, cam_rot, aircraft_model, px_std)
604+ context = (; true_observations, noisy_observations, runway_corners, cam_pos, cam_rot, px_std)
593605# 4. Main Orchestrator
594606with_theme (theme_black ()) do
595607 fig = Figure (; size= (1200 , 600 ))
596-
608+
597609 ui = setup_ui (fig, context)
598610 data = do_computations (ui, context)
599611 setup_plots (fig, ui, data, context)
@@ -602,8 +614,25 @@ with_theme(theme_black()) do
602614end
603615end
604616
617+ # ╔═╡ f8f76174-cfd2-48a1-a8cb-3f9bc92d2d07
618+ params (RotZYX (roll= 0.5 , pitch= 1 , yaw= 1.5 ))
619+
620+ # ╔═╡ 00d65922-f2db-4d2e-8082-4831207fbcf6
621+ let
622+ foo = Observable {Any} (1 )
623+ bar:: Observable{Union{Int, Float64}} = @lift (2 * $ (foo))
624+ foo[] = 1.5
625+ typeof (bar)
626+ end
627+
628+ # ╔═╡ 8f0d83c4-d841-4608-b42a-477f6c585da4
629+ let
630+ unit = rad
631+ 0 unit ± 1.5 unit
632+ end
633+
605634# ╔═╡ Cell order:
606- # ╠═ 46af6473-88bf-49b9-8dc9-0a72e995f784
635+ # ╟─ 46af6473-88bf-49b9-8dc9-0a72e995f784
607636# ╠═b5b8f3c8-c4dc-11f0-82e6-e3e1218a8fd8
608637# ╟─64d2c0fd-2542-4b2c-80f6-134ed8434c3b
609638# ╠═47423636-18d6-42cb-85e6-4a0909dc168d
619648# ╠═c6a57e0f-50c7-461a-a6e8-9281991b9e44
620649# ╠═b027b7ad-098e-4048-97d1-f4ce311c5ac4
621650# ╠═36e1df5f-9cf1-43d1-a2a4-9e63c56ae7c8
622- # ╠═59a0ab1e-0360-4d24-9320-fb3966062b9d
623651# ╠═120a3051-4909-4e65-a35d-82e76b706567
624652# ╠═b495605a-ffe7-4783-a490-1d635731da0a
625653# ╠═58a21d5e-8a66-45b2-8202-aee966463df3
628656# ╠═df5a6bf7-3f5b-4804-99de-291bdabeacdb
629657# ╠═18ebe84e-5710-48b7-9849-130b5b55715c
630658# ╟─982214a6-fd01-4166-aefe-36f051067be2
659+ # ╠═99dc4716-4809-4581-9e62-08c95eba6885
660+ # ╠═e7e2b951-391e-49e7-ab2b-58d5be1d22b3
631661# ╠═8a4de21a-acbc-4ce0-9315-6cc86376e3b1
632662# ╠═a5214c33-0e64-4ac2-8484-ca03bbf660ad
633663# ╟─5c6760d3-7aed-4a17-a5e6-5dbf420fc6e1
634664# ╟─76ad9899-7dd2-4795-b1b6-b44e34b747af
635665# ╠═25348c41-f099-459c-9b19-250a66a01cab
666+ # ╠═f8f76174-cfd2-48a1-a8cb-3f9bc92d2d07
667+ # ╠═00d65922-f2db-4d2e-8082-4831207fbcf6
668+ # ╠═8f0d83c4-d841-4608-b42a-477f6c585da4
0 commit comments