discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

Linear rails in the NopSCAD library, a few helper functions.

HW
Harvey white
Wed, Jan 28, 2026 6:03 AM

I'm modeling a PnP machine, and as such, I use linear rails.  I want to
be able to put the slide (and attached parts) in various positions, but
I don't want the slide to overrun the rail.  I want it to behave as if
it were a real physical object with stops on the rail.

I start off with the following call in the case of one carriage on a
linear rail:

|module head_Z_slide_mount(zpos = 25)|

|{|

|    length = 102;            // sets actual travel of the slide|

|// which contains the  following macro:|

|z1pos = limit1(length, zpos);|

|// which is applied in |

|    translate([z1pos-15,-15,26.8]) sensor_flag();|

|}|

|the limit1 function accounts for the size of the linear rail carriage,
the position commanded, and the whole length of the rail travel.|

|The position of the slide cannot be made less than zero, and cannot be
made more than the length.  Adjust the adder on z1pos to match the
position of the object to the slide.  This will work with animation as
well, and makes the modeling more accurate.  The offset needed on the X
dimension (here) has to do with the position of the attached object. 
This algorithm will work with any linear motion with a few
modifications.  The function is:|

|
// copied from nopSCADlib
function limit(x, min, max) = max(min(x, max), min);

// single slide limit
// given a linear slide of len, and a slide position from 0 to len
(maximum extent)
// keep slide from going below 0, and beyond end of rail. Compensate for
carriage length.|

|// comment, this is adapted for NopSCADlib.  Note that the normal call
(without presets) is len and slide position.|

|// carriage is the type of carriage on the particular rail. 
carriage[1] is the length of the whole slide, which subtracts from the
overall length of the movement.  Separation = 0 is needed since there is
only one slide to be moved.|

|function limit1(len, slide_position, carriage = MGN12H_carriage,
separation = 0) =
    limit(len - limit(slide_position,0,len-1*carriage[1]), 0,
len)-len/2-carriage[1]/2 ;

// dual slide limit
// given a linear slide of len, and a slide position from 0 to len
(maximum extent)
// keep slide pair from going below 0, and beyond end of rail.
Compensate for carriage length and
// space between carriages.
|

|// comment:|

|// this handles the case where there are two slides on a single rail,
both locked to a wider load.  An example of this would be the head on
the X rail of a PNP machine.|

|// the two slides are separated by <separation> where the default is
1.0mm, and can be larger.  This treats both slides as a continuous slide
formed of two carriages with <separation> between them.|

|// again, the leftmost slide cannot go below zero, and the rightmost
slide cannot go beyond the <limit>.|

|function limit2(len, slide_position, carriage = MGN12H_carriage,
separation = 1) =
    limit( len -
limit(slide_position,0,len-2*carriage[1]-separation/2), 0,
len)-len/2-carriage[1]/2 ;
|

Harvey

|
|

