torture.py
1 #!/usr/bin/env python 2 # Copyright (C) 2012 Jeff Epler <jepler@unpythonic.net> 3 # 4 # This program is free software; you can redistribute it and/or modify 5 # it under the terms of the GNU General Public License as published by 6 # the Free Software Foundation; either version 2 of the License, or 7 # (at your option) any later version. 8 # 9 # This program is distributed in the hope that it will be useful, 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 # GNU General Public License for more details. 13 # 14 # You should have received a copy of the GNU General Public License 15 # along with this program; if not, write to the Free Software 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 """ 18 This program creates "torture test" ngc files. These include arcs (helices) 19 in any plane, straight feeds, and traverses all in a random order with 20 differing feeds. 21 22 Run the resulting file in a stepper inifile with no headroom, and kick 23 things up a notch by using different max velocities and accelerations. 24 Turning feed override past 100% has also helped turn up bugs. 25 """ 26 27 from random import * 28 from math import sin, cos, pi 29 30 distances = [-10,1,-.1,0,0,.1,1,10] 31 radii = [.1, 1, 10] 32 arcangles = range(0, 360, 45) 33 aangles = [-361,-89,-1,1,91,359] 34 chance_angular = .5 35 chance_angular_helix = .5 36 chance_lineaxis = .2 37 38 def feed(): 39 "Half the time, change the feed rate" 40 if random() < .5: return 41 print "F%d" % randrange(100, 1000, 10), 42 43 def torture_arc(x, y, z, a, b, c, u, v, w): 44 "Generate a random arc (helix)" 45 plane = randrange(3) 46 print "G%d" % (plane+17), 47 48 direction = randrange(2) 49 print "G%d" % (direction+2), 50 51 feed() 52 53 theta = choice(arcangles) 54 theta1 = choice(arcangles) 55 r = choice(radii) 56 q = choice(distances) 57 58 print "(%d %d)" % (theta*180/pi, theta1*180/pi), 59 if plane == 0: # XY plane 60 ox = -cos(theta)*r 61 oy = -sin(theta)*r 62 print "I%f J%f" % (ox, oy), 63 64 z = z + q 65 x = x + ox + cos(theta1)*r 66 y = y + oy + sin(theta1)*r 67 68 elif plane == 1: # XZ plane 69 ox = -cos(theta)*r 70 oz = -sin(theta)*r 71 print "I%f K%f" % (ox, oz), 72 73 x = x + ox + sin(theta1)*r 74 z = z + oz + cos(theta1)*r 75 y = y + q 76 77 else: # YZ plane 78 oy = -cos(theta)*r 79 oz = -sin(theta)*r 80 print "J%f K%f" % (oy, oz), 81 82 x = x + q 83 y = y + oy + cos(theta1)*r 84 z = z + oz + sin(theta1)*r 85 86 if random() < chance_angular_helix: 87 a = a + choice(aangles) 88 print "A%f" % a, 89 90 if random() < chance_angular_helix: 91 b = b + choice(aangles) 92 print "B%f" % b, 93 94 if random() < chance_angular_helix: 95 c = c + choice(aangles) 96 print "C%f" % c, 97 98 if random() < chance_angular_helix: 99 u = u + randrange(-500, 500)/100. 100 print "U%f" % u, 101 102 if random() < chance_angular_helix: 103 v = v + randrange(-500, 500)/100. 104 print "V%f" % v, 105 106 if random() < chance_angular_helix: 107 w = w + randrange(-500, 500)/100. 108 print "W%f" % w, 109 110 print "X%f Y%f Z%f" % (x, y, z) 111 112 return x, y, z, a, b, c, u, v, w 113 114 def torture_line(x, y, z, a, b, c, u, v, w): 115 "Generate a random traverse or straight feed" 116 kind = randrange(2) 117 p = "" 118 p += "G%d " % kind 119 120 if random() < chance_lineaxis: 121 x = x + randrange(-10, 11)/2. 122 p += "X%f " % x 123 124 if random() < chance_lineaxis: 125 y = y + randrange(-10, 11)/2. 126 p += "Y%f " % y 127 128 if random() < chance_lineaxis: 129 z = z + randrange(-10, 11)/2. 130 p += "Z%f " % z 131 132 if random() < chance_lineaxis: 133 a = a + randrange(-180, 80)/2. 134 p += "A%f " % a 135 136 if random() < chance_lineaxis: 137 b = b + randrange(-180, 80)/2. 138 p += "B%f " % b 139 140 if random() < chance_lineaxis: 141 c = c + randrange(-180, 80)/2. 142 p += "C%f " % c 143 144 if random() < chance_lineaxis: 145 u = u + randrange(-500, 500)/100. 146 p += "U%f " % u 147 148 if random() < chance_lineaxis: 149 v = v + randrange(-500, 500)/100. 150 p += "V%f " % v 151 152 if random() < chance_lineaxis: 153 w = w + randrange(-500, 500)/100. 154 p += "W%f " % w 155 156 if len(p) > 4: 157 if kind == 1: feed() 158 print p 159 160 return x, y, z, a, b, c, u, v, w 161 162 def torture_main(runs): 163 """Generate random chains of movement several times, restarting near the 164 center each time motion gets too far away.""" 165 funcs = [torture_line, torture_arc] 166 #funcs = [torture_arc] 167 def R(x,l=-50, k=50): return x < l or x > k 168 169 print "g21" 170 for i in range(runs): 171 x = y = 0 172 z = 20 173 a = b = c = u = v = w = 0 174 if chance_angular or chance_angular_helix: 175 print "G0 X0 Y0 A0 B0 C0 U0 V0 W0 Z20" 176 else: 177 print "G0 X0 Y0 Z20" 178 print "F100" 179 180 while 1: 181 x, y, z, a, b, c, u, v, w = choice(funcs)(x, y, z, a, b, c, u, v, w) 182 if (R(x) or R(y) or R(z,-10,30) or 183 R(a,-30000,30000) or R(b, -30000,30000) or R(c, -30000,30000) or 184 R(u) or R(v) or R(w)): 185 break 186 187 # Do ten runs then print m2 188 torture_main(20) 189 print "m2"