How Eigenride works

Eigenride compares bikes by how they are likely to behave for you, not just by their geometry numbers. This page explains the model behind every number on the site: what it captures, what it assumes, where each default comes from and where it stops being useful.

The short version: we turn a published geometry chart, a typical build and your rider profile into the 25 parameters of the linearised Carvallo-Whipple bicycle model (Meijaard et al. 2007), then study that model's hands-free stability and steady-turn steering. Everything that is estimated rather than measured is labelled as an estimate, and we show how much the headline results move when the estimates are wrong.

Every default number quoted below lives in one file, engine/src/bikedyn/constants.json. Both engines (the Python reference and the TypeScript engine that runs in your browser) read that same file, so this page, the reference engine and the site cannot drift apart. If a value here and a value in constants.json ever disagree, constants.json is right and this page is out of date.

1. The model

The Whipple bicycle

The Carvallo-Whipple model treats a bicycle as four rigid bodies joined by two hinges:

Body What it contains in Eigenride
R, rear wheel Rim, tyre, sealant or tube, spokes, rear hub, rotor
B, rear frame Frame, seatpost, saddle, crankset and pedals, chain, cassette, rear derailleur, rear brake, and the whole rider
H, front frame Fork, headset, stem, bar, levers or brakes and shifters, front brake, any front load
F, front wheel As the rear wheel, with the front hub

The wheels are knife-edged discs that roll without slipping on flat, level ground. The rider is rigidly attached to the rear frame and does not touch the bars: this is a hands-free model. Linearising about straight-ahead, upright running at constant speed v gives two coupled equations in lean angle phi and steer angle delta:

M q'' + v C1 q' + (g K0 + v^2 K2) q = f,     q = [phi, delta]

M, C1, K0 and K2 are 2 by 2 matrices built from the 25 benchmark parameters (wheelbase w, trail c, steer axis tilt lambda, gravity g, and the mass, centre of mass and inertia of each body). Eigenride uses the formulas published by Meijaard, Papadopoulos, Ruina and Schwab (2007) exactly as written. For their benchmark bicycle both engines reproduce the published matrices to 14 digits and give a weave speed of 4.2923825 m/s and a capsize speed of 6.0242620 m/s, within 1e-9 m/s of the same speeds computed independently in 40-digit arithmetic.

What we compute from it

Eigenvalues and modes. For each speed we compute the four eigenvalues of the state matrix. A negative real part means that motion dies away; a positive one means it grows. The modes are named from the eigenvalues at each speed:

Charts colour modes consistently across speed by following each eigenvalue from one speed to the next (the matching that moves them the least), not by re-sorting at every speed.

Stability window. The speeds at which every mode is stable: from the weave speed up to the capsize speed. We sweep 0 to 15 m/s (0 to 54 km/h) in 0.05 m/s steps and then refine each crossing to about 1e-12 m/s with Brent's method. The capsize speed is cross-checked with the closed-form speed at which det(g K0 + v^2 K2) = 0.

Mode detail at evaluation speeds. Weave frequency (Hz) and damping ratio, capsize time constant (1 / real part, shown only when capsize is unstable) and castering time constant. Every bike, of every category and on every page, is evaluated at the same four speeds: 10, 20, 30 and 40 km/h, so bikes of different families compare fairly. Every steering figure shown as a single number (in a headline, the summary, a sensitivity or an uncertainty range) is at the reference speed, 10 km/h: the lowest evaluation speed, where bikes differ most.

Steady-turn steering. In a steady turn at small lean with no lean torque from the rider, the model gives two ratios:

2. From a geometry chart to model parameters

Frame placement

We place the frame in a side view with the bottom bracket (BB) at the origin, x forward and z up, using the numbers manufacturers publish:

Changes to the build and pitch correction

Build changes are applied to the frame first, then the whole bike is rotated about the BB until the ground line touches both tyres again ("pitch correction"). All reported angles, trail, wheelbase, front and rear centre and BB height come from the rotated points. A positive pitch change means nose up (slacker).

Examples the tests check: a 73 degree head angle, 45 mm offset and 339 mm wheel radius give 56.6 mm of trail; fitting a 27.5 inch rear wheel to a 29er of about 1250 mm wheelbase slackens the head angle by about 1 degree (0.8 to 1.1) and lowers the BB by about 12 mm (10 to 14).