I'm modeling a PnP machine, and as such, I use linear rails.  I want to be able to put the slide (and attached parts) in various positions, but I don't want the slide to overrun the rail.  I want it to behave as if it were a real physical object with stops on the rail. I start off with the following call in the case of one carriage on a linear rail: |module head_Z_slide_mount(zpos = 25)| |{| |    length = 102;            // sets actual travel of the slide| |// which contains the  following macro:| |z1pos = limit1(length, zpos);| |// which is applied in | |    translate([z1pos-15,-15,26.8]) sensor_flag();| |}| |the limit1 function accounts for the size of the linear rail carriage, the position commanded, and the whole length of the rail travel.| |The position of the slide cannot be made less than zero, and cannot be made more than the length.  Adjust the adder on z1pos to match the position of the object to the slide.  This will work with animation as well, and makes the modeling more accurate.  The offset needed on the X dimension (here) has to do with the position of the attached object.  This algorithm will work with any linear motion with a few modifications.  The function is:| | // copied from nopSCADlib function limit(x, min, max) = max(min(x, max), min); // single slide limit // given a linear slide of len, and a slide position from 0 to len (maximum extent) // keep slide from going below 0, and beyond end of rail. Compensate for carriage length.| |// comment, this is adapted for NopSCADlib.  Note that the normal call (without presets) is len and slide position.| |// carriage is the type of carriage on the particular rail.  carriage[1] is the length of the whole slide, which subtracts from the overall length of the movement.  Separation = 0 is needed since there is only one slide to be moved.| |function limit1(len, slide_position, carriage = MGN12H_carriage, separation = 0) =     limit(len - limit(slide_position,0,len-1*carriage[1]), 0, len)-len/2-carriage[1]/2 ; // dual slide limit // given a linear slide of len, and a slide position from 0 to len (maximum extent) // keep slide pair from going below 0, and beyond end of rail. Compensate for carriage length and // space between carriages. | |// comment:| |// this handles the case where there are two slides on a single rail, both locked to a wider load.  An example of this would be the head on the X rail of a PNP machine.| |// the two slides are separated by <separation> where the default is 1.0mm, and can be larger.  This treats both slides as a continuous slide formed of two carriages with <separation> between them.| |// again, the leftmost slide cannot go below zero, and the rightmost slide cannot go beyond the <limit>.| |function limit2(len, slide_position, carriage = MGN12H_carriage, separation = 1) =     limit( len - limit(slide_position,0,len-2*carriage[1]-separation/2), 0, len)-len/2-carriage[1]/2 ; | Harvey | |
HW
Harvey white
Wed, Jan 28, 2026 6:21 AM

Apparently Thunderbird does not play nice with code formatting. I'll fix
this and put up another version tomorrow.  If you want, just delete the
| characters.

Harvey

On 1/28/2026 1:03 AM, Harvey white via Discuss wrote:

I'm modeling a PnP machine, and as such, I use linear rails.  I want
to be able to put the slide (and attached parts) in various positions,
but I don't want the slide to overrun the rail.  I want it to behave
as if it were a real physical object with stops on the rail.

I start off with the following call in the case of one carriage on a
linear rail:

|module head_Z_slide_mount(zpos = 25)|

|{|

|    length = 102;            // sets actual travel of the slide|

|// which contains the  following macro:|

|z1pos = limit1(length, zpos);|

|// which is applied in |

|    translate([z1pos-15,-15,26.8]) sensor_flag();|

|}|

|the limit1 function accounts for the size of the linear rail
carriage, the position commanded, and the whole length of the rail
travel.|

|The position of the slide cannot be made less than zero, and cannot
be made more than the length.  Adjust the adder on z1pos to match the
position of the object to the slide.  This will work with animation as
well, and makes the modeling more accurate.  The offset needed on the
X dimension (here) has to do with the position of the attached
object.  This algorithm will work with any linear motion with a few
modifications.  The function is:|

|
// copied from nopSCADlib
function limit(x, min, max) = max(min(x, max), min);

// single slide limit
// given a linear slide of len, and a slide position from 0 to len
(maximum extent)
// keep slide from going below 0, and beyond end of rail. Compensate
for carriage length.|

|// comment, this is adapted for NopSCADlib.  Note that the normal
call (without presets) is len and slide position.|

|// carriage is the type of carriage on the particular rail.
carriage[1] is the length of the whole slide, which subtracts from the
overall length of the movement.  Separation = 0 is needed since there
is only one slide to be moved.|

|function limit1(len, slide_position, carriage = MGN12H_carriage,
separation = 0) =
    limit(len - limit(slide_position,0,len-1*carriage[1]), 0,
len)-len/2-carriage[1]/2 ;

// dual slide limit
// given a linear slide of len, and a slide position from 0 to len
(maximum extent)
// keep slide pair from going below 0, and beyond end of rail.
Compensate for carriage length and
// space between carriages.
|

|// comment:|

|// this handles the case where there are two slides on a single rail,
both locked to a wider load.  An example of this would be the head on
the X rail of a PNP machine.|

|// the two slides are separated by <separation> where the default is
1.0mm, and can be larger.  This treats both slides as a continuous
slide formed of two carriages with <separation> between them.|

|// again, the leftmost slide cannot go below zero, and the rightmost
slide cannot go beyond the <limit>.|

|function limit2(len, slide_position, carriage = MGN12H_carriage,
separation = 1) =
    limit( len -
limit(slide_position,0,len-2*carriage[1]-separation/2), 0,
len)-len/2-carriage[1]/2 ;
|

Harvey

|
|


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

Apparently Thunderbird does not play nice with code formatting. I'll fix this and put up another version tomorrow.  If you want, just delete the | characters. Harvey On 1/28/2026 1:03 AM, Harvey white via Discuss wrote: > I'm modeling a PnP machine, and as such, I use linear rails.  I want > to be able to put the slide (and attached parts) in various positions, > but I don't want the slide to overrun the rail.  I want it to behave > as if it were a real physical object with stops on the rail. > > I start off with the following call in the case of one carriage on a > linear rail: > > |module head_Z_slide_mount(zpos = 25)| > > |{| > > |    length = 102;            // sets actual travel of the slide| > > |// which contains the  following macro:| > > |z1pos = limit1(length, zpos);| > > |// which is applied in | > > |    translate([z1pos-15,-15,26.8]) sensor_flag();| > > |}| > > |the limit1 function accounts for the size of the linear rail > carriage, the position commanded, and the whole length of the rail > travel.| > > |The position of the slide cannot be made less than zero, and cannot > be made more than the length.  Adjust the adder on z1pos to match the > position of the object to the slide.  This will work with animation as > well, and makes the modeling more accurate.  The offset needed on the > X dimension (here) has to do with the position of the attached > object.  This algorithm will work with any linear motion with a few > modifications.  The function is:| > > | > // copied from nopSCADlib > function limit(x, min, max) = max(min(x, max), min); > > // single slide limit > // given a linear slide of len, and a slide position from 0 to len > (maximum extent) > // keep slide from going below 0, and beyond end of rail. Compensate > for carriage length.| > > |// comment, this is adapted for NopSCADlib.  Note that the normal > call (without presets) is len and slide position.| > > |// carriage is the type of carriage on the particular rail. > carriage[1] is the length of the whole slide, which subtracts from the > overall length of the movement.  Separation = 0 is needed since there > is only one slide to be moved.| > > |function limit1(len, slide_position, carriage = MGN12H_carriage, > separation = 0) = >     limit(len - limit(slide_position,0,len-1*carriage[1]), 0, > len)-len/2-carriage[1]/2 ; > > // dual slide limit > // given a linear slide of len, and a slide position from 0 to len > (maximum extent) > // keep slide pair from going below 0, and beyond end of rail. > Compensate for carriage length and > // space between carriages. > | > > |// comment:| > > |// this handles the case where there are two slides on a single rail, > both locked to a wider load.  An example of this would be the head on > the X rail of a PNP machine.| > > |// the two slides are separated by <separation> where the default is > 1.0mm, and can be larger.  This treats both slides as a continuous > slide formed of two carriages with <separation> between them.| > > |// again, the leftmost slide cannot go below zero, and the rightmost > slide cannot go beyond the <limit>.| > > |function limit2(len, slide_position, carriage = MGN12H_carriage, > separation = 1) = >     limit( len - > limit(slide_position,0,len-2*carriage[1]-separation/2), 0, > len)-len/2-carriage[1]/2 ; > | > > > Harvey > > | > | > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org