chain - a parametric chain generator
A chain wrapped around a set of sprockets can be generated with the Chain class by providing the size and locations of the sprockets, how the chain wraps and optionally the chain parameters.
For example, one can create the chain for a bicycle with a rear deraileur as follows:
import cadquery as cq
from cq_warehouse.chain import Chain
MM = 1
derailleur_chain = Chain(
spkt_teeth=[32, 10, 10, 16],
positive_chain_wrap=[True, True, False, True],
spkt_locations=[
(0, 158.9 * MM, 50 * MM),
(+190 * MM, 0, 50 * MM),
(+190 * MM, 78.9 * MM, 50 * MM),
(+205 * MM, 158.9 * MM, 50 * MM),
],
)
if "show_object" in locals():
show_object(derailleur_chain.cq_object, name="derailleur_chain")
The chain is created on the XY plane (methods to move the chain are described below) with the sprocket centers being described by:
a two dimensional tuple (x,y)
a three dimensional tuple (x,y,z) which will result in the chain being created parallel to the XY plane, offset by “z”
the cadquery Vector class which will displace the chain by Vector.z
To control the path of the chain between the sprockets, the user must indicate the desired
direction for the chain to wrap around the sprocket. This is done with the positive_chain_wrap
parameter which is a list of boolean values - one for each sprocket - indicating a counter
clock wise or positive angle around the z-axis when viewed from the positive side of the XY
plane. The following diagram illustrates the most complex chain path where the chain
traverses wraps from positive to positive, positive to negative, negative to positive and
negative to negative directions (positive_chain_wrap values are shown within the arrows
starting from the largest sprocket):
- class Chain(spkt_teeth, spkt_locations, positive_chain_wrap, chain_pitch=12.7, roller_diameter=7.9375, roller_length=2.3812499999999996, link_plate_thickness=1.0, spkt_normal=(0, 0, 1))
Roller Chain
Create a new chain object as defined by the given parameters. The input parameter defaults are appropriate for a standard bicycle chain.
- Parameters
spkt_teeth (list[int]) – list of the number of teeth on each sprocket the chain will wrap around
spkt_locations (list[VectorLike]) – location of the sprocket centers
positive_chain_wrap (list[bool]) – the direction chain wraps around the sprockets, True for counter clockwise viewed from positive Z
chain_pitch (float) – distance between two adjacent pins in a single link. Defaults to 1/2 inch.
roller_diameter (float) – size of the cylindrical rollers within the chain. Defaults to 5/16 inch.
roller_length (float) – distance between the inner links, i.e. the length of the link rollers. Defaults to 3/32 inch.
link_plate_thickness (float) – thickness of the link plates (both inner and outer link plates). Defaults to 1 mm.
spkt_normal (VectorLike) – direction of the sprocket axes - only required for two sprocket configurations. Defaults to (0, 0, 1).
- Variables
pitch_radii (float) – radius of the circle formed by the center of the chain rollers on each sprocket
chain_links (int) – length of the chain in links
num_rollers (int) – number of link rollers in the entire chain
roller_loc (list[Vector]) – location of each roller in the chain
chain_angles (list[tuple[float,float]]) – chain entry and exit angles in degrees for each sprocket
spkt_initial_rotation (list[float]) – angle in degrees to rotate each sprocket in-order to align the teeth with the gaps in the chain
chain_plane (Plane) – the plane defined by the location of the sprockets
cq_object – cadquery chain object
- Raises
ValueError – invalid roller diameter
ValueError – length of spkt_teeth, spkt_locations, positive_chain_wrap not equal
ValueError – sprockets in the same location
Examples
c = Chain( spkt_teeth=[32, 32], spkt_locations=[(-300, 0), (300, 0)], positive_chain_wrap=[True, True] ) print(c.spkt_initial_rotation) # [5.625, 193.82627377380086] c.cq_object.save('chain.step') # save the cadquery assembly as a STEP file
- assemble_chain_transmission(spkts)
Build Socket/Chain Assembly
Create the transmission assembly from sprockets for a chain
- Parameters
spkts (
list
[Sprocket
]) – sprockets to include in transmission- Return type
Assembly
- Returns
Chain wrapped around sprockets
- static make_link(chain_pitch=12.7, link_plate_thickness=1, inner=True, roller_length=2.3812499999999996, roller_diameter=7.9375)
Create roller chain link pair
Create either inner or outer link pairs. Inner links include rollers while outer links include fake roller pins.
- Parameters
chain_pitch (
float
) – distance between roller pin centers. Defaults to 0.5*INCH.link_plate_thickness (
float
) – thickness of single plate connecting rollers. Defaults to 1*MM.inner (
bool
) – is this an inner (or outer) chain link?. Defaults to True.roller_length (
float
) – length of the internal roller. Defaults to (3 / 32)*INCH.roller_diameter (
float
) – diameter of the internal roller. Defaults to (5 / 16)*INCH.
- Return type
Workplane
- Returns
A single link pair
Note that the chain is perfectly tight as it wraps around the sprockets and does not support any slack. Therefore, as the chain wraps back around to the first link it will either overlap or gap this link - this can be seen in the above figure at the top of the largest sprocket. Adjust the locations of the sprockets to control this value.
Note that the make_link instance method uses the @cache decorator to greatly improve the rate at links can be generated as a chain is composed of many copies of the links.
Once a chain or complete transmission has been generated it can be re-oriented as follows:
two_sprocket_chain = Chain(
spkt_teeth = [32, 32],
positive_chain_wrap = [True, True],
spkt_locations = [ (-5 * IN, 0), (+5 * IN, 0) ]
)
relocated_transmission = two_sprocket_chain.assemble_chain_transmission(
spkts = [spkt32.cq_object, spkt32.cq_object]
).rotate(axis=(0,1,1),angle=45).translate((20, 20, 20))
Future Enhancements
Two future enhancements are being considered:
Non-planar chains - If the sprocket centers contain
z
values, the chain would follow the path of a spline between the sockets to approximate the path of a bicycle chain where the front and rear sprockets are not in the same plane. Currently, thez
values of the first sprocket define thez
offset of the entire chain.Sprocket Location Slots - Typically on or more of the sprockets in a chain transmission will be adjustable to allow the chain to be tight around the sprockets. This could be implemented by allowing the user to specify a pair of locations defining a slot for a given sprocket indicating that the sprocket location should be selected somewhere along this slot to create a perfectly fitting chain.