1
0
mirror of https://gitlab.com/Anson-Projects/projects.git synced 2025-06-15 14:36:47 +00:00

Update julia

This commit is contained in:
Anson Biggs 2024-03-11 05:27:38 +00:00
parent 1d205652a3
commit fceed3189a
12 changed files with 1139 additions and 309 deletions

View File

@ -1,14 +1,15 @@
{
"name": "Anson's Projects",
"image": "registry.gitlab.com/anson-projects/projects:latest",
"customizations": {
"vscode": {
"extensions": [
"quarto.quarto",
"julialang.language-julia",
"redhat.vscode-yaml",
"ms-azuretools.vscode-docker"
]
}
"name": "Anson's Projects",
// "image": "registry.gitlab.com/anson-projects/projects:latest",
"build": { "dockerfile": "../Dockerfile" },
"customizations": {
"vscode": {
"extensions": [
"quarto.quarto",
"julialang.language-julia",
"redhat.vscode-yaml",
"ms-azuretools.vscode-docker"
]
}
}
}
}

View File

@ -7,17 +7,14 @@ build:
- /kaniko/executor
--context "${CI_PROJECT_DIR}"
--dockerfile "${CI_PROJECT_DIR}/Dockerfile"
--destination "${CI_REGISTRY_IMAGE}:${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME}"
--destination "${CI_REGISTRY_IMAGE}:latest"
rules:
- if: '$CI_COMMIT_BRANCH == "master"'
--destination "${CI_REGISTRY_IMAGE}:${CI_COMMIT_BRANCH}"
--destination "${CI_REGISTRY_IMAGE}:develop"
staging:
cache:
paths:
- _freeze
stage: deploy
image: ${CI_REGISTRY_IMAGE}:latest
image: ${CI_REGISTRY_IMAGE}:${CI_COMMIT_BRANCH}
script:
- echo "Building the project with Quarto..."
- quarto render --to html --output-dir public

View File

