2021-03-06 05:10:28 -05:00
//
// NopSCADlib Copyright Chris Palmer 2020
// nop.head@gmail.com
// hydraraptor.blogspot.com
//
// This file is part of NopSCADlib.
//
// NopSCADlib is free software: you can redistribute it and/or modify it under the terms of the
// GNU General Public License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// NopSCADlib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with NopSCADlib.
// If not, see <https://www.gnu.org/licenses/>.
//
//
//! Parameterised Core XY implementation. Draws the belts and provides utilities for positioning the pulleys.
//!
//! The belts are positioned according the bottom left "anchor" pulley and the top right drive pulley.
//! Implementation has the following features:
//! 1. The drive and idler pulleys may be different sizes.
//! 2. The belt separation is parameterised.
//! 3. The separation of the plain and toothed pulleys on the Y carriages is parameterised, in both the X and the Y direction.
//! 4. The drive pulleys may be offset in the X and Y directions. If this is done, extra idler pulleys are added. This
//! allows flexible positioning of the motors.
//
include < ../core.scad >
include < ../vitamins/belts.scad >
include < ../vitamins/pulleys.scad >
coreXY_GT2_20_20 = [ "coreXY_20_20" , GT2x6 , GT2x20ob_pulley , GT2x20_toothed_idler , GT2x20_plain_idler , [ 0 , 0 , 1 ] , [ 0 , 0 , 0.5 , 1 ] , [ 0 , 1 , 0 ] , [ 0 , 0.5 , 0 , 1 ] ] ;
coreXY_GT2_20_16 = [ "coreXY_20_16" , GT2x6 , GT2x20ob_pulley , GT2x16_toothed_idler , GT2x16_plain_idler , [ 0 , 0 , 1 ] , [ 0 , 0 , 0.5 , 1 ] , [ 0 , 1 , 0 ] , [ 0 , 0.5 , 0 , 1 ] ] ;
coreXY_GT2_16_16 = [ "coreXY_16_16" , GT2x6 , GT2x16_pulley , GT2x16_toothed_idler , GT2x16_plain_idler , [ 0 , 0 , 1 ] , [ 0 , 0 , 0.5 , 1 ] , [ 0 , 1 , 0 ] , [ 0 , 0.5 , 0 , 1 ] ] ;
function coreXY_belt ( type ) = type [ 1 ] ; //! Belt type
function coreXY_drive_pulley ( type ) = type [ 2 ] ; //! Drive pulley type
function coreXY_toothed_idler ( type ) = type [ 3 ] ; //! Toothed idler type
function coreXY_plain_idler ( type ) = type [ 4 ] ; //! Plain idler type
function coreXY_upper_belt_colour ( type ) = type [ 5 ] ; //! Colour of the upper belt
function coreXY_upper_tooth_colour ( type ) = type [ 6 ] ; //! Colour of the upper belt's teeth
function coreXY_lower_belt_colour ( type ) = type [ 7 ] ; //! Colour of the lower belt
function coreXY_lower_tooth_colour ( type ) = type [ 8 ] ; //! Colour of the lower belt's teeth
// used to offset the position of the drive pulley and the y-carriage plain idler pulley
// relative to the anchor pulley so that the belts align properly
function coreXY_drive_pulley_x_alignment ( type ) = //! Belt alignment offset of the drive pulley relative to the anchor pulley
( pulley_od ( coreXY_drive_pulley ( type ) ) - pulley_od ( coreXY_toothed_idler ( type ) ) ) / 2 ;
function coreXY_coincident_separation ( type ) = //! Value of x, y separation to make y-carriage pulleys coincident
[ - coreXY_plain_idler_offset ( type ) . x , - ( pulley_od ( coreXY_plain_idler ( type ) ) + pulley_od ( coreXY_toothed_idler ( type ) ) ) / 2 , 0 ] ;
function coreXY_plain_idler_offset ( type ) = //! Offset of y-carriage plain idler
[ ( pulley_od ( coreXY_plain_idler ( type ) ) + pulley_od ( coreXY_drive_pulley ( type ) ) ) / 2 + coreXY_drive_pulley_x_alignment ( type ) , pulley_od ( coreXY_plain_idler ( type ) ) / 2 , 0 ] ;
function coreXY_toothed_idler_offset ( type ) = //! offset of y-carriage toothed idler
[ 0 , - pulley_pr ( coreXY_toothed_idler ( type ) ) , 0 ] ;
// helper functions for positioning idlers when the stepper motor drive pulley is offset
function coreXY_drive_toothed_idler_offset ( type ) = //! Offset of toothed drive idler pulley
[ 0 , coreXY_drive_pulley_x_alignment ( type ) , 0 ] ;
function coreXY_drive_plain_idler_offset ( type ) = //! Offset of plain drive idler pulley
[ coreXY_plain_idler_offset ( type ) . x , - ( pulley_od ( coreXY_plain_idler ( type ) ) + pulley_od ( coreXY_drive_pulley ( type ) ) ) / 2 , 0 ] ;
module coreXY_half ( type , size , pos , separation_y = 0 , x_gap = 0 , plain_idler_offset = 0 , drive_pulley_offset = [ 0 , 0 ] , show_pulleys = false , lower_belt = false , hflip = false ) { //! Draw one belt of a coreXY setup
// y-carriage toothed pulley
p0_type = coreXY_toothed_idler ( type ) ;
p0 = [ size . x / 2 , - size . y / 2 - pulley_od ( p0_type ) / 2 + pos . y - separation_y / 2 ] ;
// bottom right toothed idler pulley
p1_type = p0_type ;
p1 = [ size . x / 2 , - size . y / 2 ] ;
// bottom left anchor toothed idler pulley
p2_type = p0_type ;
p2 = [ - size . x / 2 , - size . y / 2 ] ;
// stepper motor drive pulley
p3d_type = coreXY_drive_pulley ( type ) ;
p3d = [ - size . x / 2 + coreXY_drive_pulley_x_alignment ( type ) + drive_pulley_offset . x ,
size . y / 2 + drive_pulley_offset . y
] ;
// toothed idler for offset stepper motor drive pulley
p3t_type = coreXY_toothed_idler ( type ) ;
p3t = [ - size . x / 2 + ( drive_pulley_offset . x > 0 ? 0 : 2 * coreXY_drive_pulley_x_alignment ( type ) ) ,
size . y / 2 + coreXY_drive_pulley_x_alignment ( type ) + drive_pulley_offset . y
] ;
// y-carriage plain pulley
p4_type = coreXY_plain_idler ( type ) ;
p4 = [ - size . x / 2 + pulley_od ( p4_type ) / 2 + pulley_od ( p3d_type ) / 2 + coreXY_drive_pulley_x_alignment ( type ) + plain_idler_offset ,
- size . y / 2 + pulley_od ( p4_type ) / 2 + pos . y + separation_y / 2
] ;
// plain idler for offset stepper motor drive pulley
p3p_type = p4_type ;
p3p = [ drive_pulley_offset . x > 0 ? p4 . x : - p0 . x - pulley_od ( p0_type ) ,
size . y / 2 - pulley_od ( p3p_type ) / 2 - pulley_od ( p3d_type ) / 2 + drive_pulley_offset . y
] ;
// dummy pulleys for y separation
p5_type = p4_type ;
p5 = [ pos . x - size . x / 2 , - size . y / 2 + pos . y + separation_y / 2 ] ;
p6_type = p0_type ;
p6 = [ pos . x - size . x / 2 , - size . y / 2 + pos . y - separation_y / 2 ] ;
module show_pulleys ( show_pulleys ) { // Allows the pulley colour to be set for debugging
2021-03-06 11:32:36 -05:00
if ( is_list ( show_pulleys ) )
color ( show_pulleys )
2021-03-06 05:10:28 -05:00
children ( ) ;
2021-03-06 11:32:36 -05:00
else if ( show_pulleys )
children ( ) ;
2021-03-06 05:10:28 -05:00
}
show_pulleys ( show_pulleys ) {
translate ( p0 )
pulley_assembly ( p0_type ) ; // y-carriage toothed pulley
translate ( p1 )
pulley_assembly ( p1_type ) ; // bottom right toothed idler pulley
translate ( p2 )
pulley_assembly ( p2_type ) ; // bottom left anchor toothed idler pulley
translate ( p3d )
hflip ( hflip )
pulley_assembly ( p3d_type ) ; // top left stepper motor drive pulley
if ( drive_pulley_offset . x ) { // idler pulleys for offset stepper motor drive pulley
translate ( p3t )
pulley_assembly ( p3t_type ) ; // toothed idler
translate ( p3p )
pulley_assembly ( p3p_type ) ; // plain idler
}
translate ( p4 )
pulley_assembly ( p4_type ) ; // y-carriage plain pulley
}
path0a = [
[ p0 . x , p0 . y , pulley_od ( p0_type ) / 2 ] ,
[ p1 . x , p1 . y , pulley_od ( p1_type ) / 2 ] ,
[ p2 . x , p2 . y , pulley_od ( p2_type ) / 2 ]
] ;
path0b = [
[ p3d . x , p3d . y , pulley_od ( p3d_type ) / 2 ] ,
[ p4 . x , p4 . y , - pulley_od ( p4_type ) / 2 ]
] ;
path0c = [
[ p3t . x , p3t . y , pulley_od ( p3t_type ) / 2 ] ,
[ p3d . x , p3d . y , pulley_od ( p3d_type ) / 2 ] ,
[ p3p . x , p3p . y , - pulley_od ( p3p_type ) / 2 ] ,
[ p4 . x , p4 . y , - pulley_od ( p4_type ) / 2 ]
] ;
path0d = [
[ p3p . x , p3p . y , - pulley_od ( p3p_type ) / 2 ] ,
[ p3d . x , p3d . y , pulley_od ( p3d_type ) / 2 ] ,
[ p3t . x , p3t . y , pulley_od ( p3t_type ) / 2 ] ,
[ p4 . x , p4 . y , - pulley_od ( p4_type ) / 2 ]
] ;
path1 = [ // use eps for corner radius to get sharp corners so this part of the belt is deleted by the gap
[ p5 . x , p5 . y , eps ] ,
[ p6 . x , p6 . y , eps ]
] ;
belt = coreXY_belt ( type ) ;
path0 = drive_pulley_offset . x = = 0 ? concat ( path0a , path0b ) : drive_pulley_offset . x > 0 ? concat ( path0a , path0c ) : concat ( path0a , path0d ) ;
path = separation_y = = 0 ? path0 : concat ( path0 , path1 ) ;
belt ( type = belt ,
points = path ,
gap = [ x_gap + eps , abs ( separation_y ) + 2 ] ,
gap_pos = [ pos . x - size . x / 2 , pos . y - size . y / 2 + belt_pitch_height ( belt ) - belt_thickness ( belt ) / 2 ] ,
belt_colour = lower_belt ? coreXY_lower_belt_colour ( type ) : coreXY_upper_belt_colour ( type ) ,
tooth_colour = lower_belt ? coreXY_lower_tooth_colour ( type ) : coreXY_upper_tooth_colour ( type ) ) ;
}
module coreXY ( type , size , pos , separation , x_gap , plain_idler_offset = 0 , upper_drive_pulley_offset , lower_drive_pulley_offset , show_pulleys = false ) { //! Wrapper module to draw both belts of a coreXY setup
translate ( [ size . x / 2 - separation . x / 2 , size . y / 2 , - separation . z / 2 ] ) {
// lower belt
hflip ( )
explode ( 25 )
coreXY_half ( type , size , [ size . x - pos . x - separation . x , pos . y ] , separation . y , x_gap , plain_idler_offset , [ - lower_drive_pulley_offset . x , lower_drive_pulley_offset . y ] , show_pulleys , lower_belt = true , hflip = true ) ;
// upper belt
translate ( [ separation . x , 0 , separation . z ] )
explode ( 25 )
coreXY_half ( type , size , [ pos . x , pos . y ] , separation . y , x_gap , plain_idler_offset , upper_drive_pulley_offset , show_pulleys , lower_belt = false , hflip = false ) ;
}
}
module coreXY_belts ( type , carriagePosition , coreXYPosBL , coreXYPosTR , separation , x_gap = 20 , upper_drive_pulley_offset = [ 0 , 0 ] , lower_drive_pulley_offset = [ 0 , 0 ] , show_pulleys = false ) { //! Draw the coreXY belts
assert ( coreXYPosBL . z = = coreXYPosTR . z ) ;
coreXYSize = coreXYPosTR - coreXYPosBL ;
translate ( coreXYPosBL )
coreXY ( type , coreXYSize , [ carriagePosition . x - coreXYPosBL . x + separation . x / 2 , carriagePosition . y - coreXYPosBL . y ] , separation = separation , x_gap = x_gap , plain_idler_offset = 0 , upper_drive_pulley_offset = upper_drive_pulley_offset , lower_drive_pulley_offset = lower_drive_pulley_offset , show_pulleys = show_pulleys ) ;
}