Explanation of the math for moving the sled?

Where could I go to understand more of the math of how the sled handles coordinates – i.e. turning cartesian into cord movement?

@rjon17469 has been very successfully leading the charge on that front.

This thread has some great information, but I think even more improvements have been made since then:

I’d be happy to run though it!

I’m pulling the latest code from the kinematics off GitHub, so this is as of where it stands right now. I cleaned up a little of the formatting on the way.

First, the distance from the center of each motor axis to the center of the cutting bit is determined. This is based on the coordinates of the motors, determined by either measurements or the calibration process, and uses the target coordinates for the bit:

Motor1Distance = sqrt((-1*_xCordOfMotor - xTarget)^2 + (_yCordOfMotor - yTarget)^2)
Motor2Distance = sqrt((_xCordOfMotor - xTarget)^2 + (_yCordOfMotor - yTarget)^2)

Next, we determine what the angles of the chains are from the motors to the cutting bit, as well as how much chain is wrapped around the sprocket. Note that the chain length technically begins at the 12 o’clock position on the sprocket, so some chain will always be wrapped around the sprocket.

Also note that this now depends on if the chain exits the sprocket to go to the sled from the top or bottom of the sprocket. Something to look forward to in the next release!

If the chain exits from the top of the sprocket (conventional design):

Chain1Angle = asin((_yCordOfMotor - yTarget)/Motor1Distance) + asin(R/Motor1Distance)
Chain2Angle = asin((_yCordOfMotor - yTarget)/Motor2Distance) + asin(R/Motor2Distance)
Chain1AroundSprocket = R * Chain1Angle
Chain2AroundSprocket = R * Chain2Angle

If the chain exits from the bottom of the sprocket (new possible configuration):

Chain1Angle = asin((_yCordOfMotor - yTarget)/Motor1Distance) - asin(R/Motor1Distance)
Chain2Angle = asin((_yCordOfMotor - yTarget)/Motor2Distance) - asin(R/Motor2Distance)
Chain1AroundSprocket = R * (3.14159 - Chain1Angle)
Chain2AroundSprocket = R * (3.14159 - Chain2Angle)

Next we calculate the straight length of chain from the motors to the bit. Note here that the chain does not actually come from the center of the motor, as so far we have been calculating. It actually comes from the tangential spot on the sprocket, so we account for that in this step:

Chain1Straight = sqrt(Motor1Distance^2 - R^2)
Chain2Straight = sqrt(Motor2Distance^2 - R^2)

This next step is a bit more complicated. Here, we account and correct for chain sag in the straight portion of the chain. To do this, we use the chainSagCorrection value as part of the equation. The chainSagCorrection value is a combined coefficient, and includes the weight of the sled, among other factors. This step works by determining the percentage error of the straight line chain length, based on the chain angle, chain length, and chain tension, respectively, and then adding that percentage error into the chain length to compensate:

Chain1Straight *= 1 + ((chainSagCorrection / 1000000000000) * cos(Chain1Angle)^2 * Chain1Straight^2 * ((tan(Chain2Angle) * cos(Chain1Angle)) + sin(Chain1Angle))^2)
Chain2Straight *= 1 + ((chainSagCorrection / 1000000000000) * cos(Chain2Angle)^2 * Chain2Straight^2 * ((tan(Chain1Angle) * cos(Chain2Angle)) + sin(Chain2Angle))^2)

Next, we add the chain length wrapped around the sprocket to the straight chain length:

Chain1 = Chain1AroundSprocket + Chain1Straight
Chain2 = Chain2AroundSprocket + Chain2Straight

And finally we subtract the distance added by the linkage rotation mechanism:

Chain1 = Chain1 - rotationDiskRadius
Chain2 = Chain2 - rotationDiskRadius

That’s it in a nutshell!

8 Likes

@rjon17469, Quick question

Shouldn’t these be

Chain1Straight = sqrt(Motor1Distance^2 + R^2)

Chain2Straight = sqrt(Motor2Distance^2 + R^2)

??

Not quite. For this portion, imagine you have the motor with sprocket, and then the center of the cutting bit somewhere on the bed.

First draw a straight line from the center of the motor axis to the center of the bit. Then draw another line from the center of the bit to a tangential spot on the sprocket. Finally, complete the triangle with a line from the tangential spot on the sprocket to the motor axis center. This is a right angle triangle, with the right angle at the tangential point on the sprocket (because tangents of circles are always at right angles to the radius). This means the motor distance is the hypotenuse of the triangle. This gives the equation:

(hypotenuse)^2 = (radius)^2 + (tangent)^2

Solving for the tangent, which is the straight length of chain, we get the aforementioned equation.

1 Like

note that this is the simplified math made possible by the triangulation
kinematics (made possible with the linkage or ring kits), the original
quadrilateral kinematics are significantly messier.

2 Likes

Great point, thanks for clarifying @dlang!

also note that you not only need to account for the amount of chain on the
sprocket, you need to account for the fact that the chain leaves the sprocket at
some horizontal and vertical distance away from the origin (top center of the
sprocket), which ever so slightly changes the angle of the chains from that
point to the center of the bit compared to from the origin to the center of the
bit.

Reece, are we accounting for that slight offset?

This is accomplished by the equations that @Joshua was asking about, where the straight chain length is calculated from the motor distance and sprocket radius. I found it was cleaner to accomplish it this way than to try to translate the motor position into a constantly moving point on the sprockets.

The chain angle is calculated based on the exit point from the sprocket, which is why the chain angle equations are different for the chain on top versus the chain on bottom configurations.

The difference in chain angles for the top and bottom configurations isn’t large, but here it is:

Top:

Chain1Angle = asin((_yCordOfMotor - yTarget)/Motor1Distance) + asin(R/Motor1Distance)
Chain2Angle = asin((_yCordOfMotor - yTarget)/Motor2Distance) + asin(R/Motor2Distance)

Bottom:

Chain1Angle = asin((_yCordOfMotor - yTarget)/Motor1Distance) - asin(R/Motor1Distance)
Chain2Angle = asin((_yCordOfMotor - yTarget)/Motor2Distance) - asin(R/Motor2Distance)

Note the + versus - sign on the last asin statement. This makes the chain angle slightly shallower for the chain on bottom configuration, which we would expect.

there should be a change in the horizontal distance and vertical distance. This
is accounting for the vertical distance (If I’m reading it correctly), do we
also have a correction on the horizontal distance?

I could easily be missing something here, it would be FAR from the first time
:slight_smile:

It is accounted for, but it is difficult to see.

Note that the only time that cartesian coordinates are used is for the initial motor distance equations. After that, polar coordinates are used for all remaining steps. Therefore, this difference in horizontal and vertical distance is translated into the chain angle differences and the sprocket radius, which we see used in the equations.

1 Like

Imaginary numbers? Shades of EE school

LOL. Don’t forget the ^2 in there before the square root. :blush:

Remove the multiply and add the two numbers instead? ( -x-y )^2 to ( x+y )^2. Forget what that’s called, commutation, association, rumination?

That’s not a bad idea! If you wanted to you could submit a PR and clean it up!

2 Likes

My last serious source control use was SCCS and CVS, haven’t really tried to figure out all this pushing, pulling, forking, and spooning.

2 Likes

Thanks. I knew I was missing something. Because the sprocket radius is so small compared to the two lengths, I was visualizing it wrong.