webgcode
417 строк · 13.2 Кб
1"use strict";2require(['libs/jsparse', 'cnc/gcode/parser', 'cnc/gcode/simulation', 'cnc/util'], function (jp, parser, simulation, u) {3function p(obj) {4return new u.Point(obj.x, obj.y, obj.z);5}6
7test("G0 evaluation", function () {8var code = 'G0 X10';9var result = parser.evaluate(code);10equal(result.length, 1, '"' + code + '" code length');11deepEqual(result[0], {12feedRate: 3000,13lineNo: 0,14speedTag: "rapid",15from: p({x: 0, y: 0, z: 0}),16to: p({x: 10, y: 0, z: 0}),17type: "line"18}, '"' + code + '" second component check');19});20test("G0 evaluation with expression", function () {21var code = 'G0 X[5+5]';22var result = parser.evaluate(code);23equal(result.length, 1, '"' + code + '" code length');24deepEqual(result[0], {25feedRate: 3000,26lineNo: 0,27speedTag: "rapid",28from: p({x: 0, y: 0, z: 0}),29to: p({x: 10, y: 0, z: 0}),30type: "line"31}, '"' + code + '" second component check');32});33test("G1 evaluation", function () {34var code = 'G1 X10';35var result = parser.evaluate(code);36equal(result.length, 1, '"' + code + '" code length');37deepEqual(result[0], {38feedRate: 200,39lineNo: 0,40speedTag: "normal",41from: p({x: 0, y: 0, z: 0}),42to: p({x: 10, y: 0, z: 0}),43type: "line"44}, '"' + code + '" second component check');45});46test("G2 evaluation", function () {47var code = 'G2 X10 Y0 Z0 I5 J0 F200';48var result = parser.evaluate(code);49equal(result.length, 1, '"' + code + '" code length');50deepEqual(result[0], {51angularDistance: -Math.PI,52center: {53first: 5,54second: 055},56feedRate: 200,57lineNo: 0,58speedTag: "normal",59from: p({x: 0, y: 0, z: 0}),60fromAngle: -Math.PI,61plane: {62firstCenterCoord: "i",63firstCoord: "x",64lastCoord: "z",65secondCenterCoord: "j",66secondCoord: "y"67},68radius: 5,69to: p({x: 10, y: 0, z: 0}),70type: "arc"71}, '"' + code + '" second component check');72});73test("G3 evaluation", function () {74var code = 'G3 X5 Y5 Z0 I5 J0 F200';75var result = parser.evaluate(code);76equal(result.length, 1, '"' + code + '" code length');77deepEqual(result[0], {78angularDistance: 3 * Math.PI / 2,79center: {80first: 5,81second: 082},83feedRate: 200,84lineNo: 0,85speedTag: "normal",86from: p({x: 0, y: 0, z: 0}),87fromAngle: -Math.PI,88plane: {89firstCenterCoord: "i",90firstCoord: "x",91lastCoord: "z",92secondCenterCoord: "j",93secondCoord: "y"94},95radius: 5,96to: p({x: 5, y: 5, z: 0}),97type: "arc"98}, '"' + code + '" second component check');99});100test("jsparse number evaluation", function () {101
102function testValue(str, expected, specialParser) {103if (specialParser == undefined)104specialParser = parser.createParser();105var parsed = jp.wsequence(specialParser.expression, jp.expect(jp.end))(jp.ps(str));106deepEqual(parsed.ast[0], expected, str + ' = ' + expected);107}108
109function testValues(values, specialParser) {110$.each(values, function (_, input) {111testValue(input[0], input[1], specialParser);112});113}114
115$.each(["-10", "+1.5", "-1.5", "1", "1.5", ".5", "-.5", "+.55"], function (_, str) {116testValue(str, parseFloat(str));117});118testValues([119['1+2', 3],120['-1+2', 1],121['-1+-2', -3],122['1+2+-1', 2],123['1+2++1', 4]124]);125testValues([126['1-2', -1],127['-1-+2', -3],128['-1-2', -3],129['1-2-1', -2],130['1+2--1', 4]131]);132testValues([133['1*2', 2],134['-1*+2', -2],135['-1*2', -2],136['1*2-1', 1],137['1+2*-1', -1],138['1/2', 0.5],139['-1/+2', -0.5],140['-1/2', -0.5],141['1/2-1', -0.5],142['1+2/-1', -1],143['2/-1*3+1', -5],144['[1 + 2] * -1', -3]145]);146testValues([147['3**2', 9],148['3**2**3', Math.pow(Math.pow(3, 2), 3)], //yeah, it's left in g-code149['3**2+3', 12]150]);151testValues([152['3**2LT100+100', 1],153['1EQ0', 0],154['1EQ1', 1],155['0EQ1', 0],156['1NE0', 1],157['1NE1', 0],158['0NE1', 1],159['1GT0', 1],160['1GT1', 0],161['0GT1', 0],162['1GE0', 1],163['1GE1', 1],164['0GE1', 0],165['1LT0', 0],166['1LT1', 0],167['0LT1', 1],168['1LE0', 0],169['1LE1', 1],170['0LE1', 1],171['1AND1', 1],172['1AND0', 0],173['0AND0', 0],174['1XOR1', 0],175['1XOR0', 1],176['0XOR0', 0],177['1OR1', 1],178['1OR0', 1],179['0OR0', 0]180]);181testValues([182['EXP[2-1]', Math.E],183['ABS[-1]', 1],184['ACOS[1]', 0],185['ASIN[1]', Math.PI / 2],186['COS[0]', 1],187['EXP[1]', Math.E],188['FIX[2.8]', 2],189['FIX[-2.8]', -3],190['FUP[2.8]', 3],191['FUP[ -2.8 ]', -2],192['ATAN[-1] / [1]', -Math.PI / 4],193['ATAN[-1] / [1] / [-0.5]', Math.PI / 2]194]);195var p1 = parser.createParser();196p1.memory['var1'] = 3;197testValues([198['#3 + 5', 5],199['#<_3_aa_b2z>+ 5', 5],200['#<var1>', 3],201['#<VAR1>', 3]202], p1);203
204var p2 = parser.createParser();205p2.line(jp.ps('#54 = [COS[0]]'));206p2.line(jp.ps('#<lol>=12\n'));207//check that affectation are done after reading on the same line208p2.line(jp.ps('#<v1>=10 #<v2>=[#<v1>+1]\n'));209testValues([210['#54', 1],211['#<lol>', 12],212['#<undefined>', 0],213['#<v2>', 1],214['#<v1>', 10]215], p2);216deepEqual(parser.createParser().parseLine("#4 = 4.000000 #5 = 5.000000 G1 X10 F[3000] X [12+#4]"), {217f: [3000],218g: [1],219x: [10, 12]220});221deepEqual(parser.createParser().parseLine('G02X10Y30R10 '), {222g: [2],223r: [10],224x: [10],225y: [30]226});227deepEqual(parser.createParser().parseLine('G01Z[-1.000000*#7+#10]F#4 '), {228g: [1],229f: [0],230z: [0]231});232});233test("simple speed planning", function () {234var data = [235{length: 3, maxAcceleration: 8, squaredSpeed: 16, originalSpeed: 4}236];237simulation.planSpeed(data);238var segment = {239acceleration: {length: 0},240deceleration: {length: 0},241duration: 1.25,242length: 3,243maxAcceleration: 8,244originalSpeed: 4,245squaredSpeed: 16,246fragments: [247{248duration: 0.5,249fromSqSpeed: 0,250length: 1,251segment: null,252startX: 0,253stopX: 1,254toSqSpeed: 16,255type: "acceleration"256},257{258duration: 0.25,259length: 1,260segment: null,261startX: 1,262stopX: 2,263squaredSpeed: 16,264type: "constant"265},266{267duration: 0.5,268fromSqSpeed: 16,269length: 1,270segment: null,271startX: 2,272stopX: 3,273toSqSpeed: 0,274type: "deceleration"275}276]277};278$.each(segment.fragments, function (_, fragment) {279fragment.segment = segment;280});281deepEqual(data, [segment], 'speed planning check');282});283test("short distance speed planning", function () {284var data = [285{length: 2, maxAcceleration: 8, squaredSpeed: 25, originalSpeed: 5}286];287simulation.planSpeed(data);288var segment = {289acceleration: {length: 0},290deceleration: {length: 0},291duration: 1,292length: 2,293maxAcceleration: 8,294originalSpeed: 5,295squaredSpeed: 16,296fragments: [297{298duration: 0.5,299fromSqSpeed: 0,300length: 1,301segment: null,302startX: 0,303stopX: 1,304toSqSpeed: 16,305type: "acceleration"306},307{308duration: 0.5,309fromSqSpeed: 16,310length: 1,311segment: null,312startX: 1,313stopX: 2,314toSqSpeed: 0,315type: "deceleration"316}317]318};319$.each(segment.fragments, function (_, fragment) {320fragment.segment = segment;321});322deepEqual(data, [segment], 'should not go full speed');323});324test("two segments speed planning", function () {325var data = [326{length: 3, maxAcceleration: 8, squaredSpeed: 16, originalSpeed: 4},327{length: 3, maxAcceleration: 8, squaredSpeed: 16, originalSpeed: 4}328];329simulation.planSpeed(data);330var segment1 = {331acceleration: {length: 0},332deceleration: {length: 1},333duration: 1,334length: 3,335maxAcceleration: 8,336originalSpeed: 4,337squaredSpeed: 16,338fragments: [339{340duration: 0.5,341fromSqSpeed: 0,342length: 1,343segment: null,344startX: 0,345stopX: 1,346toSqSpeed: 16,347type: "acceleration"348},349{350duration: 0.5,351squaredSpeed: 16,352length: 2,353segment: null,354startX: 1,355stopX: 3,356type: "constant"357}358]359};360$.each(segment1.fragments, function (_, fragment) {361fragment.segment = segment1;362});363var segment2 = {364acceleration: {length: 1},365deceleration: {length: 0},366duration: 1,367length: 3,368maxAcceleration: 8,369originalSpeed: 4,370squaredSpeed: 16,371fragments: [372{373duration: 0.5,374length: 2,375segment: null,376startX: 0,377stopX: 2,378squaredSpeed: 16,379type: "constant"380},381{382duration: 0.5,383fromSqSpeed: 16,384toSqSpeed: 0,385length: 1,386segment: null,387startX: 2,388stopX: 3,389type: "deceleration"390}391]392};393$.each(segment2.fragments, function (_, fragment) {394fragment.segment = segment2;395});396deepEqual(data, [segment1, segment2], 'should transition smoothly between segments');397});398test("rd(x, y, z)", function () {399equal(rd(0, 2, 1), 1.7972103521033886);400equal(rd(2, 3, 4), 0.16510527294261057);401});402test("rf(x, y, z)", function () {403equal(rf(1, 2, 4), 0.6850858166334359);404equal(rf(1, 2, 0), 1.31102877714606);405equal(rf(2, 3, 4), 0.5840828416771515);406});407test("E(m)", function () {408equal(completeEllipticIntegralSecondKind(0.5), 1.350643881047675);409});410test("E(phi,m)", function () {411equal(incompleteEllipticIntegralSecondKind(Math.PI / 4, 0.5), 0.748186504177661);412equal(incompleteEllipticIntegralSecondKind(Math.PI / 4, 0.7), 0.7323015038648828);413equal(incompleteEllipticIntegralSecondKind(Math.PI / 2, 0.7), 1.2416705679458233);414equal(incompleteEllipticIntegralSecondKind(-Math.PI / 2, 0.7), -1.2416705679458233);415equal(incompleteEllipticIntegralSecondKind(-3 * Math.PI + 0.5, 0.5), -7.613952326493532);416});417});