Static geometry metrics

Metric Definition
Trail (rF sin(lambda) - offset) / cos(lambda), lambda = 90 degrees - head angle, after pitch correction
Mechanical trail trail x cos(lambda) (perpendicular distance from the contact patch to the steer axis)
Wheel flop trail x sin(head angle) x cos(head angle)
Wheelbase, front centre, rear centre horizontal axle-to-axle, BB-to-front-axle and BB-to-rear-axle distances
BB height ground to BB centre with the tyres on this build
Front wheel load the share of the total weight (rider, bike and any front load) on the front wheel, standing still
Saddle-to-bar reach and drop from your saddle point to the hand position on this build, forward and down (negative is above): what the setup gives, against your bike fit's hand reach and hand drop
Toe clearance the gap between your shoe's toe and the front tyre, with the crank forward and level, in side view; negative is overlap (needs a shoe size; the fit search's computation, below)
Pedal strike the lean at which the inside pedal, at the bottom of its stroke, comes within 10 mm of flat ground, and the speed at which a steady turn in a 10 m radius corner needs that lean

Pedal strike. The inside pedal is at the bottom of its stroke: its underside sits 10 mm below the spindle, so its height above the ground is the BB height less the crank length and 10 mm. Its outer edge sits the half Q-factor (75 mm road and gravel, 85 mm mountain) plus 55 mm of pedal outboard of the centre plane. The whole bike leans about the line through the two tyre contact points, so a point at height h and y to the inside of the turn comes down to h cos(lean) - y sin(lean). The pedal strike lean is the lean at which that is 10 mm, the clearance a rider needs to keep pedalling. The speed is the one at which a steady turn in a 10 m radius corner needs that lean, v = sqrt(g R tan(lean)) with R = 10 m, so "Pedal strike: 27° lean, above 25 km/h in a 10 m corner" means that pedalling through that corner any faster puts the pedal on the ground. When the pedal is already within 10 mm of the ground with the bike upright (a very low BB with long cranks), the lean and speed are 0 and the site says "pedal within 10 mm of the ground upright". The bike is rigid and unloaded on a thin tyre: tyre squash, suspension sag and the tyre rolling onto its shoulder make real clearance a little smaller, and a rider leaning the bike more or less than the body changes the lean the bike needs. The clearance and the corner radius are pedal_strike in constants.json.

Data checks

When a chart publishes wheelbase, front centre, trail or both BB drop and BB height, we compare them with what the other numbers imply and flag differences of more than 5 mm (wheelbase, front centre, BB height) or 3 mm (trail). We also flag values outside plausible ranges (for example head angle 60 to 76 degrees, chainstay 370 to 480 mm; the full list is validation.ranges) and missing fields the dynamics need (stack, reach, head angle, fork offset, chainstay).

3. The rider

You are 85 to 90% of the total mass, so where your mass sits matters more than most frame numbers. Eigenride builds you from 16 rigid segments (head, upper, middle and lower trunk, and left and right upper arm, forearm, hand, thigh, shank and foot) using the segment masses, centre of mass positions and radii of gyration of de Leva (1996). The body model setting (Rider button) picks the table: male (the default; reference stature 1741 mm) or female (reference stature 1735 mm). Segment lengths scale with your height; arm segments are further scaled to your arm length. Leg segments are scaled to your inseam in the same way for both tables: thigh plus shank is the same multiple of the inseam (1.046, the male table's at the default inseam), and the female table only changes how that length splits between thigh and shank. Segment masses scale with your mass and always add up to it exactly.

Compared with the male table, the female one puts more of the mass in the thighs, hips and lower trunk and less in the upper trunk, arms and head, with a shorter upper trunk, forearm, hand and foot. For the same height, mass and bike this moves the rider's centre of mass a little forward and changes the trunk and arm inertia; the effect on the stable window is small (about a tenth of a km/h for a typical road bike).

The female numbers are de Leva's Table 4, female column, cross-checked against two independent reproductions (the Visual3D documentation of the table and the biobuddy biomechanics library). The model also needs the heights of two landmarks, the suprasternale (top of the breastbone) and the shoulder joint centres, which place the neck and the shoulders on the trunk. For both tables they come from de Leva's own Tables 2 and 3: suprasternale 0.8079 x height and shoulder joints 0.7985 x height for men, 0.8092 and 0.7911 for women. These reproduce the paper's hip-to-suprasternale and hip-to-shoulder trunk lengths for each sex. (Before engine 0.4.0 the male ratios were 0.8363 and 0.7982, of unrecorded origin; they gave a hip-to-shoulder trunk about 10% shorter than de Leva's and a longer neck gap.)

