Skip to content

Commit

Permalink
add settings to KiteViewer
Browse files Browse the repository at this point in the history
  • Loading branch information
Uwe Fechner committed Mar 30, 2024
1 parent 0a5e69e commit 02051a6
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 57 deletions.
8 changes: 8 additions & 0 deletions mwes/mwe_05.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using KiteViewers, KiteUtils
se().segments=12
viewer=Viewer3D(se(), true; precompile=true)
segments=se().segments
state=demo_state_4p(segments+1)
update_system(viewer, state, kite_scale=0.25)
sleep(5)
close(viewer.screen)
2 changes: 1 addition & 1 deletion src/KiteViewers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ end
# all calls in this block will be precompiled, regardless of whether
# they belong to your package or not (on Julia 1.8 and higher)
viewer=Viewer3D(true; precompile=true)
segments=6
segments=se().segments
state=demo_state_4p(segments+1)
update_system(viewer, state, kite_scale=0.25)
close(viewer.screen)
Expand Down
93 changes: 46 additions & 47 deletions src/common.jl
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ function create_coordinate_system(scene, points = 10, max_x = 15.0)
end

# draw the kite power system, consisting of the tether, the kite and the state (text and numbers)
function init_system(scene; show_kite=true)
function init_system(kv::AbstractKiteViewer, scene; show_kite=true)
sphere = Sphere(Point3f(0, 0, 0), Float32(0.07 * SCALE))
meshscatter!(scene, part_positions, marker=sphere, markersize=1.0, color=:yellow)
meshscatter!(scene, kv.part_positions, marker=sphere, markersize=1.0, color=:yellow)
cyl = Cylinder(Point3f(0,0,-0.5), Point3f(0,0,0.5), Float32(0.035 * SCALE))
meshscatter!(scene, positions, marker=cyl, rotations=rotations, markersize=markersizes, color=:yellow)
meshscatter!(scene, kv.positions, marker=cyl, rotations=kv.rotations, markersize=kv.markersizes, color=:yellow)
if show_kite
meshscatter!(scene, kite_pos, marker=KITE, markersize = 0.25, rotations=quat, color=:blue)
end
Expand All @@ -60,104 +60,103 @@ function init_system(scene; show_kite=true)
else
font="Courier New"
end
if se().fixed_font != ""
font=se().fixed_font
if kv.set.fixed_font != ""
font=kv.set.fixed_font
end
text!(scene, textnode, position = Point2f(50, 110), fontsize=TEXT_SIZE, font=font, align = (:left, :top), show_axis = false, space=:pixel)
text!(scene, textnode2, position = Point2f(630, 735), fontsize=TEXT_SIZE, font=font, align = (:left, :bottom), show_axis = false, space=:pixel)
end

# update the kite power system, consisting of the tether, the kite and the state (text and numbers)
function update_system(kv::AKV, state::SysState; scale=1.0, kite_scale=1.0)
segments=se().segments
azimuth = state.azimuth
if azimuth 0 # suppress -0 and replace it with 0
azimuth=zero(azimuth)
end
fourpoint = length(state.Z) > segments+1
fourpoint = length(state.Z) > kv.set.segments+1
if fourpoint
height = state.Z[end-2]
else
height = state.Z[end]
end
# move the particles to the correct position
for i in range(1, length=se().segments+1)
points[i] = Point3f(state.X[i], state.Y[i], state.Z[i]) * scale
for i in range(1, length=kv.set.segments+1)
kv.points[i] = Point3f(state.X[i], state.Y[i], state.Z[i]) * scale
end
if fourpoint
pos_pod = Point3f(state.X[segments+1], state.Y[segments+1], state.Z[segments+1]) * scale
pos_pod = Point3f(state.X[kv.set.segments+1], state.Y[kv.set.segments+1], state.Z[kv.set.segments+1]) * scale
# enlarge 4 point kite
for i in segments+2:length(state.Z)
for i in kv.set.segments+2:length(state.Z)
pos_abs = Point3f(state.X[i], state.Y[i], state.Z[i]) * scale
pos_rel = pos_abs-pos_pod
points[i] = pos_abs + (kite_scale-1.0) * pos_rel
kv.points[i] = pos_abs + (kite_scale-1.0) * pos_rel
end
end
part_positions[] = [(points[k]) for k in 1:length(state.Z)]
kv.part_positions[] = [(kv.points[k]) for k in 1:length(state.Z)]

