Merge pull request 'Finished ross content, added skill matrix, li, and ul, and improved many existing components, created and refactored to unified layouts and grid, visual improvements with proper column to row collapsing' (#13) from website-content-updates into main
Reviewed-on: #13
This commit was merged in pull request #13.
This commit is contained in:
@@ -1,6 +1,9 @@
|
|||||||
ADCP
|
ADCP
|
||||||
|
Altium
|
||||||
ASSEM
|
ASSEM
|
||||||
astrojs
|
astrojs
|
||||||
|
Atmel
|
||||||
|
barebones
|
||||||
Candian
|
Candian
|
||||||
caperren
|
caperren
|
||||||
CEOAS
|
CEOAS
|
||||||
@@ -10,6 +13,7 @@ CONSERV
|
|||||||
Corwin
|
Corwin
|
||||||
dangerousthings
|
dangerousthings
|
||||||
Dechorionator
|
Dechorionator
|
||||||
|
ebox
|
||||||
fhhs
|
fhhs
|
||||||
flowbite
|
flowbite
|
||||||
HDFS
|
HDFS
|
||||||
@@ -19,10 +23,13 @@ hwupload
|
|||||||
iceops
|
iceops
|
||||||
ITAR
|
ITAR
|
||||||
Jetson
|
Jetson
|
||||||
|
KFSK
|
||||||
leconte
|
leconte
|
||||||
Loctite
|
Loctite
|
||||||
luxon
|
luxon
|
||||||
MGMT
|
MGMT
|
||||||
|
Mokai
|
||||||
|
Multimeters
|
||||||
nixos
|
nixos
|
||||||
offroad
|
offroad
|
||||||
Onshape
|
Onshape
|
||||||
@@ -30,6 +37,7 @@ OSSM
|
|||||||
OSURC
|
OSURC
|
||||||
Perren
|
Perren
|
||||||
Perren's
|
Perren's
|
||||||
|
Pixhawk
|
||||||
pubpath
|
pubpath
|
||||||
RFID
|
RFID
|
||||||
RSSI
|
RSSI
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 1.2 MiB |
@@ -2,4 +2,4 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<h1 class="text-xl font-extrabold md:text-3xl"><slot /></h1>
|
<h1 class="text-xl font-extrabold sm:text-2xl md:text-3xl"><slot /></h1>
|
||||||
|
|||||||
@@ -2,4 +2,4 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<h2 class="my-4 font-bold md:text-2xl"><slot /></h2>
|
<h2 class="text-lg font-bold sm:text-xl md:text-2xl"><slot /></h2>
|
||||||
|
|||||||
@@ -2,4 +2,4 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<h3 class="mt-4 mb-2 font-bold md:text-lg"><slot /></h3>
|
<h3 class="text-md font-semibold sm:text-lg md:text-xl"><slot /></h3>
|
||||||
|
|||||||
9
src/components/Li.astro
Normal file
9
src/components/Li.astro
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<>
|
||||||
|
<li>
|
||||||
|
<slot />
|
||||||
|
</li>
|
||||||
|
</>
|
||||||
@@ -9,10 +9,12 @@ interface Props {
|
|||||||
const { title, href, target = "_blank" } = Astro.props;
|
const { title, href, target = "_blank" } = Astro.props;
|
||||||
---
|
---
|
||||||
|
|
||||||
<a
|
<div class="mx-auto">
|
||||||
class="text-caperren-green border-caperren-green hover:border-caperren-green-light hover:text-caperren-green-light rounded-2xl border-2 bg-black p-2"
|
<a
|
||||||
href={href}
|
class="text-caperren-green border-caperren-green hover:border-caperren-green-light hover:text-caperren-green-light rounded-2xl border-2 bg-black p-2"
|
||||||
target={target}
|
href={href}
|
||||||
>
|
target={target}
|
||||||
{title}
|
>
|
||||||
</a>
|
{title}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ import { Image } from "astro:assets";
|
|||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
<div
|
<div
|
||||||
class="z-40 mt-1 hidden w-full lg:block lg:w-auto"
|
class="z-40 mt-6 hidden w-full lg:mt-0 lg:block lg:w-auto"
|
||||||
id="navbar-multi-level"
|
id="navbar-multi-level"
|
||||||
>
|
>
|
||||||
<NestedNavbarEntry items={siteLayout} />
|
<NestedNavbarEntry items={siteLayout} />
|
||||||
|
|||||||
@@ -19,29 +19,34 @@ const { pathname } = Astro.url;
|
|||||||
---
|
---
|
||||||
|
|
||||||
<ul
|
<ul
|
||||||
class={"flex flex-col p-4 bg-black border-caperren-green " +
|
class:list={[
|
||||||
(depth ? "space-y-2" : "items-start lg:flex-row lg:space-x-8 lg:mt-0 ")}
|
"border-caperren-green flex flex-col space-y-4 space-x-8 bg-black",
|
||||||
|
depth
|
||||||
|
? "space-y-4 py-4"
|
||||||
|
: "items-start lg:mt-0 lg:flex-row lg:space-y-0 lg:space-x-8",
|
||||||
|
]}
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
items.map(
|
items.map(
|
||||||
(entry) =>
|
(entry) =>
|
||||||
(entry.enabled ?? true) && (
|
(entry.enabled ?? true) && (
|
||||||
<li>
|
<li class="">
|
||||||
{Array.isArray(entry.children) && entry.children.length ? (
|
{Array.isArray(entry.children) && entry.children.length ? (
|
||||||
<div
|
<div>
|
||||||
class={
|
|
||||||
pathname.startsWith(getHrefPath(entry))
|
|
||||||
? "border-caperren-green border-b-2"
|
|
||||||
: ""
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<button
|
<button
|
||||||
id={"dropdownNavbarLink" + getNavLinkSuffix(entry)}
|
id={"dropdownNavbarLink" + getNavLinkSuffix(entry)}
|
||||||
data-dropdown-toggle={
|
data-dropdown-toggle={
|
||||||
"dropdownNavbar" + getNavLinkSuffix(entry)
|
"dropdownNavbar" + getNavLinkSuffix(entry)
|
||||||
}
|
}
|
||||||
data-dropdown-placement="bottom"
|
data-dropdown-placement="bottom-start"
|
||||||
class="hover:text-caperren-green-light lg:hover:text-caperren-green-light flex w-full items-center justify-between px-3 py-2 lg:p-0 lg:hover:bg-transparent"
|
data-dropdown-offset-distance="5"
|
||||||
|
data-dropdown-offset-skidding="12"
|
||||||
|
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",
|
||||||
|
pathname.startsWith(getHrefPath(entry))
|
||||||
|
? "border-caperren-green border-b-2"
|
||||||
|
: false,
|
||||||
|
]}
|
||||||
>
|
>
|
||||||
{entry.navText}
|
{entry.navText}
|
||||||
<svg
|
<svg
|
||||||
@@ -61,7 +66,7 @@ const { pathname } = Astro.url;
|
|||||||
</button>
|
</button>
|
||||||
<div
|
<div
|
||||||
id={"dropdownNavbar" + getNavLinkSuffix(entry)}
|
id={"dropdownNavbar" + getNavLinkSuffix(entry)}
|
||||||
class="border-caperren-green z-10 hidden w-screen border bg-black shadow-sm lg:w-max"
|
class="border-caperren-green z-10 hidden w-max max-w-screen border bg-black px-6 shadow-sm"
|
||||||
>
|
>
|
||||||
<Astro.self
|
<Astro.self
|
||||||
items={entry.children}
|
items={entry.children}
|
||||||
@@ -71,17 +76,16 @@ const { pathname } = Astro.url;
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div
|
<div>
|
||||||
class={
|
|
||||||
pathname === getHrefPath(entry)
|
|
||||||
? "border-caperren-green border-b-2"
|
|
||||||
: ""
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<a
|
<a
|
||||||
href={getHrefPath(entry)}
|
href={getHrefPath(entry)}
|
||||||
target={getHrefPath(entry).startsWith("/") ? "" : "_blank"}
|
target={getHrefPath(entry).startsWith("/") ? "" : "_blank"}
|
||||||
class="hover:text-caperren-green-light ring-caperren-green-dark block bg-transparent px-3 py-2 lg:p-0"
|
class:list={[
|
||||||
|
"hover:text-caperren-green-light ring-caperren-green-dark block bg-transparent lg:p-0",
|
||||||
|
pathname === getHrefPath(entry)
|
||||||
|
? "border-caperren-green border-b-2"
|
||||||
|
: false,
|
||||||
|
]}
|
||||||
aria-current={
|
aria-current={
|
||||||
pathname === getHrefPath(entry) ? "page" : undefined
|
pathname === getHrefPath(entry) ? "page" : undefined
|
||||||
}
|
}
|
||||||
|
|||||||
36
src/components/Ol.astro
Normal file
36
src/components/Ol.astro
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
---
|
||||||
|
import Li from "@components/Li.astro";
|
||||||
|
import type { ComponentPropsBase } from "@interfaces/components.ts";
|
||||||
|
|
||||||
|
import type { lineItem } from "@interfaces/ul-li.ts";
|
||||||
|
|
||||||
|
interface Props extends ComponentPropsBase {
|
||||||
|
lineItems?: lineItem[];
|
||||||
|
depth?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { class: className, lineItems, depth = 0 } = Astro.props;
|
||||||
|
---
|
||||||
|
|
||||||
|
<ol
|
||||||
|
class:list={["list-inside list-disc", className, depth > 0 ? "ps-3" : false]}
|
||||||
|
>
|
||||||
|
{
|
||||||
|
lineItems ? (
|
||||||
|
lineItems.map((line) => (
|
||||||
|
<Li>
|
||||||
|
{line.item}
|
||||||
|
{line.subItems ? (
|
||||||
|
<Astro.self
|
||||||
|
class={className}
|
||||||
|
lineItems={line.subItems}
|
||||||
|
depth={depth + 1}
|
||||||
|
/>
|
||||||
|
) : undefined}
|
||||||
|
</Li>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<slot />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</ol>
|
||||||
21
src/components/PageGroup.astro
Normal file
21
src/components/PageGroup.astro
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
---
|
||||||
|
const hasHeader = Astro.slots.has("header");
|
||||||
|
const hasDefault = Astro.slots.has("default");
|
||||||
|
---
|
||||||
|
|
||||||
|
<div class="grid grid-cols-1 gap-3">
|
||||||
|
{
|
||||||
|
Astro.slots.has("header") && (
|
||||||
|
<div>
|
||||||
|
<slot name="header" />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Astro.slots.has("default") && (
|
||||||
|
<div class="grid grid-cols-1 gap-3">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</div>
|
||||||
@@ -1,7 +1,13 @@
|
|||||||
---
|
---
|
||||||
|
import type { ComponentPropsBase } from "@interfaces/components.ts";
|
||||||
|
|
||||||
|
interface Props extends ComponentPropsBase {
|
||||||
|
initialTab?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { class: className, initialTab = true } = Astro.props;
|
||||||
|
---
|
||||||
|
|
||||||
---
|
<div class:list={className}>
|
||||||
|
{initialTab && <> </>}<slot />
|
||||||
<div class="">
|
|
||||||
<slot />
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,6 +2,6 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<div class="space-y-2">
|
<div class="grid grid-cols-1 gap-2">
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -7,6 +7,10 @@ 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",
|
||||||
|
GUI: "Graphical user interface",
|
||||||
|
NUC: "A small and low-power computer made by Intel",
|
||||||
|
PCBs: "Printed circuit boards",
|
||||||
|
UPS: "Uninterruptible power supply",
|
||||||
};
|
};
|
||||||
|
|
||||||
const key: string | undefined = Astro.props.key;
|
const key: string | undefined = Astro.props.key;
|
||||||
|
|||||||
30
src/components/SkillMatrix/SkillMatrix.astro
Normal file
30
src/components/SkillMatrix/SkillMatrix.astro
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
---
|
||||||
|
import H3 from "@components/H3.astro";
|
||||||
|
import PageGroup from "@components/PageGroup.astro";
|
||||||
|
import Ul from "@components/Ul.astro";
|
||||||
|
|
||||||
|
import type { categorySkills } from "@interfaces/skill-matrix.ts";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
categorizedSkills: categorySkills[];
|
||||||
|
}
|
||||||
|
|
||||||
|
const { categorizedSkills } = Astro.props;
|
||||||
|
---
|
||||||
|
|
||||||
|
<PageGroup>
|
||||||
|
<Fragment slot="header"><H3>Relevant Skills</H3></Fragment>
|
||||||
|
<div
|
||||||
|
class="border-caperren-green grid grid-flow-row gap-6 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4"
|
||||||
|
>
|
||||||
|
{
|
||||||
|
categorizedSkills.map((categorySkills) => (
|
||||||
|
<div>
|
||||||
|
<div class="text-sm font-extrabold">{categorySkills.category}</div>
|
||||||
|
<hr class="text-caperren-green" />
|
||||||
|
<Ul class="text-sm" lineItems={categorySkills.skills} />
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</PageGroup>
|
||||||
36
src/components/Ul.astro
Normal file
36
src/components/Ul.astro
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
---
|
||||||
|
import Li from "@components/Li.astro";
|
||||||
|
import type { ComponentPropsBase } from "@interfaces/components.ts";
|
||||||
|
|
||||||
|
import type { lineItem } from "@interfaces/ul-li.ts";
|
||||||
|
|
||||||
|
interface Props extends ComponentPropsBase {
|
||||||
|
lineItems?: lineItem[];
|
||||||
|
depth?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { class: className, lineItems, depth = 0 } = Astro.props;
|
||||||
|
---
|
||||||
|
|
||||||
|
<ul
|
||||||
|
class:list={["list-inside list-disc", className, depth > 0 ? "ps-3" : false]}
|
||||||
|
>
|
||||||
|
{
|
||||||
|
lineItems ? (
|
||||||
|
lineItems.map((line) => (
|
||||||
|
<Li>
|
||||||
|
{line.item}
|
||||||
|
{line.subItems ? (
|
||||||
|
<Astro.self
|
||||||
|
class={className}
|
||||||
|
lineItems={line.subItems}
|
||||||
|
depth={depth + 1}
|
||||||
|
/>
|
||||||
|
) : undefined}
|
||||||
|
</Li>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<slot />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
@@ -4,7 +4,7 @@ export const siteLayout: navLink[] = [
|
|||||||
{ navText: "About", path: "" },
|
{ navText: "About", path: "" },
|
||||||
{ navText: "Education", path: "education" },
|
{ navText: "Education", path: "education" },
|
||||||
{
|
{
|
||||||
navText: "Experiences",
|
navText: "Experience",
|
||||||
path: "experience",
|
path: "experience",
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
@@ -29,7 +29,6 @@ export const siteLayout: navLink[] = [
|
|||||||
path: "osu-ceoas-ocean-mixing-group",
|
path: "osu-ceoas-ocean-mixing-group",
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
enabled: false,
|
|
||||||
navText: "Robotics Oceanographic Surface Sampler",
|
navText: "Robotics Oceanographic Surface Sampler",
|
||||||
path: "robotic-oceanographic-surface-sampler",
|
path: "robotic-oceanographic-surface-sampler",
|
||||||
},
|
},
|
||||||
|
|||||||
6
src/interfaces/skill-matrix.ts
Normal file
6
src/interfaces/skill-matrix.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import type { lineItem } from "@interfaces/ul-li.ts";
|
||||||
|
|
||||||
|
export interface categorySkills {
|
||||||
|
category: string;
|
||||||
|
skills: lineItem[];
|
||||||
|
}
|
||||||
4
src/interfaces/ul-li.ts
Normal file
4
src/interfaces/ul-li.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
export interface lineItem {
|
||||||
|
item: string;
|
||||||
|
subItems?: lineItem[];
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ import "@styles/global.css";
|
|||||||
import Footer from "@components/Footer.astro";
|
import Footer from "@components/Footer.astro";
|
||||||
import H1 from "@components/H1.astro";
|
import H1 from "@components/H1.astro";
|
||||||
import Navbar from "@components/Navbar.astro";
|
import Navbar from "@components/Navbar.astro";
|
||||||
|
import PageGroup from "@components/PageGroup.astro";
|
||||||
|
|
||||||
import { pathToMetadata } from "@data/site-layout.ts";
|
import { pathToMetadata } from "@data/site-layout.ts";
|
||||||
|
|
||||||
@@ -39,28 +40,32 @@ const pageEnabled = pathToMetadata(Astro.url.pathname).enabled ?? true;
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>{pageEnabled ? pageTitle : "Corwin Perren"}</title>
|
<title>{pageEnabled ? pageTitle : "Corwin Perren"}</title>
|
||||||
</head>
|
</head>
|
||||||
<body class="flex h-dvh w-full max-w-full flex-col bg-black text-white">
|
<body
|
||||||
|
class="grid h-dvh w-full max-w-full grid-cols-1 gap-0 bg-black text-white"
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
id="content-body-scrolling"
|
id="content-body-scrolling"
|
||||||
class="grow overflow-x-hidden overflow-y-scroll"
|
class="grow overflow-x-hidden overflow-y-scroll"
|
||||||
>
|
>
|
||||||
<Navbar />
|
<Navbar />
|
||||||
<main class="mx-6 my-6">
|
<main class="mx-6 my-2">
|
||||||
<div class="mb-2 md:mb-6">
|
{
|
||||||
{
|
showTitle && pageEnabled && (
|
||||||
title && showTitle && pageEnabled && (
|
<PageGroup>
|
||||||
<H1 bottomMargin={!subTitles}>{title}</H1>
|
<Fragment slot="header">
|
||||||
)
|
<div class="leading-3">
|
||||||
}
|
<H1>{title}</H1>
|
||||||
{
|
{subTitles?.map((subTitle) => (
|
||||||
showTitle &&
|
<p class="md:text-md text-sm font-bold italic">
|
||||||
pageEnabled &&
|
{subTitle}
|
||||||
subTitles?.map((subTitle) => (
|
</p>
|
||||||
<p class="text-sm font-bold md:text-xl">{subTitle}</p>
|
))}
|
||||||
))
|
</div>
|
||||||
}
|
</Fragment>
|
||||||
</div>
|
</PageGroup>
|
||||||
<div>
|
)
|
||||||
|
}
|
||||||
|
<div class="grid grid-cols-1 gap-4">
|
||||||
{pageEnabled ? <slot /> : <H1>Under Construction</H1>}
|
{pageEnabled ? <slot /> : <H1>Under Construction</H1>}
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
---
|
---
|
||||||
import PdfViewer from "@components/Media/PdfViewer.astro";
|
|
||||||
import BaseLayout from "@layouts/BaseLayout.astro";
|
import BaseLayout from "@layouts/BaseLayout.astro";
|
||||||
|
|
||||||
|
import PdfViewer from "@components/Media/PdfViewer.astro";
|
||||||
---
|
---
|
||||||
|
|
||||||
<BaseLayout {...Astro.props}>
|
<BaseLayout {...Astro.props}>
|
||||||
<div class="h-dvh">
|
<div class="mt-2 h-dvh">
|
||||||
<PdfViewer class="mx-auto" pdf={Astro.props.resume} />
|
<PdfViewer pdf={Astro.props.resume} />
|
||||||
</div>
|
</div>
|
||||||
</BaseLayout>
|
</BaseLayout>
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import H2 from "@components/H2.astro";
|
|||||||
import H3 from "@components/H3.astro";
|
import H3 from "@components/H3.astro";
|
||||||
import InlineLink from "@components/InlineLink.astro";
|
import InlineLink from "@components/InlineLink.astro";
|
||||||
import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro";
|
import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro";
|
||||||
|
import PageGroup from "@components/PageGroup.astro";
|
||||||
import Table from "@components/Table.astro";
|
import Table from "@components/Table.astro";
|
||||||
import Timeline from "@components/Timeline/Timeline.astro";
|
import Timeline from "@components/Timeline/Timeline.astro";
|
||||||
|
|
||||||
@@ -108,16 +109,24 @@ const courseTable: tableData = {
|
|||||||
|
|
||||||
<BaseLayout title="Education">
|
<BaseLayout title="Education">
|
||||||
<Carousel carouselGroup={diplomaCarouselGroup} />
|
<Carousel carouselGroup={diplomaCarouselGroup} />
|
||||||
<H2>Timeline</H2>
|
<PageGroup>
|
||||||
<Timeline timeline={timeline} />
|
<Fragment slot="header"><H2>Timeline</H2></Fragment>
|
||||||
<H2>Oregon State University</H2>
|
<Timeline timeline={timeline} />
|
||||||
<H3>
|
</PageGroup>
|
||||||
<InlineLink
|
<PageGroup>
|
||||||
class="font-bold md:text-lg"
|
<Fragment slot="header"><H2>Oregon State University</H2></Fragment>
|
||||||
href="https://github.com/caperren/school_archives/tree/master/OSU%20Coursework"
|
<PageGroup>
|
||||||
>Coursework Archives</InlineLink
|
<Fragment slot="header">
|
||||||
>
|
<InlineLink
|
||||||
</H3>
|
class="font-bold md:text-lg"
|
||||||
<H3>Course Listing</H3>
|
href="https://github.com/caperren/school_archives/tree/master/OSU%20Coursework"
|
||||||
<Table data={courseTable} />
|
><H3>Coursework Archives</H3></InlineLink
|
||||||
|
>
|
||||||
|
</Fragment>
|
||||||
|
</PageGroup>
|
||||||
|
<PageGroup>
|
||||||
|
<Fragment slot="header"><H3>Course Listing</H3></Fragment>
|
||||||
|
<Table data={courseTable} />
|
||||||
|
</PageGroup>
|
||||||
|
</PageGroup>
|
||||||
</BaseLayout>
|
</BaseLayout>
|
||||||
|
|||||||
@@ -3,8 +3,13 @@ import ExperienceLayout from "@layouts/ExperienceLayout.astro";
|
|||||||
|
|
||||||
import H2 from "@components/H2.astro";
|
import H2 from "@components/H2.astro";
|
||||||
import H3 from "@components/H3.astro";
|
import H3 from "@components/H3.astro";
|
||||||
|
import InlineLink from "@components/InlineLink.astro";
|
||||||
import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro";
|
import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro";
|
||||||
|
import Video from "@components/Media/Video.astro";
|
||||||
|
import PageGroup from "@components/PageGroup.astro";
|
||||||
import Paragraph from "@components/Paragraph.astro";
|
import Paragraph from "@components/Paragraph.astro";
|
||||||
|
import Paragraphs from "@components/Paragraphs.astro";
|
||||||
|
import PopoverWordDefinition from "@components/PopoverWordDefinition.astro";
|
||||||
import Timeline from "@components/Timeline/Timeline.astro";
|
import Timeline from "@components/Timeline/Timeline.astro";
|
||||||
|
|
||||||
import type { carouselGroup } from "@interfaces/image-carousel.ts";
|
import type { carouselGroup } from "@interfaces/image-carousel.ts";
|
||||||
@@ -56,83 +61,89 @@ const headerCarouselGroup: carouselGroup = {
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
import InlineLink from "@components/InlineLink.astro";
|
|
||||||
import Video from "@components/Media/Video.astro";
|
|
||||||
import Paragraphs from "@components/Paragraphs.astro";
|
|
||||||
import PopoverWordDefinition from "@components/PopoverWordDefinition.astro";
|
|
||||||
import { subTitles } from "./osu-ceoas-ocean-mixing-group.ts";
|
import { subTitles } from "./osu-ceoas-ocean-mixing-group.ts";
|
||||||
---
|
---
|
||||||
|
|
||||||
<ExperienceLayout title="LeConte Glacier Deployments" subTitles={subTitles}>
|
<ExperienceLayout title="LeConte Glacier Deployments" subTitles={subTitles}>
|
||||||
<Carousel carouselGroup={headerCarouselGroup} />
|
<Carousel carouselGroup={headerCarouselGroup} />
|
||||||
<H2>Summary</H2>
|
<PageGroup>
|
||||||
<H3>Timeline</H3>
|
<Fragment slot="header"><H2>Summary</H2></Fragment>
|
||||||
<Timeline timeline={deploymentTimeline} />
|
<PageGroup>
|
||||||
<H3>Location</H3>
|
<Fragment slot="header"><H3>Timeline</H3></Fragment>
|
||||||
<iframe
|
<Timeline timeline={deploymentTimeline} />
|
||||||
class="w-full"
|
</PageGroup>
|
||||||
width="600"
|
<PageGroup>
|
||||||
height="450"
|
<Fragment slot="header"><H3>Location</H3></Fragment>
|
||||||
src="https://maps.google.com/maps?q=leconte%20glacier&t=k&z=11&ie=UTF8&iwloc=B&output=embed"
|
<iframe
|
||||||
></iframe>
|
class="w-full"
|
||||||
<H2>Details</H2>
|
width="600"
|
||||||
<Paragraphs>
|
height="450"
|
||||||
<Paragraph>
|
src="https://maps.google.com/maps?q=leconte%20glacier&t=k&z=11&ie=UTF8&iwloc=B&output=embed"
|
||||||
As part of my time working on the
|
></iframe>
|
||||||
<InlineLink
|
</PageGroup>
|
||||||
href="/experience/osu-ceoas-ocean-mixing-group/robotic-oceanographic-surface-sampler"
|
</PageGroup>
|
||||||
>
|
<PageGroup>
|
||||||
Robotic Oceanographic Surface Sampler</InlineLink
|
<Fragment slot="header"><H2>Details</H2></Fragment>
|
||||||
>, I had the fantastic opportunity to be deployed at the LeConte Glacier
|
<Paragraphs>
|
||||||
in Alaska! This started in early 2017 with setup and ocean trials in
|
<Paragraph>
|
||||||
nearby Petersburg. The team had sent multiple shipping containers with our
|
As part of my time working on the
|
||||||
robotic platforms and most equipment to assemble, test, and debug them a
|
<InlineLink
|
||||||
few months prior, allowing us to get to work the moment we arrived. We
|
href="/experience/osu-ceoas-ocean-mixing-group/robotic-oceanographic-surface-sampler"
|
||||||
spent multiple weeks at the docks with our makeshift workstations built
|
>
|
||||||
from plywood and pelican cases, validating the hardware we'd sent, and
|
Robotic Oceanographic Surface Sampler</InlineLink
|
||||||
making adjustments with improved hardware we'd hand-carried on our
|
>, I had the fantastic opportunity to be deployed at the LeConte Glacier
|
||||||
flights. This also provided a great opportunity to work out any final
|
in Alaska! This started in early 2017 with setup and ocean trials in
|
||||||
firmware and/or software bugs while the vehicles were still relatively
|
nearby Petersburg. The team had sent multiple shipping containers with
|
||||||
easy to retrieve. After a short trip back home to recover, and prep any
|
our robotic platforms and most equipment to assemble, test, and debug
|
||||||
last minute items we'd forgotten, our research team flew back and headed
|
them a few months prior, allowing us to get to work the moment we
|
||||||
for the glacier!
|
arrived. We spent multiple weeks at the docks with our makeshift
|
||||||
</Paragraph>
|
workstations built from plywood and pelican cases, validating the
|
||||||
<Paragraph>
|
hardware we'd sent, and making adjustments with improved hardware we'd
|
||||||
The towering mountain of ice sits roughly 30 miles from Petersburg, so
|
hand-carried on our flights. This also provided a great opportunity to
|
||||||
we'd commissioned an off-season fishing vessel, Steller, and it's crew, to
|
work out any final firmware and/or software bugs while the vehicles were
|
||||||
take us as close to it as was reasonably safe. The team worked 24 hours a
|
still relatively easy to retrieve. After a short trip back home to
|
||||||
day, on two shifts, deploying and retrieving the ROSS platforms,
|
recover, and prep any last minute items we'd forgotten, our research
|
||||||
performing repairs (as needed), recovering/processing collected data,
|
team flew back and headed for the glacier!
|
||||||
manually deploying the ship's <PopoverWordDefinition key="CTD" />, and
|
</Paragraph>
|
||||||
occasionally spending considerable time pushing icebergs the size of
|
<Paragraph>
|
||||||
houses away from an <PopoverWordDefinition key="ADCP" /> mounted to Steller
|
The towering mountain of ice sits roughly 30 miles from Petersburg, so
|
||||||
using fiberglass poles. Many hardware failures had to be solved during these
|
we'd commissioned an off-season fishing vessel, Steller, and it's crew,
|
||||||
long days, and it was a very rewarding and creative experience to work around
|
to take us as close to it as was reasonably safe. The team worked 24
|
||||||
the limitations of this isolated (and salty) environment.
|
hours a day, on two shifts, deploying and retrieving the ROSS platforms,
|
||||||
</Paragraph>
|
performing repairs (as needed), recovering/processing collected data,
|
||||||
<Paragraph>
|
manually deploying the ship's <PopoverWordDefinition key="CTD" />, and
|
||||||
On top of being a unique engineering and team building experience, LeConte
|
occasionally spending considerable time pushing icebergs the size of
|
||||||
lives among the most beautiful places I've yet to experience in this life.
|
houses away from an <PopoverWordDefinition key="ADCP" /> mounted to Steller
|
||||||
There's something special about being somewhere so incredibly remote and
|
using fiberglass poles. Many hardware failures had to be solved during these
|
||||||
untouched by humans. The pristine evergreen forests, eerie blue-green hues
|
long days, and it was a very rewarding and creative experience to work around
|
||||||
of the glacier and icebergs, ancient towering mountains, and genuinely
|
the limitations of this isolated (and salty) environment.
|
||||||
curious looks from local land and marine life unfamiliar with human
|
</Paragraph>
|
||||||
presence made it humbly clear that for once we as humans were the odd ones
|
<Paragraph>
|
||||||
out. These trips were ones that I will treasure and think back on fondly
|
On top of being a unique engineering and team building experience,
|
||||||
on for the rest of my life.
|
LeConte lives among the most beautiful places I've yet to experience in
|
||||||
</Paragraph>
|
this life. There's something special about being somewhere so incredibly
|
||||||
</Paragraphs>
|
remote and untouched by humans. The pristine evergreen forests, eerie
|
||||||
<H2>Videos</H2>
|
blue-green hues of the glacier and icebergs, ancient towering mountains,
|
||||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
and genuinely curious looks from local land and marine life unfamiliar
|
||||||
{
|
with human presence made it humbly clear that for once we as humans were
|
||||||
videos.map((video) => (
|
the odd ones out. These trips were ones that I will treasure and think
|
||||||
<Video
|
back on fondly on for the rest of my life.
|
||||||
videoPath={video}
|
</Paragraph>
|
||||||
autoPlay={true}
|
</Paragraphs>
|
||||||
loop={true}
|
</PageGroup>
|
||||||
playsInline={true}
|
<PageGroup>
|
||||||
/>
|
<Fragment slot="header"><H2>Videos</H2></Fragment>
|
||||||
))
|
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||||
}
|
{
|
||||||
</div>
|
videos.map((video) => (
|
||||||
|
<Video
|
||||||
|
videoPath={video}
|
||||||
|
autoPlay={true}
|
||||||
|
loop={true}
|
||||||
|
playsInline={true}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</PageGroup>
|
||||||
</ExperienceLayout>
|
</ExperienceLayout>
|
||||||
|
|||||||
@@ -26,4 +26,5 @@ export const deploymentTimeline: timelineEntry[] = [
|
|||||||
export const subTitles = [
|
export const subTitles = [
|
||||||
"Oregon State University",
|
"Oregon State University",
|
||||||
"College of Earth, Ocean, and Atmospheric Sciences",
|
"College of Earth, Ocean, and Atmospheric Sciences",
|
||||||
|
"Ocean Mixing Group",
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -3,17 +3,26 @@ import ExperienceLayout from "@layouts/ExperienceLayout.astro";
|
|||||||
|
|
||||||
import H2 from "@components/H2.astro";
|
import H2 from "@components/H2.astro";
|
||||||
import H3 from "@components/H3.astro";
|
import H3 from "@components/H3.astro";
|
||||||
|
import InlineLink from "@components/InlineLink.astro";
|
||||||
|
import Li from "@components/Li.astro";
|
||||||
import LinkButton from "@components/LinkButton.astro";
|
import LinkButton from "@components/LinkButton.astro";
|
||||||
import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro";
|
import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro";
|
||||||
import PdfViewer from "@components/Media/PdfViewer.astro";
|
import PdfViewer from "@components/Media/PdfViewer.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 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 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";
|
||||||
|
|
||||||
import electronics_box from "@assets/experience/osu-ceoas-ocean-mixing-group/robotic-oceanographic-surface-sampler/electronics-box.jpg";
|
import electronics_box from "@assets/experience/osu-ceoas-ocean-mixing-group/robotic-oceanographic-surface-sampler/electronics-box.jpg";
|
||||||
import jet_drive from "@assets/experience/osu-ceoas-ocean-mixing-group/robotic-oceanographic-surface-sampler/jet-drive.jpg";
|
import jet_drive from "@assets/experience/osu-ceoas-ocean-mixing-group/robotic-oceanographic-surface-sampler/jet-drive.jpg";
|
||||||
|
import ross_ebox_4p0 from "@assets/experience/osu-ceoas-ocean-mixing-group/robotic-oceanographic-surface-sampler/ross-ebox-4p0.jpg";
|
||||||
import ross_on_vessel_at_night from "@assets/experience/osu-ceoas-ocean-mixing-group/robotic-oceanographic-surface-sampler/ross-on-vessel-at-night.jpg";
|
import ross_on_vessel_at_night from "@assets/experience/osu-ceoas-ocean-mixing-group/robotic-oceanographic-surface-sampler/ross-on-vessel-at-night.jpg";
|
||||||
import ross_on_vessel from "@assets/experience/osu-ceoas-ocean-mixing-group/robotic-oceanographic-surface-sampler/ross-on-vessel.jpg";
|
import ross_on_vessel from "@assets/experience/osu-ceoas-ocean-mixing-group/robotic-oceanographic-surface-sampler/ross-on-vessel.jpg";
|
||||||
import publication from "@assets/experience/osu-ceoas-ocean-mixing-group/robotic-oceanographic-surface-sampler/ross-publication.pdf";
|
import publication from "@assets/experience/osu-ceoas-ocean-mixing-group/robotic-oceanographic-surface-sampler/ross-publication.pdf";
|
||||||
@@ -31,6 +40,7 @@ const headerCarouselGroup: carouselGroup = {
|
|||||||
ross_team,
|
ross_team,
|
||||||
ross_on_vessel,
|
ross_on_vessel,
|
||||||
ross_on_vessel_at_night,
|
ross_on_vessel_at_night,
|
||||||
|
ross_ebox_4p0,
|
||||||
electronics_box,
|
electronics_box,
|
||||||
jet_drive,
|
jet_drive,
|
||||||
ui,
|
ui,
|
||||||
@@ -50,6 +60,72 @@ const timeline: timelineEntry[] = [
|
|||||||
date: "May 2018",
|
date: "May 2018",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const categorizedSkills: categorySkills[] = [
|
||||||
|
{
|
||||||
|
category: "Electrical",
|
||||||
|
skills: [
|
||||||
|
{
|
||||||
|
item: "Schematic & PCB Design",
|
||||||
|
subItems: [{ item: "Altium Designer" }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
item: "PCB Assembly & Rework",
|
||||||
|
subItems: [
|
||||||
|
{ item: "Handheld Soldering" },
|
||||||
|
{ item: "Handheld Hot-Air Reflow" },
|
||||||
|
{ item: "Oven Reflow" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
item: "Electrical Diagnostics",
|
||||||
|
subItems: [
|
||||||
|
{ item: "Multimeters" },
|
||||||
|
{ item: "Oscilloscopes" },
|
||||||
|
{ item: "Logic Analyzers" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
item: "Harnessing Fabrication",
|
||||||
|
subItems: [
|
||||||
|
{ item: "DC Power & Signal" },
|
||||||
|
{ item: "Low Frequency RF (<1GHz)" },
|
||||||
|
{ item: "Waterproofing" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
item: "Simulation",
|
||||||
|
subItems: [{ item: "LTspice" }],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
category: "Software & Environments",
|
||||||
|
skills: [
|
||||||
|
{ item: "Git" },
|
||||||
|
{
|
||||||
|
item: "Programming Languages",
|
||||||
|
subItems: [
|
||||||
|
{ item: "Python 2/3" },
|
||||||
|
{ item: "Bash Shell Scripting" },
|
||||||
|
{ item: "Low-Level Embedded C/C++ (Atmel Studio)" },
|
||||||
|
{ item: "High-Level Embedded C/C++ (Arduino/Teensy)" },
|
||||||
|
{ item: "Matlab" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
item: "Operating Systems",
|
||||||
|
subItems: [
|
||||||
|
{
|
||||||
|
item: "Linux",
|
||||||
|
subItems: [{ item: "Ubuntu" }, { item: "Raspbian" }],
|
||||||
|
},
|
||||||
|
{ item: "Microsoft Windows" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
---
|
---
|
||||||
|
|
||||||
<ExperienceLayout
|
<ExperienceLayout
|
||||||
@@ -57,56 +133,158 @@ const timeline: timelineEntry[] = [
|
|||||||
subTitles={subTitles}
|
subTitles={subTitles}
|
||||||
>
|
>
|
||||||
<Carousel carouselGroup={headerCarouselGroup} />
|
<Carousel carouselGroup={headerCarouselGroup} />
|
||||||
<div class="mt-4 flex items-center justify-center">
|
<div class="grid grid-flow-row place-content-center gap-4 md:grid-flow-col">
|
||||||
<LinkButton
|
<LinkButton
|
||||||
href="https://tos.org/oceanography/article/autonomous-ctd-profiling-from-the-robotic-oceanographic-surface-sampler"
|
href="https://tos.org/oceanography/article/autonomous-ctd-profiling-from-the-robotic-oceanographic-surface-sampler"
|
||||||
title="Official Scientific Publication"
|
title="Official Scientific Publication"
|
||||||
/>
|
/>
|
||||||
|
<LinkButton
|
||||||
|
href="https://www.kfsk.org/2017/04/19/remote-controlled-kayaks-ready-research-leconte-glacier/"
|
||||||
|
title="KFSK Petersburg Feature / Interview"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<H2>Summary</H2>
|
<PageGroup>
|
||||||
<H3>Timeline</H3>
|
<Fragment slot="header"><H2>Summary</H2></Fragment>
|
||||||
<Timeline timeline={timeline} />
|
<PageGroup>
|
||||||
<H3>Key Takeaways</H3>
|
<Fragment slot="header"><H3>Timeline</H3></Fragment>
|
||||||
<ul class="list-inside list-disc">
|
<Timeline timeline={timeline} />
|
||||||
<li>
|
</PageGroup>
|
||||||
<div class="inline-block">
|
<PageGroup>
|
||||||
Assembled, fabricated, and debugged both custom and
|
<Fragment slot="header"><H3>Key Takeaways</H3></Fragment>
|
||||||
<PopoverWordDefinition key="COTS" />
|
<Ul>
|
||||||
hardware and electronics.
|
<Li
|
||||||
</div>
|
>Hand assembled and validated dozens of custom <PopoverWordDefinition
|
||||||
</li>
|
key="PCBs"
|
||||||
<li>Two</li>
|
/>, wiring harnesses, and electronics boxes</Li
|
||||||
<li>Three</li>
|
>
|
||||||
</ul>
|
<Li
|
||||||
<h3 class="my-4 font-bold md:text-lg">Skills Used</h3>
|
>Wrote, debugged, and assisted with development of embedded firmware</Li
|
||||||
<div
|
>
|
||||||
class="border-caperren-green relative grid grid-flow-row gap-6 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4"
|
<Li
|
||||||
>
|
>Accompanied the team on two deployments to the LeConte glacier in
|
||||||
<div>
|
Alaska to gather ice-water melt and mixing data</Li
|
||||||
<div class="text-sm font-extrabold">Software</div>
|
>
|
||||||
<hr class="text-caperren-green" />
|
</Ul>
|
||||||
<ul class="list-inside list-disc text-sm">
|
</PageGroup>
|
||||||
<li>One</li>
|
<SkillMatrix categorizedSkills={categorizedSkills} />
|
||||||
<li>Two</li>
|
</PageGroup>
|
||||||
</ul>
|
<PageGroup>
|
||||||
|
<Fragment slot="header"><H2>Details</H2></Fragment>
|
||||||
|
<PageGroup>
|
||||||
|
<Fragment slot="header"><H3>ROSS Overview</H3></Fragment>
|
||||||
|
<Paragraphs>
|
||||||
|
<Paragraph>
|
||||||
|
ROSS was a gasoline-powered water-sampling robotics platform built
|
||||||
|
around a Mokai jet-drive kayak. It's purpose was to continuously, and
|
||||||
|
often autonomously, gather water data over extremely long distances
|
||||||
|
and/or in locations where human-safety concerns would make gathering
|
||||||
|
it manually too risky. There were a variety of sensors it could be
|
||||||
|
outfitted with depending on the needs of the exact research project
|
||||||
|
and destination, but some common ones were an <PopoverWordDefinition
|
||||||
|
key="ADCP"
|
||||||
|
/> for gathering 3D water current vector data, a <PopoverWordDefinition
|
||||||
|
key="CTD"
|
||||||
|
/> for measuring water conductivity/temperature/depth, and a high-precision
|
||||||
|
GPS for generating meaningful 3D plots of the sensor data. These kayaks
|
||||||
|
have been deployed to places like the Indian/Pacific Ocean mixing line,
|
||||||
|
and along the active LeConte glacier terminus in Alaska, gathering novel
|
||||||
|
data on how vastly different bodies of water act when mixing.
|
||||||
|
</Paragraph>
|
||||||
|
<Paragraph>
|
||||||
|
In its original configuration, the Mokai kayak's throttle and steering
|
||||||
|
were already drive-by-wire, which made it an excellent starting point
|
||||||
|
for automating. It was also designed for easy transport, breaking down
|
||||||
|
into three major compartments that could easily fit in the back of a
|
||||||
|
short-bed pickup. For our custom hulls, Mokai also thickened the
|
||||||
|
plastic significantly and provided a bare minimum of electronics. This
|
||||||
|
barebones platform was then modified by our team to include a
|
||||||
|
storm-surge-rated intake and exhaust for the engine, a keel to improve
|
||||||
|
rough sea stability, a large alternator, and a plethora of mount
|
||||||
|
points the electronics, batteries, fuel, sensors, and radios.
|
||||||
|
</Paragraph>
|
||||||
|
<Paragraph>
|
||||||
|
In terms of the electronics and software for this project, the kayak
|
||||||
|
itself was centered around a Pixhawk flight controller flashed with a
|
||||||
|
modified Rover variant (this was before a dedicated boat option
|
||||||
|
existed). One pelican-case electronics box housed this controller, a
|
||||||
|
small <PopoverWordDefinition key="NUC" /> with <PopoverWordDefinition
|
||||||
|
key="UPS"
|
||||||
|
/>, wifi router, radio control receiver, satellite modem, and quite a
|
||||||
|
few custom <PopoverWordDefinition key="PCBs" /> for interfacing with external
|
||||||
|
electronics and implementing glue logic/safety overrides. A second box housed
|
||||||
|
nothing but sealed lead-acid batteries, which were charged by the alternator
|
||||||
|
on later revisions of the platform. The PC ran a custom python script, which
|
||||||
|
interfaced with a Matlab GUI over a remote radio link. The kayak could also
|
||||||
|
be overridden with an FrSky RC controller, when at close range, and additionally
|
||||||
|
allowed for direct control without the PC needing to be in-the-loop. To
|
||||||
|
see some of the custom hardware inside of these boxes, check out Nick McComb's
|
||||||
|
design pages for them
|
||||||
|
<InlineLink
|
||||||
|
href="https://nickmccomb.net/college/printed-circuit-boards#omg"
|
||||||
|
>here</InlineLink
|
||||||
|
>! For even more context on ROSS, and history from before I joined the
|
||||||
|
project, check out his <InlineLink
|
||||||
|
href="https://nickmccomb.net/college/ross">summary page</InlineLink
|
||||||
|
>.
|
||||||
|
</Paragraph>
|
||||||
|
</Paragraphs>
|
||||||
|
</PageGroup>
|
||||||
|
<PageGroup>
|
||||||
|
<Fragment slot="header"><H3>My Experience</H3></Fragment>
|
||||||
|
<Paragraphs>
|
||||||
|
<Paragraph>
|
||||||
|
I first started on this project by doing what I thought was a one-off
|
||||||
|
help session for Nick, working on an issue he was having getting
|
||||||
|
ROSS's engine to start and shut down properly. I had more experience
|
||||||
|
with engines, and engine control, so I quickly realized that a beefier
|
||||||
|
and high-voltage-rated relay was needed to avoid arc-welding the
|
||||||
|
contacts closed during shutdown. He rolled out a <InlineLink
|
||||||
|
href="https://nickmccomb.net/college/printed-circuit-boards/ross-ebox-auxillary"
|
||||||
|
>new board revision</InlineLink
|
||||||
|
> with those changes and it was the final version used for the rest of ROSS's
|
||||||
|
lifetime. This little taste of the project, and some wishful prodding from
|
||||||
|
Nick, was enough for me to join the team part-time.
|
||||||
|
</Paragraph>
|
||||||
|
<Paragraph>
|
||||||
|
While the original plan for me was to re-write the <PopoverWordDefinition
|
||||||
|
key="GUI"
|
||||||
|
/> for ROSS in Python using Qt, it turns out they needed my help on the
|
||||||
|
electrical and firmware side more than anything, so most of my time at the
|
||||||
|
lab was focused on that. I hand-assembled so many of Nick's circuit boards
|
||||||
|
at this lab that I still can pick his out of a lot from design aesthetic
|
||||||
|
alone! I also helped with plenty of wiring harness builds, electrical box
|
||||||
|
fabrication, embedded firmware development, and of course, plenty of electrical
|
||||||
|
and software debugging. One thing that this project taught me very quickly
|
||||||
|
was how difficult it was to make reliable hardware in a high vibration,
|
||||||
|
electrically noisy, and salt-laden environments. The number of PCBs we went
|
||||||
|
through, alongside wiring harnesses, was pretty incredible considering the
|
||||||
|
lengths we went to in order to protect them.
|
||||||
|
</Paragraph>
|
||||||
|
<Paragraph>
|
||||||
|
A very unique aspect of this team/project, and a large part of why I
|
||||||
|
was drawn to it, was that it was about as hands-on as you could
|
||||||
|
possibly get. Doubly so for an undergraduate student! Not only did I
|
||||||
|
get to design and repair a real robot, but it was actually being used
|
||||||
|
for proper scientific research! We would regularly go to Newport, OR
|
||||||
|
for testing and have to make crazy additions and repairs on the fly.
|
||||||
|
This got even more extreme during my deployments to the <InlineLink
|
||||||
|
href="http://localhost:4321/experience/osu-ceoas-ocean-mixing-group/robotic-oceanographic-surface-sampler"
|
||||||
|
>LeConte glacier</InlineLink
|
||||||
|
>, as you had to get creative and fix things with what you had on-hand
|
||||||
|
due to how remote we were. These are experiences that graduate
|
||||||
|
students rarely even get to have, so I'm extremely thankful and fond
|
||||||
|
of the time I spent here. Huge shout out to <InlineLink
|
||||||
|
href="https://nickmccomb.net">Nick</InlineLink
|
||||||
|
>, again, who made it possible in the first place! Also be sure to
|
||||||
|
check out the scientific paper on this project below!
|
||||||
|
</Paragraph>
|
||||||
|
</Paragraphs>
|
||||||
|
</PageGroup>
|
||||||
|
</PageGroup>
|
||||||
|
<PageGroup>
|
||||||
|
<Fragment slot="header"><H2>Official Scientific Publication</H2></Fragment>
|
||||||
|
<div class="h-334">
|
||||||
|
<PdfViewer pdf={publication} />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
</PageGroup>
|
||||||
<div class="text-sm font-extrabold">Electrical</div>
|
|
||||||
<hr class="text-caperren-green" />
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<div class="text-sm font-extrabold">Mechanical</div>
|
|
||||||
<hr class="text-caperren-green" />
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<div class="text-sm font-extrabold">Other</div>
|
|
||||||
<hr class="text-caperren-green" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<H2>Details</H2>
|
|
||||||
power and voltage logging
|
|
||||||
<H2>Official Scientific Publication</H2>
|
|
||||||
<div class="h-334">
|
|
||||||
<PdfViewer pdf={publication} />
|
|
||||||
</div>
|
|
||||||
</ExperienceLayout>
|
</ExperienceLayout>
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import H2 from "@components/H2.astro";
|
|||||||
import H3 from "@components/H3.astro";
|
import H3 from "@components/H3.astro";
|
||||||
import InlineLink from "@components/InlineLink.astro";
|
import InlineLink from "@components/InlineLink.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 Paragraph from "@components/Paragraph.astro";
|
||||||
import Paragraphs from "@components/Paragraphs.astro";
|
import Paragraphs from "@components/Paragraphs.astro";
|
||||||
|
|
||||||
@@ -27,42 +28,49 @@ const rfidImplantCarouselGroup: carouselGroup = {
|
|||||||
---
|
---
|
||||||
|
|
||||||
<HobbyLayout title="Body Mods">
|
<HobbyLayout title="Body Mods">
|
||||||
<H2>RFID Implant</H2>
|
<PageGroup>
|
||||||
<Carousel carouselGroup={rfidImplantCarouselGroup} />
|
<Fragment slot="header"><H2>RFID Implant</H2></Fragment>
|
||||||
<H3>Details</H3>
|
|
||||||
<Paragraphs>
|
<Carousel carouselGroup={rfidImplantCarouselGroup} />
|
||||||
<Paragraph>
|
<PageGroup>
|
||||||
Back when I was in college, a few of my friends and I got this crazy idea
|
<Fragment slot="header"><H3>Details</H3></Fragment>
|
||||||
to all get RFID implants together. They are essentially the same things
|
|
||||||
you'd use to microchip a pet, but with a slightly different firmware
|
<Paragraphs>
|
||||||
configuration, allowing scans with any 125KHz-compatible reader. The
|
<Paragraph>
|
||||||
implants came from <InlineLink
|
Back when I was in college, a few of my friends and I got this crazy
|
||||||
href="https://dangerousthings.com/product/xem/"
|
idea to all get RFID implants together. They are essentially the same
|
||||||
>dangerousthings.com</InlineLink
|
things you'd use to microchip a pet, but with a slightly different
|
||||||
>, and we were lucky enough to have a vet-med student as a friend who made
|
firmware configuration, allowing scans with any 125KHz-compatible
|
||||||
the installation a quick and painless process! I'm glad that I'm not
|
reader. The implants came from <InlineLink
|
||||||
afraid of needles, as the 16 gauge injector the kit came with was nothing
|
href="https://dangerousthings.com/product/xem/"
|
||||||
to scoff at. Since healing, you would never know the implant was there,
|
>dangerousthings.com</InlineLink
|
||||||
with the site leaving no scar or visible indication of its presence.
|
>, and we were lucky enough to have a vet-med student as a friend who
|
||||||
</Paragraph>
|
made the installation a quick and painless process! I'm glad that I'm
|
||||||
<Paragraph>
|
not afraid of needles, as the 16 gauge injector the kit came with was
|
||||||
With that out of the way, our group began work on hardware which would
|
nothing to scoff at. Since healing, you would never know the implant
|
||||||
support the new implants. The goal was to have a generic usb-keyboard
|
was there, with the site leaving no scar or visible indication of its
|
||||||
emulator for typing passwords with a valid scan, a car off-acc-on ignition
|
presence.
|
||||||
replacement, and a fairly specialized modification to the OSU Robotics
|
</Paragraph>
|
||||||
Club's doorway scanning system so they would support these on top of the
|
<Paragraph>
|
||||||
official OSU ID cards. As tends to happen, life got busy, and only the
|
With that out of the way, our group began work on hardware which would
|
||||||
usb-keyboard emulator actually came to fruition. The electronics and
|
support the new implants. The goal was to have a generic usb-keyboard
|
||||||
primary firmware were handled by <InlineLink href="https://nickmccomb.net"
|
emulator for typing passwords with a valid scan, a car off-acc-on
|
||||||
>Nick McComb</InlineLink
|
ignition replacement, and a fairly specialized modification to the OSU
|
||||||
>, enclosure by <InlineLink href="https://dylanthrush.com"
|
Robotics Club's doorway scanning system so they would support these on
|
||||||
>Dylan Thrush</InlineLink
|
top of the official OSU ID cards. As tends to happen, life got busy,
|
||||||
>, and I supported some minor firmware development and debugging. If you
|
and only the usb-keyboard emulator actually came to fruition. The
|
||||||
want to see an example of the keyboard emulator unlocking a PC, check out
|
electronics and primary firmware were handled by <InlineLink
|
||||||
the video on <InlineLink
|
href="https://nickmccomb.net">Nick McComb</InlineLink
|
||||||
href="https://nickmccomb.net/college/printed-circuit-boards/computer-access-module"
|
>, enclosure by <InlineLink href="https://dylanthrush.com"
|
||||||
>Nick's website</InlineLink
|
>Dylan Thrush</InlineLink
|
||||||
>!
|
>, and I supported some minor firmware development and debugging. If
|
||||||
</Paragraph>
|
you want to see an example of the keyboard emulator unlocking a PC,
|
||||||
</Paragraphs>
|
check out the video on <InlineLink
|
||||||
|
href="https://nickmccomb.net/college/printed-circuit-boards/computer-access-module"
|
||||||
|
>Nick's website</InlineLink
|
||||||
|
>!
|
||||||
|
</Paragraph>
|
||||||
|
</Paragraphs>
|
||||||
|
</PageGroup>
|
||||||
|
</PageGroup>
|
||||||
</HobbyLayout>
|
</HobbyLayout>
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
---
|
---
|
||||||
|
import HobbyLayout from "@layouts/HobbyLayout.astro";
|
||||||
|
|
||||||
|
import H2 from "@components/H2.astro";
|
||||||
import LinkButton from "@components/LinkButton.astro";
|
import LinkButton from "@components/LinkButton.astro";
|
||||||
import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro";
|
import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro";
|
||||||
import HobbyLayout from "@layouts/HobbyLayout.astro";
|
import PageGroup from "@components/PageGroup.astro";
|
||||||
|
import Paragraph from "@components/Paragraph.astro";
|
||||||
|
import Paragraphs from "@components/Paragraphs.astro";
|
||||||
|
|
||||||
import type { carouselGroup } from "@interfaces/image-carousel.ts";
|
import type { carouselGroup } from "@interfaces/image-carousel.ts";
|
||||||
|
|
||||||
@@ -31,44 +36,53 @@ const headerCarouselGroup: carouselGroup = {
|
|||||||
};
|
};
|
||||||
---
|
---
|
||||||
|
|
||||||
<HobbyLayout title="Motorcycling - Chubby Buttons 2 Mount">
|
<HobbyLayout
|
||||||
|
title="Chubby Buttons 2 Mount"
|
||||||
|
subTitles={["Hobbies", "Motorcycling"]}
|
||||||
|
>
|
||||||
<Carousel carouselGroup={headerCarouselGroup} />
|
<Carousel carouselGroup={headerCarouselGroup} />
|
||||||
<div class="mt-4 flex items-center justify-center">
|
<div class="flex items-center justify-center">
|
||||||
<LinkButton
|
<LinkButton
|
||||||
href="https://cad.onshape.com/documents/816b0b1bef7883d4dc25c66c/v/e11fe68753e080b72015cfb8/e/3802abbd9d7b7c4d2c7ebad3"
|
href="https://cad.onshape.com/documents/816b0b1bef7883d4dc25c66c/v/e11fe68753e080b72015cfb8/e/3802abbd9d7b7c4d2c7ebad3"
|
||||||
title="Onshape CAD Design Files"
|
title="Onshape CAD Design Files"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<p class="mt-4">
|
<PageGroup>
|
||||||
Having ridden motorcycles since I was sixteen, and being an avid music
|
<Fragment slot="header"><H2>Details</H2></Fragment>
|
||||||
enjoyer, I'd been looking for a way to improve my music listening experience
|
<Paragraphs>
|
||||||
while on-the-go. One large pain-point I'd always had was with controlling
|
<Paragraph>
|
||||||
track selection and volume levels while my gloves were on, as smartphones
|
Having ridden motorcycles since I was sixteen, and being an avid music
|
||||||
don't respond very well to this, if at all. In 2023 I found out about chubby
|
enjoyer, I'd been looking for a way to improve my music listening
|
||||||
buttons, a low-power and highly water-resistant media controller
|
experience while riding. One large pain-point I'd always had was
|
||||||
specifically designed for use with gloves! The only problem was that it was
|
controlling track selection and volume levels while my gloves were on,
|
||||||
designed to be worn on your arm using a strap, which isn't very practical on
|
as smartphones don't respond very well to this, if at all. In 2023 I
|
||||||
a motorcycle.
|
found out about chubby buttons, a low-power and highly water-resistant
|
||||||
</p>
|
media controller specifically designed for use with gloves! The only
|
||||||
<p class="mt-4">
|
problem was that it was designed to be worn on your arm using a strap,
|
||||||
When starting this project, I'd recently gotten a 3D Printer, so having some
|
which isn't very practical on a motorcycle.
|
||||||
baseline modelling skills I took some measurements, and began designing a
|
</Paragraph>
|
||||||
proper mount. I already owned and used many 1" RAM compatible mounts and
|
<Paragraph>
|
||||||
gear on my bikes, so I decided to make this one natively support the ball
|
When starting this project, I'd recently gotten a 3D printer, so having
|
||||||
size to use an existing clamp I had stored away. This design was the first
|
some baseline modelling skills I took some measurements, and began
|
||||||
where I decided to use heat-set inserts in the plastic, along with some
|
designing a proper mount. I already owned and used many 1" RAM
|
||||||
medium-strength Loctite on the fasteners, due to the high-vibration
|
compatible mounts and gear on my bikes, so I decided to make this one
|
||||||
environment the mount would see. The print was also done using a UV
|
natively support the ball size to use an existing clamp I had stored
|
||||||
resistant, high-temp rated, and non-water-absorbing ASA filament, as the
|
away. This design was the first where I decided to use heat-set inserts
|
||||||
direct expose to the elements would not allow something like cheap PLA to
|
in the plastic, along with some medium-strength Loctite on the
|
||||||
last very long.
|
fasteners, due to the high-vibration environment the mount would see.
|
||||||
</p>
|
The print was also done using a UV resistant, high-temp rated, and
|
||||||
<p class="mt-4">
|
non-water-absorbing ASA filament, as the direct exposure to the elements
|
||||||
While my first iteration was sized appropriately and went together with no
|
would not allow something like cheap PLA to last very long.
|
||||||
issues, the ball mount neck ended up snapping due to a low infill
|
</Paragraph>
|
||||||
percentage. After changing that area to 100% infill, including a handful of
|
<Paragraph>
|
||||||
the rear mount layers that it attached to, a second iteration has worked
|
While my first iteration was sized appropriately and went together with
|
||||||
perfectly for a few years now! If you're interested in printing this
|
no issues, the ball mount neck ended up snapping due to a low infill
|
||||||
yourself, feel free to download the model using the button under the photos!
|
percentage. After changing that area to 100% infill, including a handful
|
||||||
</p>
|
of the layers at the rear mounting face where the neck attaches, a
|
||||||
|
second iteration has worked perfectly for a few years now! If you're
|
||||||
|
interested in printing this yourself, feel free to download the model
|
||||||
|
using the button under the photos!
|
||||||
|
</Paragraph>
|
||||||
|
</Paragraphs>
|
||||||
|
</PageGroup>
|
||||||
</HobbyLayout>
|
</HobbyLayout>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import HobbyLayout from "@layouts/HobbyLayout.astro";
|
|||||||
import H2 from "@components/H2.astro";
|
import H2 from "@components/H2.astro";
|
||||||
import H3 from "@components/H3.astro";
|
import H3 from "@components/H3.astro";
|
||||||
import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro";
|
import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro";
|
||||||
|
import PageGroup from "@components/PageGroup.astro";
|
||||||
|
|
||||||
import type { carouselGroup } from "@interfaces/image-carousel.ts";
|
import type { carouselGroup } from "@interfaces/image-carousel.ts";
|
||||||
|
|
||||||
@@ -39,26 +40,35 @@ const kz750CarouselGroup: carouselGroup = {
|
|||||||
};
|
};
|
||||||
---
|
---
|
||||||
|
|
||||||
<HobbyLayout title="Motorcycling - Lineup">
|
<HobbyLayout title="Lineup" subTitles={["Hobbies", "Motorcycling"]}>
|
||||||
<H2>Current Lineup</H2>
|
<PageGroup>
|
||||||
<H3>2015 Yamaha FJR 1300</H3>
|
<Fragment slot="header"><H2>Current Lineup</H2></Fragment>
|
||||||
<Carousel carouselGroup={fjrCarouselGroup} />
|
<PageGroup>
|
||||||
|
<Fragment slot="header"><H3>2015 Yamaha FJR 1300</H3></Fragment>
|
||||||
<H3>2021 CSC SG400</H3>
|
<Carousel carouselGroup={fjrCarouselGroup} />
|
||||||
<Carousel carouselGroup={cscCarouselGroup} />
|
</PageGroup>
|
||||||
|
<PageGroup>
|
||||||
<H2>Prior Lineup</H2>
|
<Fragment slot="header"><H3>2021 CSC SG400</H3></Fragment>
|
||||||
<H3>2005 Suzuki DRZ 400</H3>
|
<Carousel carouselGroup={cscCarouselGroup} />
|
||||||
<Carousel carouselGroup={drzCarouselGroup} />
|
</PageGroup>
|
||||||
|
</PageGroup>
|
||||||
<h3 class="my-4 font-bold underline md:text-lg">
|
<PageGroup>
|
||||||
1991 Kawasaki Concours ZG1000
|
<Fragment slot="header"><H2>Prior Lineup</H2></Fragment>
|
||||||
</h3>
|
<PageGroup>
|
||||||
<Carousel carouselGroup={concoursCarouselGroup} />
|
<Fragment slot="header"><H3>2005 Suzuki DRZ 400</H3></Fragment>
|
||||||
|
<Carousel carouselGroup={drzCarouselGroup} />
|
||||||
<H3>1979 Kawasaki KZ750</H3>
|
</PageGroup>
|
||||||
<Carousel carouselGroup={kz750CarouselGroup} />
|
<PageGroup>
|
||||||
|
<Fragment slot="header"><H3>1991 Kawasaki Concours ZG1000</H3></Fragment>
|
||||||
<H3>1991 Kawasaki Ninja 600R</H3>
|
<Carousel carouselGroup={concoursCarouselGroup} />
|
||||||
<Carousel carouselGroup={ninjaCarouselGroup} />
|
</PageGroup>
|
||||||
|
<PageGroup>
|
||||||
|
<Fragment slot="header"><H3>1979 Kawasaki KZ750</H3></Fragment>
|
||||||
|
<Carousel carouselGroup={kz750CarouselGroup} />
|
||||||
|
</PageGroup>
|
||||||
|
<PageGroup>
|
||||||
|
<Fragment slot="header"><H3>1991 Kawasaki Ninja 600R</H3></Fragment>
|
||||||
|
<Carousel carouselGroup={ninjaCarouselGroup} />
|
||||||
|
</PageGroup>
|
||||||
|
</PageGroup>
|
||||||
</HobbyLayout>
|
</HobbyLayout>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import BaseLayout from "@layouts/BaseLayout.astro";
|
|||||||
import H2 from "@components/H2.astro";
|
import H2 from "@components/H2.astro";
|
||||||
import InlineLink from "@components/InlineLink.astro";
|
import InlineLink from "@components/InlineLink.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 Paragraph from "@components/Paragraph.astro";
|
||||||
import Paragraphs from "@components/Paragraphs.astro";
|
import Paragraphs from "@components/Paragraphs.astro";
|
||||||
|
|
||||||
@@ -21,76 +22,81 @@ const headerCarouselGroup: carouselGroup = {
|
|||||||
|
|
||||||
<BaseLayout title="About" showTitle={false}>
|
<BaseLayout title="About" showTitle={false}>
|
||||||
<Carousel carouselGroup={headerCarouselGroup} />
|
<Carousel carouselGroup={headerCarouselGroup} />
|
||||||
<H2>Who Am I</H2>
|
<PageGroup>
|
||||||
<Paragraphs>
|
<Fragment slot="header"><H2>Who Am I</H2></Fragment>
|
||||||
<Paragraph>
|
<Paragraphs>
|
||||||
My name is Corwin Perren, and I'm a multi-disciplinary engineer with a <InlineLink
|
<Paragraph>
|
||||||
href="/education">degree in computer science</InlineLink
|
My name is Corwin Perren, and I'm a multi-disciplinary engineer with a <InlineLink
|
||||||
> from Oregon State University. For as long as I can remember, I've been fascinated
|
href="/education">degree in computer science</InlineLink
|
||||||
by how things work, never being shy about taking them apart to learn the gritty
|
> from Oregon State University. For as long as I can remember, I've been fascinated
|
||||||
details. At a young age, I began tinkering, adding lights and fans and doorbells
|
by how things work, never being shy about taking them apart to learn the gritty
|
||||||
to the pretend cardboard box houses my brother and I would play in. Later, I
|
details. At a young age, I began tinkering, adding lights and fans and doorbells
|
||||||
learned to solder, work on vehicles and engines, install and run Linux, manage
|
to the pretend cardboard box houses my brother and I would play in. Later,
|
||||||
enterprise computing infrastructure, build and repair computers, write scripts,
|
I learned to solder, work on vehicles and engines, install and run Linux,
|
||||||
and by the end of high school set out with a clear goal for my college years.
|
manage enterprise computing infrastructure, build and repair computers, write
|
||||||
I wanted to learn and teach myself enough to be able to think up almost any
|
scripts, and by the end of high school set out with a clear goal for my college
|
||||||
project, encompassing all facets of engineering, and be capable of driving it
|
years. I wanted to learn and teach myself enough to be able to think up almost
|
||||||
to completion with my own skill set.
|
any project, encompassing all facets of engineering, and be capable of driving
|
||||||
</Paragraph>
|
it to completion with my own skill set.
|
||||||
<Paragraph>
|
</Paragraph>
|
||||||
I think young me would be very pleased by how well I managed to achieve
|
<Paragraph>
|
||||||
that goal! Through college, I learned electronics and PCB design, embedded
|
I think young me would be very pleased by how well I managed to achieve
|
||||||
and pc programming, basic mechanical design and fabrication, on top of
|
that goal! Through college, I learned electronics and PCB design,
|
||||||
learning how to work well with others in a team. I quickly realized that
|
embedded and pc programming, basic mechanical design and fabrication, on
|
||||||
robotics was an ideal focus due to its inherent multi-disciplinary nature,
|
top of learning how to work well with others in a team. I quickly
|
||||||
and joined the OSU Robotics Club, which introduced me to people who are
|
realized that robotics was an ideal focus due to its inherent
|
||||||
still my best friends today. Through student engineering jobs, I had the
|
multi-disciplinary nature, and joined the OSU Robotics Club, which
|
||||||
unique opportunity to work on some incredible projects such as the
|
introduced me to people who are still my best friends today. Through
|
||||||
<InlineLink
|
student engineering jobs, I had the unique opportunity to work on some
|
||||||
href="/experience/osu-ceoas-ocean-mixing-group/robotic-oceanographic-surface-sampler"
|
incredible projects such as the
|
||||||
>robotic oceanographic surface sampler</InlineLink
|
<InlineLink
|
||||||
>
|
href="/experience/osu-ceoas-ocean-mixing-group/robotic-oceanographic-surface-sampler"
|
||||||
and an <InlineLink
|
>robotic oceanographic surface sampler</InlineLink
|
||||||
href="/experience/osu-sinnhuber-aquatic-research-laboratory/zebrafish-embryo-pick-and-plate"
|
>
|
||||||
>embryo pick-and-plate machine</InlineLink
|
and an <InlineLink
|
||||||
>. One my my proudest moments was when our club's mars rover took first
|
href="/experience/osu-sinnhuber-aquatic-research-laboratory/zebrafish-embryo-pick-and-plate"
|
||||||
place at the Candian International Rover Challenge in 2018, for which I
|
>embryo pick-and-plate machine</InlineLink
|
||||||
was the <InlineLink
|
>. One my my proudest moments was when our club's mars rover took first
|
||||||
href="/experience/osu-robotics-club/mars-rover-software-team-lead"
|
place at the Candian International Rover Challenge in 2018, for which I
|
||||||
>software lead</InlineLink
|
was the <InlineLink
|
||||||
>!
|
href="/experience/osu-robotics-club/mars-rover-software-team-lead"
|
||||||
</Paragraph>
|
>software lead</InlineLink
|
||||||
<Paragraph>
|
>!
|
||||||
After a short three-month <InlineLink
|
</Paragraph>
|
||||||
href="/experience/spacex/avionics-test-engineering-internship"
|
<Paragraph>
|
||||||
>internship</InlineLink
|
After a short three-month <InlineLink
|
||||||
> at SpaceX in Hawthorne at the end of college, I applied for a <InlineLink
|
href="/experience/spacex/avionics-test-engineering-internship"
|
||||||
href="/experience/spacex/hardware-test-engineer-i-ii"
|
>internship</InlineLink
|
||||||
>test engineering</InlineLink
|
> at SpaceX in Hawthorne at the end of college, I applied for a <InlineLink
|
||||||
> position with the company's Starlink team and was hired in mid-2019. For six
|
href="/experience/spacex/hardware-test-engineer-i-ii"
|
||||||
years, I developed test system hardware, software, harnesses, mechanical fixtures,
|
>test engineering</InlineLink
|
||||||
devops infrastructure, websites, and tooling to ensure that Starlink, Falcon,
|
> position with the company's Starlink team and was hired in mid-2019. For
|
||||||
Dragon, and Starship component tests were producing well-validated and reliable
|
six years, I developed test system hardware, software, harnesses, mechanical
|
||||||
hardware. Through it all, I got to apply and hone every skill I had developed,
|
fixtures, devops infrastructure, websites, and tooling to ensure that Starlink,
|
||||||
while learning countless more. Now though, it's on to the next adventure, whatever
|
Falcon, Dragon, and Starship component tests were producing well-validated
|
||||||
that may be!
|
and reliable hardware. Through it all, I got to apply and hone every skill
|
||||||
</Paragraph>
|
I had developed, while learning countless more. Now though, it's on to the
|
||||||
<Paragraph>
|
next adventure, whatever that may be!
|
||||||
To learn more about my experiences, hobbies, interests, and skills, feel
|
</Paragraph>
|
||||||
free to explore the site! While the short summary above provides some
|
<Paragraph>
|
||||||
insight into who I am, it leaves out plenty! For example, I've been an
|
To learn more about my experiences, hobbies, interests, and skills, feel
|
||||||
avid <InlineLink href="/hobby/motorcycling/lineup"
|
free to explore the site! While the short summary above provides some
|
||||||
>motorcycle rider</InlineLink
|
insight into who I am, it leaves out plenty! For example, I've been an
|
||||||
> since I was sixteen, and have an <InlineLink href="/hobby/body-mods"
|
avid <InlineLink href="/hobby/motorcycling/lineup"
|
||||||
>rfid implant</InlineLink
|
>motorcycle rider</InlineLink
|
||||||
> in my hand!
|
> since I was sixteen, and have an <InlineLink href="/hobby/body-mods"
|
||||||
</Paragraph>
|
>rfid implant</InlineLink
|
||||||
<Paragraph>
|
> in my hand!
|
||||||
If you're interested in contacting me, feel free to message on <InlineLink
|
</Paragraph>
|
||||||
href="https://github.com/caperren">LinkedIn</InlineLink
|
<Paragraph class="mt-8 flex flex-col items-center" initialTab={false}>
|
||||||
>, or via the primary contact methods on my <InlineLink
|
<div>
|
||||||
href="/resume/2025-11-10-infrastructure-engineer">resume</InlineLink
|
If you're interested in contacting me, feel free to message on <InlineLink
|
||||||
>.
|
href="https://github.com/caperren">LinkedIn</InlineLink
|
||||||
</Paragraph>
|
>, or via the primary contact methods on my <InlineLink
|
||||||
</Paragraphs>
|
href="/resume/2025-11-10-infrastructure-engineer">resume</InlineLink
|
||||||
|
>.
|
||||||
|
</div>
|
||||||
|
</Paragraph>
|
||||||
|
</Paragraphs>
|
||||||
|
</PageGroup>
|
||||||
</BaseLayout>
|
</BaseLayout>
|
||||||
|
|||||||
Reference in New Issue
Block a user