Estimated when you leave a measurement blank

Measurement Estimated as
Inseam 0.47 x height
Arm length (shoulder joint to wrist) de Leva upper arm plus forearm: 0.3163 x height (male), 0.3109 x height (female)
Shoulder width 0.226 x height
Saddle height (BB centre to the saddle point, in a straight line) 0.883 x inseam, lowered by any crank length above 170 mm
Saddle setback (how far the saddle point sits behind the BB, measured level) the saddle point on the reference seat angle for the category family at your saddle height: 73.5 degrees road, 73 gravel, 75.5 mountain
Crank length (when the maker does not publish it) 172.5 mm (road, gravel), 175 mm (XC), 170 mm (trail, enduro), 165 mm (DH)

Defaults when you leave a riding input blank

Input Default
Hand position hoods on a drop bar; on a flat bar the hands are always on the grips
Power 200 W on road bikes, 180 W on gravel and mountain bikes
Cadence 90 rpm on road bikes, 85 on gravel, 80 on mountain bikes
Hand load limit 30% of your weight

The saddle point is where the sit bones rest, about halfway between the nose and the tail of the saddle; saddle height and setback are both measured to it. The saddle height and setback make the estimated saddle, one rule every page uses: the analysis and the fit search place you the same way, and nothing moves the saddle afterwards. The frame's own seat angle shows only as the saddle offset in the fit search (the seatpost setback the frame needs). The measurements are estimates for a generic adult and are labelled "Estimated"; the riding inputs are defaults, labelled "Default". A shoe size is never estimated: without one, toe clearance is not worked out.

Each length has one allowed range, the same in the rider profile dialog, on the fit page and in the engine (rider.ranges_mm): inseam 550 to 1100 mm, arm length 450 to 900 mm, shoulder width 280 to 550 mm, saddle height 500 to 950 mm, saddle setback 0 to 350 mm, hand reach 200 to 900 mm and hand drop -300 to 250 mm.

Only the arm length estimate depends on the body model, because it comes straight from the de Leva tables. The inseam, shoulder width and saddle height ratios, and the hip and shoulder spacing below, are the same for both: we have no source for sex-specific values that fits this model, so if yours differ, enter your own measurements.

Pose

  1. Pelvis on the saddle: the hip joints sit 0.040 x height above and 0.020 x height ahead of the saddle point, 0.049 x height either side of the centreline.
  2. Feet on the pedals, cranks horizontal (right pedal forward), ball of the foot over the spindle, a 15 mm sole and pedal stack. Knees come from two-link inverse kinematics.
  3. Hands on the bars. Hand contact relative to the bar clamp centre (forward, up): hoods (75, 15) mm, drops (35, -115) mm, tops (0, 0) mm, grips (-40, 25) mm. Hands are spaced at the bar width (hoods, drops), 120 mm either side of the stem (tops) or 70 mm in from the bar ends (grips). Default bar widths: 400 mm (road race), 420 mm (endurance), 440 mm (gravel), 760 to 800 mm (mountain).
  4. Trunk angle is solved so that your arms reach the hands with a 15 degree elbow bend. If the bars are out of reach the arms are modelled straighter; if they are unusually close, the trunk is set to 80 degrees. Both cases are flagged.
  5. Head in line with the trunk, raised to at least 65 degrees from horizontal so the eyes look forward.

Each segment's inertia is built about its own axes, rotated into the bike's axes and added to the rear frame with the parallel axis theorem. The model is symmetric left to right, so the small products of inertia from the horizontal cranks are dropped.

Contact loads

How your weight splits between hands, saddle and pedals, and the core strength required, in steady seated pedalling on the flat, from the same posed rider. It is a static, side-view model with vertical forces only:

