Biomechanical ML coaching that perfects your form, and tracks your workout in real-time.
Built at BACSA Hacks 2026
Next.js · TailwindCSS · Three.js · MediaPipe · Flask · Gemini · MongoDB
70% of gym injuries are caused by bad form. People new to working out are 2.5× more likely to get injured and a personal trainer costs hundreds of dollars an hour. We built FormCop, a browser-based ML fitness coach that watches you work out in real time, counts your reps, corrects your posture, and stores your full workout history.
- 3D animated exercise selector with Mixamo FBX models rendered via Three.js / R3F
- Real-time pose tracking using a custom-tuned MediaPipe ML model with EMA smoothing
- Live coaching overlay via instant text instructions while you move
- Automatic rep counting with per-rep joint angle logging (Pushup, Squat, Bicep Curl)
- Duration tracking for timed exercises (Plank, Wall Sit, Handstand)
- AI form analysis powered by Gemini 2.5 Flash Lite — full set feedback after every set
- Workout session tracker to see every set and rep logged in the current session
- Full workout history dashboard with all past sessions stored in MongoDB
| Exercise | Type | Tracked Metric |
|---|---|---|
| Squat | Dynamic | Reps + joint angles |
| Bicep Curl | Dynamic | Reps + elbow angles |
| Pushup | Dynamic | Reps + back / elbow angles |
| Plank | Static | Hold duration (seconds) |
| Wall Sit | Static | Hold duration (seconds) |
| Handstand | Static | Hold duration (seconds) |
| Layer | Technology |
|---|---|
| Frontend | Next.js 16 (App Router), Tailwind CSS, Framer Motion |
| 3D Rendering | Three.js via React Three Fiber + Drei, Mixamo FBX models, SkeletonUtils |
| Pose ML | MediaPipe PoseLandmarker (GPU delegate) with custom EMA smoothing filter |
| Set Feedback | Google Gemini 2.5 Flash Lite — receives joint angles, timestamps & rep data |
| Backend | Python Flask (modular blueprints), Flask-CORS |
| Database | MongoDB Atlas (cloud) — stores users, passwords, and workout history as JSON |
| Auth | Username/password via MongoDB + localStorage persistence (AuthContext) |
| State | React Context API — AuthContext, WorkoutContext |
- Node.js 18+
- Python 3.10+
- MongoDB Atlas account (free tier works)
- Google Gemini API key
git clone https://github.com/BryanYeeee/FormCop.git
cd formcopcd frontend
npm install
npm run devThe Next.js dev server starts at http://localhost:3000
cd backend
python -m venv venv && source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txtCreate a .env file in the backend folder:
GEMINI_API_KEY=your_gemini_api_key_here
Update the MongoDB URI in mongo/mongo.py with your Atlas connection string, then:
python app.pyThe Flask API starts at http://localhost:8080
In your Atlas cluster create a database named bacsa with a collection named userinfo. Insert at least one user document:
{ "username": "yourname", "password": "yourpassword", "workouts": [] }- User logs in →
POST /mongo/→ username stored in AuthContext + localStorage - User selects exercise → ExerciseSelector →
router.push('/workout/[id]') - PoseTracker runs MediaPipe on webcam frames, calculates joint angles via
processPose - Each rep is stored in
repTrackingstate with peak angles + timestamp - User taps Submit Set → Gemini analysis → FeedbackPanel displayed
- User taps Finish →
addSet()called on WorkoutContext →router.push('/tracker') - User either repeats steps 2-6 or taps End Workout →
endWorkout(username)→POST /mongo/new→ clears context →router.push('/home') - Dashboard fetches
GET /mongo/get?username=...→ renders collapsible workout cards
| Method | Endpoint | Description |
|---|---|---|
POST |
/mongo/ |
Login — body: { username, password } |
POST |
/mongo/new |
Save workout — body: { username, workout } |
GET |
/mongo/get |
Fetch workouts — query: ?username=xxx |
POST |
/api/ |
Analyze form — body: { name, angles, forces } |
- Rian Mehta (BCS)
- Faiyad Ahmed Masnoon (BCS)
- Bryan Yee (BCS)
- Martin Lam (KPE)
Built in under 12 hours at BACSA hacks