From 6c5f6b8459b17aa2316902a7fa5c9e354ec854b3 Mon Sep 17 00:00:00 2001 From: Anson Date: Sat, 20 Mar 2021 15:15:37 -0700 Subject: [PATCH 1/3] added monte carlo simulation --- thrust.jl | 54 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/thrust.jl b/thrust.jl index 4284e77..c4841e9 100644 --- a/thrust.jl +++ b/thrust.jl @@ -1,37 +1,42 @@ using Unitful using DataFrames using Plots +# using Gadfly using UnitfulRecipes using Roots using CSV +using MonteCarloMeasurements +unsafe_comparisons(true) + # Tank https://www.amazon.com/Empire-Paintball-BASICS-Pressure-Compressed/dp/B07B6M48SR/ -V = 90u"inch^3" -P0 = 4500.0u"psi" -Wtank = 2.3u"lb" -Pmax = 100u"psi" +V = (85 ± 5)u"inch^3" +P0 = (4200.0 ± 300)u"psi" +Wtank = (2.3 ± 0.2)u"lb" +Pmax = (100 ± 5)u"psi" Wsolenoid = 1.5u"kg" # Params -d_nozzle = (1 // 16) * u"inch" +d_nozzle = ((1 // 16) ± 0.001)u"inch" a_nozzle = (pi / 4) * d_nozzle^2 -Poutmax = 800u"psi" +Poutmax = (800 ± 50)u"psi" # Universal Stuff -P_amb = 1u"atm" -γ = 1.4 +P_amb = (1 ± 0.2)u"atm" +γ = 1.4 ± 0.05 R = 287.05u"J/(kg * K)" -T = 300u"K" +T = (300 ± 20)u"K" # Setting up while loop -t = 1.0u"s" +t = 0.0u"s" P = P0 |> u"Pa" M = V * (P / (R * T)) |> u"kg" -df = DataFrame(Thrust = 0.0u"N", Pressure = P, Time = t, Mass = M) -ts = 0.001u"s" -while M > 0.01u"kg" +# df = DataFrame(Thrust = (0 ± 0)u"N", Pressure = P, Time = t, Mass = M) +df = DataFrame() +ts = 10u"ms" +while M > 0.1u"kg" # while t < 30u"s" # Calculate what is leaving tank P = minimum([P, Pmax]) @@ -44,16 +49,25 @@ while M > 0.01u"kg" # Calculate what is still in the tank 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) - df_step = DataFrame(Thrust = Thrust, Pressure = P, Time = t, Mass = M) - append!(df, df_step) + if df == DataFrame() + df = DataFrame(Thrust = Thrust, Pressure = P, Time = t, Mass = M) + else + append!(df, DataFrame(Thrust = Thrust, Pressure = P, Time = t, Mass = M)) + end + t = t + ts end +impulse = sum(df.Thrust) * ts |> u"N*s" println("---------------------------\n\n\n\n") -println("Total Impulse: ", sum(df.Thrust) * ts) +println("Total Impulse: ", impulse) println("Burn Time: ", t) +plot(impulse) println("Mass Total: ", Wtank + Wsolenoid + maximum(df.Mass)) -print(describe(df)) -plot(df.Time, df.Thrust, title = "Thrust Over Time") -CSV.write("thrustdata.csv", df .|> ustrip) +# plot(sum(df.Thrust) * ts |> u"N*s") +# print(describe(df)) +# df.Time = round(u"s", df.Time) +# plot(df.Time, df.Thrust, title = "Thrust Over Time") +# CSV.write("thrustdata.csv", df .|> ustrip) +# plot(df.Time .|> u"s" .|> ustrip, df.Thrust .|> u"N" .|> ustrip)> ustrip, df.Thrust .|> u"N" .|> ustrip) \ No newline at end of file From b9237f9a435a494ee317b585b137170c938a6454 Mon Sep 17 00:00:00 2001 From: Anson Date: Mon, 22 Mar 2021 06:06:00 -0700 Subject: [PATCH 2/3] switched to measurements.jl --- calcs.jl | 124 ------------------------------------------------------ thrust.jl | 41 ++++++++---------- 2 files changed, 18 insertions(+), 147 deletions(-) delete mode 100644 calcs.jl diff --git a/calcs.jl b/calcs.jl deleted file mode 100644 index 6fd4137..0000000 --- a/calcs.jl +++ /dev/null @@ -1,124 +0,0 @@ -### A Pluto.jl notebook ### -# v0.12.20 - -using Markdown -using InteractiveUtils - -# This Pluto notebook uses @bind for interactivity. When running this notebook outside of Pluto, the following 'mock version' of @bind gives bound variables a default value (instead of an error). -macro bind(def, element) - quote - local el = $(esc(element)) - global $(esc(def)) = Core.applicable(Base.get, el) ? Base.get(el) : missing - el - end -end - -# ╔═╡ 7d1e8730-81f7-11eb-0b4d-d7c878032280 -begin - using Unitful - using Roots - using PlutoUI -end - -# ╔═╡ d8461f50-833d-11eb-04f2-f9e262a97ba5 -md"## Air Compressor Thrust Calcs" - -# ╔═╡ 2a976cf0-833e-11eb-3892-03869a9b0acc -html"" - -# ╔═╡ b0efd6c2-81f9-11eb-2aad-efc9bdd8c220 -@bind diam Slider(0.1:.1:6.5, default=.5) - -# ╔═╡ bc06c722-81fa-11eb-05ac-e38ac21ce27e -@bind p Slider(15:6000, default=126) - -# ╔═╡ 99835750-81fe-11eb-3a7e-1132eb3cdd90 -@bind w Slider(.5:.25:20, default=5) - -# ╔═╡ a9f59000-81f7-11eb-15c0-4520acb6543f -begin - M = w*u"kg" - - P_amb = 1u"atm" - P_c = p*u"psi" - - d_nozzle = diam*u"mm" - a_nozzle = (pi/4)*d_nozzle^2 - - γ = 1.4 - R = 287.05u"J/(kg * K)" - T = 300u"K" - - burn_time = 5u"s" - - V = 68u"inch^3" -end; - -# ╔═╡ 764dcf30-81fa-11eb-3155-559823202b8f -md"Area of Nozzle: $(a_nozzle) | $(round(u\"inch^2\",a_nozzle, digits = 4))" - -# ╔═╡ b4a957a0-833e-11eb-1ca9-0d87d162790f -md"Diameter of Nozzle: $(d_nozzle) | $(round(u\"inch\",d_nozzle, digits = 4))" - -# ╔═╡ a7bef990-81fa-11eb-3976-817c3e383e64 -md"Pressure of system: $(P_c)" - -# ╔═╡ b113c030-81fe-11eb-2042-776472e720ac -md"Mass of Lander: $(M) | $(round(u\"lb\",M, digits = 2))" - -# ╔═╡ a9317cb0-81f7-11eb-26e5-95719252409b -begin - ve = sqrt((2 * γ / (γ - 1)) * R * T * (1 - P_amb / P_c)^((γ - 1) / γ)) |> u"m/s" - - ρ = P_c / (R * T) |> u"kg/m^3" - ṁ = ρ * a_nozzle * ve |> u"kg/s" -end; - -# ╔═╡ cf5b7030-846d-11eb-2f23-290624c7d684 -M_air = ρ*V |> u"kg" - -# ╔═╡ 2149b640-846e-11eb-262b-299ded0c61c5 -M_air / ṁ - -# ╔═╡ c57fe2d0-81f7-11eb-27d7-4b5c0520998d -Thrust = ṁ * ve + a_nozzle * (P_c - P_amb) |> u"N" - -# ╔═╡ 213ef2c0-81fb-11eb-1425-15bfcf1dc14c -volume_air = ṁ * burn_time / ρ |> u"inch^3"; - -# ╔═╡ 9388c570-833d-11eb-3baa-758b5cb19065 -md"Air Needed: $(round(ustrip(volume_air/burn_time)*.004329,digits=3)) Gallon/s" - -# ╔═╡ e85b0e90-81fe-11eb-0dd5-0b3df376a4f7 -begin - W_earth = 9.81u"m/s^2" * M |> u"N" - W_moon = 1.623u"m/s^2" * M |> u"N" -end; - -# ╔═╡ 57844480-833a-11eb-3a57-bf00cecde849 -md"Thrust to Weight Ratio Earth: $(Thrust/W_earth)" - -# ╔═╡ a5c735d0-833a-11eb-2bae-71ba4af6b3a1 -md"Thrust to Weight Ratio Moon: $(Thrust/W_moon)" - -# ╔═╡ Cell order: -# ╟─d8461f50-833d-11eb-04f2-f9e262a97ba5 -# ╟─2a976cf0-833e-11eb-3892-03869a9b0acc -# ╟─7d1e8730-81f7-11eb-0b4d-d7c878032280 -# ╟─764dcf30-81fa-11eb-3155-559823202b8f -# ╟─b4a957a0-833e-11eb-1ca9-0d87d162790f -# ╟─b0efd6c2-81f9-11eb-2aad-efc9bdd8c220 -# ╟─a7bef990-81fa-11eb-3976-817c3e383e64 -# ╠═bc06c722-81fa-11eb-05ac-e38ac21ce27e -# ╟─b113c030-81fe-11eb-2042-776472e720ac -# ╠═99835750-81fe-11eb-3a7e-1132eb3cdd90 -# ╠═a9f59000-81f7-11eb-15c0-4520acb6543f -# ╠═a9317cb0-81f7-11eb-26e5-95719252409b -# ╠═2149b640-846e-11eb-262b-299ded0c61c5 -# ╠═cf5b7030-846d-11eb-2f23-290624c7d684 -# ╠═c57fe2d0-81f7-11eb-27d7-4b5c0520998d -# ╟─213ef2c0-81fb-11eb-1425-15bfcf1dc14c -# ╠═9388c570-833d-11eb-3baa-758b5cb19065 -# ╟─e85b0e90-81fe-11eb-0dd5-0b3df376a4f7 -# ╟─57844480-833a-11eb-3a57-bf00cecde849 -# ╟─a5c735d0-833a-11eb-2bae-71ba4af6b3a1 diff --git a/thrust.jl b/thrust.jl index c4841e9..5d44e9a 100644 --- a/thrust.jl +++ b/thrust.jl @@ -1,20 +1,17 @@ using Unitful using DataFrames using Plots -# using Gadfly using UnitfulRecipes using Roots using CSV -using MonteCarloMeasurements +using Measurements -unsafe_comparisons(true) - # 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 = (100 ± 5)u"psi" +Pmax = (800 ± 50)u"psi" Wsolenoid = 1.5u"kg" @@ -33,10 +30,10 @@ T = (300 ± 20)u"K" t = 0.0u"s" P = P0 |> u"Pa" M = V * (P / (R * T)) |> u"kg" -# df = DataFrame(Thrust = (0 ± 0)u"N", Pressure = P, Time = t, Mass = M) -df = DataFrame() -ts = 10u"ms" -while M > 0.1u"kg" +ts = 1u"ms" +df = DataFrame(Thrust = (0 ± 0)u"N", Pressure = P, Time = t, Mass = M) + +while M > 0.01u"kg" # while t < 30u"s" # Calculate what is leaving tank P = minimum([P, Pmax]) @@ -49,25 +46,23 @@ while M > 0.1u"kg" # Calculate what is still in the tank M = M - ṁ * ts |> u"kg" P = (M * R * T) / V |> u"Pa" - # df_step = DataFrame(Thrust = Thrust, Pressure = P, Time = t, Mass = M) - - if df == DataFrame() - df = DataFrame(Thrust = Thrust, Pressure = P, Time = t, Mass = M) - else - append!(df, DataFrame(Thrust = Thrust, Pressure = P, Time = t, Mass = M)) - end t = t + ts + + df_step = DataFrame(Thrust = Thrust, Pressure = P, Time = t, Mass = M) + append!(df, df_step) end + impulse = sum(df.Thrust) * ts |> u"N*s" println("---------------------------\n\n\n\n") println("Total Impulse: ", impulse) println("Burn Time: ", t) -plot(impulse) + println("Mass Total: ", Wtank + Wsolenoid + maximum(df.Mass)) -# plot(sum(df.Thrust) * ts |> u"N*s") -# print(describe(df)) -# df.Time = round(u"s", df.Time) -# plot(df.Time, df.Thrust, title = "Thrust Over Time") -# CSV.write("thrustdata.csv", df .|> ustrip) -# plot(df.Time .|> u"s" .|> ustrip, df.Thrust .|> u"N" .|> ustrip)> ustrip, df.Thrust .|> u"N" .|> ustrip) \ No newline at end of file + +print(describe(df)) + +plot(df.Time[1:150:end], df.Thrust[1:150:end], title = "Thrust Over Time") + +savefig("ThrustCurve.png") + From 5bbb7933e177f395a80b4243f3b5b42ac1246333 Mon Sep 17 00:00:00 2001 From: Anson Date: Mon, 22 Mar 2021 06:18:49 -0700 Subject: [PATCH 3/3] Data now gets printed to readme.md --- ThrustCurve.png | Bin 0 -> 21247 bytes readme.md | 8 ++++++++ thrust.jl | 21 +++++++++++++++++++++ 3 files changed, 29 insertions(+) create mode 100644 ThrustCurve.png create mode 100644 readme.md diff --git a/ThrustCurve.png b/ThrustCurve.png new file mode 100644 index 0000000000000000000000000000000000000000..ac42fec2315f3b2fb828c800f8843c6d3371fb4a GIT binary patch literal 21247 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%0D5C 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 |VZq9YYOZ^Es3D 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 literal 0 HcmV?d00001 diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..9531269 --- /dev/null +++ b/readme.md @@ -0,0 +1,8 @@ +# Air Prop Thrust +Total Impulse: 405.0 ± 39.0 N s + +![Thrust Over Time](ThrustCurve.png) + +More Data: + +