The page flags a setup when the hand load is over your hand load limit (default 30% of your weight), when core strength required is over 100% ("more than a typical rider holds sitting hands-free at 60 degrees"), or when the hands would have to pull up on the bars.

For a 1830 mm, 78 kg rider on a road bike on the hoods the model gives 24 to 26% of body weight on the hands at 200 W and 18 to 20% at 400 W, and about half on the saddle at 100 to 200 W, in line with load-cell measurements of 49 to 52% on the saddle at 125 W. In the model the saddle's fore-aft position and the hand position set the hand load (a saddle further forward, or the drops, load the hands); stem length and spacers mostly change the trunk angle.

Not modelled: aerodynamic drag (it unloads the hands a little at speed), standing, horizontal forces at the hands and saddle, and where on the saddle you actually sit (the model puts all the saddle load at the saddle point). The loads are not calibrated against hand and pedal measurements and are shown as estimates.

Relative drag

How much air a setup puts in your way, compared with yourself in a reference position. It is a comparison of positions from the same posed rider, not a measured drag coefficient.

For a 1830 mm, 78 kg rider on the hoods the model gives about 100% on a road race bike, 102% on an endurance bike, 106% on a gravel bike and 115 to 118% on a mountain bike, and each 20 mm of spacers adds about half a point. Anything that scales every position alike (the real drag coefficient, clothing, helmet, air density) cancels in the percentage, and the body proportions of the rider mostly cancel too.

Frontal area rises only slowly with trunk angle. In photographs of 21 cyclists it scaled with trunk angle to the power 0.0965 in time trial positions (Heil 2001), and the bicycle added a nearly constant 0.12 m² of frontal area in road positions (Heil 2002). Measured drag changes between positions are often larger than frontal area alone suggests, because the drag coefficient changes too; the model keeps it fixed, so it probably understates the difference between an upright and a low position. Not modelled: wind and yaw, clothing, helmet, bottles and bags, the shape of the frame and wheels beyond the tyre, and pedalling legs (the cranks stay horizontal).

Hand reach and drop errors

Your bike fit is complete when your rider profile has a saddle height, saddle setback, hand reach and hand drop: the reach and drop are measured from the saddle point, so they mean something only from a known saddle. Every setup has a saddle-to-bar reach and drop: from your saddle point to the hand position its build gives. With a complete bike fit, the engine works out for every setup how far that is from yours: the hand reach error is the saddle-to-bar reach minus your hand reach (positive is further forward), and the hand drop error is your hand drop minus the saddle-to-bar drop (positive is higher), in mm. The comparison shows them, and the fit search uses the same numbers to judge a size.

Fit search

The fit page asks which sizes fit you, and with what build. The saddle is always your rider profile's: your saddle height and setback, or the estimated saddle where you have not given them. The search never moves it. The hand position is yours (hoods by default; the grips on a flat bar). The two modes differ only in where the hands go:

For each frame the stem clamp moves up the steer axis with spacers and along the stem, so for each stem angle you can buy (-17 to +17 degrees on drop bars, -10 to +10 on flat bars) the stem length and spacer stack that put the hands where they need to be solve a 2 by 2 linear system. Lengths are kept within limits, rounded to 10 mm stems and 5 mm spacers, and the best angle kept: first a hand point within 8 mm, then the fewest parts outside their usual ranges, then the angle closest to the category's usual one. The saddle offset is the setback you need against the frame's seat line at your saddle height; a setback post and rail travel cover -10 to +25 mm easily and -20 to +45 mm at a stretch.

Seatpost. The saddle also has to be reachable up and down. The seatpost showing is your saddle height along the seat line, less the seat tube length and 55 mm from the saddle point down to the rails. Too much and the frame is too small (a long post, flex, and past the minimum insertion); too little and it is too big. On road and gravel bikes 100 to 250 mm is usual and 60 to 300 mm the limit (a 350 to 400 mm post). On mountain bikes the post is a dropper, which needs room: 180 to 280 mm usual (about a 150 mm dropper and up), 140 to 320 mm the limit. Downhill bikes are ridden with the saddle low and are not checked. Seat tube lengths are as published, which mixes centre-to-top and centre-to-centre; the difference (10 to 20 mm) is inside the ranges.