function calc_positions(s)
tmp = [(points[k] + points[k+1])/2 for k in 1:segments]
tmp = [(kv.points[k] + kv.points[k+1])/2 for k in 1:kv.set.segments]
if fourpoint
push!(tmp, (points[s+1]+points[s+4]) / 2) # S6
push!(tmp, (points[s+2]+points[s+5]) / 2) # S8
push!(tmp, (points[s+3]+points[s+5]) / 2) # S7
push!(tmp, (points[s+2]+points[s+4]) / 2) # S2
push!(tmp, (points[s+1]+points[s+5]) / 2) # S5
push!(tmp, (points[s+4]+points[s+3]) / 2) # S4
push!(tmp, (points[s+1]+points[s+2]) / 2) # S1
push!(tmp, (points[s+3]+points[s+2]) / 2) # S9
push!(tmp, (kv.points[s+1]+kv.points[s+4]) / 2) # S6
push!(tmp, (kv.points[s+2]+kv.points[s+5]) / 2) # S8
push!(tmp, (kv.points[s+3]+kv.points[s+5]) / 2) # S7
push!(tmp, (kv.points[s+2]+kv.points[s+4]) / 2) # S2
push!(tmp, (kv.points[s+1]+kv.points[s+5]) / 2) # S5
push!(tmp, (kv.points[s+4]+kv.points[s+3]) / 2) # S4
push!(tmp, (kv.points[s+1]+kv.points[s+2]) / 2) # S1
push!(tmp, (kv.points[s+3]+kv.points[s+2]) / 2) # S9
end
tmp
end
function calc_markersizes(s)
tmp = [Point3f(1, 1, norm(points[k+1] - points[k])) for k in 1:segments]
tmp = [Point3f(1, 1, norm(kv.points[k+1] - kv.points[k])) for k in 1:kv.set.segments]
if fourpoint
push!(tmp, Point3f(1, 1, norm(points[s+1] - points[s+4]))) # S6
push!(tmp, Point3f(1, 1, norm(points[s+2] - points[s+5]))) # S8
push!(tmp, Point3f(1, 1, norm(points[s+3] - points[s+5]))) # S7
push!(tmp, Point3f(1, 1, norm(points[s+2] - points[s+4]))) # S2
push!(tmp, Point3f(1, 1, norm(points[s+1] - points[s+5]))) # S5
push!(tmp, Point3f(1, 1, norm(points[s+4] - points[s+3]))) # S4
push!(tmp, Point3f(1, 1, norm(points[s+1] - points[s+2]))) # S1
push!(tmp, Point3f(1, 1, norm(points[s+3] - points[s+2]))) # S9
push!(tmp, Point3f(1, 1, norm(kv.points[s+1] - kv.points[s+4]))) # S6
push!(tmp, Point3f(1, 1, norm(kv.points[s+2] - kv.points[s+5]))) # S8
push!(tmp, Point3f(1, 1, norm(kv.points[s+3] - kv.points[s+5]))) # S7
push!(tmp, Point3f(1, 1, norm(kv.points[s+2] - kv.points[s+4]))) # S2
push!(tmp, Point3f(1, 1, norm(kv.points[s+1] - kv.points[s+5]))) # S5
push!(tmp, Point3f(1, 1, norm(kv.points[s+4] - kv.points[s+3]))) # S4
push!(tmp, Point3f(1, 1, norm(kv.points[s+1] - kv.points[s+2]))) # S1
push!(tmp, Point3f(1, 1, norm(kv.points[s+3] - kv.points[s+2]))) # S9
end
tmp
end
function calc_rotations(s)
tmp = [normalize(points[k+1] - points[k]) for k in 1:segments]
tmp = [normalize(kv.points[k+1] - kv.points[k]) for k in 1:kv.set.segments]
if fourpoint
push!(tmp, normalize(points[s+1] - points[s+4]))
push!(tmp, normalize(points[s+2] - points[s+5]))
push!(tmp, normalize(points[s+3] - points[s+5]))
push!(tmp, normalize(points[s+2] - points[s+4]))
push!(tmp, normalize(points[s+1] - points[s+5]))
push!(tmp, normalize(points[s+4] - points[s+3]))
push!(tmp, normalize(points[s+1] - points[s+2]))
push!(tmp, normalize(points[s+3] - points[s+2]))
push!(tmp, normalize(kv.points[s+1] - kv.points[s+4]))
push!(tmp, normalize(kv.points[s+2] - kv.points[s+5]))
push!(tmp, normalize(kv.points[s+3] - kv.points[s+5]))
push!(tmp, normalize(kv.points[s+2] - kv.points[s+4]))
push!(tmp, normalize(kv.points[s+1] - kv.points[s+5]))
push!(tmp, normalize(kv.points[s+4] - kv.points[s+3]))
push!(tmp, normalize(kv.points[s+1] - kv.points[s+2]))
push!(tmp, normalize(kv.points[s+3] - kv.points[s+2]))
end
tmp
end

# move, scale and turn the cylinder correctly
positions[] = calc_positions(segments)
markersizes[] = calc_markersizes(segments)
rotations[] = calc_rotations(segments)
kv.positions[] = calc_positions(kv.set.segments)
kv.markersizes[] = calc_markersizes(kv.set.segments)
kv.rotations[] = calc_rotations(kv.set.segments)

