-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
151 additions
and
114 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
--- | ||
title: "🏃♀️Running AI Running Coach" | ||
author: "Jesus Martinez" | ||
date: "2024-07-02" | ||
categories: [exercise, fitness] | ||
--- | ||
|
||
### I'm not getting any younger 😁 | ||
|
||
Two years ago, back pain became a constant companion. | ||
Forget work and leisure activities – just getting through the day was a battle. | ||
Doctors offered little relief, and exercise, while suggested, was only mentioned because I brought it up. | ||
|
||
<img src="images/vallarta.png" alt="watch" width="400"/> | ||
|
||
Then, a vacation miracle! While in vacation with my family in Puerto Vallarta, the pain started to fade. | ||
I had been spending a lot of time in the water. | ||
Could swimming be the answer? | ||
Soon after returning to home to Houston I signed up for the YMCA and committed to a 5am swimming routine before starting work around 6am. | ||
|
||
### Recovery | ||
|
||
Fast forward 6 months and the pain is 100% manageable. | ||
Increadible! I had always been a fairly active person. | ||
I played a lot of tennis in my life but an unfortunate illness (which probably contributed to my back pain) ended my prospect of ever playing in college at around the age of 16. | ||
Then school became my focus and before I knew it, I was married with kids and a full time job. | ||
It goes without saying that exercise was not the focus of my daily routine. | ||
|
||
I highly suspect this was part of the problem. | ||
In any case, I was super excited to have dodged the bullet of chronic lower back pain at least for the time being. | ||
Undoubtibly, this woke me up and realized I need to stay healthy for a longer period of life, not just to be happy but to provide for my family. | ||
|
||
### Enter the Wearable Tech | ||
|
||
Fast forward to this summer. I've always resisted adding more gadgets to my life, especially those nagging notification machines (phones, social media). But my wife's new Garmin watch, with its focus on fitness and the ability to silence notifications, piqued my curiosity. It could track my swims, runs, cycles, walks, and even sleep – all the activities I enjoy. | ||
She let me test it just to see how well it would measure my swims. | ||
It is surpringly accurate! | ||
|
||
<img src="images/watch.png" alt="watch" width="200"/> | ||
|
||
Sold! Borrowing her watch to test the swim tracking feature sealed the deal. Suddenly, something manual became beautifully automated. | ||
I upgraded to a Garmin Instinct 2 Solar and haven't looked back. | ||
Setting a goal to run a 5k under 25 minutes, I can now create a training plan and monitor my progress, preventing overexertion. | ||
|
||
## From Personal Progress to AI Project | ||
|
||
This newfound world of fitness data has sparked a side project for the rest of the summer: an AI coach prototype. | ||
The idea? Record my running form and link it to the data my Garmin provides. The challenge is figuring out how to tie it all together and use natural language to provide realistic feedback on correcting my form. | ||
|
||
<img src="images/seeya.png" alt="watch" width="200"/> | ||
|
||
|
||
Stay Tuned! | ||
|
||
Over the summer, I'll be documenting the development of this AI coach prototype. Follow along to see if I can turn this data into a helpful training companion (and maybe help others improve their form too!). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,162 +1,144 @@ | ||
// Sandstone 5.1.3 | ||
// Bootswatch | ||
/*-- scss:defaults --*/ | ||
|
||
$theme: "spacelab" !default; | ||
$theme: "sandstone" !default; | ||
|
||
// | ||
// Color system | ||
// | ||
|
||
$white: #fff !default; | ||
$gray-100: #f8f9fa !default; | ||
$gray-200: #eee !default; | ||
$gray-300: #dee2e6 !default; | ||
$gray-200: #f8f5f0 !default; | ||
$gray-300: #dfd7ca !default; | ||
$gray-400: #ced4da !default; | ||
$gray-500: #999 !default; | ||
$gray-600: #777 !default; | ||
$gray-500: #98978b !default; | ||
$gray-600: #8e8c84 !default; | ||
$gray-700: #495057 !default; | ||
$gray-800: #333 !default; | ||
$gray-900: #2d2d2d !default; | ||
$gray-800: #3e3f3a !default; | ||
$gray-900: #212529 !default; | ||
$b-text: #111 !default; | ||
$black: #000 !default; | ||
|
||
$blue: #446e9b !default; | ||
$blue: #325d88 !default; | ||
$indigo: #6610f2 !default; | ||
$purple: #6f42c1 !default; | ||
$pink: #e83e8c !default; | ||
$red: #cd0200 !default; | ||
$orange: #fd7e14 !default; | ||
$yellow: #d47500 !default; | ||
$green: #3cb521 !default; | ||
$red: #d9534f !default; | ||
$orange: #f47c3c !default; | ||
$yellow: #ffc107 !default; | ||
$green: #93c54b !default; | ||
$teal: #20c997 !default; | ||
$cyan: #3399f3 !default; | ||
$cyan: #29abe0 !default; | ||
|
||
$primary: $blue !default; | ||
$secondary: $gray-500 !default; | ||
$secondary: $gray-600 !default; | ||
$success: $green !default; | ||
$info: $cyan !default; | ||
$warning: $yellow !default; | ||
$warning: $orange !default; | ||
$danger: $red !default; | ||
$light: $gray-200 !default; | ||
$dark: $gray-800 !default; | ||
|
||
$min-contrast-ratio: 2.65 !default; | ||
$min-contrast-ratio: 2 !default; | ||
|
||
// Background | ||
|
||
$background-color: $gray-300 !important; | ||
|
||
// Body | ||
|
||
$body-color: $gray-600 !default; | ||
$body-color: $b-text !default; | ||
|
||
// Links | ||
|
||
$link-color: $info !default; | ||
$link-color: $blue !default; | ||
|
||
// Fonts | ||
|
||
// stylelint-disable-next-line value-keyword-case | ||
$font-family-sans-serif: "Open Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol" !default; | ||
$headings-color: $gray-900 !default; | ||
$font-family-sans-serif: Roboto, -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol" !default; | ||
$headings-font-weight: 400 !default; | ||
|
||
// Dropdowns | ||
|
||
$dropdown-link-color: $gray-600 !default; | ||
$dropdown-link-hover-color: $dropdown-link-color !default; | ||
$dropdown-link-hover-bg: $gray-200 !default; | ||
$dropdown-link-active-color: $dropdown-link-color !default; | ||
$dropdown-link-active-bg: $dropdown-link-hover-bg !default; | ||
|
||
// Navs | ||
|
||
$nav-link-padding-x: .9rem !default; | ||
$nav-link-disabled-color: $gray-300 !default; | ||
$nav-tabs-border-color: $gray-300 !default; | ||
$nav-tabs-link-hover-border-color: $gray-300 !default; | ||
$nav-tabs-link-active-bg: $white !default; | ||
$nav-pills-link-active-color: $gray-600 !default; | ||
$nav-pills-link-active-bg: $gray-200 !default; | ||
|
||
// Navbar | ||
|
||
$navbar-dark-color: rgba($white, .75) !default; | ||
$navbar-dark-hover-color: $white !default; | ||
$navbar-light-color: rgba($black, .4) !default; | ||
$navbar-light-hover-color: $info !default; | ||
$navbar-light-active-color: $info !default; | ||
$navbar-light-hover-color: $black !default; | ||
$navbar-light-active-color: $black !default; | ||
|
||
// Pagination | ||
|
||
$pagination-color: $gray-600 !default; | ||
$pagination-bg: $gray-200 !default; | ||
$pagination-border-color: $gray-300 !default; | ||
$pagination-hover-color: $pagination-color !default; | ||
$pagination-active-color: $pagination-color !default; | ||
$pagination-active-bg: $gray-300 !default; | ||
$pagination-active-border-color: $gray-300 !default; | ||
$pagination-disabled-color: $gray-300 !default; | ||
$pagination-disabled-bg: $gray-200 !default; | ||
$pagination-disabled-border-color: $pagination-border-color !default; | ||
|
||
/*-- scss:rules --*/ | ||
// Cards | ||
|
||
$card-border-color: rgba($gray-300, .75) !default; | ||
$card-cap-bg: rgba($gray-200, .25) !default; | ||
|
||
// Variables | ||
// Popovers | ||
|
||
$web-font-path: "https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,400;0,700;1,400;1,700&display=swap" !default; | ||
@if $web-font-path { | ||
@import url($web-font-path); | ||
} | ||
$popover-header-bg: $gray-200 !default; | ||
|
||
// Mixins = | ||
// Modals | ||
|
||
@mixin btn-shadow($color) { | ||
@include gradient-y-three-colors(tint-color($color, 24%), $color, 50%, shade-color($color, 8%)); | ||
filter: none; | ||
border: 1px solid shade-color($color, 20%); | ||
} | ||
$modal-content-border-color: $gray-300 !default; | ||
$modal-header-border-color: $modal-content-border-color !default; | ||
|
||
// Navbar | ||
// Progress bars | ||
|
||
$progress-bg: $gray-300 !default; | ||
$progress-border-radius: 10px !default; | ||
$progress-bar-color: $primary !default; | ||
|
||
// List group | ||
|
||
$list-group-border-color: $gray-300 !default; | ||
$list-group-hover-bg: $gray-200 !default; | ||
$list-group-active-color: $body-color !default; | ||
$list-group-active-bg: $gray-200 !default; | ||
$list-group-active-border-color: $gray-300 !default; | ||
$list-group-disabled-color: $gray-500 !default; | ||
$list-group-disabled-bg: $white !default; | ||
$list-group-action-color: $list-group-active-color !default; | ||
$list-group-action-active-color: $list-group-active-color !default; | ||
$list-group-action-active-bg: $gray-300 !default; | ||
|
||
// Breadcrumbs | ||
|
||
.navbar { | ||
.nav-link, | ||
.navbar-brand { | ||
text-shadow: -1px -1px 0 rgba($black, .1); | ||
transition: color ease-in-out .2s; | ||
} | ||
|
||
@each $color, $value in $theme-colors { | ||
&.bg-#{$color} { | ||
@include btn-shadow($value); | ||
} | ||
} | ||
|
||
&.bg-light, &.navbar-default { | ||
.nav-link, | ||
.navbar-brand { | ||
text-shadow: 1px 1px 0 rgba(255, 255, 255, .1); | ||
} | ||
|
||
.navbar-brand { | ||
color: $navbar-light-color; | ||
|
||
&:hover { | ||
color: $info; | ||
} | ||
} | ||
} | ||
} | ||
|
||
// Buttons | ||
|
||
.btn { | ||
text-shadow: -1px -1px 0 rgba($black, .1); | ||
|
||
&-link { | ||
text-shadow: none; | ||
} | ||
} | ||
|
||
@each $color, $value in $theme-colors { | ||
.btn-#{$color} { | ||
@include btn-shadow($value); | ||
} | ||
|
||
.btn-#{$color}:not(.disabled):hover { | ||
@include btn-shadow(shade-color($value, 8%)); | ||
} | ||
} | ||
|
||
[class*="btn-outline-"] { | ||
text-shadow: none; | ||
} | ||
|
||
// Indicators | ||
|
||
.badge { | ||
&.bg-light { | ||
color: $dark; | ||
} | ||
} | ||
|
||
// Containers | ||
|
||
.card, | ||
.list-group-item { | ||
h1, | ||
h2, | ||
h3, | ||
h4, | ||
h5, | ||
h6 { | ||
color: inherit; | ||
} | ||
} | ||
$breadcrumb-padding-y: .375rem !default; | ||
$breadcrumb-padding-x: .75rem !default; | ||
$breadcrumb-bg: $pagination-bg !default; | ||
$breadcrumb-border-radius: .25rem !default; | ||
|
||
// Close | ||
|
||
$btn-close-color: $white !default; | ||
$btn-close-opacity: .8 !default; | ||
$btn-close-hover-opacity: 1 !default; |