Hip and knee through the pedal stroke. For your saddle the model turns the cranks through a full circle (5 degree steps), with the ball of the foot over the spindle and the foot tipped toe down from 0 degrees at the top of the stroke to 10 at the bottom, and solves the knee as in the pose, with the trunk at the angle of the pose on the fitted build. It reports the closed hip angle (trunk line to thigh, at its smallest, near the top) and the knee bend at the bottom and top (0 is a straight leg). The limits are fitters' rules of thumb, not measurements: the hip no more closed than 45 degrees (a floor quoted mostly from time-trial fitting), the knee bent no more than 115 degrees at the top (120 on mountain bikes; 110 and 115 are the usual targets), and 25 to 40 degrees at the bottom (25 to 45 on mountain bikes; 25 to 35 is the static target). An angle outside these ranges is a warning that says which way the saddle would need to move; it never moves the saddle and never changes the verdict. Moving the saddle forward opens the hip by about 1 degree per 10 mm; so does raising the trunk, degree for degree. The same warnings appear wherever the size and build are shown: the bike page, the fit page and the comparison.

In practice the hip limit rarely binds on a road or mountain bike: with the trunk at 45 degrees the model's closed hip angle is about 70 degrees, and it falls to 45 only with the trunk near 20 degrees, an aero position. A saddle that is low for your legs is what usually trips the knee limit. The knee at the bottom of the stroke is set mostly by saddle height and turns on how you angle your foot (another 10 degrees of toe down at the bottom adds 5 to 10 degrees of knee bend), so it is reported but only flagged when you gave the saddle height. The angles are flagged in the results either way when they fall outside these ranges.

Toe clearance. With your shoe size, each size also gets the toe clearance: the gap between the shoe's toe and the front tyre, with the crank forward and level, in side view (as when the bars turn). Foot length is 6.67 x EU size - 15 mm, with the ball of the foot over the spindle (72% of foot length from the heel), a 10 mm toe box and the toe 20 mm above the spindle. Any overlap makes a size fit only with compromises, since it is common and legal on small road frames; more than 20 mm of overlap means it does not fit, because the toe will catch the tyre in slow, tight turns. Without a shoe size it is not checked.

A size fits when the hands land within 8 mm with usual parts (stems of 80 to 130 mm road, 60 to 120 gravel, 35 to 80 mountain; up to 40 mm of spacers; stem angles up to 10 degrees), the seatpost showing is in the usual range and, with a shoe size, the toe clears the tyre. It fits with compromises when everything is within its limits but the stem length, stem angle, spacers, saddle offset, seatpost showing or toe clearance is outside the usual range (each is named in the reasons with that range), and does not fit otherwise. When no stem and spacers sold can put the hands where they need to be, the reason gives the closest build and says whether the parts could not reach far enough down or up. Each fitted build carries the contact loads at your power, and opens in the comparison with its parts, so its stability and steering are for the bike as you would set it up; analysing that size at that build gives the same saddle, saddle-to-bar reach and drop, trunk angle, hand load and core strength required as the fit page.

The fit page groups its results by model (brand, model and year), each model's sizes in size-run order. Models are ordered by their best verdict, then by brand and model name, then newest year first, so a model's sizes read together, as on its bike page. Until you show every size, each model shows only its best size: the size that fits without compromises with the hands closest to where they need to be (the smallest hand miss, the earlier size in the size run on a tie). Models with no such size are hidden until then.

4. Masses of the bike

The masses of the frame, fork, wheels and other parts are category presets (components.by_category and wheels.by_category in constants.json), always listed as estimates. They cannot be entered.

Category Frame Fork Wheel (front / rear, 700c or 29)
Road race 0.95 kg 0.40 kg about 1.05 / 1.2 kg
Road endurance 1.10 kg 0.45 kg about 1.2 / 1.35 kg
Gravel 1.20 kg 0.50 kg about 1.4 / 1.55 kg
XC 1.90 kg 1.50 kg about 1.6 / 1.75 kg
Trail 2.90 kg 2.00 kg about 2.1 / 2.25 kg
Enduro 3.30 kg 2.40 kg about 2.4 / 2.6 kg
DH 4.20 kg 2.90 kg about 2.7 / 2.9 kg

