205 lines
8.8 KiB
HTML
205 lines
8.8 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
<title>ClimbingBoardGPT</title>
|
|
<link rel="stylesheet" href="/static/app.css?v=19" />
|
|
</head>
|
|
<body>
|
|
<!-- Top-level status: the app script replaces this with model readiness. -->
|
|
<header class="site-header">
|
|
<div>
|
|
<p class="eyebrow">ClimbingBoardGPT</p>
|
|
<h1>Board-climbing route generation and grade prediction</h1>
|
|
<p>Transformer demo for Tension Board 2 12x12 and Kilter Board Original 16x12 routes.</p>
|
|
</div>
|
|
<div id="health" class="health">Loading…</div>
|
|
</header>
|
|
|
|
<main class="layout">
|
|
<!-- Left column: generation controls, prediction controls, and project notes. -->
|
|
<section class="controls">
|
|
<div class="card">
|
|
<h2>Generate a climb</h2>
|
|
<label>Board
|
|
<select id="gen-board">
|
|
<option value="tb2">Tension Board 2 (12x12)</option>
|
|
<option value="kilter">Kilter Board Original (16x12)</option>
|
|
</select>
|
|
</label>
|
|
<label>Angle
|
|
<select id="gen-angle"></select>
|
|
</label>
|
|
<label>Target V-grade
|
|
<select id="gen-grade"></select>
|
|
</label>
|
|
<label>Temperature
|
|
<input id="gen-temperature" type="number" value="0.9" min="0.1" max="2.0" step="0.1" />
|
|
<span class="field-help">Lower = safer/common; higher = more creative/weird. Use temperature ≤ 2.</span>
|
|
</label>
|
|
<button id="generate-btn">Generate</button>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<h2>Predict grade</h2>
|
|
<label>Board
|
|
<select id="pred-board">
|
|
<option value="tb2">Tension Board 2 (12x12)</option>
|
|
<option value="kilter">Kilter Board Original (16x12)</option>
|
|
</select>
|
|
</label>
|
|
<label>Angle
|
|
<select id="pred-angle"></select>
|
|
</label>
|
|
<label>Frames string
|
|
<textarea id="pred-frames" rows="5" placeholder="Click holds below, or paste p652r5p631r6p322r6p326r7"></textarea>
|
|
</label>
|
|
<button id="predict-btn" disabled>Predict pasted / clicked climb</button>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<h2>Click holds to build a climb</h2>
|
|
<label>Role for next clicked hold
|
|
<select id="click-role">
|
|
<option value="start">start</option>
|
|
<option value="middle" selected>middle</option>
|
|
<option value="finish">finish</option>
|
|
<option value="foot">foot</option>
|
|
</select>
|
|
</label>
|
|
<div class="button-row">
|
|
<button id="undo-hold-btn" class="secondary">Undo</button>
|
|
<button id="clear-holds-btn" class="secondary">Clear board</button>
|
|
</div>
|
|
<p class="small">
|
|
Click a hold on the board image. The app appends the corresponding
|
|
frame token using the selected semantic role.
|
|
</p>
|
|
<ul id="builder-list" class="builder-list"></ul>
|
|
</div>
|
|
|
|
<div class="card explain" id="explain-card">
|
|
<h2>What the controls mean</h2>
|
|
<dl>
|
|
<dt>Temperature</dt>
|
|
<dd>Sampling randomness. Lower values are more conservative; higher values are more exploratory.</dd>
|
|
|
|
<dt>Target V-grade</dt>
|
|
<dd>The grade token given to the generator. The generated route is also checked by the grade predictor.</dd>
|
|
|
|
<dt>Known climb</dt>
|
|
<dd>An exact match against the tokenized dataset: same board, same angle, and same hold-role set.</dd>
|
|
|
|
<dt>Validity</dt>
|
|
<dd>A structural check: enough holds, no duplicate placements, at least one start, and at least one finish.</dd>
|
|
</dl>
|
|
</div>
|
|
|
|
<div class="card note" id="model-disclaimer-card">
|
|
<h2>Research demo caveat</h2>
|
|
<p>
|
|
This is an experimental model demo. Generated climbs and predicted grades may be wrong, especially at rare grades or sparse board/angle combinations.
|
|
</p>
|
|
</div>
|
|
|
|
<div class="card explain">
|
|
<h2>How this works</h2>
|
|
<p>
|
|
Routes are converted into tokens such as
|
|
<code><BOARD_TB2></code>, <code><ANGLE_40></code>,
|
|
and <code><TB2_p652_start></code>.
|
|
</p>
|
|
<p>
|
|
The generator samples a token sequence. The grade predictor removes the grade token and estimates difficulty from the board, angle, and hold-role tokens.
|
|
</p>
|
|
</div>
|
|
|
|
<div class="card note">
|
|
<h2>Links</h2>
|
|
<ul class="link-list">
|
|
<li><a href="https://pawelsarkowicz.xyz" target="_blank" rel="noreferrer">pawelsarkowicz.xyz</a></li>
|
|
<li><a href="https://github.com/psark007/ClimbingBoardGPT" target="_blank" rel="noreferrer">ClimbingBoardGPT repo</a></li>
|
|
<li><a href="https://github.com/psark007/ClimbingBoardGPT/blob/main/LICENSE" target="_blank" rel="noreferrer">License</a></li>
|
|
<li><a href="https://github.com/psark007/Tension-Board-2-Analysis" target="_blank" rel="noreferrer">Tension Board 2 Analysis repo</a></li>
|
|
<li><a href="https://github.com/psark007/Kilter-Board-Analysis" target="_blank" rel="noreferrer">Kilter Board Analysis repo</a></li>
|
|
<li><a href="https://tensionclimbing.com/products/tension-board-2" target="_blank" rel="noreferrer">Tension Board 2</a></li>
|
|
<li><a href="https://settercloset.com/collections/kilter-board" target="_blank" rel="noreferrer">Kilter Board</a></li>
|
|
<li><a href="https://github.com/karpathy/nanoGPT" target="_blank" rel="noreferrer">nanoGPT</a></li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="card note" id="data-acknowledgement-card">
|
|
<h2>Data acknowledgement</h2>
|
|
<p>
|
|
Board layouts, hold metadata, and route data are derived from Tension Board 2 and Kilter Board datasets.
|
|
This project is unaffiliated with Tension Climbing or Kilter.
|
|
The route generator is inspired by Andrej Karpathy's
|
|
<a href="https://github.com/karpathy/nanoGPT" target="_blank" rel="noreferrer">nanoGPT</a>.
|
|
</p>
|
|
</div>
|
|
|
|
<div class="card note" id="angle-scope-card">
|
|
<h2>Angle scope</h2>
|
|
<p>
|
|
The physical boards can be used at steeper angles than this demo exposes. This model snapshot is intentionally restricted to the angle range used in training/evaluation: TB2 up to 50° and Kilter up to 55°.
|
|
</p>
|
|
<p>
|
|
The restriction avoids asking the models to extrapolate into sparse, noisier high-angle data where grades and route distributions are less reliable.
|
|
</p>
|
|
</div>
|
|
|
|
<div class="card note" id="edge-grade-caveat-card">
|
|
<h2>High-grade caveat</h2>
|
|
<p>
|
|
Generation and prediction are both less reliable at edge-case grades, especially around V10 and above. Those grades are rarer in the data, so the generator has weaker grade control and the predictor has less signal for accurate scoring.
|
|
</p>
|
|
</div>
|
|
|
|
<div class="card note">
|
|
<h2>To-do</h2>
|
|
<p>
|
|
This demo currently focuses on the full-board layouts: Tension Board 2 Mirror 12x12 and Kilter Board Original 16x12. Other board sizes are future work.
|
|
</p>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Right column: generated/predicted route result and SVG board overlay. -->
|
|
<section class="viewer">
|
|
<div class="result-card">
|
|
<div class="result-header">
|
|
<h2 id="result-title">Choose a board and run a request</h2>
|
|
<p id="result-subtitle">The climb overlay will appear below. You can also click holds to build a route for prediction.</p>
|
|
<div id="warning-box" class="warning-box" hidden></div>
|
|
<button id="clear-board-btn" class="secondary clear-board">Clear board</button>
|
|
</div>
|
|
|
|
<p class="result-note">
|
|
Known climb means an exact match against the tokenized dataset for the same board, angle, and hold-role set.
|
|
</p>
|
|
|
|
<div id="board-stage" class="board-stage">
|
|
<img id="board-bg" alt="Board background" />
|
|
<svg id="overlay" xmlns="http://www.w3.org/2000/svg"></svg>
|
|
</div>
|
|
|
|
<details class="json-block">
|
|
<summary>Raw result JSON</summary>
|
|
<pre id="raw-json">{}</pre>
|
|
</details>
|
|
</div>
|
|
</section>
|
|
</main>
|
|
|
|
<!-- External project links and license metadata. -->
|
|
<footer class="site-footer">
|
|
<span>© Pawel Sarkowicz</span>
|
|
<a href="https://pawelsarkowicz.xyz" target="_blank" rel="noreferrer">pawelsarkowicz.xyz</a>
|
|
<a href="https://github.com/psark007/ClimbingBoardGPT" target="_blank" rel="noreferrer">ClimbingBoardGPT</a>
|
|
<a href="https://github.com/psark007/ClimbingBoardGPT/blob/main/LICENSE" target="_blank" rel="noreferrer">License</a>
|
|
</footer>
|
|
|
|
<script src="/static/app.js?v=17"></script>
|
|
</body>
|
|
</html>
|