A Clojure(script) library designed to do bicycle gear calculations for fixed-gear, internal hubs and cassettes.
There are calculations for gear-inches, meters of development, and gain-ratios For fixed gear riders there is also the number of skid patches and gears within 2% of a gear. And finally, given a gear, the speed at a given cadence/RPMs.
The original idea was that this library provides everything needed to create a nice gear calculator SPA in clojurescript. But then, well, it's so simple, it would be nice if it worked in clojure, and then it would be nice to use clojure.spec, so here we are, on the way.
Compiles for both clojure and clojurescript. Spec is used for the input structures.
not yet on clojars. lein pom; lein compile; lein install
dependencies
[eag/bike-gear-calc "0.1.0"]
At this point tests are correct, but float comparisons are not always.
The API is settling on maps at the moment. Fill in an bgc/any-bike map then call bike with it.
There are specs for the input bike maps. They will be coerced to their types and validated. The any-bike is a superset of the three types of bike.
The way to use this is to create an any-bike and fill it in how you like. There are minimal defaults. So you could just send it straight to the bike function.
Set the the :type to :fixie, :internal, or :deraileur bike
then call bike
. (bgc/bike <your-any-bike>)
The default for a :type
of :any is to treat it as a fixie.
(:require [bike-gear-calc.core :as bgc])
(let [anybike (bgc/any-bike)
myfixie (assoc anybike :type :fixie)]
(bgc/bike myfixie))
This will give you everything it can for the bike you give it.
The data namespace has maps for wheel size, crank lengths, standard cassette/freewheel configurations and the internal ratios for a number of internally geared hubs
Wheel sizes used in the calculations are the diameter in millimeters. This is where errors can be introduced, it might be best to just measure yours instead of using the wheel sizes from data. But then again an error of few millimeters isn't going to change things that much.
I did not write this, it came from the bike forums somewhere I think.
Simplify the gear ratio to the smallest equivalent whole number ratio. For single legged skidders, the number of skid patches is the denominator. For folks who can skid with either foot forward (ambidextrous skidders): if the numerator is even, the number of skid patches is still the denominator. if the numerator is odd, the number of skid patches is the denominator * 2.
48x20 => 24x10 => 12x5 results in 5 skid patches for both single and ambidextrous skidders. 43x18 results in 18 patches for single skidders but 36 for ambidextrous skidders.
Notice that the number of skid patches doubles not when the chainring is odd, but when the simplified gear numerator is odd, thus ... 42x16 => 21x8 results in 8 patches for single skidders but 16 for ambidextrous skidders. What gear should I choose? Non-skidders should choose even toothed gears to maximize chain and sprocket life. Single-legged skidders should choose odd toothed chainrings to maximize skid patches. Ambidextrous skidders can choose even toothed gears where the chainring simplifies to an odd number to get both extended drivetrain wear and doubled skid patches.
None of the ideas behind this are new. The data for wheel sizes, freewheels and the internal gear hub ratios came from Sheldon Brown's gear calculator site at Harris Cyclery. The calculations for skid patches is also well known, mostly being discussed on the bike forums. Gain Ratios were Sheldon's idea. It has been many years now, and I don't know that anyone uses them. But I made a function for them in case anyone likes them.
In sheldon's words. Gain ratio is calculated like this.
Divide the wheel radius in mm, by the crank length in mm. this will yield a single radius ratio applicable to all of the gears of a given bike. The individual gear ratios are calculated as with gear inches, using this radius ratio instead of the wheel size.
- Deploy to clojars
- Fix floating point comparisons in the tests
- Store internal hub, deraileur cluster and wheel names as data for the bike.
- Accomodate schlumpf and other geared bottom brackets.
- circleci / jenkins ?
- Add clojure specs for the data. -- part way done.
- An old fashioned, printable gear shifting chart ?
- Perhaps a CLI ?
- defrecords ? maps and namespaces are working ok at the moment.
- better wheel sizes.
There are currently two good ways to use this. You can pass the appropriate parameters to bike in one of the 3 bike namespaces fixie, hub-gear, or deraileur-gear. Or you can get an (any-bike) map from core and fill it in as you wish, then give that to one of the bike functions. This is makes it easy to have a bike definition that could be a hub-bike, a fixed gear or a deraileur gear bike and create one of the three from it.
The data namespace has wheel-sizes, internal-hubs, sprocket-clusters, and crank-lengths to aide with the choices.
With spec, you should be able to get these with (doc ::bike-gear-calc/fixie)
.
bike-gear-calc.fixie/bike A new fixie wants these.
- ring - The chainring size.
- sprocket - The sprocket size
- wheel-dia - The wheel diameter in mm. default 670 = 25x700c.
- crank-len - The crank length in mm. default 170
bike-gear-calc.hub-gear/bike A new hub-gear wants all that plus.
- internal-ratios - a vector of ratios
bike-gear-calc.deraileur-gear/bike A deraileur-gear bike wants these.
- rings - A vector of chainrings
- sprockets - A vector of sprockets
- wheel-dia - The wheel diameter in mm.
- crank-len - The crank length in mm.
Your new bike will have a variety of data depending upon the bike.
hub-gear and deraileur gear bikes get a list of gear-maps which have
:gear-inches, :meters-dev, and :gain-ratio along with the :ratio
or :sprocket. Additionally there is also :speeds which is a list of
speeds at rpm. The default is km/h set :mph true
to get mph
Deraileur bikes divide their vectors of gear maps by ring size. For example, if you have 3 rings, there will be a vector of 3 maps each with a vector of gears
Fixed gear bikes have all of that plus :close-gears and :skid-patches. Close gears is a list of bike maps with gears which are within 2% of the gear ratio of the current bike. These will be filled in just like the parent fixed gear bike but without :close-gears
Skid patches is a vector of two numbers. The first is the number of single footed skid patches and the second is the number of ambidextrous skid patches.
Copyright © 2019 Eric Gebhart
This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0.
This Source Code may also be made available under the following Secondary Licenses when the conditions for such availability set forth in the Eclipse Public License, v. 2.0 are satisfied: GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version, with the GNU Classpath Exception which is available at https://www.gnu.org/software/classpath/license.html.