5. Uncertainty, sensitivity and the summary

Uncertainty ranges

Masses and the rider's exact position are estimates, so every analysis is repeated at the four corners of: all estimated bike masses and inertias x 0.8 or x 1.2, and the whole rider moved 30 mm forward or back. Each headline metric (weave and capsize speed, window width, front wheel load, and turning force, steer torque and steer-to-lean ratio at the reference speed) is shown with the range over the nominal run and these four.

Speeds are only found inside the analysed speed range (0 to 54 km/h by default). When a run's capsize speed lies above the top of that range, it counts as the top of the range and the range is marked open-ended there ("beyond"); likewise a weave speed below the bottom of the range. A stable window that runs into either end of the range has a width that is only a lower bound, so its range is also marked open-ended. A run with no stable window at all counts as a width of zero. Open-ended ranges are never narrower than what the runs show; the true spread can be wider.

What moves this bike

For each bike we change one adjustable input at a time and report the change in weave and capsize speed, trail, front wheel load and turning force at the reference speed per step: +1 degree head angle, +5 mm fork offset, +10 mm stem, +10 mm spacers, +2 mm tyre width (front and rear) and +1 kg front load. We use central differences (half the difference between one step up and one step down), except for front load when there is none to remove, where we use one step up against the nominal. The head angle is changed with an angle-set, and the frame's pitch takes back part of each step (see above: a 1 degree angle-set moves the head angle on the ground by only about 0.75 degrees), so those effects are divided by the head angle change that actually results. The row is per degree of the head angle we report.

Plain-language summary

The summary is generated by fixed rules, never by a language model. Each bike is compared with Bike A. A difference is reported only if it is at least a threshold (turning force 15% or, when percentages make no sense, 1 N per g; trail 3 mm; weave or capsize speed 1 km/h; window width 1.5 km/h; front wheel load 2 percentage points) and larger than the uncertainty range of either bike. Otherwise the bikes are called similar. At most four differences are listed, in this order: turning force, trail, weave speed, window width, capsize speed, front wheel load.

Turning force (the force at each hand to hold a turn, at the reference speed) comes first because that is where bikes really differ: across the catalogue the hands-free stable window moves by a few km/h at most, since the rider dominates it, while the force a turn takes varies by a factor of four or more between road and mountain bikes. When a sentence says nothing about stability and both bikes have a stable window, it ends by saying their hands-free stability is similar.

If only one of the two bikes has a hands-free stable window, the summary says so first and never calls the bikes similar. A speed beyond the analysed range is a bound rather than a value (a capsize speed "beyond 54 km/h", a window width that is "at least" its analysed part), so a difference that involves one is reported as "at least" that much, and only when the bound makes its direction certain; otherwise that metric is left out of the comparison.

6. Limitations

Be clear about what the numbers are and are not.

7. How the engines are kept honest

The Python reference engine (engine/, package bikedyn) holds the verbatim benchmark formulas and golden tests against Meijaard et al. (2007). It also generates a conformance fixture with full outputs for over 100 cases: the benchmark bicycle, road, endurance, gravel, low-trail 650b, XC, trail, enduro, mullet and DH frames, every seed frame in the curated dataset, and varied riders and changes to the build. The TypeScript engine that runs in your browser must reproduce every number in that fixture to a relative or absolute tolerance of 1e-6, and every label, warning and summary sentence exactly, or the build fails. Rules that could otherwise differ between the two engines are pinned down in code and tests: eigenvalues are put in a canonical order and tracked by a fixed matching rule, roots are found with the same Brent algorithm, speed grids are computed the same way, and numbers in text are rounded half away from zero.

Each result carries an engine_version and a param_hash: a SHA-256 hash of the normalised inputs plus the engine version, so identical inputs give identical results and cached results are never reused across engine changes.

References

Benchmark check

The benchmark bicycle from Meijaard et al. (2007), run through this site's engine in your browser and compared with the same speeds computed from the paper's matrices in 40-digit arithmetic.

Benchmark bicycleReference (m/s)This browser (m/s)Difference
Weave speed4.2923825…
Capsize speed6.0242620…