4 rows × 7 columns

variablemeanminmedianmaxnmissingeltype
SymbolQuantityQuantityQuantityQuantityInt64DataType
1Thrust69.0±6.7 N0.0±0.0 N86.7±9.2 N86.7±9.2 N0Quantity{Measurement{Float64}, 𝐋 𝐌 𝐓^-2, FreeUnits{(N,), 𝐋 𝐌 𝐓^-2, nothing}}
2Pressure1.21e7±2.0e6 Pa620000.0±440000.0 Pa1.12e7±2.8e6 Pa2.9e7±2.1e6 Pa0Quantity{Measurement{Float64}, 𝐌 𝐋^-1 𝐓^-2, FreeUnits{(Pa,), 𝐌 𝐋^-1 𝐓^-2, nothing}}
3Time2.9325 s0.0 s2.9325 s5.865 s0Quantity{Float64, 𝐓, FreeUnits{(s,), 𝐓, nothing}}
4Mass0.196±0.043 kg0.01±0.0077 kg0.181±0.054 kg0.468±0.053 kg0Quantity{Measurement{Float64}, 𝐌, FreeUnits{(kg,), 𝐌, nothing}}
diff --git a/thrust.jl b/thrust.jl index 5d44e9a..6e5e423 100644 --- a/thrust.jl +++ b/thrust.jl @@ -5,6 +5,7 @@ using UnitfulRecipes using Roots using CSV using Measurements +using Printf # Tank https://www.amazon.com/Empire-Paintball-BASICS-Pressure-Compressed/dp/B07B6M48SR/ @@ -64,5 +65,25 @@ print(describe(df)) plot(df.Time[1:150:end], df.Thrust[1:150:end], title = "Thrust Over Time") +### Save data to readme.md + savefig("ThrustCurve.png") +b = IOBuffer(); +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 +Total Impulse: %s + +![Thrust Over Time](ThrustCurve.png) + +More Data: + +%s +""" impulse table + +write("readme.md", readme) \ No newline at end of file