Skip to content

Commit a4216c2

Browse files
committed
Fixes an issue that toolpath may be empty due to incorrect motion mode
1 parent 3e2a49b commit a4216c2

File tree

3 files changed

+169
-20
lines changed

3 files changed

+169
-20
lines changed

src/Interpreter.js

Lines changed: 49 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ import {
1010
const noop = () => {};
1111

1212
/**
13-
* fromPairs([['a', 1], ['b', 2]]);
14-
* // => { 'a': 1, 'b': 2 }
13+
* Returns an object composed from arrays of property names and values.
14+
* @example
15+
* fromPairs([['a', 1], ['b', 2]]);
16+
* // => { 'a': 1, 'b': 2 }
1517
*/
1618
const fromPairs = (pairs) => {
1719
let index = -1;
@@ -55,25 +57,52 @@ const interpret = (self, data) => {
5557
const words = groups[i];
5658
const word = words[0] || [];
5759
const letter = word[0];
58-
const arg = word[1];
59-
let cmd = (letter + arg);
60+
const code = word[1];
61+
let cmd = '';
6062
let args = {};
6163

62-
if ((letter === 'G') || (letter === 'M')) {
63-
self.cmd = cmd;
64-
args = fromPairs(words.slice(1)); // returns an object composed from arrays of property names and values
65-
} else {
66-
// Use the same command if the line does not start with Gxx or Mxx.
67-
// For example:
68-
// G0 Z0.25
69-
// X-0.5 Y0.
70-
// Z0.1
71-
// G01 Z0. F5.
72-
// X0.5 Y0. I0. J-0.5
73-
// X0. Y-0.5 I-0.5 J0.
74-
// X-0.5 Y0. I0. J0.5
75-
cmd = self.cmd;
76-
args = fromPairs(words); // returns an object composed from arrays of property names and values.
64+
if (letter === 'G') {
65+
cmd = (letter + code);
66+
args = fromPairs(words.slice(1));
67+
68+
// Motion Mode
69+
if (code === 0 || code === 1 || code === 2 || code === 3 || code === 38.2 || code === 38.3 || code === 38.4 || code === 38.5) {
70+
self.motionMode = cmd;
71+
} else if (code === 80) {
72+
self.motionMode = '';
73+
}
74+
} else if (letter === 'M') {
75+
cmd = (letter + code);
76+
args = fromPairs(words.slice(1));
77+
} else if (letter === 'T') { // T1 ; w/o M6
78+
cmd = letter;
79+
args = code;
80+
} else if (letter === 'F') { // F750 ; w/o motion command
81+
cmd = letter;
82+
args = code;
83+
} else if (letter === 'X' || letter === 'Y' || letter === 'Z' || letter === 'A' || letter === 'B' || letter === 'C' || letter === 'I' || letter === 'J' || letter === 'K') {
84+
// Use previous motion command if the line does not start with G-code or M-code.
85+
// @example
86+
// G0 Z0.25
87+
// X-0.5 Y0.
88+
// Z0.1
89+
// G01 Z0. F5.
90+
// G2 X0.5 Y0. I0. J-0.5
91+
// X0. Y-0.5 I-0.5 J0.
92+
// X-0.5 Y0. I0. J0.5
93+
// @example
94+
// G01
95+
// M03 S0
96+
// X5.2 Y0.2 M03 S0
97+
// X5.3 Y0.1 M03 S1000
98+
// X5.4 Y0 M03 S0
99+
// X5.5 Y0 M03 S0
100+
cmd = self.motionMode;
101+
args = fromPairs(words);
102+
}
103+
104+
if (!cmd) {
105+
continue;
77106
}
78107

79108
if (typeof self.handlers[cmd] === 'function') {
@@ -89,7 +118,7 @@ const interpret = (self, data) => {
89118
};
90119

91120
class Interpreter {
92-
cmd = '';
121+
motionMode = 'G0';
93122
handlers = {};
94123

95124
constructor(options) {

test/fixtures/t2laser.nc

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
( Generated by T2Laser )
2+
( Image2Gcode for Grbl )
3+
( Start Point: Center )
4+
( Frame Mode : Abs. )
5+
( X Maximum : 84.4 )
6+
( Y Maximum : 99.9 )
7+
( Laser Max : 1000 )
8+
( Feed Rate : 750 )
9+
( Resolution : 0.1 )
10+
( Image Name : text4272.png )
11+
M6 T1
12+
T2
13+
G21
14+
G90
15+
F750
16+
M05
17+
G00X0Y0F750
18+
G92X42.2Y49.95
19+
G90
20+
G00 X0 Y0
21+
G01
22+
M03 S0
23+
X5.2 Y0.2 M03 S0
24+
X5.3 Y0.1 M03 S1000
25+
X5.4 Y0 M03 S0
26+
X5.5 Y0 M03 S0
27+
X5.4 Y0.1 M03 S1000
28+
X5.2 Y0.3 M03 S1000
29+
X5.1 Y0.4 M03 S0
30+
X5.2 Y0.4 M03 S0
31+
X5.3 Y0.3 M03 S1000
32+
X5.5 Y0.1 M03 S1000
33+
X5.6 Y0 M03 S0
34+
X5.7 Y0 M03 S0
35+
X5.6 Y0.1 M03 S1000
36+
X5.2 Y0.5 M03 S1000
37+
X5.1 Y0.6 M03 S0
38+
X5.2 Y0.6 M03 S0
39+
X5.3 Y0.5 M03 S1000
40+
X5.7 Y0.1 M03 S1000
41+
X5.8 Y0 M03 S0
42+
X5.9 Y0 M03 S0
43+
X5.8 Y0.1 M03 S1000
44+
X5.2 Y0.7 M03 S1000
45+
X5.1 Y0.8 M03 S0
46+
X5.2 Y0.8 M03 S0
47+
X5.3 Y0.7 M03 S1000
48+
X5.9 Y0.1 M03 S1000
49+
X6 Y0 M03 S0
50+
X6.1 Y0 M03 S0
51+
X6 Y0.1 M03 S1000
52+
X5.2 Y0.9 M03 S1000

test/index.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,4 +240,72 @@ describe('G-code Interpreter', () => {
240240
});
241241
});
242242

243+
describe('G-code: T2Laser', () => {
244+
class Runner extends Interpreter {
245+
calls = {};
246+
247+
constructor(options) {
248+
super(options);
249+
}
250+
M3(args) {
251+
expect(args).to.be.an('object');
252+
this.calls.M3 = (this.calls.M3 || 0) + 1;
253+
}
254+
M5(args) {
255+
expect(args).to.be.an('object');
256+
this.calls.M5 = (this.calls.M5 || 0) + 1;
257+
}
258+
M6(args) {
259+
expect(args).to.be.an('object');
260+
expect(args.T).to.equal(1);
261+
this.calls.M6 = (this.calls.M6 || 0) + 1;
262+
}
263+
T(args) {
264+
expect(args).to.be.an('number');
265+
expect(args).to.equal(2);
266+
this.calls.T = (this.calls.T || 0) + 1;
267+
}
268+
F(args) {
269+
expect(args).to.be.an('number');
270+
this.calls.F = (this.calls.F || 0) + 1;
271+
}
272+
G0(args) {
273+
expect(args).to.be.an('object');
274+
this.calls.G0 = (this.calls.G0 || 0) + 1;
275+
}
276+
G1(args) {
277+
expect(args).to.be.an('object');
278+
this.calls.G1 = (this.calls.G1 || 0) + 1;
279+
}
280+
}
281+
282+
it('should call each function with the expected number of times.', (done) => {
283+
const file = 'test/fixtures/t2laser.nc';
284+
const runner = new Runner();
285+
runner.loadFromFileSync(file);
286+
expect(runner.calls.M3).to.equal(31);
287+
expect(runner.calls.M5).to.equal(1);
288+
expect(runner.calls.M6).to.equal(1);
289+
expect(runner.calls.T).to.equal(1);
290+
expect(runner.calls.F).to.equal(1);
291+
expect(runner.calls.G0).to.equal(2);
292+
expect(runner.calls.G1).to.equal(31);
293+
done();
294+
});
295+
296+
it('should call each function with the expected number of times.', (done) => {
297+
const file = 'test/fixtures/t2laser.nc';
298+
const string = fs.readFileSync(file, 'utf8');
299+
const runner = new Runner();
300+
runner.loadFromStringSync(string);
301+
expect(runner.calls.M3).to.equal(31);
302+
expect(runner.calls.M5).to.equal(1);
303+
expect(runner.calls.M6).to.equal(1);
304+
expect(runner.calls.T).to.equal(1);
305+
expect(runner.calls.F).to.equal(1);
306+
expect(runner.calls.G0).to.equal(2);
307+
expect(runner.calls.G1).to.equal(31);
308+
done();
309+
});
310+
});
243311
});

0 commit comments

Comments
 (0)