@ -1,17 +1,40 @@
FROM ghcr.io/quarto-dev/quarto-full:1.5.22
FROM ubuntu:22.04
ARG DEBIAN_FRONTEND=noninteractive
ENV JULIA_VERSION=1.10.2 \
JULIA_MAJOR_VERSION=1.10 \
JULIA_PATH=/usr/local/julia
RUN apt-get update && apt-get install -y --no-install-recommends \
apt-utils dialog \
git iproute2 procps lsb-release \
python3 python3-pip \
python3 python3-pip python3-dev \
r-base \
julia \
&& rm -rf /var/lib/apt/lists/*
gcc g++ \
wget curl tar\
&& rm -rf /var/lib/apt/lists/*
# Use a RUN command for architecture detection and conditional logic
RUN wget https://github.com/quarto-dev/quarto-cli/releases/download/v1.4.550/quarto-1.4.550-linux-$(if [ "$(uname -m)" = "x86_64" ]; then echo "amd64"; else echo "arm64"; fi).tar.gz -O quarto.tar.gz \
&& tar -xzf quarto.tar.gz -C /opt \
&& mkdir -p /opt/quarto \
&& mv /opt/quarto-1.4.550/* /opt/quarto/ \
&& ln -s /opt/quarto/bin/quarto /usr/local/bin/quarto \
&& rm -rf quarto.tar.gz /opt/quarto-1.4.550
RUN python3 -m pip install jupyter
# Assuming Project.toml and Manifest.toml are copied to the correct locations
COPY Project.toml /root/.julia/environments/v1.4/
COPY Manifest.toml /root/.julia/environments/v1.4/
RUN curl -fsSL "https://julialang-s3.julialang.org/bin/linux/$(if [ "$(uname -m)" = "x86_64" ]; then echo "x64"; else echo "aarch64"; fi)/${JULIA_MAJOR_VERSION}/julia-${JULIA_VERSION}-linux-$(if [ "$(uname -m)" = "x86_64" ]; then echo "x86_64"; else echo "aarch64"; fi).tar.gz" -o julia.tar.gz \
&& tar -xzf julia.tar.gz -C /tmp \
&& mv /tmp/julia-${JULIA_VERSION} ${JULIA_PATH} \
&& rm -rf julia.tar.gz /tmp/julia-${JULIA_VERSION} \
&& ln -s ${JULIA_PATH}/bin/julia /usr/local/bin/julia
COPY Project.toml /root/.julia/environments/v${JULIA_MAJOR_VERSION}/
COPY Manifest.toml /root/.julia/environments/v${JULIA_MAJOR_VERSION}/
RUN julia -e "using Pkg; Pkg.instantiate(); Pkg.precompile()"
ENV QUARTO_DENO_EXTRA_OPTIONS=--v8-flags=--stack-size=10000

File diff suppressed because it is too large Load Diff

View File

@ -2,9 +2,11 @@
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
Colors = "5ae59095-9a9b-59fe-a467-6f913c188581"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
GR_jll = "d2c73de3-f751-5644-a686-071e5b155ba9"
IJulia = "7073ff75-c697-5162-941a-fcdaad2a7d2a"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Measurements = "eff96d63-e80a-5855-80a2-b1b0885c5ab7"
PlotlyJS = "f0f68f2c-4968-5e81-91da-67840de0976a"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
Revise = "295af30f-e4ad-537b-8983-00126c2a3abe"
SatelliteToolbox = "6ac157d9-b43d-51bb-8fab-48bf53814f4a"

View File

@ -10,7 +10,7 @@ categories:
- Notes
creative_commons: CC BY
image: banner.png
freeze: true
freeze: auto
---

View File

@ -5,7 +5,7 @@ description: |
repository_url: https://gitlab.com/lander-team/air-prop-simulation
date: 2021-04-01
date-modified: 2024-02-29
date-modified: 2024-03-10
categories:
- Julia
- Capstone
@ -13,7 +13,7 @@ categories:
- Code
- Aerospace
creative_commons: CC BY
jupyter: julia-1.4
jupyter: julia-1.10
format:
html:
@ -21,7 +21,7 @@ format:
code-fold: false
execute:
output: false
freeze: true
freeze: auto
---
For Capstone my team was tasked with designing a system capable of moving mining equipment and materials around the surface of the Moon using a propulsive landing. The system had to be tested on Earth with something feasible for our team to build in 2 semesters. One of the first considerations my capstone advisor wanted was to test the feasibility of an air propulsion system instead of the obvious solution that of using solid rocket motors. This document is just _napkin math_ to determine if the system is even feasibly and is not meant to be a rigorous study of an air propulsion system that would easily keep a capstone team busy by itself.
@ -32,7 +32,7 @@ For Capstone my team was tasked with designing a system capable of moving mining
#| code-fold: true
#| code-summary: Imports
using Plots
theme(:ggplot2); # In true R spirit
plotlyjs()
using Unitful
using DataFrames
@ -49,28 +49,28 @@ I chose an off-the-shelf paintball gun tank for the pressure vessel. The primary
```{julia}
#| code-fold: false
# 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
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
```
The nozzle diameter was changed until the air prop system had a _burn time_ similar to a G18ST rocket motor. The propulsion system's total impulse is not dependant on the nozzle diameter, so this was just done to make it plot nicely with the rest of the rocket motors since, at this time, it is unknown what the optimal thrust profile is.
```{julia}
# Params
d_nozzle = ((1 // 18) ± 0.001)u"inch"
a_nozzle = (pi / 4) * d_nozzle^2
d_nozzle = ((1 // 18) ± 0.001)u"inch";
a_nozzle = (pi / 4) * d_nozzle^2;
```
These are just universal values for what a typical day would look like during the summer in Northern Arizona. [@cengel_thermodynamics]
```{julia}
# Universal Stuff
P_amb = (1 ± 0.2)u"atm"
γ = 1.4 ± 0.05
R = 287.05u"J/(kg * K)"
T = (300 ± 20)u"K"
P_amb = (1 ± 0.2)u"atm";
γ = 1.4 ± 0.05;
R = 287.05u"J/(kg * K)";
T = (300 ± 20)u"K";
```
The actual simulation is quite simple. The basic idea is that using the current pressure, you can calculate $\dot{m}$, which allows calculating the Thrust, and then you can subtract the current mass of air in the tank by $\dot{m}$ and recalculate pressure using the new mass then repeat the whole process.
@ -83,31 +83,29 @@ $$ T = \dot{m} \cdot v_\text{Exit} + A_\text{Nozzle} \cdot (P - P_\text{Ambient}
The initial pressure difference is `{julia} P0 - P_amb |> u"psi"`, which is massive, so the area of the nozzle significantly alters the thrust profile. The paintball tanks come with pressure regulators, in our case, 800 psi which is still a huge number compared to atmospheric pressure. While the total impulse of the system doesn't change with different nozzle areas, the peak thrust and _burn time_ vary greatly. One of the benefits of doing air propulsion and the reason it was even considered so seriously is that it should be possible to change the nozzle diameter in flight, allowing thrust to be throttled, making controlled landing easier to control.
```{julia}
df = let
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=P0, Time=0.0u"s", 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"
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=P0, Time=0.0u"s", 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"
Thrust = ṁ * ve + a_nozzle * (P - P_amb) |> u"N"
# Calculate what is still in the tank
M = M - ṁ * ts |> u"kg"
P = (M * R * T) / V |> u"Pa"
t = t + ts
# 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)
append!(df, df_step)
end
df
df_step = DataFrame(Thrust=Thrust, Pressure=P, Time=t, Mass=M)
append!(df, df_step)
end
```
## Analysis
@ -117,10 +115,10 @@ Below in figure 1, the result of the simulation is plotted. Notice the massive e
```{julia}
#| code-folding: true
#| results: 'show'
#| fig-cap: 'Air Propulsion Simulation'
#| preview: false
#| output: true
#| class-output: preview-image
thrust_values = df.Thrust .|> ustrip .|> value;
thrust_uncertainties = df.Thrust .|> ustrip .|> uncertainty;
@ -140,16 +138,14 @@ plot(df.Time .|> ustrip, thrust_values,
In Figure 2, the air propulsion simulation is compared to commercially available rocket motors. This early in the project, we have no idea whether short burns or longer burns are ideal for a propulsive landing, so the air propulsion system was compared to a variety of different motors with unique profiles.
```{julia}
#| code-folding: true
#| results: 'show'
#| code-folding: tru
#| fig-cap: "Rocket Motor Data: [@thrustcurve]"
#| preview: false
#| output: true
f10 = CSV.read("AeroTech_F10.csv", DataFrame);
f15 = CSV.read("Estes_F15.csv", DataFrame);
g8 = CSV.read("AeroTech_G8ST.csv", DataFrame);
plot(air.Time, air.Thrust, label="Air Propulsion", legend=:topleft);
plot(air.Time, air.Thrust, label="Air Propulsion", legend=:outertopright);
for (d, l) in [(f10, "F10"), (f15, "F15"), (g8, "G8ST")]
plot!(d[!, "Time (s)"], d[!, "Thrust (N)"], label=l)
@ -167,4 +163,4 @@ In the end, the air propulsion system's performance has a very impressive total
After determining that solid model rocket motors are the best option for the current mission scope, the next step is determining what motor to use. There are many great options, and deciding what thrust profile is ideal may have to wait until a Simulink simulation of the landing can be built so that the metrics of each motor can be constrained more. Instead of throttling motors, the current working idea is that thrust vector control may be a way to squeeze a little more control out of a solid rocket motor. Thrust Vector Control will undoubtedly be challenging to control, so another essential piece that needs exploring is whether an LQR controller is feasible or if a PID controller is accurate enough to control our system.
Codebase: https://gitlab.com/lander-team/air-prop-simulation
Codebase: [https://gitlab.com/lander-team/air-prop-simulation](https://gitlab.com/lander-team/air-prop-simulation)

View File

@ -18,10 +18,8 @@ format:
html:
code-tools: true
code-fold: false
kernel:
id: julia-1.4
project: ../../
freeze: true
jupyter: julia-1.10
freeze: auto
---
Determining the eclipses a satellite will encounter is a major driving factor when designing a mission in space. Thermal and power budgets have to be made with the fact that a satellite will periodically be in the complete darkness of space where it will receive no solar radiation to power the solar panels and keep the spacecraft from freezing.
@ -62,13 +60,14 @@ ISS (ZARYA)
Now that we have the TLE, we can pass that into SatelliteToolbox's orbit propagator. Before propagating the orbit, we need to have a range of time steps to pass into the propagator. The TLE gives the mean motion, n, which is the revolutions per day, so using that, we can calculate the amount of time required for one orbit, which is all that we're worried about for this analysis. The propagator returns a tuple containing the Orbital elements, a position vector with units meters, and a velocity vector with units meters per second. For this analysis were only worried about the position vector.
```{julia mean-motion, result='show'}
ISS[1].n
ISS.mean_motion
```
```{julia orbit-propagation}
orbit = init_orbit_propagator(Val{:twobody}, ISS[1]);
time = 0:0.1:((24/ISS[1].n).*60*60); # ISS[1].n gives the mean motion, or orbits per day.
o, r, v = propagate!(orbit, time);
orbit = Propagators.init(Val(:SGP4), ISS);
time = 0:0.1:((24/ISS.mean_motion).*60*60);
propagated = Propagators.propagate!.(orbit, time);
r = first.(propagated); # Get distance from propagator
```
We just need to use the radii and vectors discussed earlier to determine if the ISS is in the penumbra or umbra. This is a lot of trigonometry and vector math that I won't bore anyone with. However, using the diagrams above and following the code in the sunlight function, you should follow what's happening. For a rigorous discussion, check out [@vallado].

View File

@ -12,7 +12,7 @@ categories:
- Code
- Python
- CI/CD
freeze: true
freeze: auto
---
## The Problem

View File

@ -12,7 +12,7 @@ categories:
bibliography: citations.bib
creative_commons: CC BY
image: banner.jpg
freeze: true
freeze: auto
---
## The Current State of Crypto

View File

@ -13,7 +13,7 @@ categories:
- Code
image: clusters.svg
draft: false
freeze: true
freeze: auto
---
## Gathering Data

View File

@ -13,7 +13,7 @@ categories:
- Code
image: Figures/inertia3d.png
draft: false
freeze: true
freeze: auto
---
## Gathering Data