hexagon logo

Alignment in Subroutine Not Working

Hi All,

I've worked with subroutines a bit before, but so far mostly to put math stuff in one place out of the main program. Today I'm working on writing an external subroutine to measure a threaded hole using something like this: < https://www.pcdmisforum.com/forum/pc...ion-of-threads>. I think this might be my first subroutine that I've actually tried to measure features in.

My first step in the subroutine is to create an alignment directly over the hole, which vastly simplifies the feature programming. However, PC-DMIS is not using the alignment properly. Move points move the machine relative to the alignment as I would expect; however, it is trying to probe all of my measured features as if they were at the CAD origin rather than at the center of my alignment!

Here is my subroutine code so far:


SUBROUTINE/THREADSCANNER,
POSITION = : POSITION OF HOLE IN ACTIVE ALIGNMENT,
DIRECTION = : DIRECTION VECTOR (POINTING STRAIGHT OUT OF HOLE) IN ACTIVE ALIGNMENT,
ORIENTATION = : VECTOR NORMAL TO DIRECTION, POINTING TO SIDE TO VERTICALLY SCAN,
MINOR_DIA = : NOMINAL MINOR DIAMETER OF HOLE,
MAX_DEPTH = : DEPTH TO START VERTICAL SCAN AT (MUST BE AT LEAST 2*PITCH BELOW TOP),
PITCH = : PITCH OF THREAD,
SCAN_REVS = : NUMBER OF REVOLUTIONS TO SPIRAL SCAN (MUST FIT WITHIN HOLE),
MOVESPD = : SPEED DURING MOTION,
RADIAL_DISTANCE_TOL = 0.001 : POINTS WITHIN THIS DISTANCE FROM HIGH POINT WILL BE CONSIDERED ON THE CREST,
MIN_CREST_TOL = 0.125 : MINIMUM ACCEPTABLE CREST WIDTH AS A PERCENTAGE OF PITCH,
MAX_CREST_TOL = 0.375 : MAXIMUM ACCEPTABLE CREST WIDTH AS A PERCENTAGE OF PITCH,
=
$$ NO,
**WARNING: THIS WILL MOVE THE MACHINE!!!**
If you type in dumb numbers, it will do dumb things.
Also, make sure your tip angle is right.
ACCELERATION/MAXACCELX=250, MAXACCELY=250, MAXACCELZ=250
MOVESPEED/ MOVESPD
$$ NO,
Align to hole, move to top
POSITION_POINT=GENERIC/POINT,DEPENDENT,CARTESIAN,$
NOM/XYZ,<POSITION.X,POSITION.Y,POSITION.Z>,$
MEAS/XYZ,<POSITION.X,POSITION.Y,POSITION.Z>,$
NOM/IJK,<DIRECTION.X,DIRECTION.Y,DIRECTION.Z>,$
MEAS/IJK,<DIRECTION.X,DIRECTION.Y,DIRECTION.Z>
ORIENTATION_LINE=GENERIC/LINE,DEPENDENT,CARTESIAN,$
NOM/XYZ,<POSITION.X,POSITION.Y,POSITION.Z>,$
MEAS/XYZ,<POSITION.X,POSITION.Y,POSITION.Z>,$
NOM/IJK,<ORIENTATION.X,ORIENTATION.Y,ORIENTATION.Z>,$
MEAS/IJK,<ORIENTATION.X,ORIENTATION.Y,ORIENTATION.Z>,$
DISTANCE/1,1
[COLOR=#2980b9]HOLE_ALIGNMENT=ALIGNMENT/START,RECALL:STARTUP,LIST=YES
ALIGNMENT/LEVEL,ZPLUS,POSITION_POINT
ALIGNMENT/ROTATE,XPLUS,TO,ORIENTATION_LINE,ABOUT,ZPLUS
ALIGNMENT/TRANS,XAXIS,POSITION_POINT
ALIGNMENT/TRANS,YAXIS,POSITION_POINT
ALIGNMENT/TRANS,ZAXIS,POSITION_POINT
ALIGNMENT/END[/COLOR]
[COLOR=#27ae60]MOVE/POINT,NORMAL,<0,0,0>
MOVE/POINT,NORMAL,<0,0,0.1>
MOVE/POINT,NORMAL,<0.05,0,0>
MOVE/POINT,NORMAL,<0,0,0>
MOVE/INCREMENT,<0,0,0.1>
MOVE/INCREMENT,<0.1,0,0>[/COLOR]
[COLOR=#e74c3c]TEST_MEAS_POINT=FEAT/POINT,CARTESIAN
THEO/<0,0,0>,<0,0,1>
ACTL/<0,0,0>,<0,0,1>
MEAS/POINT,1,WORKPLANE
HIT/BASIC,NORMAL,<0,0,0>,<0,0,1>,<0,0,0>,USE THEO=YES
ENDMEAS/[/COLOR]
[COLOR=#e74c3c]TEST_POINT =FEAT/CONTACT/VECTOR POINT/DEFAULT,CARTESIAN
THEO/<0,0,0>,<0,0,1>
ACTL/<0,0,0>,<0,0,1>
TARG/<0,0,0>,<0,0,1>
SNAP=NO
SHOW FEATURE PARAMETERS=NO
SHOW CONTACT PARAMETERS=YES
AVOIDANCE MOVE=NO,DISTANCE=0.4
SHOW HITS=NO[/COLOR]
$$ NO,
Set scanning options to take ~1 second with 100 points, make vertical scan
ASSIGN/VERTICAL_SCAN_LENGTH=PITCH*2
ASSIGN/VERTICAL_SCAN_LENGTH_MM=VERTICAL_SCAN_LENGTH*25.4
SCANSPEED/VERTICAL_SCAN_LENGTH_MM
OPTIONPROBE/MAXFORCE=0.36,LOWFORCE=0.06,UPPERFORCE=0.18,TRIGGE RFORCE=0.06,
PROBEACCURACY=0.1,POSACCURACY=0.1,#RETURNDATA=7,
RETURNSPEED=1,SCANPNTDENSITY=100/VERTICAL_SCAN_LENGTH_MM,
SCANACCELERATION=10,SCANOFFSETFORCE=0.06,
PROBINGMODE=DFL,MANFINEPROBING=NO
PREHIT/MINOR_DIA/2
RETRACT/MINOR_DIA/2
TOUCHSPEED/ 1
[COLOR=#e74c3c]VERT_LINE_SCAN=BASICSCAN/LINE,NUMBER OF HITS=2,SHOW HITS=YES,SHOWALLPARAMS=YES
<MINOR_DIA/2,0,-MAX_DEPTH>,<MINOR_DIA/2,0,-MAX_DEPTH+VERTICAL_SCAN_LENGTH>,CutVec=0,1,0,DirVe c=0,0,1
InitVec=-1,0,0,EndVec=-1,0,0,THICKNESS=0,PROBECOMP=YES,AVOIDANCE MOVE=NO,DISTANCE=0
FILTER/NULLFILTER,
EXEC MODE=DEFINED
BOUNDARY/PLANE,<0,0,0>,PlaneVec=0,0,-1,Crossings=1
HITTYPE/VECTOR
NOMS MODE=NOM,0.05
HIT/VECTOR,<0,0,0>,<-1,0,0>,<0,0,0>,T=0
HIT/VECTOR,<0,0,0>,<-1,0,0>,<0,0,0>,T=0
ENDSCAN[/COLOR]
ENDSUB/



The move points in green work, both in simulation and on the machine; the features in red do not work in either simulation or reality (or at least, the first one doesn't in reality; I didn't let it bury itself in my part just to test the next two Slight smile ). Here's the code I'm calling it with, if that helps:


MOVE/CLEARPLANE
MILL_MILL_1=CALLSUB/THREADSCANNER,"THREAD_SCANNER":MPOINT(-0.15,0.375,0),MPOINT(0,0,1),MPOINT(0,1,0),0.07,0.0 5,1/56,1,20,,



This is preceded by manual, rough, and finish alignments which I can post as well if that would be helpful.

Does anyone know why my alignment might work for movements but not for measurements, or how I can fix it so it works for both?

Thank you,
Matthew
  • Just realized that this only works for 2D patterns but can 'easily' be configured to 3D. Here it is:
    STARTUP    =ALIGNMENT/START,RECALL:USE_PART_SETUP,LIST=YES
                ALIGNMENT/END
                MODE/MANUAL
                FORMAT/TEXT,OPTIONS, ,HEADINGS,SYMBOLS, ;NOM,TOL,MAXMIN, , , , 
                LOADPROBE/LSPX1_2X40
                TIP/T1A0B0, SHANKIJK=0, 0, 1, ANGLE=0
                GOTO/SUBLIBEND
    $$ NO,
                _____________________________________________________________________________________________
    
                By: Kp61dude!
                Create date: 01-13-2020
    
                Description:
                inputs- Vector I and J 
                return- Angle
                Calculates angle of vector I and J and returns angle ranging from 0 to 360. Agle start is at
                positive axis and rotates positive in counter clockwise about positive Z axis.
    
                Example #1
                Inputs are I = .707, J = .707
                Output is 45° 
    
                Example #2
                Inputs are I = -.707, J = .707
                Output is 135°
    
                Example #3
                Inputs are I = -1, J = 0
                Output is 180°
                _____________________________________________________________________________________________
    
                SUBROUTINE/ANG_FROM_IJ,
                    II =  : ,
                    JJ =  : ,
                    RETVAL =  : ,
                     = 
    $$ NO,
    
                 Example copied from:
                  https://academo.org/demos/rotation-about-point/
                  https://stackoverflow.com/questions/6247153/angle-from-2d-unit-vector
                  https://www.gamefromscratch.com/post/2012/11/24/GameDev-math-recipes-Rotating-one-point-around-another-point.aspx
    
                  original syntax: C++
    
    
    
                ASSIGN/DEBUG=0
    $$ NO,
    
    
    
    
    
    
                IF/DEBUG
                  ASSIGN/LOG_FILE="C:\users\public\documents\wai\pc-dmis\2015.1\DEBUG_LOG.TXT"
                END_IF/
                IF/DEBUG
    FPTR         =FILE/OPEN,LOG_FILE,APPEND
                  FILE/WRITELINE,FPTR,"*********************************************"
                  FILE/WRITELINE,FPTR,"BEFORE: Values inside ang sub are:"
                  FILE/WRITELINE,FPTR,II
                  FILE/WRITELINE,FPTR,"and"
                  FILE/WRITELINE,FPTR,JJ
                  FILE/WRITELINE,FPTR,"_____________________________________________"
                  FILE/CLOSE,FPTR,KEEP
                END_IF/
                ASSIGN/II=DOUBLE(II)
                ASSIGN/JJ=DOUBLE(JJ)
                IF/DEBUG
    FPTR         =FILE/OPEN,LOG_FILE,APPEND
                  FILE/WRITELINE,FPTR,"*********************************************"
                  FILE/WRITELINE,FPTR,"AFTER: Values inside ang sub are:"
                  FILE/WRITELINE,FPTR,II
                  FILE/WRITELINE,FPTR,"and"
                  FILE/WRITELINE,FPTR,JJ
                  FILE/WRITELINE,FPTR,"_____________________________________________"
                  FILE/CLOSE,FPTR,KEEP
                END_IF/
                IF/II < 0.0000001 AND II > -0.0000001
                  ASSIGN/II=0
                  IF/DEBUG
    FPTR           =FILE/OPEN,LOG_FILE,APPEND
                    FILE/WRITELINE,FPTR,"*********************************************"
                    FILE/WRITELINE,FPTR,"debugA"
                    FILE/WRITELINE,FPTR,"_____________________________________________"
                    FILE/CLOSE,FPTR,KEEP
                  END_IF/
                END_IF/
                IF/JJ < 0.0000001 AND JJ > -0.0000001
                  ASSIGN/JJ=0
                  IF/DEBUG
    FPTR           =FILE/OPEN,LOG_FILE,APPEND
                    FILE/WRITELINE,FPTR,"*********************************************"
                    FILE/WRITELINE,FPTR,"debugB"
                    FILE/WRITELINE,FPTR,"_____________________________________________"
                    FILE/CLOSE,FPTR,KEEP
                  END_IF/
                END_IF/
    $$ NO,
    
    
    
    
                IF/II == 0
                  IF/(JJ > 0)
                    ASSIGN/RETVAL=90
                    IF/DEBUG
    FPTR             =FILE/OPEN,LOG_FILE,APPEND
                      FILE/WRITELINE,FPTR,"*********************************************"
                      FILE/WRITELINE,FPTR,"debug1 " + RETVAL
                      FILE/WRITELINE,FPTR,"_____________________________________________"
                      FILE/CLOSE,FPTR,KEEP
                    END_IF/
                  GOTO/MIRET
                END_IF/
                ELSE_IF/(JJ == 0)
                  ASSIGN/RETVAL=0
                  IF/DEBUG
    FPTR           =FILE/OPEN,LOG_FILE,APPEND
                    FILE/WRITELINE,FPTR,"*********************************************"
                    FILE/WRITELINE,FPTR,"debug2 " + RETVAL
                    FILE/WRITELINE,FPTR,"_____________________________________________"
                    FILE/CLOSE,FPTR,KEEP
                  END_IF/
                GOTO/MIRET
                END_ELSEIF/
                ELSE/
                  ASSIGN/RETVAL=270
                  IF/DEBUG
    FPTR           =FILE/OPEN,LOG_FILE,APPEND
                    FILE/WRITELINE,FPTR,"*********************************************"
                    FILE/WRITELINE,FPTR,"debug3 " + RETVAL
                    FILE/WRITELINE,FPTR,"_____________________________________________"
                    FILE/CLOSE,FPTR,KEEP
                  END_IF/
                GOTO/MIRET
                END_ELSE/
                END_IF/
                ELSE_IF/JJ == 0
                  IF/(II >= 0)
                    ASSIGN/RETVAL=0
                    IF/DEBUG
    FPTR             =FILE/OPEN,LOG_FILE,APPEND
                      FILE/WRITELINE,FPTR,"*********************************************"
                      FILE/WRITELINE,FPTR,"debug4 " + RETVAL
                      FILE/WRITELINE,FPTR,"_____________________________________________"
                      FILE/CLOSE,FPTR,KEEP
                    END_IF/
                  GOTO/MIRET
                END_IF/
                ELSE/
                  ASSIGN/RETVAL=180
                  IF/DEBUG
    FPTR           =FILE/OPEN,LOG_FILE,APPEND
                    FILE/WRITELINE,FPTR,"*********************************************"
                    FILE/WRITELINE,FPTR,"debug5 " + RETVAL
                    FILE/WRITELINE,FPTR,"_____________________________________________"
                    FILE/CLOSE,FPTR,KEEP
                  END_IF/
                GOTO/MIRET
                END_ELSE/
                END_ELSEIF/
                ASSIGN/RETVAL=RAD2DEG(ATAN(JJ/II))
                IF/DEBUG
    FPTR         =FILE/OPEN,LOG_FILE,APPEND
                  FILE/WRITELINE,FPTR,"*********************************************"
                  FILE/WRITELINE,FPTR,"debug6 " + RETVAL
                  FILE/WRITELINE,FPTR,"_____________________________________________"
                  FILE/CLOSE,FPTR,KEEP
                END_IF/
                IF/II < 0 AND JJ < 0
                  ASSIGN/RETVAL=180 + RETVAL
                  IF/DEBUG
    FPTR           =FILE/OPEN,LOG_FILE,APPEND
                    FILE/WRITELINE,FPTR,"*********************************************"
                    FILE/WRITELINE,FPTR,"debug7 " + RETVAL
                    FILE/WRITELINE,FPTR,"_____________________________________________"
                    FILE/CLOSE,FPTR,KEEP
                  END_IF/
                END_IF/
                ELSE_IF/II < 0
                  ASSIGN/RETVAL=180 + RETVAL
                  IF/DEBUG
    FPTR           =FILE/OPEN,LOG_FILE,APPEND
                    FILE/WRITELINE,FPTR,"*********************************************"
                    FILE/WRITELINE,FPTR,"debug8 " + RETVAL
                    FILE/WRITELINE,FPTR,"_____________________________________________"
                    FILE/CLOSE,FPTR,KEEP
                  END_IF/
                END_ELSEIF/
                ELSE_IF/JJ < 0
                  ASSIGN/RETVAL=270 + (90 + RETVAL)
                  IF/DEBUG
    FPTR           =FILE/OPEN,LOG_FILE,APPEND
                    FILE/WRITELINE,FPTR,"*********************************************"
                    FILE/WRITELINE,FPTR,"debug9 " + RETVAL
                    FILE/WRITELINE,FPTR,"_____________________________________________"
                    FILE/CLOSE,FPTR,KEEP
                  END_IF/
                END_ELSEIF/
                ASSIGN/RETVAL=RETVAL
    MIRET      =LABEL/
                IF/DEBUG
    FPTR         =FILE/OPEN,LOG_FILE,APPEND
                  FILE/WRITELINE,FPTR,"*********************************************"
                  FILE/WRITELINE,FPTR,"RETVAL " + RETVAL
                  FILE/WRITELINE,FPTR,"_____________________________________________"
                  FILE/CLOSE,FPTR,KEEP
                END_IF/
                ENDSUB/
    
    


    If you go thru it all and clean it... please repost clean version!!!
  • continued....

    $$ NO,
                _____________________________________________________________________________________________
    
                By: Kp61dude!
                Create date: 01-13-2020
    
                Description:
                inputs- X, Y, Z, I, J, K                     0
                return- creates 4 auto vector points at each | location in a patter similar to below.
                Patter origin at [S] defined by inputs.      *
    
    
                                                  [S] 
                                                   0
                                                   |
                                                   *
                                       qqqqqqqqqqqqqqqqqqqqqqqqp
                                    pqpwffffffffffffffffffffffvkpp
                                   qqpwwwwwwwwwwwwwwwwwwwwwwwwwwvqp
                                   qgvwwwwwwwwwwwwwwwwwwwwwwwwwwwqqp
                                   qpwwwwwwwwwwwwwwwwwwwwwwwwwwwwqqp
                                   qpwwwwwwwwwwwulgggljwwwwwwwwwwqqp
                                   qpwwwwwwwwwgqp     qgpwwwwwwwwqqp
                                   qpwwwwwwwukp         qpwwwwwwwqqp
                               0-* qpwwwwwwwwqb         qqjwwwwwwqqp *-0
                                   qpwwwwwwwqq          qqbwwwwwwqqp
                                   qpwwwwwwwwqp         qpvwwwwwwqqp
                                   qpwwwwwwwwdqp       qgvwwwwwwwqqp
                                   qpwwwwwwwwwdmpgjjyqmkvwwwwwwwwqqp
                                   qpwwwwwwwwwwwvvvvvvvwwwwwwwwwwqqp          0
                                  jqpwwwwwwwwwwwwwwwwwwwwwwwwwwwwvqp          |
                                 jqpvwwwwwwwwwwwwwwwwwwwwwwwwwwwwwqqpj        *
                qggqggqggqggqggqgmmhwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwhmbqggqggqggqggqggqgg
                mmmmmmmmmmmmmmmmvwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwvmmmmmmmmmmmmmmmmmm
                wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
                wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
                wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
                _____________________________________________________________________________________________
    
                SUBROUTINE/CREATE_POINT_PATTERN,
                    I_X = 0 : ,
                    I_Y = 0 : ,
                    I_Z = 0 : ,
                    I_I = 0 : ,
                    I_J = 0 : ,
                    I_K = 0 : ,
                     = 
    $$ NO,
    
    
    
    
    
    
                ASSIGN/DEBUG=1
    $$ NO,
    
    
    
    
    
    
                IF/DEBUG
                  ASSIGN/LOG_FILE="C:\users\public\documents\wai\pc-dmis\2015.1\DEBUG_LOG.TXT"
      $$ NO,
                  clears old contents
    FPTR         =FILE/OPEN,LOG_FILE,WRITE
                  FILE/WRITELINE,FPTR,"Started: " + SYSTEMTIME("hh:mm:ss tt") + ", " + SYSTEMDATE("MM'/'dd'/'yyyy")
                  FILE/CLOSE,FPTR,KEEP
                END_IF/
                ASSIGN/POS=MPOINT(I_X,I_Y,I_Z)
                ASSIGN/POSIJK.XYZ=MPOINT(I_I,I_J,I_K)
                IF/DEBUG
    FPTR         =FILE/OPEN,LOG_FILE,APPEND
                  FILE/WRITELINE,FPTR,"*********************************************"
                  FILE/WRITELINE,FPTR,"individual XYZ : " +  POS.XYZ
                  FILE/WRITELINE,FPTR,"individual IJK : " +  POSIJK.XYZ
                  FILE/WRITELINE,FPTR,"_____________________________________________"
                  FILE/CLOSE,FPTR,KEEP
                END_IF/
                IF/POS.XYZ == 0 AND POSIJK.XYZ == 0
                  COMMENT/OPER,NO,FULL SCREEN=NO,AUTO-CONTINUE=NO,
                  Subroutine: SUB_BLOCK
                  ERROR: cannnot pass null.
                GOTO/SUB_RET
                END_IF/
                IF/DEBUG
    FPTR         =FILE/OPEN,LOG_FILE,APPEND
                  FILE/WRITELINE,FPTR,"*********************************************"
                  FILE/WRITELINE,FPTR,"Information about point SB1:"
                  FILE/WRITELINE,FPTR,"XYZ: " + SB1.XYZ
                  FILE/WRITELINE,FPTR,"IJK: " + SB1.IJK
                  FILE/WRITELINE,FPTR,"_____________________________________________"
                  FILE/CLOSE,FPTR,KEEP
                END_IF/
    SB1        =FEAT/CONTACT/VECTOR POINT/DEFAULT,CARTESIAN
                THEO/<POS.X+0,POS.Y+0,POS.Z+0>,<I_I+0,I_J+0,I_K+0>
                ACTL/<0.0295,0,-0.0295>,<0.0001264,-0.0000672,1>
                TARG/<POS.X+0,POS.Y+0,POS.Z+0>,<I_I+0,I_J+0,I_K+0>
                SHOW FEATURE PARAMETERS=NO
                SHOW CONTACT PARAMETERS=YES
                  AVOIDANCE MOVE=NO,DISTANCE=0.3937
                SHOW HITS=NO
                MOVE/POINT,NORMAL,<,,0.1500>
    $$ NO,
    
    
    
    
                ASSIGN/PASS_I=FORMAT("%.6f", I_I)
                ASSIGN/PASS_J=FORMAT("%.6f", I_J)
                ASSIGN/IANG=0
                IF/DEBUG
    FPTR         =FILE/OPEN,LOG_FILE,APPEND
                  FILE/WRITELINE,FPTR,"*********************************************"
                  FILE/WRITELINE,FPTR,"BEFORE"
                  FILE/WRITELINE,FPTR,"formated: " + FORMAT("%.20f", PASS_I)
                  FILE/WRITELINE,FPTR,"formated: " + FORMAT("%.20f", PASS_J)
                  FILE/WRITELINE,FPTR,"returned ang: " + IANG + " <<<<<<"
                  FILE/WRITELINE,FPTR,"        main sub        "
                  FILE/WRITELINE,FPTR,"_____________________________________________"
                  FILE/CLOSE,FPTR,KEEP
                END_IF/
    TODANGLE   =CALLSUB/ANG_FROM_IJ,:PASS_I,PASS_J,IANG,,,
                IF/DEBUG
    FPTR         =FILE/OPEN,LOG_FILE,APPEND
                  FILE/WRITELINE,FPTR,"*********************************************"
                  FILE/WRITELINE,FPTR,"AFTER"
                  FILE/WRITELINE,FPTR,"formated: " + FORMAT("%.20f", PASS_I)
                  FILE/WRITELINE,FPTR,"formated: " + FORMAT("%.20f", PASS_J)
                  FILE/WRITELINE,FPTR,"returned ang: " + IANG + " <<<<<<"
                  FILE/WRITELINE,FPTR,"        main sub        "
                  FILE/WRITELINE,FPTR,"_____________________________________________"
                  FILE/CLOSE,FPTR,KEEP
                END_IF/
                ASSIGN/TARGPNTX=SB1.X -.14
                ASSIGN/TARGPNTY=SB1.Y - .25
                ASSIGN/IANG=DEG2RAD(IANG)
                ASSIGN/ROTATEDX=COS(IANG) * (TARGPNTX - SB1.X) - SIN(IANG) * (TARGPNTY - SB1.Y) + SB1.X
                ASSIGN/ROTATEDY=SIN(IANG) * (TARGPNTX - SB1.X) + COS(IANG) * (TARGPNTY - SB1.Y) + SB1.Y
                IF/DEBUG
    FPTR         =FILE/OPEN,LOG_FILE,APPEND
                  FILE/WRITELINE,FPTR,"*********************************************"
                  FILE/WRITELINE,FPTR,"information for point: SB2"
                  FILE/WRITELINE,FPTR,"Point targs X: " + TARGPNTX
                  FILE/WRITELINE,FPTR,"Point targs Y: " + TARGPNTY
                  FILE/WRITELINE,FPTR,"Point rotated X: " + ROTATEDX
                  FILE/WRITELINE,FPTR,"Point rotated Y: " + ROTATEDY
                  FILE/WRITELINE,FPTR,"_____________________________________________"
                  FILE/CLOSE,FPTR,KEEP
                END_IF/
    SB2        =FEAT/CONTACT/VECTOR POINT/DEFAULT,CARTESIAN
                THEO/<ROTATEDX,ROTATEDY,SB1.Z>,<SB1.I,SB1.J,SB1.K>
                ACTL/<-0.1356,-0.2524,0>,<1,0,0>
                TARG/<ROTATEDX,ROTATEDY,SB1.Z>,<SB1.I,SB1.J,SB1.K>
                SHOW FEATURE PARAMETERS=NO
                SHOW CONTACT PARAMETERS=YES
                  AVOIDANCE MOVE=NO,DISTANCE=0.3937
                SHOW HITS=NO
    
    
  • continued....

    $$ NO,
    
    
    
    
                ASSIGN/TARGPNTX=SB1.X-.07
                ASSIGN/CCTARGPNTX=DIST3D({SB1},{SB2})
                ASSIGN/TARGPNTY=SB1.Y-.13
                ASSIGN/ROTATEDX=COS(IANG) * (TARGPNTX - SB1.X) - SIN(IANG) * (TARGPNTY - SB1.Y) + SB1.X
                ASSIGN/ROTATEDY=SIN(IANG) * (TARGPNTX - SB1.X) + COS(IANG) * (TARGPNTY - SB1.Y) + SB1.Y
                ASSIGN/CALC_I_VECTOR=FUNCTION((D,I,J),COS(DEG2RAD(D))*I-SIN(DEG2RAD(D))*J)
                ASSIGN/CALC_J_VECTOR=FUNCTION((D,I,J),SIN(DEG2RAD(D))*I-COS(DEG2RAD(D))*J)
                ASSIGN/ROTATEBY=270
                ASSIGN/ROTATEDI=CALC_I_VECTOR(ROTATEBY,I_I,I_J)
                ASSIGN/ROTATEDJ=CALC_J_VECTOR(ROTATEBY,I_I,I_J)
                IF/DEBUG
    FPTR         =FILE/OPEN,LOG_FILE,APPEND
                  FILE/WRITELINE,FPTR,"*********************************************"
                  FILE/WRITELINE,FPTR,"information for point: SB3"
                  FILE/WRITELINE,FPTR,"mid calculated position: " + TARGPNTX
                  FILE/WRITELINE,FPTR,"_____________________________________________"
                  FILE/WRITELINE,FPTR,"*********************************************"
                  FILE/WRITELINE,FPTR,"Rotate vector by given angle"
                  FILE/WRITELINE,FPTR,"input angle (rotate by): " + ROTATEBY
                  FILE/WRITELINE,FPTR,"input I: " + I_I
                  FILE/WRITELINE,FPTR,"input J: " + I_J
                  FILE/WRITELINE,FPTR,"  "
                  FILE/WRITELINE,FPTR,"output I: " + ROTATEDI
                  FILE/WRITELINE,FPTR,"output J: " + ROTATEDJ
                  FILE/WRITELINE,FPTR,"_____________________________________________"
                  FILE/CLOSE,FPTR,KEEP
                END_IF/
    SB3        =FEAT/CONTACT/VECTOR POINT/DEFAULT,CARTESIAN
                THEO/<ROTATEDX,ROTATEDY,SB1.Z>,<ROTATEDI,ROTATEDJ,0+0>
                ACTL/<-0.1,-0.13,0>,<1,0,0>
                TARG/<ROTATEDX,ROTATEDY,SB1.Z>,<ROTATEDI,ROTATEDJ,0+0>
                SHOW FEATURE PARAMETERS=NO
                SHOW CONTACT PARAMETERS=YES
                  AVOIDANCE MOVE=NO,DISTANCE=0.3937
                SHOW HITS=NO
                MOVE/POINT,NORMAL,<,,0.1500>
    $$ NO,
    
    
    
    
                ASSIGN/TARGPNTX=SB3.X
                ASSIGN/TARGPNTY=SB3.Y + .25
                ASSIGN/OPPI=SB3.I*(-1)
                ASSIGN/OPPJ=SB3.J*(-1)
                ASSIGN/ROTATEDX=COS(IANG) * (TARGPNTX - SB3.X) - SIN(IANG) * (TARGPNTY - SB3.Y) + SB3.X
                ASSIGN/ROTATEDY=SIN(IANG) * (TARGPNTX - SB3.X) + COS(IANG) * (TARGPNTY - SB3.Y) + SB3.Y
                IF/DEBUG
    FPTR         =FILE/OPEN,LOG_FILE,APPEND
                  FILE/WRITELINE,FPTR,"*********************************************"
                  FILE/WRITELINE,FPTR,"information for point: SB4"
                  FILE/WRITELINE,FPTR,"Point targs X: " + TARGPNTX
                  FILE/WRITELINE,FPTR,"Point targs Y: " + TARGPNTY
                  FILE/WRITELINE,FPTR,"Point rotated X: " + ROTATEDX
                  FILE/WRITELINE,FPTR,"Point rotated Y: " + ROTATEDY
                  FILE/WRITELINE,FPTR,"opp vec I: " + OPPI
                  FILE/WRITELINE,FPTR,"opp vec J: " + OPPJ
                  FILE/WRITELINE,FPTR,"_____________________________________________"
                  FILE/CLOSE,FPTR,KEEP
                END_IF/
    SB4        =FEAT/CONTACT/VECTOR POINT/DEFAULT,CARTESIAN
                THEO/<ROTATEDX,ROTATEDY,SB1.Z>,<OPPI,OPPJ,0+0>
                ACTL/<-0.1,-0.38,-0.0295>,<-1,0,0>
                TARG/<ROTATEDX,ROTATEDY,SB1.Z>,<OPPI,OPPJ,0+0>
                SHOW FEATURE PARAMETERS=NO
                SHOW CONTACT PARAMETERS=YES
                  AVOIDANCE MOVE=NO,DISTANCE=0.3937
                SHOW HITS=NO
    SUB_RET    =LABEL/
                ENDSUB/
    SUBLIBEND  =LABEL/
    
  • You will call:
    CS1        =CALLSUB/CREATE_POINT_PATTERN...
    


    and yes all this mumbo jumbo junk put together outputs desired results. I originally created it for a video game engine my son and I are writing from scratch.


    Hey look at that I passed 1000 posts and my name changed to "PC-DMIS demi-Guru" clearly that is a bug... how am I that? Must be one of them participation trophy things.
  • This is helpful, thank you. All that rotation stuff is key - man would it be messy in 3D! I may just write logic to work for orthogonal holes, which would be 99% of my use case anyway. I will definitely post once I get something figured out! Thank you for the help and inspiration!
  • This is helpful, thank you. All that rotation stuff is key - man would it be messy in 3D! I may just write logic to work for orthogonal holes, which would be 99% of my use case anyway. I will definitely post once I get something figured out! Thank you for the help and inspiration!


    Heck yeah my pleasure!!! Glad I was of some help. Be courteous and post ideas (that you're allowed to of course).
  • This one will take a little while to decipher... please post any comments / suggestions / anything.
  • Yes, certainly. I do double duty here as an engineer and CMM programmer, so I'm off to fix some CAD models for a day or two. I'll definitely keep this updated, though!
  • I know it's been nearly a month, but I am finally making progress on this again...
  • OK, I've started to get the rotation stuff figured out. Using a vector to specify the orientation of the hole and a second to fix rotation about the hole, this (sub-)subroutine creates a matrix of three orthogonal unit vectors defining the coordinate system:

    SUBROUTINE/ORTHONORMALIZE,
    DIRECTIONVEC = : DIRECTION VECTOR,
    ORIENTATIONVEC = : ORIENTATION VECTOR,
    BASISMAT = : RETURN VARIABLE TO BE POPULATED WTIH 2D ARRAY,
    =
    $$ NO,
    Orthogonalize Orientation Vector
    ASSIGN/ORTHOVEC2=ORIENTATIONVEC - (DOT(DIRECTIONVEC, ORIENTATIONVEC)/DOT(DIRECTIONVEC, DIRECTIONVEC) * DIRECTIONVEC)
    $$ NO,
    Compute Cross Product to get third vector (guaranteed orthogonal by the cross product)
    ASSIGN/ORTHOVEC3=CROSS(DIRECTIONVEC, ORIENTATIONVEC)
    $$ NO,
    Check to make sure all vectors are nonzero
    IF/DOT(DIRECTIONVEC, DIRECTIONVEC) < 0.00000001
    COMMENT/OPER,NO,FULL SCREEN=NO,AUTO-CONTINUE=NO,
    Very small magnitude direction vector - did you input the zero vector by mistake?
    ROUTINE/END
    END_IF/
    IF/DOT(ORTHOVEC2, ORTHOVEC2) < 0.00000001
    COMMENT/OPER,NO,FULL SCREEN=NO,AUTO-CONTINUE=NO,
    Very small magnitude orthogonalized orienation vector - was it parallel to the to the direction vector?
    ROUTINE/END
    END_IF/
    IF/DOT(ORTHOVEC3, ORTHOVEC3) < 0.00000001
    COMMENT/OPER,NO,FULL SCREEN=NO,AUTO-CONTINUE=NO,
    Very small magnitude orthogonalized third vector - are your direction and orientation vectors tiny or nearly parallel?
    ROUTINE/END
    END_IF/
    $$ NO,
    Normalize orthogonal vectors
    ASSIGN/ORTHONORMALVEC1=UNIT(DIRECTIONVEC)
    ASSIGN/ORTHONORMALVEC2=UNIT(ORTHOVEC2)
    ASSIGN/ORTHONORMALVEC3=UNIT(ORTHOVEC3)
    $$ NO,
    Store results in a "matrix" (super messy because it basically needs to be transposed)
    ASSIGN/BASISMAT=ARRAY(MPOINT(ORTHONORMALVEC1.X, ORTHONORMALVEC2.X, ORTHONORMALVEC3.X), MPOINT(ORTHONORMALVEC1.Y, ORTHONORMALVEC2.Y, ORTHONORMALVEC3.Y), MPOINT(ORTHONORMALVEC1.Z, ORTHONORMALVEC2.Z, ORTHONORMALVEC3.Z))
    ENDSUB/
    


    Using the matrix created by that subroutine, this one will rotate and translate a position vector from the custom coordinate system into the current alignment:

    SUBROUTINE/TRANSFORMXYZ,
    BASISMATRIX = : MATRIX OUTPUT FROM ORTHONORMALIZE,
    POSITION_OFFSET = : POSITION VECTOR OF SUB ORIGIN RELATIVE TO ACTUAL ALIGNMENT,
    ORIGINAL_VECTOR = : UNTRANSFORMED VECTOR,
    TRANSFORMED_VECTOR = : RETURN VARIABLE FOR THE RESULT,
    =
    $$ NO,
    Rotate vector using basis matrix
    ASSIGN/ROTATED_VECTOR=MPOINT(DOT(BASISMATRIX[1], ORIGINAL_VECTOR), DOT(BASISMATRIX[2], ORIGINAL_VECTOR), DOT(BASISMATRIX[3], ORIGINAL_VECTOR))
    $$ NO,
    Translate vector using position offset
    ASSIGN/TRANSFORMED_VECTOR=ROTATED_VECTOR + POSITION_OFFSET
    ENDSUB/
    


    Finally, this sub will rotate but not translate a direction vector:

    SUBROUTINE/TRANSFORMIJK,
    BASISMATRIX = : MATRIX OUTPUT FROM ORTHONORMALIZE,
    ORIGINAL_VECTOR = : UNTRANSFORMED VECTOR,
    TRANSFORMED_VECTOR = : RETURN VARIABLE FOR THE RESULT,
    =
    $$ NO,
    Rotate vector using basis matrix - don't translate
    ASSIGN/TRANSFORMED_VECTOR=MPOINT(DOT(BASISMATRIX[1], ORIGINAL_VECTOR), DOT(BASISMATRIX[2], ORIGINAL_VECTOR), DOT(BASISMATRIX[3], ORIGINAL_VECTOR))
    ENDSUB/
    


    Here's my (outer) subroutine code that actually drives things, up to the basic scan:

    SUBROUTINE/THREADSCANNER,
    POSITION = : POSITION OF HOLE IN ACTIVE ALIGNMENT,
    DIRECTION = : DIRECTION VECTOR (POINTING STRAIGHT OUT OF HOLE) IN ACTIVE ALIGNMENT,
    ORIENTATION = : VECTOR NORMAL TO DIRECTION, POINTING TO SIDE TO VERTICALLY SCAN,
    MINOR_DIA = : NOMINAL MINOR DIAMETER OF HOLE,
    MAX_DEPTH = : DEPTH TO START VERTICAL SCAN AT (MUST BE AT LEAST 2*PITCH BELOW TOP),
    PITCH = : PITCH OF THREAD,
    SCAN_REVS = : NUMBER OF REVOLUTIONS TO SPIRAL SCAN (MUST FIT WITHIN HOLE),
    MOVESPD = : SPEED DURING MOTION,
    RADIAL_DISTANCE_TOL = 0.0002 : POINTS WITHIN THIS DISTANCE FROM HIGH POINT WILL BE CONSIDERED ON THE CREST,
    MIN_CREST_TOL = 0.125 : MINIMUM ACCEPTABLE CREST WIDTH AS A PERCENTAGE OF PITCH,
    MAX_CREST_TOL = 0.375 : MAXIMUM ACCEPTABLE CREST WIDTH AS A PERCENTAGE OF PITCH,
    =
    $$ NO,
    **WARNING: THIS WILL MOVE THE MACHINE!!!**
    If you type in dumb numbers, it will do dumb things.
    Also, make sure your tip angle is right.
    ACCELERATION/MAXACCELX=250, MAXACCELY=250, MAXACCELZ=250
    MOVESPEED/ MOVESPD
    MODE/DCC
    TOUCHSPEED/ 1
    ASSIGN/PREHITAMOUNT=MIN(ARRAY(MINOR_DIA/2,0.02))
    PREHIT/PREHITAMOUNT
    RETRACT/PREHITAMOUNT
    $$ NO,
    Calculate vector space basis for hole coordinate system
    ASSIGN/HOLE_BASIS=0
    CS1 =CALLSUB/ORTHONORMALIZE,[emoticon:6D505171FAA4497C85C5CA27290C555D]IRECTION,ORIENTATION,HOLE_BASIS,,
    $$ NO,
    Make sure it actually calculated something
    IF/HOLE_BASIS == 0
    COMMENT/OPER,NO,FULL SCREEN=NO,AUTO-CONTINUE=NO,
    Orthonormalization of direction and orientation vectors failed! Exiting.
    ROUTINE/END
    END_IF/
    $$ NO,
    Move to start point using transformation
    ASSIGN/START_POINT=MPOINT(0,0,0)
    CS2 =CALLSUB/TRANSFORMXYZ,:HOLE_BASIS,POSITION,START_POINT,STAR T_POINT,,
    MOVE/POINT,NORMAL,<START_POINT.X,START_POINT.Y,START_PO INT.Z>
    $$ NO,
    Calculate and set scan density to yield ~100 points over 2 pitch lengths
    ASSIGN/SCAN_DENSITY=100/(PITCH*25.4)
    OPTIONPROBE/MAXFORCE=0.36,LOWFORCE=0.06,UPPERFORCE=0.18,TRIGGE RFORCE=0.06,
    PROBEACCURACY=0.1,POSACCURACY=0.1,#RETURNDATA=7,
    RETURNSPEED=1,SCANPNTDENSITY=SCAN_DENSITY,
    SCANACCELERATION=10,SCANOFFSETFORCE=0.06,
    PROBINGMODE=DFL,MANFINEPROBING=NO
    $$ NO,
    Calculate scan speed to spend ~1 second scanning, ignoring acceleration time
    SCANSPEED/2*PITCH*25.4
    $$ NO,
    Set and transform scan points
    ASSIGN/SCAN_START_POINT=MPOINT(-MAX_DEPTH, MINOR_DIA/2, 0)
    ASSIGN/SCAN_END_POINT=MPOINT(-MAX_DEPTH+2*PITCH, MINOR_DIA/2, 0)
    CS8 =CALLSUB/TRANSFORMXYZ,:HOLE_BASIS,POSITION,SCAN_START_POINT ,SCAN_START_POINT,,
    CS9 =CALLSUB/TRANSFORMXYZ,:HOLE_BASIS,POSITION,SCAN_END_POINT,S CAN_END_POINT,,
    $$ NO,
    Set and transform scan vectors
    ASSIGN/SCAN_INIT_VEC=MPOINT(0, -1, 0)
    ASSIGN/SCAN_DIR_VEC=MPOINT(1, 0, 0)
    ASSIGN/SCAN_CUT_VEC=MPOINT(0, 0, 1)
    ASSIGN/SCAN_END_VEC=MPOINT(0, -1, 0)
    CS10 =CALLSUB/TRANSFORMIJK,:HOLE_BASIS,SCAN_INIT_VEC,SCAN_INIT_V EC,,
    CS11 =CALLSUB/TRANSFORMIJK,:HOLE_BASIS,SCAN_DIR_VEC,SCAN_DIR_VEC ,,
    CS12 =CALLSUB/TRANSFORMIJK,:HOLE_BASIS,SCAN_CUT_VEC,SCAN_CUT_VEC ,,
    CS13 =CALLSUB/TRANSFORMIJK,:HOLE_BASIS,SCAN_END_VEC,SCAN_END_VEC ,,
    $$ NO,
    Scan Hole Wall
    WALL_LINE_SCAN=BASICSCAN/LINE,NUMBER OF HITS=2,SHOW HITS=YES,SHOWALLPARAMS=YES
    <SCAN_START_POINT.X,SCAN_START_POINT.Y,SCAN_START_ POINT.Z>,<SCAN_END_POINT.X,SCAN_END_POINT.Y,SCAN_E ND_POINT.Z>,CutVec=SCAN_CUT_VEC.I,SCAN_CUT_VEC.J,S CAN_CUT_VEC.K,DirVec=SCAN_DIR_VEC.I,SCAN_DIR_VEC.J ,SCAN_DIR_VEC.K
    InitVec=SCAN_INIT_VEC.I,SCAN_INIT_VEC.J,SCAN_INIT_ VEC.K,EndVec=SCAN_END_VEC.I,SCAN_END_VEC.J,SCAN_EN D_VEC.K,THICKNESS=0,PROBECOMP=YES,AVOIDANCE MOVE=NO,DISTANCE=0
    FILTER/NULLFILTER,
    EXEC MODE=RELEARN
    BOUNDARY/PLANE,<SCAN_END_POINT.X,SCAN_END_POINT.Y,SCAN_END_ POINT.Z>,PlaneVec=-SCAN_DIR_VEC.I,-SCAN_DIR_VEC.J,-SCAN_DIR_VEC.K,Crossings=1
    HITTYPE/VECTOR
    NOMS MODE=FINDNOMS,0.05
    HIT/VECTOR,<0,0,0>,<0,-1,0>,<0,0,0>,T=0
    HIT/VECTOR,<0,0,0>,<0,-1,0>,<0,0,0>,T=0
    ENDSCAN
    COMMENT/OPER,NO,FULL SCREEN=NO,AUTO-CONTINUE=NO,
    "Numhits:" + WALL_LINE_SCAN.NUMHITS
    


    I'm having some trouble with the basic scan analysis - I need to calculate the distance between the points in the scan and the (possibly skewed) central axis of my hole. But I'm making progress.