if fourpoint
s = segments
s = kv.set.segments
q0 = state.orient # SVector in the order w,x,y,z
quat[] = Quaternionf(q0[2], q0[3], q0[4], q0[1]) # the constructor expects the order x,y,z,w
kite_pos[] = 0.8 * 0.5 * (points[s+4] + points[s+5]) + 0.2 * points[s+1]
kite_pos[] = 0.8 * 0.5 * (kv.points[s+4] + kv.points[s+5]) + 0.2 * kv.points[s+1]
else
# move and turn the kite to the new position
q0 = state.orient # SVector in the order w,x,y,z
quat[] = Quaternionf(q0[2], q0[3], q0[4], q0[1]) # the constructor expects the order x,y,z,w
kite_pos[] = Point3f(state.X[segments+1], state.Y[segments+1], state.Z[segments+1]) * scale
kite_pos[] = Point3f(state.X[kv.set.segments+1], state.Y[kv.set.segments+1], state.Z[kv.set.segments+1]) * scale
end

# calculate power and energy
power = state.force * state.v_reelout
dt = 1/se().sample_freq
dt = 1/kv.set.sample_freq
if abs(power) < 0.001
power = 0
end
Expand Down
33 changes: 24 additions & 9 deletions src/viewer3D.jl
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,13 @@ SOFTWARE. =#
p2 = Observable(Vector{Point2f}(undef, 6000)) # 5 min
pos_x = Observable(0.0f0)

points = Vector{Point3f}(undef, se().segments+1+4)
# points = Vector{Point3f}(undef, se().segments+1+4)
quat = Observable(Quaternionf(0,0,0,1)) # orientation of the kite
kite_pos = Observable(Point3f(1,0,0)) # position of the kite
positions = Observable([Point3f(x,0,0) for x in 1:se().segments+KITE_SPRINGS]) # positions of the tether segments
part_positions = Observable([Point3f(x,0,0) for x in 1:se().segments+1+4]) # positions of the tether particles
markersizes = Observable([Point3f(1,1,1) for x in 1:se().segments+KITE_SPRINGS]) # includes the segment length
rotations = Observable([Point3f(1,0,0) for x in 1:se().segments+KITE_SPRINGS]) # unit vectors corresponding with
# positions = Observable([Point3f(x,0,0) for x in 1:se().segments+KITE_SPRINGS]) # positions of the tether segments
# part_positions = Observable([Point3f(x,0,0) for x in 1:se().segments+1+4]) # positions of the tether particles
# markersizes = Observable([Point3f(1,1,1) for x in 1:se().segments+KITE_SPRINGS]) # includes the segment length
# rotations = Observable([Point3f(1,0,0) for x in 1:se().segments+KITE_SPRINGS]) # unit vectors corresponding with
# the orientation of the segments
end

Expand All @@ -76,6 +76,12 @@ mutable struct Viewer3D <: AKV
scene3D::LScene
cam::Camera3D
screen::GLMakie.Screen
points::Vector{Point{3, Float32}}
positions::Observable{Vector{GeometryBasics.Point{3, Float32}}}
part_positions::Observable{Vector{GeometryBasics.Point{3, Float32}}}
markersizes::Observable{Vector{GeometryBasics.Point{3, Float32}}}
rotations::Observable{Vector{GeometryBasics.Point{3, Float32}}}
set::Settings
btn_RESET::Button
btn_ZOOM_in::Button
btn_ZOOM_out::Button
Expand Down Expand Up @@ -120,7 +126,11 @@ function set_status(kv::AKV, status_text)
status[] = status_text
end

function Viewer3D(show_kite=true, autolabel="Autopilot"; precompile=false)
function Viewer3D(show_kite=true, autolabel="Autopilot"; precompile=false)
set = se()
Viewer3D(set, show_kite, autolabel; precompile)
end
function Viewer3D(set::Settings, show_kite=true, autolabel="Autopilot"; precompile=false)
global last_status
WIDTH = 840
HEIGHT = 900
Expand Down Expand Up @@ -197,11 +207,16 @@ function Viewer3D(show_kite=true, autolabel="Autopilot"; precompile=false)
GUI_ACTIVE[1] = true

reset_view(cam, scene3D)

s = Viewer3D(fig, scene3D, cam, gl_screen, btn_RESET, btn_ZOOM_in, btn_ZOOM_out,
points=Vector{Point3f}(undef, se().segments+1+4)
pos=Observable([Point3f(x,0,0) for x in 1:set.segments+KITE_SPRINGS])
part_pos=Observable([Point3f(x,0,0) for x in 1:se().segments+1+4])
markersizes = Observable([Point3f(1,1,1) for x in 1:se().segments+KITE_SPRINGS])
rotations = Observable([Point3f(1,0,0) for x in 1:se().segments+KITE_SPRINGS])
s = Viewer3D(fig, scene3D, cam, gl_screen, points, pos, part_pos, markersizes,
rotations, set, btn_RESET, btn_ZOOM_in, btn_ZOOM_out,
btn_PLAY_PAUSE, btn_AUTO, btn_PARKING, btn_STOP, menu1, menu2, btn_OK,
sw, 0, 0, show_kite, false)
txt2 = init_system(s.scene3D; show_kite=show_kite)
txt2 = init_system(s, s.scene3D; show_kite=show_kite)

camera = cameracontrols(s.scene3D.scene)
reset_view(camera, s.scene3D)
Expand Down

0 comments on commit 02051a6

Please sign in to comment.