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
@@ -1,6 +1,9 @@
|
||||
ADCP
|
||||
Altium
|
||||
ASSEM
|
||||
astrojs
|
||||
Atmel
|
||||
barebones
|
||||
Candian
|
||||
caperren
|
||||
CEOAS
|
||||
@@ -10,6 +13,7 @@ CONSERV
|
||||
Corwin
|
||||
dangerousthings
|
||||
Dechorionator
|
||||
ebox
|
||||
fhhs
|
||||
flowbite
|
||||
HDFS
|
||||
@@ -19,10 +23,13 @@ hwupload
|
||||
iceops
|
||||
ITAR
|
||||
Jetson
|
||||
KFSK
|
||||
leconte
|
||||
Loctite
|
||||
luxon
|
||||
MGMT
|
||||
Mokai
|
||||
Multimeters
|
||||
nixos
|
||||
offroad
|
||||
Onshape
|
||||
@@ -30,6 +37,7 @@ OSSM
|
||||
OSURC
|
||||
Perren
|
||||
Perren's
|
||||
Pixhawk
|
||||
pubpath
|
||||
RFID
|
||||
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;
|
||||
---
|
||||
|
||||
<a
|
||||
<div class="mx-auto">
|
||||
<a
|
||||
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"
|
||||
href={href}
|
||||
target={target}
|
||||
>
|
||||
>
|
||||
{title}
|
||||
</a>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -39,7 +39,7 @@ import { Image } from "astro:assets";
|
||||
</svg>
|
||||
</button>
|
||||
<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"
|
||||
>
|
||||
<NestedNavbarEntry items={siteLayout} />
|
||||
|
||||
@@ -19,29 +19,34 @@ const { pathname } = Astro.url;
|
||||
---
|
||||
|
||||
<ul
|
||||
class={"flex flex-col p-4 bg-black border-caperren-green " +
|
||||
(depth ? "space-y-2" : "items-start lg:flex-row lg:space-x-8 lg:mt-0 ")}
|
||||
class:list={[
|
||||
"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(
|
||||
(entry) =>
|
||||
(entry.enabled ?? true) && (
|
||||
<li>
|
||||
<li class="">
|
||||
{Array.isArray(entry.children) && entry.children.length ? (
|
||||
<div
|
||||
class={
|
||||
pathname.startsWith(getHrefPath(entry))
|
||||
? "border-caperren-green border-b-2"
|
||||
: ""
|
||||
}
|
||||
>
|
||||
<div>
|
||||
<button
|
||||
id={"dropdownNavbarLink" + getNavLinkSuffix(entry)}
|
||||
data-dropdown-toggle={
|
||||
"dropdownNavbar" + getNavLinkSuffix(entry)
|
||||
}
|
||||
data-dropdown-placement="bottom"
|
||||
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-placement="bottom-start"
|
||||
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}
|
||||
<svg
|
||||
@@ -61,7 +66,7 @@ const { pathname } = Astro.url;
|
||||
</button>
|
||||
<div
|
||||
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
|
||||
items={entry.children}
|
||||
@@ -71,17 +76,16 @@ const { pathname } = Astro.url;
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div
|
||||
class={
|
||||
pathname === getHrefPath(entry)
|
||||
? "border-caperren-green border-b-2"
|
||||
: ""
|
||||
}
|
||||
>
|
||||
<div>
|
||||
<a
|
||||
href={getHrefPath(entry)}
|
||||
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={
|
||||
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="">
|
||||
<slot />
|
||||
<div class:list={className}>
|
||||
{initialTab && <> </>}<slot />
|
||||
</div>
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
|
||||
---
|
||||
|
||||
<div class="space-y-2">
|
||||
<div class="grid grid-cols-1 gap-2">
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
@@ -7,6 +7,10 @@ const keys: { [key: string]: string } = {
|
||||
ADCP: "Acoustic doppler current profiler",
|
||||
COTS: "Consumer off-the-shelf",
|
||||
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;
|
||||
|
||||
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: "Education", path: "education" },
|
||||
{
|
||||
navText: "Experiences",
|
||||
navText: "Experience",
|
||||
path: "experience",
|
||||
children: [
|
||||
{
|
||||
@@ -29,7 +29,6 @@ export const siteLayout: navLink[] = [
|
||||
path: "osu-ceoas-ocean-mixing-group",
|
||||
children: [
|
||||
{
|
||||
enabled: false,
|
||||
navText: "Robotics 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 H1 from "@components/H1.astro";
|
||||
import Navbar from "@components/Navbar.astro";
|
||||
import PageGroup from "@components/PageGroup.astro";
|
||||
|
||||
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" />
|
||||
<title>{pageEnabled ? pageTitle : "Corwin Perren"}</title>
|
||||
</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
|
||||
id="content-body-scrolling"
|
||||
class="grow overflow-x-hidden overflow-y-scroll"
|
||||
>
|
||||
<Navbar />
|
||||
<main class="mx-6 my-6">
|
||||
<div class="mb-2 md:mb-6">
|
||||
<main class="mx-6 my-2">
|
||||
{
|
||||
title && showTitle && pageEnabled && (
|
||||
<H1 bottomMargin={!subTitles}>{title}</H1>
|
||||
showTitle && pageEnabled && (
|
||||
<PageGroup>
|
||||
<Fragment slot="header">
|
||||
<div class="leading-3">
|
||||
<H1>{title}</H1>
|
||||
{subTitles?.map((subTitle) => (
|
||||
<p class="md:text-md text-sm font-bold italic">
|
||||
{subTitle}
|
||||
</p>
|
||||
))}
|
||||
</div>
|
||||
</Fragment>
|
||||
</PageGroup>
|
||||
)
|
||||
}
|
||||
{
|
||||
showTitle &&
|
||||
pageEnabled &&
|
||||
subTitles?.map((subTitle) => (
|
||||
<p class="text-sm font-bold md:text-xl">{subTitle}</p>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
<div>
|
||||
<div class="grid grid-cols-1 gap-4">
|
||||
{pageEnabled ? <slot /> : <H1>Under Construction</H1>}
|
||||
</div>
|
||||
</main>
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
---
|
||||
import PdfViewer from "@components/Media/PdfViewer.astro";
|
||||
import BaseLayout from "@layouts/BaseLayout.astro";
|
||||
|
||||
import PdfViewer from "@components/Media/PdfViewer.astro";
|
||||
---
|
||||
|
||||
<BaseLayout {...Astro.props}>
|
||||
<div class="h-dvh">
|
||||
<PdfViewer class="mx-auto" pdf={Astro.props.resume} />
|
||||
<div class="mt-2 h-dvh">
|
||||
<PdfViewer pdf={Astro.props.resume} />
|
||||
</div>
|
||||
</BaseLayout>
|
||||
|
||||
@@ -5,6 +5,7 @@ import H2 from "@components/H2.astro";
|
||||
import H3 from "@components/H3.astro";
|
||||
import InlineLink from "@components/InlineLink.astro";
|
||||
import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro";
|
||||
import PageGroup from "@components/PageGroup.astro";
|
||||
import Table from "@components/Table.astro";
|
||||
import Timeline from "@components/Timeline/Timeline.astro";
|
||||
|
||||
@@ -108,16 +109,24 @@ const courseTable: tableData = {
|
||||
|
||||
<BaseLayout title="Education">
|
||||
<Carousel carouselGroup={diplomaCarouselGroup} />
|
||||
<H2>Timeline</H2>
|
||||
<PageGroup>
|
||||
<Fragment slot="header"><H2>Timeline</H2></Fragment>
|
||||
<Timeline timeline={timeline} />
|
||||
<H2>Oregon State University</H2>
|
||||
<H3>
|
||||
</PageGroup>
|
||||
<PageGroup>
|
||||
<Fragment slot="header"><H2>Oregon State University</H2></Fragment>
|
||||
<PageGroup>
|
||||
<Fragment slot="header">
|
||||
<InlineLink
|
||||
class="font-bold md:text-lg"
|
||||
href="https://github.com/caperren/school_archives/tree/master/OSU%20Coursework"
|
||||
>Coursework Archives</InlineLink
|
||||
><H3>Coursework Archives</H3></InlineLink
|
||||
>
|
||||
</H3>
|
||||
<H3>Course Listing</H3>
|
||||
</Fragment>
|
||||
</PageGroup>
|
||||
<PageGroup>
|
||||
<Fragment slot="header"><H3>Course Listing</H3></Fragment>
|
||||
<Table data={courseTable} />
|
||||
</PageGroup>
|
||||
</PageGroup>
|
||||
</BaseLayout>
|
||||
|
||||
@@ -3,8 +3,13 @@ import ExperienceLayout from "@layouts/ExperienceLayout.astro";
|
||||
|
||||
import H2 from "@components/H2.astro";
|
||||
import H3 from "@components/H3.astro";
|
||||
import InlineLink from "@components/InlineLink.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 Paragraphs from "@components/Paragraphs.astro";
|
||||
import PopoverWordDefinition from "@components/PopoverWordDefinition.astro";
|
||||
import Timeline from "@components/Timeline/Timeline.astro";
|
||||
|
||||
import type { carouselGroup } from "@interfaces/image-carousel.ts";
|
||||
@@ -56,26 +61,29 @@ 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";
|
||||
---
|
||||
|
||||
<ExperienceLayout title="LeConte Glacier Deployments" subTitles={subTitles}>
|
||||
<Carousel carouselGroup={headerCarouselGroup} />
|
||||
<H2>Summary</H2>
|
||||
<H3>Timeline</H3>
|
||||
<PageGroup>
|
||||
<Fragment slot="header"><H2>Summary</H2></Fragment>
|
||||
<PageGroup>
|
||||
<Fragment slot="header"><H3>Timeline</H3></Fragment>
|
||||
<Timeline timeline={deploymentTimeline} />
|
||||
<H3>Location</H3>
|
||||
</PageGroup>
|
||||
<PageGroup>
|
||||
<Fragment slot="header"><H3>Location</H3></Fragment>
|
||||
<iframe
|
||||
class="w-full"
|
||||
width="600"
|
||||
height="450"
|
||||
src="https://maps.google.com/maps?q=leconte%20glacier&t=k&z=11&ie=UTF8&iwloc=B&output=embed"
|
||||
></iframe>
|
||||
<H2>Details</H2>
|
||||
</PageGroup>
|
||||
</PageGroup>
|
||||
<PageGroup>
|
||||
<Fragment slot="header"><H2>Details</H2></Fragment>
|
||||
<Paragraphs>
|
||||
<Paragraph>
|
||||
As part of my time working on the
|
||||
@@ -85,23 +93,23 @@ import { subTitles } from "./osu-ceoas-ocean-mixing-group.ts";
|
||||
Robotic Oceanographic Surface Sampler</InlineLink
|
||||
>, I had the fantastic opportunity to be deployed at the LeConte Glacier
|
||||
in Alaska! This started in early 2017 with setup and ocean trials in
|
||||
nearby Petersburg. The team had sent multiple shipping containers with our
|
||||
robotic platforms and most equipment to assemble, test, and debug them a
|
||||
few months prior, allowing us to get to work the moment we arrived. We
|
||||
spent multiple weeks at the docks with our makeshift workstations built
|
||||
from plywood and pelican cases, validating the hardware we'd sent, and
|
||||
making adjustments with improved hardware we'd hand-carried on our
|
||||
flights. This also provided a great opportunity to work out any final
|
||||
firmware and/or software bugs while the vehicles were still relatively
|
||||
easy to retrieve. After a short trip back home to recover, and prep any
|
||||
last minute items we'd forgotten, our research team flew back and headed
|
||||
for the glacier!
|
||||
nearby Petersburg. The team had sent multiple shipping containers with
|
||||
our robotic platforms and most equipment to assemble, test, and debug
|
||||
them a few months prior, allowing us to get to work the moment we
|
||||
arrived. We spent multiple weeks at the docks with our makeshift
|
||||
workstations built from plywood and pelican cases, validating the
|
||||
hardware we'd sent, and making adjustments with improved hardware we'd
|
||||
hand-carried on our flights. This also provided a great opportunity to
|
||||
work out any final firmware and/or software bugs while the vehicles were
|
||||
still relatively easy to retrieve. After a short trip back home to
|
||||
recover, and prep any last minute items we'd forgotten, our research
|
||||
team flew back and headed for the glacier!
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
The towering mountain of ice sits roughly 30 miles from Petersburg, so
|
||||
we'd commissioned an off-season fishing vessel, Steller, and it's crew, to
|
||||
take us as close to it as was reasonably safe. The team worked 24 hours a
|
||||
day, on two shifts, deploying and retrieving the ROSS platforms,
|
||||
we'd commissioned an off-season fishing vessel, Steller, and it's crew,
|
||||
to take us as close to it as was reasonably safe. The team worked 24
|
||||
hours a day, on two shifts, deploying and retrieving the ROSS platforms,
|
||||
performing repairs (as needed), recovering/processing collected data,
|
||||
manually deploying the ship's <PopoverWordDefinition key="CTD" />, and
|
||||
occasionally spending considerable time pushing icebergs the size of
|
||||
@@ -111,18 +119,20 @@ import { subTitles } from "./osu-ceoas-ocean-mixing-group.ts";
|
||||
the limitations of this isolated (and salty) environment.
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
On top of being a unique engineering and team building experience, LeConte
|
||||
lives among the most beautiful places I've yet to experience in this life.
|
||||
There's something special about being somewhere so incredibly remote and
|
||||
untouched by humans. The pristine evergreen forests, eerie blue-green hues
|
||||
of the glacier and icebergs, ancient towering mountains, 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 the odd ones
|
||||
out. These trips were ones that I will treasure and think back on fondly
|
||||
on for the rest of my life.
|
||||
On top of being a unique engineering and team building experience,
|
||||
LeConte lives among the most beautiful places I've yet to experience in
|
||||
this life. There's something special about being somewhere so incredibly
|
||||
remote and untouched by humans. The pristine evergreen forests, eerie
|
||||
blue-green hues of the glacier and icebergs, ancient towering mountains,
|
||||
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
|
||||
the odd ones out. These trips were ones that I will treasure and think
|
||||
back on fondly on for the rest of my life.
|
||||
</Paragraph>
|
||||
</Paragraphs>
|
||||
<H2>Videos</H2>
|
||||
</PageGroup>
|
||||
<PageGroup>
|
||||
<Fragment slot="header"><H2>Videos</H2></Fragment>
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||
{
|
||||
videos.map((video) => (
|
||||
@@ -135,4 +145,5 @@ import { subTitles } from "./osu-ceoas-ocean-mixing-group.ts";
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</PageGroup>
|
||||
</ExperienceLayout>
|
||||
|
||||
@@ -26,4 +26,5 @@ export const deploymentTimeline: timelineEntry[] = [
|
||||
export const subTitles = [
|
||||
"Oregon State University",
|
||||
"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 H3 from "@components/H3.astro";
|
||||
import InlineLink from "@components/InlineLink.astro";
|
||||
import Li from "@components/Li.astro";
|
||||
import LinkButton from "@components/LinkButton.astro";
|
||||
import Carousel from "@components/Media/CustomCarousel/CustomCarousel.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 SkillMatrix from "@components/SkillMatrix/SkillMatrix.astro";
|
||||
import Timeline from "@components/Timeline/Timeline.astro";
|
||||
import Ul from "@components/Ul.astro";
|
||||
|
||||
import type { carouselGroup } from "@interfaces/image-carousel.ts";
|
||||
import type { categorySkills } from "@interfaces/skill-matrix.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 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 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";
|
||||
@@ -31,6 +40,7 @@ const headerCarouselGroup: carouselGroup = {
|
||||
ross_team,
|
||||
ross_on_vessel,
|
||||
ross_on_vessel_at_night,
|
||||
ross_ebox_4p0,
|
||||
electronics_box,
|
||||
jet_drive,
|
||||
ui,
|
||||
@@ -50,6 +60,72 @@ const timeline: timelineEntry[] = [
|
||||
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
|
||||
@@ -57,56 +133,158 @@ const timeline: timelineEntry[] = [
|
||||
subTitles={subTitles}
|
||||
>
|
||||
<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
|
||||
href="https://tos.org/oceanography/article/autonomous-ctd-profiling-from-the-robotic-oceanographic-surface-sampler"
|
||||
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>
|
||||
<H2>Summary</H2>
|
||||
<H3>Timeline</H3>
|
||||
<PageGroup>
|
||||
<Fragment slot="header"><H2>Summary</H2></Fragment>
|
||||
<PageGroup>
|
||||
<Fragment slot="header"><H3>Timeline</H3></Fragment>
|
||||
<Timeline timeline={timeline} />
|
||||
<H3>Key Takeaways</H3>
|
||||
<ul class="list-inside list-disc">
|
||||
<li>
|
||||
<div class="inline-block">
|
||||
Assembled, fabricated, and debugged both custom and
|
||||
<PopoverWordDefinition key="COTS" />
|
||||
hardware and electronics.
|
||||
</div>
|
||||
</li>
|
||||
<li>Two</li>
|
||||
<li>Three</li>
|
||||
</ul>
|
||||
<h3 class="my-4 font-bold md:text-lg">Skills Used</h3>
|
||||
<div
|
||||
class="border-caperren-green relative grid grid-flow-row gap-6 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4"
|
||||
</PageGroup>
|
||||
<PageGroup>
|
||||
<Fragment slot="header"><H3>Key Takeaways</H3></Fragment>
|
||||
<Ul>
|
||||
<Li
|
||||
>Hand assembled and validated dozens of custom <PopoverWordDefinition
|
||||
key="PCBs"
|
||||
/>, wiring harnesses, and electronics boxes</Li
|
||||
>
|
||||
<div>
|
||||
<div class="text-sm font-extrabold">Software</div>
|
||||
<hr class="text-caperren-green" />
|
||||
<ul class="list-inside list-disc text-sm">
|
||||
<li>One</li>
|
||||
<li>Two</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<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>
|
||||
<Li
|
||||
>Wrote, debugged, and assisted with development of embedded firmware</Li
|
||||
>
|
||||
<Li
|
||||
>Accompanied the team on two deployments to the LeConte glacier in
|
||||
Alaska to gather ice-water melt and mixing data</Li
|
||||
>
|
||||
</Ul>
|
||||
</PageGroup>
|
||||
<SkillMatrix categorizedSkills={categorizedSkills} />
|
||||
</PageGroup>
|
||||
<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>
|
||||
</PageGroup>
|
||||
</ExperienceLayout>
|
||||
|
||||
@@ -5,6 +5,7 @@ import H2 from "@components/H2.astro";
|
||||
import H3 from "@components/H3.astro";
|
||||
import InlineLink from "@components/InlineLink.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";
|
||||
|
||||
@@ -27,42 +28,49 @@ const rfidImplantCarouselGroup: carouselGroup = {
|
||||
---
|
||||
|
||||
<HobbyLayout title="Body Mods">
|
||||
<H2>RFID Implant</H2>
|
||||
<PageGroup>
|
||||
<Fragment slot="header"><H2>RFID Implant</H2></Fragment>
|
||||
|
||||
<Carousel carouselGroup={rfidImplantCarouselGroup} />
|
||||
<H3>Details</H3>
|
||||
<PageGroup>
|
||||
<Fragment slot="header"><H3>Details</H3></Fragment>
|
||||
|
||||
<Paragraphs>
|
||||
<Paragraph>
|
||||
Back when I was in college, a few of my friends and I got this crazy idea
|
||||
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
|
||||
configuration, allowing scans with any 125KHz-compatible reader. The
|
||||
implants came from <InlineLink
|
||||
Back when I was in college, a few of my friends and I got this crazy
|
||||
idea 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 configuration, allowing scans with any 125KHz-compatible
|
||||
reader. The implants came from <InlineLink
|
||||
href="https://dangerousthings.com/product/xem/"
|
||||
>dangerousthings.com</InlineLink
|
||||
>, and we were lucky enough to have a vet-med student as a friend who made
|
||||
the installation a quick and painless process! I'm glad that I'm not
|
||||
afraid of needles, as the 16 gauge injector the kit came with was nothing
|
||||
to scoff at. Since healing, you would never know the implant was there,
|
||||
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
|
||||
made the installation a quick and painless process! I'm glad that I'm
|
||||
not afraid of needles, as the 16 gauge injector the kit came with was
|
||||
nothing to scoff at. Since healing, you would never know the implant
|
||||
was there, with the site leaving no scar or visible indication of its
|
||||
presence.
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
With that out of the way, our group began work on hardware which would
|
||||
support the new implants. The goal was to have a generic usb-keyboard
|
||||
emulator for typing passwords with a valid scan, a car off-acc-on ignition
|
||||
replacement, and a fairly specialized modification to the OSU Robotics
|
||||
Club's doorway scanning system so they would support these on top of the
|
||||
official OSU ID cards. As tends to happen, life got busy, and only the
|
||||
usb-keyboard emulator actually came to fruition. The electronics and
|
||||
primary firmware were handled by <InlineLink href="https://nickmccomb.net"
|
||||
>Nick McComb</InlineLink
|
||||
emulator for typing passwords with a valid scan, a car off-acc-on
|
||||
ignition replacement, and a fairly specialized modification to the OSU
|
||||
Robotics Club's doorway scanning system so they would support these on
|
||||
top of the official OSU ID cards. As tends to happen, life got busy,
|
||||
and only the usb-keyboard emulator actually came to fruition. The
|
||||
electronics and primary firmware were handled by <InlineLink
|
||||
href="https://nickmccomb.net">Nick McComb</InlineLink
|
||||
>, enclosure by <InlineLink href="https://dylanthrush.com"
|
||||
>Dylan Thrush</InlineLink
|
||||
>, and I supported some minor firmware development and debugging. If you
|
||||
want to see an example of the keyboard emulator unlocking a PC, check out
|
||||
the video on <InlineLink
|
||||
>, and I supported some minor firmware development and debugging. If
|
||||
you want to see an example of the keyboard emulator unlocking a PC,
|
||||
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>
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
---
|
||||
import HobbyLayout from "@layouts/HobbyLayout.astro";
|
||||
|
||||
import H2 from "@components/H2.astro";
|
||||
import LinkButton from "@components/LinkButton.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";
|
||||
|
||||
@@ -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} />
|
||||
<div class="mt-4 flex items-center justify-center">
|
||||
<div class="flex items-center justify-center">
|
||||
<LinkButton
|
||||
href="https://cad.onshape.com/documents/816b0b1bef7883d4dc25c66c/v/e11fe68753e080b72015cfb8/e/3802abbd9d7b7c4d2c7ebad3"
|
||||
title="Onshape CAD Design Files"
|
||||
/>
|
||||
</div>
|
||||
<p class="mt-4">
|
||||
<PageGroup>
|
||||
<Fragment slot="header"><H2>Details</H2></Fragment>
|
||||
<Paragraphs>
|
||||
<Paragraph>
|
||||
Having ridden motorcycles since I was sixteen, and being an avid music
|
||||
enjoyer, I'd been looking for a way to improve my music listening experience
|
||||
while on-the-go. One large pain-point I'd always had was with controlling
|
||||
track selection and volume levels while my gloves were on, as smartphones
|
||||
don't respond very well to this, if at all. In 2023 I found out about chubby
|
||||
buttons, a low-power and highly water-resistant media controller
|
||||
specifically designed for use with gloves! The only problem was that it was
|
||||
designed to be worn on your arm using a strap, which isn't very practical on
|
||||
a motorcycle.
|
||||
</p>
|
||||
<p class="mt-4">
|
||||
When starting this project, I'd recently gotten a 3D Printer, so having some
|
||||
baseline modelling skills I took some measurements, and began designing a
|
||||
proper mount. I already owned and used many 1" RAM compatible mounts and
|
||||
gear on my bikes, so I decided to make this one natively support the ball
|
||||
size to use an existing clamp I had stored away. This design was the first
|
||||
where I decided to use heat-set inserts in the plastic, along with some
|
||||
medium-strength Loctite on the fasteners, due to the high-vibration
|
||||
environment the mount would see. The print was also done using a UV
|
||||
resistant, high-temp rated, and non-water-absorbing ASA filament, as the
|
||||
direct expose to the elements would not allow something like cheap PLA to
|
||||
last very long.
|
||||
</p>
|
||||
<p class="mt-4">
|
||||
While my first iteration was sized appropriately and went together with no
|
||||
issues, the ball mount neck ended up snapping due to a low infill
|
||||
percentage. After changing that area to 100% infill, including a handful of
|
||||
the rear mount layers that it attached to, 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!
|
||||
</p>
|
||||
enjoyer, I'd been looking for a way to improve my music listening
|
||||
experience while riding. One large pain-point I'd always had was
|
||||
controlling track selection and volume levels while my gloves were on,
|
||||
as smartphones don't respond very well to this, if at all. In 2023 I
|
||||
found out about chubby buttons, a low-power and highly water-resistant
|
||||
media controller specifically designed for use with gloves! The only
|
||||
problem was that it was designed to be worn on your arm using a strap,
|
||||
which isn't very practical on a motorcycle.
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
When starting this project, I'd recently gotten a 3D printer, so having
|
||||
some baseline modelling skills I took some measurements, and began
|
||||
designing a proper mount. I already owned and used many 1" RAM
|
||||
compatible mounts and gear on my bikes, so I decided to make this one
|
||||
natively support the ball size to use an existing clamp I had stored
|
||||
away. This design was the first where I decided to use heat-set inserts
|
||||
in the plastic, along with some medium-strength Loctite on the
|
||||
fasteners, due to the high-vibration environment the mount would see.
|
||||
The print was also done using a UV resistant, high-temp rated, and
|
||||
non-water-absorbing ASA filament, as the direct exposure to the elements
|
||||
would not allow something like cheap PLA to last very long.
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
While my first iteration was sized appropriately and went together with
|
||||
no issues, the ball mount neck ended up snapping due to a low infill
|
||||
percentage. After changing that area to 100% infill, including a handful
|
||||
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>
|
||||
|
||||
@@ -4,6 +4,7 @@ import HobbyLayout from "@layouts/HobbyLayout.astro";
|
||||
import H2 from "@components/H2.astro";
|
||||
import H3 from "@components/H3.astro";
|
||||
import Carousel from "@components/Media/CustomCarousel/CustomCarousel.astro";
|
||||
import PageGroup from "@components/PageGroup.astro";
|
||||
|
||||
import type { carouselGroup } from "@interfaces/image-carousel.ts";
|
||||
|
||||
@@ -39,26 +40,35 @@ const kz750CarouselGroup: carouselGroup = {
|
||||
};
|
||||
---
|
||||
|
||||
<HobbyLayout title="Motorcycling - Lineup">
|
||||
<H2>Current Lineup</H2>
|
||||
<H3>2015 Yamaha FJR 1300</H3>
|
||||
<HobbyLayout title="Lineup" subTitles={["Hobbies", "Motorcycling"]}>
|
||||
<PageGroup>
|
||||
<Fragment slot="header"><H2>Current Lineup</H2></Fragment>
|
||||
<PageGroup>
|
||||
<Fragment slot="header"><H3>2015 Yamaha FJR 1300</H3></Fragment>
|
||||
<Carousel carouselGroup={fjrCarouselGroup} />
|
||||
|
||||
<H3>2021 CSC SG400</H3>
|
||||
</PageGroup>
|
||||
<PageGroup>
|
||||
<Fragment slot="header"><H3>2021 CSC SG400</H3></Fragment>
|
||||
<Carousel carouselGroup={cscCarouselGroup} />
|
||||
|
||||
<H2>Prior Lineup</H2>
|
||||
<H3>2005 Suzuki DRZ 400</H3>
|
||||
</PageGroup>
|
||||
</PageGroup>
|
||||
<PageGroup>
|
||||
<Fragment slot="header"><H2>Prior Lineup</H2></Fragment>
|
||||
<PageGroup>
|
||||
<Fragment slot="header"><H3>2005 Suzuki DRZ 400</H3></Fragment>
|
||||
<Carousel carouselGroup={drzCarouselGroup} />
|
||||
|
||||
<h3 class="my-4 font-bold underline md:text-lg">
|
||||
1991 Kawasaki Concours ZG1000
|
||||
</h3>
|
||||
</PageGroup>
|
||||
<PageGroup>
|
||||
<Fragment slot="header"><H3>1991 Kawasaki Concours ZG1000</H3></Fragment>
|
||||
<Carousel carouselGroup={concoursCarouselGroup} />
|
||||
|
||||
<H3>1979 Kawasaki KZ750</H3>
|
||||
</PageGroup>
|
||||
<PageGroup>
|
||||
<Fragment slot="header"><H3>1979 Kawasaki KZ750</H3></Fragment>
|
||||
<Carousel carouselGroup={kz750CarouselGroup} />
|
||||
|
||||
<H3>1991 Kawasaki Ninja 600R</H3>
|
||||
</PageGroup>
|
||||
<PageGroup>
|
||||
<Fragment slot="header"><H3>1991 Kawasaki Ninja 600R</H3></Fragment>
|
||||
<Carousel carouselGroup={ninjaCarouselGroup} />
|
||||
</PageGroup>
|
||||
</PageGroup>
|
||||
</HobbyLayout>
|
||||
|
||||
@@ -4,6 +4,7 @@ import BaseLayout from "@layouts/BaseLayout.astro";
|
||||
import H2 from "@components/H2.astro";
|
||||
import InlineLink from "@components/InlineLink.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";
|
||||
|
||||
@@ -21,7 +22,8 @@ const headerCarouselGroup: carouselGroup = {
|
||||
|
||||
<BaseLayout title="About" showTitle={false}>
|
||||
<Carousel carouselGroup={headerCarouselGroup} />
|
||||
<H2>Who Am I</H2>
|
||||
<PageGroup>
|
||||
<Fragment slot="header"><H2>Who Am I</H2></Fragment>
|
||||
<Paragraphs>
|
||||
<Paragraph>
|
||||
My name is Corwin Perren, and I'm a multi-disciplinary engineer with a <InlineLink
|
||||
@@ -29,23 +31,24 @@ const headerCarouselGroup: carouselGroup = {
|
||||
> from Oregon State University. For as long as I can remember, I've been fascinated
|
||||
by how things work, never being shy about taking them apart to learn the gritty
|
||||
details. At a young age, I began tinkering, adding lights and fans and doorbells
|
||||
to the pretend cardboard box houses my brother and I would play in. Later, I
|
||||
learned to solder, work on vehicles and engines, install and run Linux, manage
|
||||
enterprise computing infrastructure, build and repair computers, write scripts,
|
||||
and by the end of high school set out with a clear goal for my college years.
|
||||
I wanted to learn and teach myself enough to be able to think up almost any
|
||||
project, encompassing all facets of engineering, and be capable of driving it
|
||||
to completion with my own skill set.
|
||||
to the pretend cardboard box houses my brother and I would play in. Later,
|
||||
I learned to solder, work on vehicles and engines, install and run Linux,
|
||||
manage enterprise computing infrastructure, build and repair computers, write
|
||||
scripts, and by the end of high school set out with a clear goal for my college
|
||||
years. I wanted to learn and teach myself enough to be able to think up almost
|
||||
any project, encompassing all facets of engineering, and be capable of driving
|
||||
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
|
||||
that goal! Through college, I learned electronics and PCB design, embedded
|
||||
and pc programming, basic mechanical design and fabrication, on top of
|
||||
learning how to work well with others in a team. I quickly realized that
|
||||
robotics was an ideal focus due to its inherent multi-disciplinary nature,
|
||||
and joined the OSU Robotics Club, which introduced me to people who are
|
||||
still my best friends today. Through student engineering jobs, I had the
|
||||
unique opportunity to work on some incredible projects such as the
|
||||
that goal! Through college, I learned electronics and PCB design,
|
||||
embedded and pc programming, basic mechanical design and fabrication, on
|
||||
top of learning how to work well with others in a team. I quickly
|
||||
realized that robotics was an ideal focus due to its inherent
|
||||
multi-disciplinary nature, and joined the OSU Robotics Club, which
|
||||
introduced me to people who are still my best friends today. Through
|
||||
student engineering jobs, I had the unique opportunity to work on some
|
||||
incredible projects such as the
|
||||
<InlineLink
|
||||
href="/experience/osu-ceoas-ocean-mixing-group/robotic-oceanographic-surface-sampler"
|
||||
>robotic oceanographic surface sampler</InlineLink
|
||||
@@ -67,13 +70,13 @@ const headerCarouselGroup: carouselGroup = {
|
||||
> at SpaceX in Hawthorne at the end of college, I applied for a <InlineLink
|
||||
href="/experience/spacex/hardware-test-engineer-i-ii"
|
||||
>test engineering</InlineLink
|
||||
> position with the company's Starlink team and was hired in mid-2019. For six
|
||||
years, I developed test system hardware, software, harnesses, mechanical fixtures,
|
||||
devops infrastructure, websites, and tooling to ensure that Starlink, Falcon,
|
||||
Dragon, and Starship component tests were producing well-validated and reliable
|
||||
hardware. Through it all, I got to apply and hone every skill I had developed,
|
||||
while learning countless more. Now though, it's on to the next adventure, whatever
|
||||
that may be!
|
||||
> position with the company's Starlink team and was hired in mid-2019. For
|
||||
six years, I developed test system hardware, software, harnesses, mechanical
|
||||
fixtures, devops infrastructure, websites, and tooling to ensure that Starlink,
|
||||
Falcon, Dragon, and Starship component tests were producing well-validated
|
||||
and reliable hardware. Through it all, I got to apply and hone every skill
|
||||
I had developed, while learning countless more. Now though, it's on to the
|
||||
next adventure, whatever that may be!
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
To learn more about my experiences, hobbies, interests, and skills, feel
|
||||
@@ -85,12 +88,15 @@ const headerCarouselGroup: carouselGroup = {
|
||||
>rfid implant</InlineLink
|
||||
> in my hand!
|
||||
</Paragraph>
|
||||
<Paragraph>
|
||||
<Paragraph class="mt-8 flex flex-col items-center" initialTab={false}>
|
||||
<div>
|
||||
If you're interested in contacting me, feel free to message on <InlineLink
|
||||
href="https://github.com/caperren">LinkedIn</InlineLink
|
||||
>, or via the primary contact methods on my <InlineLink
|
||||
href="/resume/2025-11-10-infrastructure-engineer">resume</InlineLink
|
||||
>.
|
||||
</div>
|
||||
</Paragraph>
|
||||
</Paragraphs>
|
||||
</PageGroup>
|
||||
</BaseLayout>
|
||||
|
||||
Reference in New Issue
Block a user