-
Notifications
You must be signed in to change notification settings - Fork 0
/
ShopBot_TanOsc_Knife_(inch).pp
457 lines (373 loc) · 14.5 KB
/
ShopBot_TanOsc_Knife_(inch).pp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
+-----------------------------------------------------------
|
| ShopBot configuration file
|
|-----------------------------------------------------------
|
| Who When What
| ====== ========== ========================================
| Ryan P ???? Written
| Joe B 9/15/2022 Changed jogs to moves. Fleshed out header
| Brian O 9/20/2022 Eliminated need for "unwind" moves. Futher fleshed out header and footer
| Brian O 11/10/2022 Modified to automatically "round" corners for turns
| Brian O 11/24/2022 Added UI to set knife parameters
+-----------------------------------------------------------
POST_NAME = "ShopBot Tan/Osc Knife (inch)(*.sbp)"
FILE_EXTENSION = "sbp"
UNITS = "inches"
DIRECT_OUTPUT = "DIRECT to ShopBot|ShopBot_run.ini"
+------------------------------------------------
| line terminating characteRS
+------------------------------------------------
LINE_ENDING = "[13][10]"
+------------------------------------------------
| Block Numbering
+------------------------------------------------
LINE_NUMBER_START = 0
LINE_NUMBER_INCREMENT = 10
LINE_NUMBER_MAXIMUM = 999999
+================================================
+
+ default formating for variables
+
+================================================
+------------------------------------------------
+ Line numbering
+------------------------------------------------
var LINE_NUMBER = [N|A|N|1.0]
+------------------------------------------------
+ Spindle Speed
+------------------------------------------------
var SPINDLE_SPEED = [S|A||1.0]
+------------------------------------------------
+ Feed Rate
+------------------------------------------------
var CUT_RATE = [FC|A||1.1|0.0166]
var PLUNGE_RATE = [FP|A||1.1|0.0166]
+------------------------------------------------
+ Tool position in x,y and z
+------------------------------------------------
var X_POSITION = [X|A||1.6]
var Y_POSITION = [Y|A||1.6]
var Z_POSITION = [Z|A||1.6]
+------------------------------------------------
+ Home tool positions
+------------------------------------------------
var X_HOME_POSITION = [XH|A||1.6]
var Y_HOME_POSITION = [YH|A||1.6]
var Z_HOME_POSITION = [ZH|A||1.6]
+------------------------------------------------
+ ArC centre positions - incremental from arC start
+------------------------------------------------
VAR ARC_CENTRE_I_INC_POSITION = [I|A||1.6]
VAR ARC_CENTRE_J_INC_POSITION = [J|A||1.6]
+================================================
+
+ Block definitions for toolpath output
+
+================================================
+ ------------------------------------------------
+ Scripted function used in postp
+ ------------------------------------------------
SCRIPT
require "strict"
pp = require "ppVariables"
Px = -999999
Py = -999999
Pz = -999999
PPx = -999999
PPy = -999999
PPz = -999999
RotationCount = 0 --Counts number of full rotations made by knife; used to correct position with VA command during lifts.
Plunge = 0
Radius = 0.1 --(Inches) Radius for auto-radius corner turning; recommend width of knife blade.
turnInc = 0.2 --(Radians) Angular increment for corner radiusing turns.
LiftAngle = 140 --(Degrees) Turn angle above which the knife will be lifted out of the material for turn.
InAngle = 0 --(Radians) Angle parallel to motion going into a corner (PPx/PPy to Px/Py)
OutAngle = 0 -- (Radians) Angle parlalel to motion going out of a corner (Px/Py to pp.X.Value/pp.Y.Value)
TurnAngle = 0
rad2Deg = 180.0 / math.pi --Conversion factor from radians to degrees.
Options = {} -- Initialize options table
Options.bladeWidth = 0.125 -- default value for blade width
Options.pulloutAngle = 120 -- default value for pullout angle
g_title = "Tangential_Oscillating_Knife" -- name for registry entry where settings are recorded.
g_default_window_width = 625 -- window width for UI in pixels
g_default_window_height = 225 -- window height for UI in pixels
InJog = 0
g_DialogHtml = [[]] -- html source for UI. Each line must be concatenated to this variable. This allows for readable formatting.
..[[<!DOCTYPE html>]]
..[[<html>]]
..[[<head>]]
..[[<title>Tangential Oscillating Knife Dialog</title>]]
..[[<style type="text/css">]]
..[[body{background-color: #F0F0F0;}]]
..[[body,td,th{font-family: Arial, Helvetica,sans-serif;font-size: 12px;}]]
..[[.ParameterDescription{color:#555; width: 70%}]]
..[[.FormButton {font-weight: bold; width: 100%; font-family: Arial, Helvetica, sans-serif; font-size: 12px;}]]
..[[</style>]]
..[[</head>]]
..[[<body>]]
..[[<table width=100%>]]
..[[<tr height="40"><td colspan="4" valign="bottom"><b>Knife Settings</b><hr></td></tr>]]
..[[<tr>]]
..[[<td width=5%>Blade Width </td>]]
..[[<td width=5%><input name="textfield" type="text" size="8" maxlength="5" ID="bladeWidth"></td>]]
..[[<td width=20% text-align="left"><span id="bladeWidthUnits">Inches</span></td>]]
..[[<td class="ParameterDescription">Width of blade (center of rotation to cutting edge).</td>]]
..[[</tr>]]
..[[<tr>]]
..[[<td width=5%>Pullout Angle </td>]]
..[[<td width=5%><input name="textfield" type="text" size="8" maxlength="5" ID="pulloutAngle"></td>]]
..[[<td width=20% text-align="left"><span id="bladeWidthUnits">Degrees</span></td>]]
..[[<td class="ParameterDescription">Minimum angle to trigger pullout for turn.</td>]]
..[[</tr>]]
..[[<tr>]]
..[[<td style="width: 100%" colspan="4"><hr width="100%"></td>]]
..[[</tr>]]
..[[</table>]]
..[[<table width=100%>]]
..[[<tr width=100%>]]
..[[<td style="width: 40%"></td>]]
..[[<td style="width: 20%"><input class="FormButton" type="button" style="font-weight: bold; width: 100%; font-family: 'Lucida Sans Unicode', 'Lucida Grande', sans-serif; font-size: 12px;" id="ButtonOK" value="OK"></td>]]
..[[<td style="width: 40%"></td>]]
..[[</tr>]]
..[[</table>]]
..[[</body>]]
..[[</html>]]
function DisplayDialog(Options) -- Called in main. Pulls up UI
local dialog = HTML_Dialog(true,g_DialogHtml, g_default_window_width, g_default_window_height, "Tangential Oscillating Knife Toolpath")
dialog:AddLabelField("GadgetTitle", g_title)
dialog:AddDoubleField("bladeWidth", Options.bladeWidth)
dialog:AddDoubleField("pulloutAngle", Options.pulloutAngle)
if not dialog:ShowDialog() then
return 0
end
Options.bladeWidth = dialog:GetDoubleField("bladeWidth")
Options.pulloutAngle = dialog:GetDoubleField("pulloutAngle")
if Options.bladeWidth <= 0 then
DisplayMessageBox("Blade width must be a positive non-zero number!")
return -1
end
if Options.pulloutAngle <= 0 then
DisplayMessageBox("Pullout Angle must be a positive non-zero number!")
return -1
end
return 1
end
function LoadDefaults(Options) -- Loads variable defaults from registry.
local registry = Registry(g_title)
Options.bladeWidth = registry:GetDouble("bladeWidth", Options.bladeWidth)
Options.pulloutAngle = registry:GetDouble("pulloutAngle", Options.pulloutAngle)
end
function SaveDefaults(Options) -- Records settings to registry for recall the next time post is run.
local registry = Registry(g_title)
registry:SetDouble("bladeWidth", Options.bladeWidth)
registry:SetDouble("pulloutAngle", Options.pulloutAngle)
end
--[[ === main =================================================
|
| Initialise variables
|
]]
function main()
if pp.Init() == false then
DisplayMessageBox('Failed to initialise ppVariables module!')
end
LoadDefaults(Options)
--MessageBox("dialog")
local dialog_result = -1
while dialog_result == -1 do
dialog_result = DisplayDialog(Options)
end
-- The user cancelled
if dialog_result == 0 then
return false
end
SaveDefaults(Options)
Radius = Options.bladeWidth
LiftAngle = Options.pulloutAngle
return true
end
function Jog()
if Px == -999999 then
pp.PostP:OutputLine("J5 " .. Round2Six(pp.X.Value) .. "," .. Round2Six(pp.Y.Value) .. "," .. Round2Six(pp.Z.Value) .. ",," .. "\r\n", false)
end
if PPz < pp.SAFEZ.Value and Px ~= -999999 then
InJog = 1
AddRotation()
pp.PostP:OutputLine("M5," .. Round2Six(Px) .. "," .. Round2Six(Py) .. "," .. Round2Six(PPz) .. ",," .. Round2Six(OutAngle*rad2Deg) .. "\r\n",false)
end
if PPz >= pp.SAFEZ.Value and Px ~= -999999 then
pp.PostP:OutputLine("J5 " .. Round2Six(Px) .. "," .. Round2Six(Py) .. "," .. Round2Six(Pz) .. ",," .. "\r\n", false)
if RotationCount ~= 0 then
pp.PostP:OutputLine("VA,,,,," .. Round2Six(OutAngle*rad2Deg - 360 * RotationCount) .. "\r\n",false)
RotationCount = 0
end
end
PPx = Px
PPy = Py
PPz = Pz
Px = pp.X.Value
Py = pp.Y.Value
Pz = pp.Z.Value
end
function AddRotation(cc)
if (PPx ~= Px or PPy ~= Py or PPz ~= Pz) and PPx ~= -999999 and Pz < pp.SAFEZ.Value then
local TurnX = Px
local TurnY = Py
local Lift = 1
local TurnDistance = 0
AngleCalculation()
if PPz >= pp.SAFEZ.Value then
pp.PostP:OutputLine("J5," .. Round2Six(PPx) .. "," .. Round2Six(PPy) .. "," .. Round2Six(PPz) .. ",," .. Round2Six(OutAngle*rad2Deg) .. "\r\n",false)
if RotationCount ~= 0 then
pp.PostP:OutputLine("VA,,,,," .. Round2Six(OutAngle*rad2Deg - 360 * RotationCount) .. "\r\n",false)
RotationCount = 0
end
Lift = 0
else
pp.PostP:OutputLine("M5," .. Round2Six(PPx) .. "," .. Round2Six(PPy) .. "," .. Round2Six(PPz) .. ",," .. Round2Six(InAngle*rad2Deg) .. "\r\n",false)
Plunge = 1
end
if TurnAngle == 0 then
Lift = 0
end
if math.abs(TurnAngle)*rad2Deg <= LiftAngle and (PPx ~= Px or PPy ~= Py) and PPz < pp.SAFEZ.Value then
local Length = math.sqrt(math.pow(PPx-Px,2) + math.pow(PPy-Py,2))
if math.abs(TurnAngle) > turnInc * 1.5 and Length > Radius then
TurnDistance = Radius*math.tan(math.abs(TurnAngle/2))
if TurnDistance < Radius then
TurnDistance = Radius
end
TurnX = Px - math.cos(InAngle) * TurnDistance
TurnY = Py - math.sin(InAngle) * TurnDistance
end
Lift = 0
end
local Angle = InAngle
if PPz < pp.SAFEZ.Value then
if Plunge == 0 then
pp.PostP:OutputLine("M5," .. Round2Six(TurnX) .. "," .. Round2Six(TurnY) .. "," .. Round2Six(Pz) .. ",," .. Round2Six(Angle*rad2Deg) .. "\r\n", false)
end
if Lift == 0 then
local segments = math.floor((math.abs(TurnAngle)*rad2Deg)/(turnInc*rad2Deg))
local count = 0
local increment = TurnAngle/segments
while count < segments do
Angle = Angle + increment
TurnX = TurnX + math.cos(InAngle) * TurnDistance*(1/segments)
TurnY = TurnY + math.sin(InAngle) * TurnDistance*(1/segments)
pp.PostP:OutputLine("M5," .. Round2Six(TurnX) .. "," .. Round2Six(TurnY) .. "," .. Round2Six(PPz) .. ",," .. Round2Six(Angle*rad2Deg) .. "\r\n", false)
count = count + 1
end
end
end
if OutAngle < 2*math.pi*RotationCount then
RotationCount = RotationCount -1
end
if OutAngle >= 2*math.pi*(RotationCount+1) then
RotationCount = RotationCount +1
end
if Lift == 1 and InJog == 0 then
pp.PostP:OutputLine("M5," .. Round2Six(TurnX) .. "," .. Round2Six(TurnY) .. "," .. Round2Six(Pz) .. ",," .. Round2Six(Angle*rad2Deg) .. "\r\n", false)
pp.PostP:OutputLine("JZ," .. Round2Six(pp.SAFEZ.Value) .. "\r\n",false)
pp.PostP:OutputLine("JB," .. Round2Six(OutAngle*rad2Deg) .. "\r\n",false)
if RotationCount ~= 0 then
pp.PostP:OutputLine("VA,,,,," .. Round2Six(OutAngle*rad2Deg - 360 * RotationCount) .. "\r\n",false)
RotationCount = 0
end
pp.PostP:OutputLine("JZ," .. Round2Six(PPz) .. "\r\n",false)
end
end
PPx = Px
PPy = Py
PPz = Pz
Px = pp.X.Value
Py = pp.Y.Value
Pz = pp.Z.Value
Plunge = 0
InJog = 0
end
function Round2Six(num)
return math.floor(num*1000000+0.5)/1000000
end
function AngleCalculation()
InAngle = math.atan2(Py-PPy,Px-PPx)
if InAngle < 0 then InAngle = InAngle + 2*math.pi end
OutAngle = math.atan2(pp.Y.Value-Py,pp.X.Value-Px)
if OutAngle < 0 then OutAngle = OutAngle + 2*math.pi end
if pp.Y.Value == Py and pp.X.Value == Px then
OutAngle = InAngle
end
TurnAngle = OutAngle - InAngle
if TurnAngle > math.pi then
TurnAngle = TurnAngle - 2*math.pi
end
if TurnAngle < -1*math.pi then
TurnAngle = TurnAngle + 2*math.pi
end
InAngle = InAngle + 2*math.pi*RotationCount
OutAngle = InAngle + TurnAngle
end
ENDSCRIPT
+---------------------------------------------
+ Start of file
+---------------------------------------------
begin HEADER
"'Created using ShopBot Tan/Osc Knife Post V1.2"
"IF %(25)=1 THEN GOTO UNIT_ERROR 'check to see software is set to metric"
"'----------------------------------------------------------------"
"C#,92 'Load Knife Settings"
"IF &ATC = 1 Then GoSub EMPTY_SPINDLE"
"IF &ATC = 2 Then GoSub EMPTY_SPINDLE"
"IF &ATC = 4 Then GoSub EMPTY_SPINDLE"
"VO,1,&Knife_X_offset,&Knife_Y_offset 'Update these offsets in C:/sbParts/Custom/KnifeSettings.sbc"
"SF,0"
"&PWSafeZ = [SAFEZ]"
"JZ,[ZH]"
"SO,5,1"
"Pause 2"
"SO,6,1"
"MS,[FC],[FP]"
+--------------------------------------------
+ Program moves
+--------------------------------------------
begin RAPID_MOVE
"<!>Jog()"
+---------------------------------------------
begin FIRST_FEED_MOVE
"<!>AddRotation('F ')"
+---------------------------------------------
begin FEED_MOVE
"<!>AddRotation('S ')"
+---------------------------------------------------
+ Commands output at toolchange
+---------------------------------------------------
begin TOOLCHANGE
"'Tool Change"
+---------------------------------------------------
+ Commands output for a new segment - toolpath
+ with same toolnumber but maybe different feedrates
+---------------------------------------------------
begin NEW_SEGMENT
"'New Path"
+---------------------------------------------
+ end of file
+---------------------------------------------
begin FOOTER
"JZ,[ZH]"
"VO,0"
"J5,[XH],[YH],[ZH],,0"
"SO,6,0"
"SO,5,0"
"END"
"EMPTY_SPINDLE:"
"C#,89"
"IF &ToolIN = 0 Then GOTO ALREADY_EMPTY"
"&tool = 0"
"C9"
"ALREADY_EMPTY:"
"Return"
"UNIT_ERROR:"
"CN, 91 'Run file explaining unit error"
"END"