The following information is based upon an old message from @rjon17469. I’ve interpretted what he described and believe I have it accurate. Please, if there are mistakes/errors, edit it or post a comment regardinging it.
Components that Make Up the Chain Length Calculation
Maslow has only one mechanism to move the sled to where it needs to go and that is by extending or shortening the chain length between the sled and the two motors. Everything reduces down to determining how long each chain needs to be to perform a certain operation. The current software (as of 8/21/18) currently performs the following to determine the chain length:
- Calculate the straight distance between the center of the motor and the center of the router bit based upon the coordinates of the motor and the target coordinates (Motor1Distance)
- Calculate the amount of chain, starting from the 12 o’clock position, that wraps around the sprocket based upon the coordinates of the motor and the the target coordinates (Chain1AroundSprocket)
- Calculate the straight chain length from the point the chain leaves the sprocket to the center of the router bit (Chain1Straight)
- Increase the straight chain length to account for chain sag.
- Sum the straight chain length and amount of chain wrapped around sprocket and subtract the rotational radius of the ring/linkage kit (Chain1)
Note 1: The above and below generally references only the left chain (Chain1). So where you see Motor1Distance, that’s the distance from the left motor to the center of the router bit. Unsurprisingly, Motor2Distance is the distance from the right motor to the center of the router bit, etc. Got it? Good.
Note 2: The below is based upon a chain-over-top feed configuration where the chain slack drops vertically toward the floor (original design). The chain-off-bottom feed configuration, where the chain slack runs horizontal along the top beam, is only different in calculation of the amount of chain that wraps around the sprocket… the formulas are very similar between the two. Chain-off-bottom feed might get detailed at some time in the future.
Motor1DistanceThe software knows (based upon calibration and other values) the x,y location of the center of the motor sprocket and, from the gcode for the desired move, the x,y location of the target. With this, Motor1Distance is easily calculated:
float Motor1Distance = sqrt(pow((-1*_xCordOfMotor - xTarget),2)+pow((_yCordOfMotor - yTarget),2));
To calculate the amount of chain that wraps around the sprocket, two individual steps are taken.
a = the angle from the target to the center of the motor sprocket.
b = the additional angle based upon the radius of the sprocket
These two angles are shown in the diagram above and are calculated as follows:
a = asin((_yCordOfMotor - yTarget)/Motor1Distance)
b = asin((RleftChainTolerance/Motor1Distance)
Currently (8/21/18), the software calculates RleftChainTolerance (“r” in the diagram) as the chain pitch * number of teeth / (2*pi) and then adjusts it to account for chain wear compensation factors. It is believed that ‘r’ should be the true pitch diameter of the sprocket and should be chain pitch / sin(180/number of teeth). Because the chain is meshed with the sprocket, there should be no adjustment made for chain wear. A proposed change to the code is forthcoming.
Once a and b are calculated, the amount of chain that wraps around the sprocket is calculated as:
Chain1Angle = a + b
Chain1AroundSprocket = RleftChainTolerance * (Chain1Angle)
As above, RleftChainTolerance is subject to a forthcoming code revision.
Knowing the the chain comes off the sprocket at a right angle, it is easy to calculate the length of chain from where it comes off the sprocket to the center of the router bit using Pythagorean’s Theorem:
Chain1Straight = sqrt ( pow(Motor1Distance,2) - pow(RleftChainTolerance,2) )
As mentioned earlier, RleftChainTolerance is subject to a forthcoming code revision
Increase Chain1Straight to Account for Chain Sag
I have no idea how this formula works, but the chainSagCorrection value that is calculated during calibration is multiplied by some glob of sines and cosines to figure out how much to increase Chain1Straight. If someone understands this math, feel free to edit the post:
Chain1Straight *= (1 + ((sysSettings.chainSagCorrection / 1000000000000) * pow(cos(Chain1Angle),2) * pow(Chain1Straight,2) * pow((tan(Chain2Angle) * cos(Chain1Angle)) + sin(Chain1Angle),2)));
So, at the end, Chain1 is calculated simply as the sum of Chain1Straight and Chain1AroundSprocket and then , because the sorftware has calculated all of this to the center of the router bit, the rotational radius (distance from center of router bit to the end of the chain) is subtracted out to arrive at the target chain length:
Chain1 = Chain1AroundSprocket + Chain1Straight;
Chain1 = Chain1 - rotationalDiskRadius;
Chain-Over-Top vs. Chain-Off_Bottom
The following is a comparison of the formulas used between the two. Need a diagram to explain better:
Chain1Angle = asin((_yCordOfMotor-yTarget)/Motor1Distance)+asin(RleftChainTolerance/Motor1Distance)
Chain1AroundSprocket = RleftChainTolerance * Chain1Angle;
Chain1Angle = asin((_yCordOfMotor-yTarget)/Motor1Distance)-asin(RleftChainTolerance/Motor1Distance)
Chain1AroundSprocket = RleftChainTolerance * (3.14159 - Chain1Angle);