Avionics test engineering internship content and about the site #15
@@ -16,6 +16,7 @@ Dechorionator
|
|||||||
ebox
|
ebox
|
||||||
fhhs
|
fhhs
|
||||||
flowbite
|
flowbite
|
||||||
|
Gitea
|
||||||
HDFS
|
HDFS
|
||||||
headshot
|
headshot
|
||||||
Homelab
|
Homelab
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 1.8 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 580 KiB |
Binary file not shown.
@@ -1,10 +1,23 @@
|
|||||||
---
|
---
|
||||||
|
import InlineLink from "@components/InlineLink.astro";
|
||||||
|
|
||||||
|
const { pathname } = Astro.url;
|
||||||
---
|
---
|
||||||
|
|
||||||
<footer
|
<footer
|
||||||
class="border-t-caperren-green-dark text-caperren-green-dark z-50 flex w-full max-w-full items-center justify-between border-t bg-black px-6 py-2 text-sm"
|
class="border-t-caperren-green-dark text-caperren-green-dark z-50 flex w-full max-w-full items-center justify-between border-t bg-black px-6 py-2 text-sm"
|
||||||
>
|
>
|
||||||
<span>{import.meta.env.PUBLIC_BUILD_ENVIRONMENT || "development"}</span>
|
<span>{import.meta.env.PUBLIC_BUILD_ENVIRONMENT || "development"}</span>
|
||||||
|
<div>
|
||||||
|
<InlineLink
|
||||||
|
class:list={[
|
||||||
|
"text-caperren-green-dark hover:text-caperren-green",
|
||||||
|
pathname === "/hobby/this-website"
|
||||||
|
? "border-caperren-green-dark hover:border-caperren-green border-b-2"
|
||||||
|
: false,
|
||||||
|
]}
|
||||||
|
href="/hobby/this-website">About This Website</InlineLink
|
||||||
|
>
|
||||||
|
</div>
|
||||||
<span>{import.meta.env.PUBLIC_REPO_VERSION_HASH || "invalid"}</span>
|
<span>{import.meta.env.PUBLIC_REPO_VERSION_HASH || "invalid"}</span>
|
||||||
</footer>
|
</footer>
|
||||||
|
|||||||
@@ -7,16 +7,10 @@ interface Props extends ComponentPropsBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { class: className, href, target } = Astro.props;
|
const { class: className, href, target } = Astro.props;
|
||||||
|
const { pathname } = Astro.url;
|
||||||
|
|
||||||
let finalTarget: string | undefined = target;
|
const finalTarget =
|
||||||
|
target === undefined ? (href.startsWith("/") ? undefined : "_blank") : target;
|
||||||
if (target === undefined) {
|
|
||||||
if (href.startsWith("/")) {
|
|
||||||
finalTarget = "";
|
|
||||||
} else {
|
|
||||||
finalTarget = "_blank";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<>
|
<>
|
||||||
@@ -24,6 +18,7 @@ if (target === undefined) {
|
|||||||
class:list={["text-blue-500", "hover:text-blue-300", className]}
|
class:list={["text-blue-500", "hover:text-blue-300", className]}
|
||||||
href={href}
|
href={href}
|
||||||
target={finalTarget}
|
target={finalTarget}
|
||||||
|
aria-current={pathname === href ? "page" : undefined}
|
||||||
>
|
>
|
||||||
<slot />
|
<slot />
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -1,26 +1,18 @@
|
|||||||
---
|
---
|
||||||
import type { navLink } from "@interfaces/site-layout.ts";
|
import type { navLink } from "@interfaces/site-layout.ts";
|
||||||
|
|
||||||
|
import { getHrefPath, getNavLinkSuffix } from "@data/site-layout.ts";
|
||||||
|
|
||||||
const items: navLink[] = Astro.props.items;
|
const items: navLink[] = Astro.props.items;
|
||||||
const depth: number = Astro.props.depth ?? 0;
|
const depth: number = Astro.props.depth ?? 0;
|
||||||
const paths: string[] = Astro.props.paths ?? [];
|
const paths: string[] = Astro.props.paths ?? [];
|
||||||
|
|
||||||
const getNavLinkSuffix = (entry: navLink): string => {
|
|
||||||
return "-" + [...paths, entry.path].join("-");
|
|
||||||
};
|
|
||||||
const getHrefPath = (entry: navLink): string => {
|
|
||||||
return entry.pubpath
|
|
||||||
? entry.pubpath
|
|
||||||
: "/" +
|
|
||||||
(paths && paths.length ? [...paths, entry.path].join("/") : entry.path);
|
|
||||||
};
|
|
||||||
|
|
||||||
const { pathname } = Astro.url;
|
const { pathname } = Astro.url;
|
||||||
---
|
---
|
||||||
|
|
||||||
<ul
|
<ul
|
||||||
class:list={[
|
class:list={[
|
||||||
"border-caperren-green flex flex-col space-y-4 space-x-8 bg-black",
|
"border-caperren-green flex flex-col space-y-4 bg-black",
|
||||||
depth
|
depth
|
||||||
? "space-y-4 py-4"
|
? "space-y-4 py-4"
|
||||||
: "items-start lg:mt-0 lg:flex-row lg:space-y-0 lg:space-x-8",
|
: "items-start lg:mt-0 lg:flex-row lg:space-y-0 lg:space-x-8",
|
||||||
@@ -29,21 +21,22 @@ const { pathname } = Astro.url;
|
|||||||
{
|
{
|
||||||
items.map(
|
items.map(
|
||||||
(entry) =>
|
(entry) =>
|
||||||
(entry.enabled ?? true) && (
|
(entry.enabled ?? true) &&
|
||||||
|
!(entry.hidden ?? false) && (
|
||||||
<li class="">
|
<li class="">
|
||||||
{Array.isArray(entry.children) && entry.children.length ? (
|
{Array.isArray(entry.children) && entry.children.length ? (
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
id={"dropdownNavbarLink" + getNavLinkSuffix(entry)}
|
id={"dropdownNavbarLink" + getNavLinkSuffix(paths, entry)}
|
||||||
data-dropdown-toggle={
|
data-dropdown-toggle={
|
||||||
"dropdownNavbar" + getNavLinkSuffix(entry)
|
"dropdownNavbar" + getNavLinkSuffix(paths, entry)
|
||||||
}
|
}
|
||||||
data-dropdown-placement="bottom-start"
|
data-dropdown-placement="bottom-start"
|
||||||
data-dropdown-offset-distance="5"
|
data-dropdown-offset-distance="5"
|
||||||
data-dropdown-offset-skidding="12"
|
data-dropdown-offset-skidding="12"
|
||||||
class:list={[
|
class:list={[
|
||||||
"hover:text-caperren-green-light lg:hover:text-caperren-green-light flex w-full items-center justify-between lg:p-0 lg:hover:bg-transparent",
|
"hover:text-caperren-green-light lg:hover:text-caperren-green-light flex w-full items-center justify-between lg:p-0 lg:hover:bg-transparent",
|
||||||
pathname.startsWith(getHrefPath(entry))
|
pathname.startsWith(getHrefPath(paths, entry))
|
||||||
? "border-caperren-green border-b-2"
|
? "border-caperren-green border-b-2"
|
||||||
: false,
|
: false,
|
||||||
]}
|
]}
|
||||||
@@ -65,7 +58,7 @@ const { pathname } = Astro.url;
|
|||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
<div
|
<div
|
||||||
id={"dropdownNavbar" + getNavLinkSuffix(entry)}
|
id={"dropdownNavbar" + getNavLinkSuffix(paths, entry)}
|
||||||
class="border-caperren-green z-10 hidden w-max max-w-screen border bg-black px-6 shadow-sm"
|
class="border-caperren-green z-10 hidden w-max max-w-screen border bg-black px-6 shadow-sm"
|
||||||
>
|
>
|
||||||
<Astro.self
|
<Astro.self
|
||||||
@@ -78,16 +71,18 @@ const { pathname } = Astro.url;
|
|||||||
) : (
|
) : (
|
||||||
<div>
|
<div>
|
||||||
<a
|
<a
|
||||||
href={getHrefPath(entry)}
|
href={getHrefPath(paths, entry)}
|
||||||
target={getHrefPath(entry).startsWith("/") ? "" : "_blank"}
|
target={
|
||||||
|
getHrefPath(paths, entry).startsWith("/") ? "" : "_blank"
|
||||||
|
}
|
||||||
class:list={[
|
class:list={[
|
||||||
"hover:text-caperren-green-light ring-caperren-green-dark block bg-transparent lg:p-0",
|
"hover:text-caperren-green-light ring-caperren-green-dark block bg-transparent lg:p-0",
|
||||||
pathname === getHrefPath(entry)
|
pathname === getHrefPath(paths, entry)
|
||||||
? "border-caperren-green border-b-2"
|
? "border-caperren-green border-b-2"
|
||||||
: false,
|
: false,
|
||||||
]}
|
]}
|
||||||
aria-current={
|
aria-current={
|
||||||
pathname === getHrefPath(entry) ? "page" : undefined
|
pathname === getHrefPath(paths, entry) ? "page" : undefined
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{entry.navText}
|
{entry.navText}
|
||||||
|
|||||||
@@ -7,10 +7,14 @@ const keys: { [key: string]: string } = {
|
|||||||
ADCP: "Acoustic doppler current profiler",
|
ADCP: "Acoustic doppler current profiler",
|
||||||
COTS: "Consumer off-the-shelf",
|
COTS: "Consumer off-the-shelf",
|
||||||
CTD: "Conductivity, temperature, and depth sensor",
|
CTD: "Conductivity, temperature, and depth sensor",
|
||||||
|
DUTs: "Devices under test",
|
||||||
GUI: "Graphical user interface",
|
GUI: "Graphical user interface",
|
||||||
NUC: "A small and low-power computer made by Intel",
|
NUC: "A small and low-power computer made by Intel",
|
||||||
PCBs: "Printed circuit boards",
|
PCBs: "Printed circuit boards",
|
||||||
|
TDD: "Test driven development",
|
||||||
UPS: "Uninterruptible power supply",
|
UPS: "Uninterruptible power supply",
|
||||||
|
VISA: "Virtual instrument software architecture",
|
||||||
|
VPS: "Virtual private server",
|
||||||
};
|
};
|
||||||
|
|
||||||
const key: string | undefined = Astro.props.key;
|
const key: string | undefined = Astro.props.key;
|
||||||
@@ -21,6 +25,12 @@ if (key && keys.hasOwnProperty(key)) {
|
|||||||
word = key;
|
word = key;
|
||||||
definition = keys[key];
|
definition = keys[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!word || !definition) {
|
||||||
|
throw new Error(
|
||||||
|
`Popover definition is missing! Inputs were\nkey: ${key}\nword: ${word}\ndefinition: ${definition}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
---
|
---
|
||||||
|
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -13,7 +13,11 @@ const { class: className, lineItems, depth = 0 } = Astro.props;
|
|||||||
---
|
---
|
||||||
|
|
||||||
<ul
|
<ul
|
||||||
class:list={["list-inside list-disc", className, depth > 0 ? "ps-3" : false]}
|
class:list={[
|
||||||
|
"list-outside list-disc",
|
||||||
|
className,
|
||||||
|
depth > 0 ? "ps-3" : "ms-3",
|
||||||
|
]}
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
lineItems ? (
|
lineItems ? (
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import type { navLink } from "@interfaces/site-layout.ts";
|
import type { navLink } from "@interfaces/site-layout.ts";
|
||||||
|
|
||||||
export const siteLayout: navLink[] = [
|
export const siteLayout: navLink[] = [
|
||||||
|
// Standard navbar entries
|
||||||
{ navText: "About", path: "" },
|
{ navText: "About", path: "" },
|
||||||
{ navText: "Education", path: "education" },
|
{ navText: "Education", path: "education" },
|
||||||
{
|
{
|
||||||
@@ -8,7 +9,6 @@ export const siteLayout: navLink[] = [
|
|||||||
path: "experience",
|
path: "experience",
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
enabled: false,
|
|
||||||
navText: "SpaceX",
|
navText: "SpaceX",
|
||||||
path: "spacex",
|
path: "spacex",
|
||||||
children: [
|
children: [
|
||||||
@@ -18,7 +18,6 @@ export const siteLayout: navLink[] = [
|
|||||||
path: "hardware-test-engineer-i-ii",
|
path: "hardware-test-engineer-i-ii",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
enabled: false,
|
|
||||||
navText: "Avionics Test Engineering Internship",
|
navText: "Avionics Test Engineering Internship",
|
||||||
path: "avionics-test-engineering-internship",
|
path: "avionics-test-engineering-internship",
|
||||||
},
|
},
|
||||||
@@ -189,6 +188,7 @@ export const siteLayout: navLink[] = [
|
|||||||
},
|
},
|
||||||
{ enabled: false, navText: "NixOS", path: "nixos" },
|
{ enabled: false, navText: "NixOS", path: "nixos" },
|
||||||
{ navText: "Body Mods", path: "body-mods" },
|
{ navText: "Body Mods", path: "body-mods" },
|
||||||
|
{ navText: "This Website", path: "this-website" },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -270,3 +270,13 @@ export const getPaths = (
|
|||||||
}
|
}
|
||||||
return [...new Set(foundPaths)];
|
return [...new Set(foundPaths)];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getNavLinkSuffix = (paths: string[], entry: navLink): string => {
|
||||||
|
return "-" + [...paths, entry.path].join("-");
|
||||||
|
};
|
||||||
|
export const getHrefPath = (paths: string[], entry: navLink): string => {
|
||||||
|
return entry.pubpath
|
||||||
|
? entry.pubpath
|
||||||
|
: "/" +
|
||||||
|
(paths && paths.length ? [...paths, entry.path].join("/") : entry.path);
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
export interface navLink {
|
export interface navLink {
|
||||||
enabled?: boolean;
|
enabled?: boolean;
|
||||||
|
hidden?: boolean;
|
||||||
navText: string;
|
navText: string;
|
||||||
path?: string;
|
path?: string;
|
||||||
pubpath?: string;
|
pubpath?: string;
|
||||||
|
|||||||
@@ -1,16 +1,28 @@
|
|||||||
---
|
---
|
||||||
|
import H2 from "@components/H2.astro";
|
||||||
|
import H3 from "@components/H3.astro";
|
||||||
|
import Li from "@components/Li.astro";
|
||||||
import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro";
|
import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro";
|
||||||
|
import PageGroup from "@components/PageGroup.astro";
|
||||||
|
import Paragraph from "@components/Paragraph.astro";
|
||||||
|
import Paragraphs from "@components/Paragraphs.astro";
|
||||||
|
import PopoverWordDefinition from "@components/PopoverWordDefinition.astro";
|
||||||
|
import SkillMatrix from "@components/SkillMatrix/SkillMatrix.astro";
|
||||||
import Timeline from "@components/Timeline/Timeline.astro";
|
import Timeline from "@components/Timeline/Timeline.astro";
|
||||||
|
import Ul from "@components/Ul.astro";
|
||||||
import ExperienceLayout from "@layouts/ExperienceLayout.astro";
|
import ExperienceLayout from "@layouts/ExperienceLayout.astro";
|
||||||
|
|
||||||
import spring_2019_interns from "@assets/experience/spacex/avionics-test-engineering-internship/spring-2019-interns.jpg";
|
import spring_2019_interns from "@assets/experience/spacex/avionics-test-engineering-internship/spring-2019-interns.jpg";
|
||||||
|
import swag from "@assets/experience/spacex/avionics-test-engineering-internship/swag.jpg";
|
||||||
|
|
||||||
|
import InlineLink from "@components/InlineLink.astro";
|
||||||
import type { carouselGroup } from "@interfaces/image-carousel.ts";
|
import type { carouselGroup } from "@interfaces/image-carousel.ts";
|
||||||
|
import type { categorySkills } from "@interfaces/skill-matrix.ts";
|
||||||
import type { timelineEntry } from "@interfaces/timeline.ts";
|
import type { timelineEntry } from "@interfaces/timeline.ts";
|
||||||
|
|
||||||
const headerCarouselGroup: carouselGroup = {
|
const headerCarouselGroup: carouselGroup = {
|
||||||
animation: "slide",
|
animation: "slide",
|
||||||
images: [spring_2019_interns],
|
images: [spring_2019_interns, swag],
|
||||||
};
|
};
|
||||||
|
|
||||||
const timeline: timelineEntry[] = [
|
const timeline: timelineEntry[] = [
|
||||||
@@ -23,58 +35,157 @@ const timeline: timelineEntry[] = [
|
|||||||
date: "March 2019",
|
date: "March 2019",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const categorizedSkills: categorySkills[] = [
|
||||||
|
{
|
||||||
|
category: "Software & Environments",
|
||||||
|
skills: [
|
||||||
|
{ item: "Git" },
|
||||||
|
{
|
||||||
|
item: "Programming Languages",
|
||||||
|
subItems: [
|
||||||
|
{ item: "Python 2/3" },
|
||||||
|
{ item: "Bash Shell Scripting" },
|
||||||
|
{ item: "Microsoft SQL" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
item: "Atlassian Suite",
|
||||||
|
subItems: [
|
||||||
|
{ item: "Jira" },
|
||||||
|
{ item: "Bitbucket" },
|
||||||
|
{ item: "Confluence" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
item: "Automation Interfaces",
|
||||||
|
subItems: [{ item: "NI MAX/VISA" }, { item: "Jira RESTful APIs" }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
item: "Operating Systems",
|
||||||
|
subItems: [
|
||||||
|
{
|
||||||
|
item: "Linux",
|
||||||
|
subItems: [{ item: "Ubuntu" }, { item: "WSL" }],
|
||||||
|
},
|
||||||
|
{ item: "Microsoft Windows" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
category: "Electrical",
|
||||||
|
skills: [
|
||||||
|
{
|
||||||
|
item: "Schematic & PCB Design",
|
||||||
|
subItems: [{ item: "Altium Designer" }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
item: "Electrical Diagnostics",
|
||||||
|
subItems: [{ item: "Multimeters" }],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
---
|
---
|
||||||
|
|
||||||
<ExperienceLayout title="SpaceX - Avionics Test Engineering Internship">
|
<ExperienceLayout
|
||||||
|
title="Avionics Test Engineering Internship"
|
||||||
|
subTitles={["Space Exploration Technologies Corporation"]}
|
||||||
|
>
|
||||||
<Carousel carouselGroup={headerCarouselGroup} />
|
<Carousel carouselGroup={headerCarouselGroup} />
|
||||||
|
<PageGroup>
|
||||||
<h2 class="my-4 font-bold md:text-2xl">Summary</h2>
|
<Fragment slot="header"><H2>Summary</H2></Fragment>
|
||||||
<h3 class="my-4 font-bold md:text-lg">Timeline</h3>
|
<PageGroup>
|
||||||
|
<Fragment slot="header"><H3>Timeline</H3></Fragment>
|
||||||
<Timeline timeline={timeline} />
|
<Timeline timeline={timeline} />
|
||||||
<h3 class="my-4 font-bold md:text-lg">Key Takeaways</h3>
|
</PageGroup>
|
||||||
<ul class="list-inside list-disc">
|
<PageGroup>
|
||||||
<li></li>
|
<Fragment slot="header"><H3>Key Takeaways</H3></Fragment>
|
||||||
</ul>
|
<Ul>
|
||||||
<h3 class="my-4 font-bold md:text-lg">Skills Used</h3>
|
<Li
|
||||||
<div
|
>Wrote re-usable, unit-tested, and safety-focused test software
|
||||||
class="border-caperren-green relative grid grid-flow-row gap-6 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4"
|
components in Python for validating high-pressure transducers</Li
|
||||||
>
|
>
|
||||||
<div>
|
<Li
|
||||||
<div class="text-sm font-extrabold">Software</div>
|
>Assisted in the running of qualification tests against flight
|
||||||
<hr class="text-caperren-green" />
|
networking hardware</Li
|
||||||
<ul class="list-inside list-disc text-sm">
|
>
|
||||||
<li>Python</li>
|
<Li
|
||||||
<li>Test Driven Development</li>
|
>Wrote software in Python to automate work-ticket generation in Jira</Li
|
||||||
</ul>
|
>
|
||||||
</div>
|
<Li
|
||||||
<div>
|
>Successfully debugged electrical faults in <PopoverWordDefinition
|
||||||
<div class="text-sm font-extrabold">Electrical</div>
|
key="PCBs"
|
||||||
<hr class="text-caperren-green" />
|
/> used in Avionics test systems</Li
|
||||||
</div>
|
>
|
||||||
<div>
|
<Li
|
||||||
<div class="text-sm font-extrabold">Other</div>
|
>Directly interfaced with the engineering team for <PopoverWordDefinition
|
||||||
<hr class="text-caperren-green" />
|
key="COTS"
|
||||||
</div>
|
/> test equipment, driving firmware fixes and providing beta test feedback</Li
|
||||||
</div>
|
>
|
||||||
<h2 class="my-4 font-bold md:text-2xl">Details</h2>
|
</Ul>
|
||||||
|
</PageGroup>
|
||||||
Though I did get to work on some really fun projects during my internship at
|
<SkillMatrix categorizedSkills={categorizedSkills} />
|
||||||
SpaceX, I unfortunately can’t go into much detail due to NDA’s and ITAR
|
</PageGroup>
|
||||||
restrictions. What I can say is that I mainly wrote Python for a new avionics
|
<PageGroup>
|
||||||
hardware test system. My experience with writing Python in the numerous other
|
<Fragment slot="header"><H2>Details</H2></Fragment>
|
||||||
projects I’ve done really helped me out here, as the framework SpaceX has
|
<Paragraphs>
|
||||||
created was quite complex and would otherwise have been fairly difficult to
|
<Paragraph>
|
||||||
write code for. I also wrote a simple tool for automating the creation of Jira
|
Working at SpaceX was a dream come true, even when it was only for a
|
||||||
work tickets so that the two teams that ended up using it wouldn’t have to
|
three month internship. I've always loved space, including the
|
||||||
have their members manually creating dozens of them as work and issues came in
|
technology related to it, as I know many others also do. I grew as a
|
||||||
through a separate system. I was also quite happy in that I got to perform
|
Trekkie, watching endless hours of rubbermaid tubs filled with VHS
|
||||||
some circuit debugging on avionics test system hardware, both for my project
|
recordings of the original series, The Next Generation, and Voyager. As
|
||||||
and for a separate test system. A final experience I had here was getting to
|
someone with a multi-disciplinary background, and with a special focus
|
||||||
work directly with the head engineer from a company that supplied a piece of
|
on robotics and automation, test engineering was a very good fit!
|
||||||
test hardware I was interfacing with. It was quite incredible to see just how
|
</Paragraph>
|
||||||
much weight a SpaceX email address had when trying to solve problems I had
|
<Paragraph>
|
||||||
found with the hardware. Not only were they responsive, but in fact were
|
During this internship, my primary goal was to create re-usable
|
||||||
willing to fast-track firmware updates for us to get things working. Coming
|
components for high pressure test systems. This involved interfacing
|
||||||
from clubs and small labs where a support email might not even get a response
|
with test rack equipment which could apply pressure to <PopoverWordDefinition
|
||||||
for months, it was quite a refreshing experience.
|
key="DUTs"
|
||||||
|
/>, and would then validate their response and performance to this
|
||||||
|
stimulus. While I'd written quite a bit of Python prior to this, the
|
||||||
|
standards for these components were (understandably!) much higher than
|
||||||
|
I'd encountered previously. This effectively meant that the internship
|
||||||
|
was a bit of a crash course in <PopoverWordDefinition key="TDD" />, as
|
||||||
|
being able to verify that the tests would apply the correct stimulus,
|
||||||
|
and in the correct way, helped reduce the chances of damaging <PopoverWordDefinition
|
||||||
|
key="DUTs"
|
||||||
|
/>, or supporting test equipment. As part of this effort, I also made
|
||||||
|
significant improvements to the driver for the piece of test equipment
|
||||||
|
which controlled how pressure was applied. While doing so, I encountered
|
||||||
|
a fair number of discrepancies in the documentation and <PopoverWordDefinition
|
||||||
|
key="VISA"
|
||||||
|
/>
|
||||||
|
commands for this device. I ended up contacting the company and was put in
|
||||||
|
contact with their engineering department, where I then drove fixes to their
|
||||||
|
firmware and documentation, ultimately resulting in a fully functional test
|
||||||
|
setup. Since I ended up <InlineLink
|
||||||
|
href="/experience/spacex/hardware-test-engineer-i-ii"
|
||||||
|
>working for the company long-term</InlineLink
|
||||||
|
>, I know that these components were used, and likely still are, for
|
||||||
|
many pressure-related validation tests at the company and worked well!
|
||||||
|
</Paragraph>
|
||||||
|
<Paragraph>
|
||||||
|
There were also a couple of side projects I worked on while here. The
|
||||||
|
first was small Python app which automated the creation of Jira work
|
||||||
|
tickets for the Lifecycle Engineering Team. Previously, a member of that
|
||||||
|
team on a rotating schedule would manually create counterpart Jira
|
||||||
|
tickets associated to a proprietary tracking system created in-house. By
|
||||||
|
manually querying the SQL database for this proprietary app, and making
|
||||||
|
it run on a schedule, tickets were made and assigned to the appropriate
|
||||||
|
teams automatically, improving the response time to these tickets, and
|
||||||
|
removing the potential for errors during the previously manual
|
||||||
|
copy/pasting efforts. In my first week, I also debugged a custom circuit
|
||||||
|
board for a motor controller test system, finding the location of a dead
|
||||||
|
short, directing a tech to repair the failure, and then verified that
|
||||||
|
the board functioned correctly afterwards. The final small project I
|
||||||
|
worked on was manually running the shock tests in the qualification
|
||||||
|
efforts for a piece of spaceflight networking gear while its owner, a
|
||||||
|
friend, could not be present.
|
||||||
|
</Paragraph>
|
||||||
|
</Paragraphs>
|
||||||
|
</PageGroup>
|
||||||
</ExperienceLayout>
|
</ExperienceLayout>
|
||||||
|
|||||||
120
src/pages/hobby/this-website.astro
Normal file
120
src/pages/hobby/this-website.astro
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
---
|
||||||
|
import ExperienceLayout from "@layouts/ExperienceLayout.astro";
|
||||||
|
|
||||||
|
import H3 from "@components/H3.astro";
|
||||||
|
import InlineLink from "@components/InlineLink.astro";
|
||||||
|
import PageGroup from "@components/PageGroup.astro";
|
||||||
|
import Paragraph from "@components/Paragraph.astro";
|
||||||
|
import Paragraphs from "@components/Paragraphs.astro";
|
||||||
|
import PopoverWordDefinition from "@components/PopoverWordDefinition.astro";
|
||||||
|
import SkillMatrix from "@components/SkillMatrix/SkillMatrix.astro";
|
||||||
|
|
||||||
|
import type { categorySkills } from "@interfaces/skill-matrix.ts";
|
||||||
|
|
||||||
|
const categorizedSkills: categorySkills[] = [
|
||||||
|
{
|
||||||
|
category: "Software & Environments",
|
||||||
|
skills: [
|
||||||
|
{
|
||||||
|
item: "DevOps",
|
||||||
|
subItems: [
|
||||||
|
{ item: "Github Actions" },
|
||||||
|
{ item: "dev/staging/production environments" },
|
||||||
|
{ item: "automatic build/test/deploy" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{ item: "Git" },
|
||||||
|
{
|
||||||
|
item: "Docker",
|
||||||
|
subItems: [
|
||||||
|
{ item: "Custom Builds" },
|
||||||
|
{ item: "Registry & Asset Management" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
item: "Programming Languages",
|
||||||
|
subItems: [
|
||||||
|
{ item: "HTML" },
|
||||||
|
{ item: "CSS" },
|
||||||
|
{ item: "Typescript" },
|
||||||
|
{ item: "Bash" },
|
||||||
|
{ item: "Makefile" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
item: "Web Frameworks",
|
||||||
|
subItems: [
|
||||||
|
{ item: "Astro" },
|
||||||
|
{ item: "tailwindcss" },
|
||||||
|
{ item: "flowbite" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
item: "Operating Systems",
|
||||||
|
subItems: [
|
||||||
|
{
|
||||||
|
item: "Linux",
|
||||||
|
subItems: [{ item: "NixOS" }, { item: "Alpine Linux" }],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
---
|
||||||
|
|
||||||
|
<ExperienceLayout title="This Website" subTitles={["Hobbies"]}>
|
||||||
|
<PageGroup>
|
||||||
|
<Fragment slot="header"><H3>Summary</H3></Fragment>
|
||||||
|
|
||||||
|
<Paragraphs>
|
||||||
|
<Paragraph>
|
||||||
|
While I've traditionally used Wordpress to build my websites in the
|
||||||
|
past, I finally decided to make a custom one after developing the skills
|
||||||
|
to do so at <InlineLink
|
||||||
|
href="/experience/spacex/hardware-test-engineer-i-ii"
|
||||||
|
>SpaceX</InlineLink
|
||||||
|
>. I still wouldn't call myself a web developer by trade, but I take
|
||||||
|
great pride in being able to create things on my own, and have also felt
|
||||||
|
that Wordpress was overkill for a simple portfolio website. It also gave
|
||||||
|
me a chance to put my DevOps skills to use at home, which I've been
|
||||||
|
wanting to do for a while.
|
||||||
|
</Paragraph>
|
||||||
|
<Paragraph>
|
||||||
|
The core framework of my website is <InlineLink
|
||||||
|
href="https://astro.build/">Astro</InlineLink
|
||||||
|
>, chosen for its focus on static site generation and de-duplication of
|
||||||
|
code via re-usable <InlineLink
|
||||||
|
href="https://docs.astro.build/en/basics/astro-components/"
|
||||||
|
>components</InlineLink
|
||||||
|
>. This seemed like the perfect middle-ground of providing enough
|
||||||
|
structure and quality-of-life features to reduce the overall effort of
|
||||||
|
building the site, without being overly bloated or opinionated. So far
|
||||||
|
I've been incredibly happy with this decision, and would recommend it to
|
||||||
|
others looking to build static websites. To add some helpful styling
|
||||||
|
utilities, and basic web components, <InlineLink
|
||||||
|
href="https://tailwindcss.com">tailwindcss</InlineLink
|
||||||
|
> and <InlineLink href="https://flowbite.com">flowbite</InlineLink> were also
|
||||||
|
added. Like my decision to use Astro, these both provided good starting points
|
||||||
|
for creating a website that felt like my own, without struggling for too long
|
||||||
|
at the start.
|
||||||
|
</Paragraph>
|
||||||
|
<Paragraph>
|
||||||
|
From the DevOps perspective, I created a Makefile within the repo for
|
||||||
|
local development targets to build, run, and test both in a pure
|
||||||
|
context, and within a Docker container. After pushing updates on a
|
||||||
|
branch to my local Gitea instance, and opening a pull request, the
|
||||||
|
website performs spelling checks, runs unit tests, and integration
|
||||||
|
tests. Once these pass, the website is built into a Docker container and
|
||||||
|
uploaded to the registry in my Gitea instance. The image is then
|
||||||
|
deployed to staging on my <PopoverWordDefinition key="VPS" />, allowing
|
||||||
|
for manual validation of the changes. In order to merge, the build,
|
||||||
|
test, and deploy actions must pass, and ideally I should be empirically
|
||||||
|
validating the staging deployment. After merging and closing the pull
|
||||||
|
request, another action builds, tests, and deploys the main branch in
|
||||||
|
the same way as before, but to production, and is what you see here!
|
||||||
|
</Paragraph>
|
||||||
|
</Paragraphs>
|
||||||
|
<SkillMatrix categorizedSkills={categorizedSkills} />
|
||||||
|
</PageGroup>
|
||||||
|
</ExperienceLayout>
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
import ResumeLayout from "@layouts/ResumeLayout.astro";
|
import ResumeLayout from "@layouts/ResumeLayout.astro";
|
||||||
|
|
||||||
import resume from "@assets/resume/corwin_perren_2025-10-27-infrastructure_engineer.pdf";
|
import resume from "@assets/resume/corwin_perren_2025-10-27_infrastructure_engineer.pdf";
|
||||||
---
|
---
|
||||||
|
|
||||||
<ResumeLayout title="2025-10-27 - Infrastructure Engineer" resume={resume} />
|
<ResumeLayout title="2025-10-27 - Infrastructure Engineer" resume={resume} />
|
||||||
|
|||||||
Reference in New Issue
Block a user