diff --git a/Project.toml b/Project.toml index 9c00d0c..a0c40a7 100644 --- a/Project.toml +++ b/Project.toml @@ -35,13 +35,13 @@ Timers = "0.1.5" julia = "1.10" [extras] +HTTP = "cd3eb016-35fb-5094-929b-558a96fad6f3" +JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" KiteModels = "b94af626-7959-4878-9336-2adc27959007" KitePodModels = "9de5dc81-f971-414a-927b-652b2f41c539" PackageCompiler = "9b87118b-4619-50d2-8e1e-99f35a4d4d9d" Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" PyPlot = "d330b81b-6aea-500a-939a-2ce795aea3ee" -HTTP = "cd3eb016-35fb-5094-929b-558a96fad6f3" -JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" StructTypes = "856f2bd8-1eba-4b0a-8007-ebc267875bd4" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" diff --git a/data/3l_settings.yaml b/data/3l_settings.yaml new file mode 100644 index 0000000..b61ad3a --- /dev/null +++ b/data/3l_settings.yaml @@ -0,0 +1,117 @@ +system: + log_file: "data/log_8700W_8ms" # filename without extension [replay only] + # use / as path delimiter, even on Windows + time_lapse: 1.0 # relative replay speed + sim_time: 100.0 # simulation time [sim only] + segments: 6 # number of tether segments + sample_freq: 3 # sample frequency in Hz + zoom: 0.03 # zoom factor for the system view + kite_scale: 3.0 # relative zoom factor for the 4 point kite + fixed_font: "" # name or filepath+filename of alternative fixed pitch font + +initial: + l_tether: 50.0 # initial tether length [m] + elevation: 70.8 # initial elevation angle [deg] + v_reel_out: 0.0 # initial reel out speed [m/s] + depower: 25.0 # initial depower settings [%] + +solver: + abs_tol: 0.006 # absolute tolerance of the DAE solver [m, m/s] + rel_tol: 0.01 # relative tolerance of the DAE solver [-] + solver: "DFBDF" # DAE solver, IDA or DImplicitEuler, DFBDF + linear_solver: "GMRES" # can be GMRES or Dense or LapackDense (only for IDA) + max_order: 4 # maximal order, usually between 3 and 5 + max_iter: 10000 # max number of iterations of the steady-state-solver + +steering: + c0: 0.0 # steering offset -0.0032 [-] + c_s: 2.59 # steering coefficient one point model; 2.59 was 0.6; TODO: check if it must be divided by kite_area + c2_cor: 0.93 # correction factor one point model + k_ds: 1.5 # influence of the depower angle on the steering sensitivity + delta_st: 0.02 # steering increment (when pressing RIGHT) + max_steering: 16.83 # max. steering angle of the side planes for four point model [degrees] + +depower: + alpha_d_max: 31.0 # max depower angle [deg] + depower_offset: 23.6 # at rel_depower=0.236 the kite is fully powered [%] + +kite: + model: "data/kite.obj" # 3D model of the kite + physical_model: "KPS4_3L" # name of the kite model to use (KPS3 or KPS4) + version: 2 # version of the model to use + mass: 0.9 # kite mass [kg] + area: 10.18 # projected kite area [m²] + rel_side_area: 30.6 # relative side area [%] + height: 2.23 # height of the kite [m] + alpha_cl: [-180.0, -160.0, -90.0, -20.0, -10.0, -5.0, 0.0, 20.0, 40.0, 90.0, 160.0, 180.0] + cl_list: [ 0.0, 0.5, 0.0, 0.08, 0.125, 0.15, 0.0, 1.0, 1.0, 0.0, -0.5, 0.0] + alpha_cd: [-180.0, -170.0, -140.0, -90.0, -20.0, 0.0, 20.0, 90.0, 140.0, 170.0, 180.0] + cd_list: [ 0.5, 0.5, 0.5, 1.0, 0.2, 0.1, 0.2, 1.0, 0.5, 0.5, 0.5] + +kps4: + alpha_zero: 10.0 # should be 4..10 [degrees] + alpha_ztip: 10.0 # [degrees] + m_k: 0.2 # relative nose distance; increasing m_k increases C2 of the turn-rate law + rel_nose_mass: 0.47 # relative nose mass + rel_top_mass: 0.4 # mass of the top particle relative to the sum of top and side particles + +kps4_3l: + radius: 2.0 + bridle_center_distance: 4.0 + middle_length: 1.5 + tip_length: 0.62 + min_steering_line_distance: 1.0 + width: 4.1 # width of the kite [m] + aero_surfaces: 3 # number of aerodynamic surfaces in 3 line model + +kcu: + kcu_mass: 8.4 # mass of the kite control unit [kg] + power2steer_dist: 1.3 # [m] + depower_drum_diameter: 0.069 # [m] + tape_thickness: 0.0006 # [m] + v_depower: 0.075 # max velocity of depowering in units per second (full range: 1 unit) + v_steering: 0.2 # max velocity of steering in units per second (full range: 2 units) + depower_gain: 3.0 # 3.0 means: more than 33% error -> full speed + steering_gain: 3.0 + +bridle: + l_bridle: 33.4 # sum of the lengths of the bridle lines [m] + h_bridle: 4.9 # height of bridle [m] + rel_compr_stiffness: 0.25 # relative compression stiffness of the kite springs + rel_damping: 6.0 # relative damping of the kite spring (relative to main tether) + +tether: + d_tether: 1 # tether diameter [mm] + cd_tether: 0.958 # drag coefficient of the tether + damping: 473.0 # unit damping coefficient [Ns] + c_spring: 614600.0 # unit spring constant coefficient [N] + rho_tether: 724.0 # density of Dyneema [kg/m³] + e_tether: 55000000000.0 # axial tensile modulus of Dyneema (M.B. Ruppert) [Pa] + # SK75: 109 to 132 GPa according to datasheet + +winch: + max_force: 4000 # maximal (nominal) tether force; short overload allowed [N] + v_ro_max: 8.0 # maximal reel-out speed [m/s] + v_ro_min: -8.0 # minimal reel-out speed (=max reel-in speed) [m/s] + +environment: + v_wind: 15.51 # wind speed at reference height [m/s] + v_wind_ref: [15.51, 0.0] # wind speed vector at reference height [m/s] + temp_ref: 15.0 # temperature at reference height [°C] + height_gnd: 0.0 # height of groundstation above see level [m] + h_ref: 6.0 # reference height for the wind speed [m] + + rho_0: 1.225 # air density at zero height and 15 °C [kg/m³] + alpha: 0.08163 # exponent of the wind profile law + z0: 0.0002 # surface roughness [m] + profile_law: 3 # 1=EXP, 2=LOG, 3=EXPLOG, 4=FAST_EXP, 5=FAST_LOG, 6=FAST_EXPLOG + # the following parameters are for calculating the turbulent wind field using the Mann model + use_turbulence: 0.0 # turbulence intensity relative to Cabau, NL + v_wind_gnds: [3.483, 5.324, 8.163] # wind speeds at ref height for calculating the turbulent wind field [m/s] + avg_height: 200.0 # average height during reel out [m] + rel_turbs: [0.342, 0.465, 0.583] # relative turbulence at the v_wind_gnds + i_ref: 0.14 # is the expected value of the turbulence intensity at 15 m/s. + v_ref: 42.9 # five times the average wind speed in m/s at hub height over the full year [m/s] + # Cabau: 8.5863 m/s * 5.0 = 42.9 m/s + height_step: 2.0 # use a grid with 2m resolution in z direction [m] + grid_step: 2.0 # grid resolution in x and y direction [m] diff --git a/data/settings.yaml b/data/settings.yaml index 7a2f889..3df09c4 100644 --- a/data/settings.yaml +++ b/data/settings.yaml @@ -59,16 +59,16 @@ kps4: rel_top_mass: 0.4 # mass of the top particle relative to the sum of top and side particles kps4_3l: - radius: 10.0 # the radius of the circle shape on which the kite lines, viewed + radius: 2.0 # the radius of the circle shape on which the kite lines, viewed # from the front [m] - bridle_center_distance: 2.0 # the distance from point the center bridle connection point of + bridle_center_distance: 4.0 # the distance from point the center bridle connection point of # the middle line to the kite [m] - middle_length: 2.0 # the cord length of the kite in the middle [m] - tip_length: 1.0 # the cord length of the kite at the tips [m] - min_steering_line_distance: 4.0 # the distance between the left and right steering bridle [m] + middle_length: 1.5 # the cord length of the kite in the middle [m] + tip_length: 0.62 # the cord length of the kite at the tips [m] + min_steering_line_distance: 1.0 # the distance between the left and right steering bridle [m] # line connections on the kite that are closest to each other [m] - width_3l: 20.0 # width of the kite [m] - aero_surfaces: 10 # the number of aerodynamic surfaces to use per mass point [-] + width_3l: 4.1 # width of the kite [m] + aero_surfaces: 3 # the number of aerodynamic surfaces to use per mass point [-] bridle: d_line: 2.5 # bridle line diameter [mm] diff --git a/examples/basic_4p_3l.jl b/examples/basic_4p_3l.jl new file mode 100644 index 0000000..e0ef743 --- /dev/null +++ b/examples/basic_4p_3l.jl @@ -0,0 +1,6 @@ +using KiteViewers, KiteUtils +viewer=Viewer3D(true); +segments=6 +state=demo_state_4p(segments+1) +update_system(viewer, state, kite_scale=0.25) +nothing \ No newline at end of file diff --git a/examples/depower_simple_3line.jl b/examples/depower_simple_3line.jl new file mode 100644 index 0000000..a59d7ac --- /dev/null +++ b/examples/depower_simple_3line.jl @@ -0,0 +1,116 @@ +using Pkg, Timers +tic() +if ! ("KitePodModels" ∈ keys(Pkg.project().dependencies)) + using TestEnv; TestEnv.activate() +end + +using KiteViewers, KiteModels, KitePodModels, Rotations + +kcu::KCU = KCU(se()) +kps4_3l::KPS4_3L = KPS4_3L(kcu) + +# the following values can be changed to match your interest +dt::Float64 = 0.3 +TIME = 50 +TIME_LAPSE_RATIO = 1 +STEPS = Int64(round(TIME/dt)) +STATISTIC = true +SHOW_KITE = true +PLOT_PERFORMANCE = false +# USE 3L SETTINGS! +update_settings() +# end of user parameter section # + +if ! @isdefined time_vec_gc; const time_vec_gc = zeros(STEPS); end +if ! @isdefined time_vec_sim; const time_vec_sim = zeros(STEPS); end +if ! @isdefined time_vec_tot; const time_vec_tot = zeros(div(STEPS, TIME_LAPSE_RATIO)); end +viewer::Viewer3D = Viewer3D(SHOW_KITE) + +function simulate(integrator, steps) + start = integrator.p.iter + start_time_ns = time_ns() + j=0; k=0 + KiteViewers.clear_viewer(viewer) + GC.gc() + max_time = 0 + set_speeds = [0.0, 0.0, 0.0] + sys_state = SysState(kps4_3l) + for i in 1:steps + if i == 1 + set_speeds = [0.0, 0.5, 0.5] + elseif i == 10 + set_speeds = [0.0, -0.3, 0.0] + elseif i == 15 + set_speeds = [0.0, 0.0, 0.0] + end + t_sim = @elapsed KiteModels.next_step!(kps4_3l, integrator; set_values=set_speeds, torque_control=false, dt=dt) + t_gc = 0.0 + t_show = 0.0 + # println(SysState(kps4_3l)) + if mod(i, TIME_LAPSE_RATIO) == 0 || i == steps + update_sys_state!(sys_state, kps4_3l) + t_show = @elapsed update_system(viewer, sys_state; scale = 0.08, kite_scale=5.0) + println("i ", i) + println(viewer.points) + end_time_ns = time_ns() + wait_until(start_time_ns + dt*1e9, always_sleep=true) + mtime = 0 + if i > 10/dt + # if we missed the deadline by more than 2 ms + mtime = time_ns() - start_time_ns + if mtime > dt*1e9 + 2e6 + print(".") + j += 1 + end + k +=1 + else + t_show = 0.0 + end + if mtime > max_time + max_time = mtime + end + time_tot = end_time_ns - start_time_ns + start_time_ns = time_ns() + time_vec_tot[div(i, TIME_LAPSE_RATIO)] = time_tot/1e9/dt*1000*dt + end + + time_vec_gc[i]=t_gc/dt*100.0 + time_vec_sim[i]=t_sim/dt*100.0 + # if viewer.stop break end + end + misses=j/k * 100 + println("\nMissed the deadline for $(round(misses, digits=2)) %. Max time: $(round((max_time*1e-6), digits=1)) ms") + (integrator.p.iter - start) / steps +end + +function play() + integrator = KiteModels.init_sim!(kps4_3l, stiffness_factor=0.3, prn=STATISTIC) + simulate(integrator, STEPS) +end + +on(viewer.btn_PLAY.clicks) do c + if viewer.stop + @async begin + play() + stop(viewer) + end + end +end +on(viewer.btn_STOP.clicks) do c + stop(viewer) +end + +toc() +play() +stop(viewer) +if PLOT_PERFORMANCE + include("plot.jl") + if false + plotx(range(dt,TIME,step=dt), time_vec_gc, time_vec_sim, time_vec_sim.+time_vec_gc; + labels=["GC time","sim_time","total_time"], + fig="depower_simple_timing") + else + plot1(range(3*TIME_LAPSE_RATIO*dt,TIME,step=dt*TIME_LAPSE_RATIO), time_vec_tot[3:end], + ylabel="time per frame [ms]") + end +end diff --git a/src/common.jl b/src/common.jl index 1d61c9d..53b89b4 100644 --- a/src/common.jl +++ b/src/common.jl @@ -73,68 +73,124 @@ function update_system(kv::AKV, state::SysState; scale=1.0, kite_scale=1.0) if azimuth ≈ 0 # suppress -0 and replace it with 0 azimuth=zero(azimuth) end - fourpoint = length(state.Z) > kv.set.segments+1 + threepoint = length(state.Z) == kv.set.segments+1 # check if this is true + fourpoint = length(state.Z) == kv.set.segments+5 + fourpoint_3l = length(state.Z) == kv.set.segments*3+6 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=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[kv.set.segments+1], state.Y[kv.set.segments+1], state.Z[kv.set.segments+1]) * scale - # enlarge 4 point kite - 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 - kv.points[i] = pos_abs + (kite_scale-1.0) * pos_rel + if threepoint || fourpoint + 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[kv.set.segments+1], state.Y[kv.set.segments+1], state.Z[kv.set.segments+1]) * scale + # enlarge 4 point kite + 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 + kv.points[i] = pos_abs + (kite_scale-1.0) * pos_rel + end + end + elseif fourpoint_3l + for i in 3:3:length(state.Z) # middle points + kv.points[i] = Point3f(state.X[i], state.Y[i], state.Z[i]) * scale end + y_kite = normalize(Point3f(state.X[end-2], state.Y[end-2], state.Z[end-2]) - Point3f(state.X[end-1], state.Y[end-1], state.Z[end-1])) + for i in 1:3:length(state.Z) # left and right points, get bigger distance to eachother + left = Point3f(state.X[i], state.Y[i], state.Z[i]) * scale + right = Point3f(state.X[i+1], state.Y[i+1], state.Z[i+1]) * scale + distance = norm(left - right) + y_local = distance * y_kite + kv.points[i] = left + (kite_scale-1.0) * y_local + kv.points[i+1] = right - (kite_scale-1.0) * y_local + end + # # enlarge 3line kite + # last_middle_line_pos = Point3f(state.X[kv.set.segments+3], state.Y[kv.set.segments+3], state.Z[kv.set.segments+3]) * scale + # for i in kv.set.segments*3+4:length(state.Z) + # pos_abs = Point3f(state.X[i], state.Y[i], state.Z[i]) * scale + # pos_rel = pos_abs-last_middle_line_pos + # kv.points[i] = pos_abs + (kite_scale-1.0) * pos_rel + # end end kv.part_positions[] = [(kv.points[k]) for k in 1:length(state.Z)] + # calc cylinder positions function calc_positions(s) - tmp = [(kv.points[k] + kv.points[k+1])/2 for k in 1:kv.set.segments] - if fourpoint - 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 + if fourpoint_3l + tmp = [(kv.points[k] + kv.points[k+3])/2 for k in 1:s*3] + push!(tmp, (kv.points[s*3+3]+kv.points[s*3+4]) / 2) + push!(tmp, (kv.points[s*3+3]+kv.points[s*3+5]) / 2) + push!(tmp, (kv.points[s*3+3]+kv.points[s*3+6]) / 2) + push!(tmp, (kv.points[s*3+4]+kv.points[s*3+5]) / 2) + push!(tmp, (kv.points[s*3+4]+kv.points[s*3+6]) / 2) + push!(tmp, (kv.points[s*3+5]+kv.points[s*3+6]) / 2) + else + tmp = [(kv.points[k] + kv.points[k+1])/2 for k in 1:s] + if fourpoint + 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 end - tmp + return tmp end function calc_markersizes(s) - 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(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 + if fourpoint_3l + tmp = [Point3f(1, 1, norm(kv.points[k+3] - kv.points[k])) for k in 1:s*3] + push!(tmp, Point3f(1, 1, norm(kv.points[s*3+3] - kv.points[s*3+4]))) + push!(tmp, Point3f(1, 1, norm(kv.points[s*3+3] - kv.points[s*3+5]))) + push!(tmp, Point3f(1, 1, norm(kv.points[s*3+3] - kv.points[s*3+6]))) + push!(tmp, Point3f(1, 1, norm(kv.points[s*3+4] - kv.points[s*3+5]))) + push!(tmp, Point3f(1, 1, norm(kv.points[s*3+4] - kv.points[s*3+6]))) + push!(tmp, Point3f(1, 1, norm(kv.points[s*3+5] - kv.points[s*3+6]))) + else + tmp = [Point3f(1, 1, norm(kv.points[k+1] - kv.points[k])) for k in 1:s] + if fourpoint + 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 end - tmp + return tmp end function calc_rotations(s) - tmp = [normalize(kv.points[k+1] - kv.points[k]) for k in 1:kv.set.segments] - if fourpoint - 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])) + if fourpoint_3l + tmp = [normalize(kv.points[k+3] - kv.points[k]) for k in 1:s*3] + push!(tmp, normalize(kv.points[s*3+3] - kv.points[s*3+4])) + push!(tmp, normalize(kv.points[s*3+3] - kv.points[s*3+5])) + push!(tmp, normalize(kv.points[s*3+3] - kv.points[s*3+6])) + push!(tmp, normalize(kv.points[s*3+4] - kv.points[s*3+5])) + push!(tmp, normalize(kv.points[s*3+4] - kv.points[s*3+6])) + push!(tmp, normalize(kv.points[s*3+5] - kv.points[s*3+6])) + else + tmp = [normalize(kv.points[k+1] - kv.points[k]) for k in 1:s] + if fourpoint + 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 end - tmp + return tmp end # move, scale and turn the cylinder correctly @@ -147,6 +203,11 @@ function update_system(kv::AKV, state::SysState; scale=1.0, kite_scale=1.0) 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 * (kv.points[s+4] + kv.points[s+5]) + 0.2 * kv.points[s+1] + elseif fourpoint_3l + 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 * (kv.points[s*3+4] + kv.points[s*3+5]) + 0.2 * kv.points[s*3+3] else # move and turn the kite to the new position q0 = state.orient # SVector in the order w,x,y,z diff --git a/src/viewer3D.jl b/src/viewer3D.jl index f80abef..c212f4f 100644 --- a/src/viewer3D.jl +++ b/src/viewer3D.jl @@ -253,7 +253,7 @@ function Viewer3D(set::Settings, show_kite=true, autolabel="Autopilot"; precompi GUI_ACTIVE[1] = true reset_view(cam, scene3D) - points=Vector{Point3f}(undef, set.segments+1+4) + points=Vector{Point3f}(undef, set.segments*3+6) pos=Observable([Point3f(x,0,0) for x in 1:set.segments+KITE_SPRINGS]) # positions of the tether segments part_pos=Observable([Point3f(x,0,0) for x in 1:set.segments+1+4]) # positions of the tether particles markersizes = Observable([Point3f(1,1,1) for x in 1:set.segments+KITE_SPRINGS]) # includes the segment length