using Unitful using DataFrames using Plots theme(:ggplot2); using CSV using Measurements using Measurements: value, uncertainty using Printf # Tank https://www.amazon.com/Empire-Paintball-BASICS-Pressure-Compressed/dp/B07B6M48SR/ V = (85 ± 5)u"inch^3" P0 = (4200.0 ± 300)u"psi" Wtank = (2.3 ± 0.2)u"lb" Pmax = (250 ± 50)u"psi" # Max Pressure that can come out the nozzle Wsolenoid = 1.5u"kg" # Params d_nozzle = ((1 // 18) ± 0.001)u"inch" a_nozzle = (pi / 4) * d_nozzle^2 # Universal Stuff P_amb = (1 ± 0.2)u"atm" γ = 1.4 ± 0.05 R = 287.05u"J/(kg * K)" T = (300 ± 20)u"K" t = 0.0u"s" P = P0 |> u"Pa" M = V * (P / (R * T)) |> u"kg" ts = 1u"ms" df = DataFrame(Thrust = (0 ± 0)u"N", Pressure = P, Time = t, Mass = M) while M > 0.005u"kg" # Calculate what is leaving tank P = minimum([P, Pmax]) ve = sqrt((2 * γ / (γ - 1)) * R * T * (1 - P_amb / P)^((γ - 1) / γ)) |> u"m/s" ρ = P / (R * T) |> u"kg/m^3" ṁ = ρ * a_nozzle * ve |> u"kg/s" Thrust = ṁ * ve + a_nozzle * (P - P_amb) |> u"N" M = M - ṁ * ts |> u"kg" P = (M * R * T) / V |> u"Pa" t = t + ts df_step = DataFrame(Thrust = Thrust, Pressure = P, Time = t, Mass = M) append!(df, df_step) end final_time = t |> u"s" impulse = sum(df.Thrust) * ts |> u"N*s" println("---------------------------\n\n\n\n") println("Burn Time: ", t) println("Mass Total: ", Wtank + Wsolenoid + maximum(df.Mass)) print(describe(df)) thrust_values = df.Thrust .|> ustrip .|> value thrust_uncertainties = df.Thrust .|> ustrip .|> uncertainty plot( df.Time .|> ustrip, thrust_values, title = "Thrust Over Time", ribbon = (thrust_uncertainties, thrust_uncertainties), fillalpha = 0.2, label = "Thrust", xlabel = "Time (s)", ylabel = "Thrust (N)", ) out = DataFrame( Thrust = thrust_values, Uncertainty = thrust_uncertainties, Time = df.Time .|> u"s" .|> ustrip, ) CSV.write("AirProp.csv", out) ### Save data to readme.md savefig("ThrustCurve.png") include("prop_compare.jl") b = IOBuffer(); t = TextDisplay(b); display(t, "text/html", describe(df)); table = String(take!(b)); # https://stackoverflow.com/a/60443621/8774114 t = TextDisplay(b); display(t, "text/html", describe(df)); table = String(take!(b)); # https://stackoverflow.com/a/60443621/8774114 readme = Printf.@sprintf """ # Air Prop Thrust `readme auto generated, run air_prop_sim.jl to recreate.` ![Thrust Over Time](ThrustCurve.png) Total Impulse: %s Burn TIme: %s More Data: %s ## Comparison to Rocket Motors ![Propulsion Comparison](prop_compare.png) https://www.thrustcurve.org/ """ impulse final_time table write("readme.md", readme);