test_interp_basics.cc
1 #include "catch.hpp" 2 3 #include <interp_testing_util.hh> // For core interp stuff and extra REQUIRE macros/ setup 4 #include <rs274ngc_interp.hh> 5 #include <interp_inspection.hh> 6 #include <interp_return.hh> 7 #include <saicanon.hh> 8 #include <interp_parameter_def.hh> 9 using namespace interp_param_global; 10 11 TEST_CASE("Interp Basics") 12 { 13 DECL_INIT_TEST_INTERP(); 14 SECTION("Interp Init") 15 { 16 REQUIRE(currentX(settings) == 0.0); 17 REQUIRE(currentY(settings) == 0.0); 18 REQUIRE(currentZ(settings) == 0.0); 19 } 20 21 SECTION("Change Units") 22 { 23 REQUIRE_INTERP_OK(test_interp.convert_length_units(G_21, settings)); 24 REQUIRE(settings->length_units == CANON_UNITS_MM); 25 // Magically jump 1 inch 26 currentX(settings) = 25.4; 27 REQUIRE_INTERP_OK(test_interp.convert_length_units(G_20, settings)); 28 REQUIRE(settings->length_units == CANON_UNITS_INCHES); 29 CHECK_FUZZ(currentX(settings), 1.0); 30 REQUIRE_INTERP_OK(test_interp.convert_length_units(G_21, settings)); 31 } 32 33 SECTION("G52 without rotation") 34 { 35 // Assume all offsets and such start at zero 36 REQUIRE(settings->length_units == CANON_UNITS_MM); 37 REQUIRE(settings->parameters[G92_X] == 0.0); 38 REQUIRE(settings->parameters[G92_Y] == 0.0); 39 REQUIRE_INTERP_OK(test_interp.execute("G52 X25.4 Y0")); 40 CHECK_FUZZ(settings->parameters[G92_X], 1.0); 41 CHECK_FUZZ(settings->parameters[G92_Y], 0.0); 42 REQUIRE_INTERP_OK(test_interp.execute("G52 Y25.4")); 43 CHECK_FUZZ(settings->parameters[G92_X], 1.0); 44 CHECK_FUZZ(settings->parameters[G92_Y], 1.0); 45 } 46 47 SECTION("G92 X and G5x Rotation") 48 { 49 // Assume all offsets and such start at zero 50 REQUIRE_INTERP_OK(test_interp.execute("G20")); 51 REQUIRE(settings->length_units == CANON_UNITS_INCHES); 52 REQUIRE_INTERP_OK(test_interp.execute("G92.1")); 53 REQUIRE(settings->parameters[G92_X] == 0.0); 54 REQUIRE_INTERP_OK(test_interp.execute("G52 X1 Y0")); 55 REQUIRE_INTERP_OK(test_interp.execute("G10 L2 P0 X1 Y0 Z0 R0")); 56 CHECK_FUZZ(currentX(settings), -2.0); 57 // FIXME this is the wrong behavior but what the interpreter currently expects 58 REQUIRE_INTERP_OK(test_interp.execute("G10 L2 P0 X1 Y0 Z0 R90")); 59 CHECK_FUZZ(currentX(settings), -0.0); 60 CHECK_FUZZ(currentY(settings), 2.0); 61 } 62 63 SECTION("G92 off-axis behavior with rotation") 64 { 65 // Assume all offsets and such start at zero 66 REQUIRE_INTERP_OK(test_interp.execute("G20")); 67 REQUIRE(settings->length_units == CANON_UNITS_INCHES); 68 REQUIRE_INTERP_OK(test_interp.execute("G92.1")); 69 REQUIRE_INTERP_OK(test_interp.execute("G52 X1 Y0")); 70 REQUIRE_INTERP_OK(test_interp.execute("G10 L2 P0 X1 Y2 Z3 A4 B5 C6 R90")); 71 // FIXME this is the wrong behavior but what the interpreter currently expects 72 CHECK_FUZZ(currentX(settings), -2.0); 73 CHECK_FUZZ(currentY(settings), 2.0); 74 // Should not be affected by rotation 75 CHECK_FUZZ(currentZ(settings), -3.0); 76 CHECK_FUZZ(currentA(settings), -4.0); 77 CHECK_FUZZ(currentB(settings), -5.0); 78 CHECK_FUZZ(currentC(settings), -6.0); 79 } 80 81 SECTION("G55 without rotation") 82 { 83 REQUIRE_INTERP_OK(test_interp.execute("G20")); 84 CHECK_FUZZ(currentX(settings), 0.0); 85 CHECK_FUZZ(currentY(settings), 0.0); 86 CHECK_FUZZ(currentZ(settings), 0.0); 87 88 currentX(settings) = 1.0; 89 currentY(settings) = 1.0; 90 currentZ(settings) = 1.0; 91 // KLUDGE hack in parameters directly to avoid depending on other functions 92 test_interp._setup.parameters[G55_X] = 2; 93 test_interp._setup.parameters[G55_Y] = 3; 94 test_interp._setup.parameters[G55_Z] = 1; 95 REQUIRE_INTERP_OK(test_interp.convert_coordinate_system(G_55, settings)); 96 CHECK_FUZZ(currentX(settings), -1.0); 97 CHECK_FUZZ(currentY(settings), -2.0); 98 CHECK_FUZZ(currentZ(settings), 0.0); 99 } 100 101 SECTION("G55 with rotation") 102 { 103 REQUIRE_INTERP_OK(test_interp.execute("G20")); 104 currentX(settings) = 0.0; 105 // KLUDGE hack in parameters directly to avoid depending on other functions 106 test_interp._setup.parameters[G55_X] = 2; 107 test_interp._setup.parameters[G55_Y] = 3; 108 test_interp._setup.parameters[G55_Z] = 1; 109 test_interp._setup.parameters[G55_R] = 90; 110 REQUIRE_INTERP_OK(test_interp.convert_coordinate_system(G_55, settings)); 111 CHECK_FUZZ(currentX(settings), -3.0); 112 CHECK_FUZZ(currentY(settings), 2.0); 113 CHECK_FUZZ(currentZ(settings), -1.0); 114 } 115 } 116 117 TEST_CASE("G10 init") 118 { 119 DECL_INIT_TEST_INTERP(); 120 121 const char *test_setup[] = { 122 "g20", 123 "g10 l2 p1 x0 y0 z0", 124 "g54", 125 "g10 l1 p1 x0 y0 z0", 126 "t1 m6 g43", 127 }; 128 execute_lines(test_interp, test_setup); 129 CHECK_FUZZ(settings->parameters[TOOL_OFFSET_X], 0.0); 130 CHECK_FUZZ(settings->parameters[TOOL_OFFSET_Y], 0.0); 131 CHECK_FUZZ(settings->parameters[TOOL_OFFSET_Z], 0.0); 132 133 SECTION("G10 L1 direct offsets") 134 { 135 // 2-pass loop ensures that tool offsets persist regardless of G43 / G49 state 136 for (int k = 0; k < 2; ++k) { 137 REQUIRE_INTERP_OK(test_interp.execute("g10 l1 p1 x0 y0 z0 ")); 138 REQUIRE_INTERP_OK(test_interp.execute("g10 l1 p1 x1")); 139 CHECK_FUZZ(settings->parameters[TOOL_OFFSET_X], 1.0); 140 CHECK_FUZZ(settings->parameters[TOOL_OFFSET_Y], 0.0); 141 CHECK_FUZZ(settings->parameters[TOOL_OFFSET_Z], 0.0); 142 143 REQUIRE_INTERP_OK(test_interp.execute("g10 l1 p1 y2")); 144 CHECK_FUZZ(settings->parameters[TOOL_OFFSET_X], 1.0); 145 CHECK_FUZZ(settings->parameters[TOOL_OFFSET_Y], 2.0); 146 CHECK_FUZZ(settings->parameters[TOOL_OFFSET_Z], 0.0); 147 148 REQUIRE_INTERP_OK(test_interp.execute("g10 l1 p1 z3")); 149 CHECK_FUZZ(settings->parameters[TOOL_OFFSET_X], 1.0); 150 CHECK_FUZZ(settings->parameters[TOOL_OFFSET_Y], 2.0); 151 CHECK_FUZZ(settings->parameters[TOOL_OFFSET_Z], 3.0); 152 153 REQUIRE_INTERP_OK(test_interp.execute("g49")); 154 } 155 } 156 } 157 158 TEST_CASE("G10 L10 ") 159 { 160 DECL_INIT_TEST_INTERP(); 161 162 SECTION("tool offsets relative to position no rotation") 163 { 164 const char *test_setup[] = { 165 "g20", 166 "g10 l2 p1 x0 y0 z0", 167 "g54", 168 "g10 l1 p1 x0 y0 z0", 169 "t1 m6 g43", 170 }; 171 REQUIRE_INTERP_OK(execute_lines(test_interp, test_setup)); 172 173 REQUIRE_INTERP_OK(test_interp.execute("g0 x.1 y.2 z.3")); 174 REQUIRE_INTERP_OK(test_interp.execute("g10 l10 p1 x1")); 175 CHECK_FUZZ(settings->parameters[TOOL_OFFSET_X], -0.9); 176 CHECK_FUZZ(settings->parameters[TOOL_OFFSET_Y], 0.0); 177 CHECK_FUZZ(settings->parameters[TOOL_OFFSET_Z], 0.0); 178 REQUIRE_INTERP_OK(test_interp.execute("g10 l10 p1 y2")); 179 CHECK_FUZZ(settings->parameters[TOOL_OFFSET_X], -0.9); 180 CHECK_FUZZ(settings->parameters[TOOL_OFFSET_Y], -1.8); 181 CHECK_FUZZ(settings->parameters[TOOL_OFFSET_Z], 0.0); 182 183 REQUIRE_INTERP_OK(test_interp.execute("g10 l10 p1 z3")); 184 CHECK_FUZZ(settings->parameters[TOOL_OFFSET_X], -0.9); 185 CHECK_FUZZ(settings->parameters[TOOL_OFFSET_Y], -1.8); 186 CHECK_FUZZ(settings->parameters[TOOL_OFFSET_Z], -2.7); 187 } 188 189 SECTION("G10 L10 tool offsets relative to position + 45 deg rotation") 190 { 191 192 const char *test_setup[] = { 193 "g20", 194 "g10 l2 p1 x0 y0 z0 r45", 195 "g54", 196 "g10 l1 p1 x0 y0 z0", 197 "t1 m6 g43", 198 }; 199 REQUIRE(execute_lines(test_interp, test_setup)); 200 201 REQUIRE_INTERP_OK(test_interp.execute("g0 x0 y0 z0")); 202 REQUIRE_INTERP_OK(test_interp.execute("g10 l10 p1 x1")); 203 REQUIRE_INTERP_OK(test_interp.execute("g43")); 204 CHECK_FUZZ(settings->parameters[TOOL_OFFSET_X], -sqrt(2.0)/2.0); 205 CHECK_FUZZ(settings->parameters[TOOL_OFFSET_Y], -sqrt(2.0)/2.0); 206 CHECK_FUZZ(settings->parameters[TOOL_OFFSET_Z], 0.0); 207 CHECK_FUZZ(currentX(settings), 1.0); 208 CHECK_FUZZ(currentY(settings), 0.0); 209 210 REQUIRE_INTERP_OK(test_interp.execute("g10 l10 p1 y1")); 211 REQUIRE_INTERP_OK(test_interp.execute("g43")); 212 CHECK_FUZZ(settings->parameters[TOOL_OFFSET_X], 0.0); 213 CHECK_FUZZ(settings->parameters[TOOL_OFFSET_Y], -sqrt(2)); 214 CHECK_FUZZ(settings->parameters[TOOL_OFFSET_Z], 0.0); 215 CHECK_FUZZ(currentX(settings), 1.0); 216 CHECK_FUZZ(currentY(settings), 1.0); 217 REQUIRE_INTERP_OK(test_interp.execute("g49")); 218 CHECK_FUZZ(settings->parameters[TOOL_OFFSET_X], 0.0); 219 CHECK_FUZZ(settings->parameters[TOOL_OFFSET_Y], -sqrt(2)); 220 CHECK_FUZZ(settings->parameters[TOOL_OFFSET_Z], 0.0); 221 CHECK_FUZZ(currentX(settings), 0.0); 222 CHECK_FUZZ(currentY(settings), 0.0); 223 } 224 } 225 226 SCENARIO("Call G10 with G92 active (based on runtest g10-with-g92)") 227 { 228 GIVEN("No G92 offsets applied") 229 { 230 DECL_INIT_TEST_INTERP(); 231 REQUIRE_INTERP_OK(test_interp.execute("g20")); 232 REQUIRE(settings->length_units == CANON_UNITS_INCHES); 233 WHEN("No offsets are applied") { 234 THEN("Both current position and current offset should be zero") { 235 CHECK_FUZZ(currentX(settings), 0.0); 236 CHECK_FUZZ(currentY(settings), 0.0); 237 CHECK_FUZZ(currentZ(settings), 0.0); 238 CHECK_FUZZ(currentWorkOffsetX(settings), 0); 239 CHECK_FUZZ(currentWorkOffsetY(settings), 0); 240 CHECK_FUZZ(currentWorkOffsetZ(settings), 0); 241 CHECK_FUZZ(currentWorkOffsetA(settings), 0); 242 CHECK_FUZZ(currentWorkOffsetB(settings), 0); 243 CHECK_FUZZ(currentWorkOffsetC(settings), 0); 244 } 245 } 246 WHEN("Work offsets are specified via G10 L2 for the active coordinate system") 247 { 248 REQUIRE_INTERP_OK(test_interp.execute("g10 l2 p0 x7 y8 z9 a10 b11 c12")); 249 THEN ("New offset values are stored and immediately applied") 250 { 251 CHECK_FUZZ(settings->origin_index, 1); // Confirm it's G54 252 CHECK_FUZZ(settings->parameters[G54_X], 7); 253 CHECK_FUZZ(settings->parameters[G54_Y], 8); 254 CHECK_FUZZ(settings->parameters[G54_Z], 9); 255 CHECK_FUZZ(settings->parameters[G54_A], 10); 256 CHECK_FUZZ(settings->parameters[G54_B], 11); 257 CHECK_FUZZ(settings->parameters[G54_C], 12); 258 CHECK_FUZZ(currentWorkOffsetX(settings), 7); 259 CHECK_FUZZ(currentWorkOffsetY(settings), 8); 260 CHECK_FUZZ(currentWorkOffsetZ(settings), 9); 261 CHECK_FUZZ(currentWorkOffsetA(settings), 10); 262 CHECK_FUZZ(currentWorkOffsetB(settings), 11); 263 CHECK_FUZZ(currentWorkOffsetC(settings), 12); 264 265 CHECK_FUZZ(currentX(settings), -7); 266 CHECK_FUZZ(currentY(settings), -8); 267 CHECK_FUZZ(currentZ(settings), -9); 268 CHECK_FUZZ(currentA(settings), -10); 269 CHECK_FUZZ(currentB(settings), -11); 270 CHECK_FUZZ(currentC(settings), -12); 271 } 272 } 273 WHEN("Work offsets are specified via G10 L2 for inactive coordinate systems") 274 { 275 REQUIRE_INTERP_OK(test_interp.execute("G54")); 276 REQUIRE_INTERP_OK(test_interp.execute("g10 l2 p2 x7 y8 z9 a10 b11 c12")); 277 CHECK_FUZZ(settings->origin_index, 1); // Confirm it's G54 278 THEN("Work offset parameters are updated but the current offset is not (nor is the current position)") { 279 CHECK_FUZZ(settings->parameters[G55_X], 7); 280 CHECK_FUZZ(settings->parameters[G55_Y], 8); 281 CHECK_FUZZ(settings->parameters[G55_Z], 9); 282 CHECK_FUZZ(settings->parameters[G55_A], 10); 283 CHECK_FUZZ(settings->parameters[G55_B], 11); 284 CHECK_FUZZ(settings->parameters[G55_C], 12); 285 286 CHECK_FUZZ(currentWorkOffsetX(settings), 0); 287 CHECK_FUZZ(currentWorkOffsetY(settings), 0); 288 CHECK_FUZZ(currentWorkOffsetZ(settings), 0); 289 CHECK_FUZZ(currentWorkOffsetA(settings), 0); 290 CHECK_FUZZ(currentWorkOffsetB(settings), 0); 291 CHECK_FUZZ(currentWorkOffsetC(settings), 0); 292 293 CHECK_FUZZ(currentX(settings), 0); 294 CHECK_FUZZ(currentY(settings), 0); 295 CHECK_FUZZ(currentZ(settings), 0); 296 CHECK_FUZZ(currentA(settings), 0); 297 CHECK_FUZZ(currentB(settings), 0); 298 CHECK_FUZZ(currentC(settings), 0); 299 } 300 } 301 WHEN("Work offsets are specified via G10 L2 for the active coordinate system") 302 { 303 REQUIRE_INTERP_OK(test_interp.execute("g10 l2 p0 x7 y8 z9 a10 b11 c12")); 304 THEN ("New offset values are stored and immediately applied") 305 { 306 CHECK_FUZZ(settings->origin_index, 1); // Confirm it's G54 307 CHECK_FUZZ(settings->parameters[G54_X], 7); 308 CHECK_FUZZ(settings->parameters[G54_Y], 8); 309 CHECK_FUZZ(settings->parameters[G54_Z], 9); 310 CHECK_FUZZ(settings->parameters[G54_A], 10); 311 CHECK_FUZZ(settings->parameters[G54_B], 11); 312 CHECK_FUZZ(settings->parameters[G54_C], 12); 313 314 CHECK_FUZZ(currentWorkOffsetX(settings), 7); 315 CHECK_FUZZ(currentWorkOffsetY(settings), 8); 316 CHECK_FUZZ(currentWorkOffsetZ(settings), 9); 317 CHECK_FUZZ(currentWorkOffsetA(settings), 10); 318 CHECK_FUZZ(currentWorkOffsetB(settings), 11); 319 CHECK_FUZZ(currentWorkOffsetC(settings), 12); 320 321 CHECK_FUZZ(currentX(settings), -7); 322 CHECK_FUZZ(currentY(settings), -8); 323 CHECK_FUZZ(currentZ(settings), -9); 324 CHECK_FUZZ(currentA(settings), -10); 325 CHECK_FUZZ(currentB(settings), -11); 326 CHECK_FUZZ(currentC(settings), -12); 327 } 328 } 329 } 330 GIVEN("G92 offsets active") 331 { 332 DECL_INIT_TEST_INTERP(); 333 REQUIRE_INTERP_OK(test_interp.execute("g20")); 334 REQUIRE(settings->length_units == CANON_UNITS_INCHES); 335 REQUIRE_INTERP_OK(test_interp.execute("g92 x3 y4 z5")); 336 constexpr double axis_offset_x = -3; 337 constexpr double axis_offset_y = -4; 338 339 WHEN("No work offsets are applied") { 340 THEN("Both current position and current offset should only be due to G92") { 341 CHECK_FUZZ(currentX(settings), -axis_offset_x); 342 CHECK_FUZZ(currentY(settings), -axis_offset_y); 343 CHECK_FUZZ(currentZ(settings), 5); 344 345 CHECK_FUZZ(currentWorkOffsetX(settings), 0); 346 CHECK_FUZZ(currentWorkOffsetY(settings), 0); 347 CHECK_FUZZ(currentWorkOffsetZ(settings), 0); 348 CHECK_FUZZ(currentWorkOffsetA(settings), 0); 349 CHECK_FUZZ(currentWorkOffsetB(settings), 0); 350 CHECK_FUZZ(currentWorkOffsetC(settings), 0); 351 } 352 } 353 WHEN("Work offsets are specified via G10 L2 for the active coordinate system with rotation") 354 { 355 constexpr double work_offset_x = 7; 356 constexpr double work_offset_y = 8; 357 358 REQUIRE_INTERP_OK(test_interp.execute("g10 l2 p0 x7 y8 z9 a10 b11 c12 R45")); 359 THEN ("Current position will be rotated in X/Y") 360 { 361 CHECK_FUZZ(settings->origin_index, 1); // Confirm it's G54 362 CHECK_FUZZ(settings->parameters[G54_X], work_offset_x); 363 CHECK_FUZZ(settings->parameters[G54_Y], work_offset_y); 364 CHECK_FUZZ(settings->parameters[G54_Z], 9); 365 CHECK_FUZZ(settings->parameters[G54_A], 10); 366 CHECK_FUZZ(settings->parameters[G54_B], 11); 367 CHECK_FUZZ(settings->parameters[G54_C], 12); 368 369 CHECK_FUZZ(currentWorkOffsetX(settings), work_offset_x); 370 CHECK_FUZZ(currentWorkOffsetY(settings), work_offset_y); 371 CHECK_FUZZ(currentWorkOffsetZ(settings), 9); 372 CHECK_FUZZ(currentWorkOffsetA(settings), 10); 373 CHECK_FUZZ(currentWorkOffsetB(settings), 11); 374 CHECK_FUZZ(currentWorkOffsetC(settings), 12); 375 376 constexpr double xy_rotation = M_PI / 4; 377 // FIXME this math is wrong but what the current interpreter expects 378 const double total_offset_x = axis_offset_x + work_offset_x; 379 const double total_offset_y = axis_offset_y + work_offset_y; 380 const double expect_x = (cos(-xy_rotation) * -total_offset_x + -sin(-xy_rotation) * -total_offset_y); 381 const double expect_y = (sin(-xy_rotation) * -total_offset_x + cos(-xy_rotation) * -total_offset_y); 382 CHECK_FUZZ(currentX(settings), expect_x); 383 CHECK_FUZZ(currentY(settings), expect_y); 384 CHECK_FUZZ(currentZ(settings), -4); 385 CHECK_FUZZ(currentA(settings), -10); 386 CHECK_FUZZ(currentB(settings), -11); 387 CHECK_FUZZ(currentC(settings), -12); 388 } 389 } 390 } 391 } 392 393 SCENARIO("Save / restore of G92 parameters") 394 { 395 GIVEN("Active G92 Offsets") 396 { 397 DECL_INIT_TEST_INTERP(); 398 REQUIRE_INTERP_OK(test_interp.execute("g20")); 399 REQUIRE(settings->length_units == CANON_UNITS_INCHES); 400 REQUIRE_INTERP_OK(test_interp.execute("g92 x3 y4 z5")); 401 constexpr double axis_offset_x = -3; 402 constexpr double axis_offset_y = -4; 403 constexpr double axis_offset_z = -5; 404 CHECK_FUZZ(settings->parameters[G92_X], axis_offset_x); 405 CHECK_FUZZ(settings->parameters[G92_Y], axis_offset_y); 406 CHECK_FUZZ(settings->parameters[G92_Z], axis_offset_z); 407 408 WHEN("Offsets are disabled with G92.2") { 409 REQUIRE_INTERP_OK(test_interp.execute("g92.2")); 410 THEN("Current position changes but internal offset parameters are unaffected") { 411 CHECK_FUZZ(currentX(settings), 0); 412 CHECK_FUZZ(currentY(settings), 0); 413 CHECK_FUZZ(currentZ(settings), 0); 414 415 CHECK_FUZZ(settings->parameters[G92_X], axis_offset_x); 416 CHECK_FUZZ(settings->parameters[G92_Y], axis_offset_y); 417 CHECK_FUZZ(settings->parameters[G92_Z], axis_offset_z); 418 419 WHEN("Offsets are re-enabled with G92.3") { 420 REQUIRE_INTERP_OK(test_interp.execute("g92.3")); 421 THEN("Original position and offsets are restored") { 422 CHECK_FUZZ(currentX(settings), -axis_offset_x); 423 CHECK_FUZZ(currentY(settings), -axis_offset_y); 424 CHECK_FUZZ(currentZ(settings), -axis_offset_z); 425 426 CHECK_FUZZ(settings->parameters[G92_X], axis_offset_x); 427 CHECK_FUZZ(settings->parameters[G92_Y], axis_offset_y); 428 CHECK_FUZZ(settings->parameters[G92_Z], axis_offset_z); 429 } 430 } 431 } 432 } 433 } 434 } 435 436 437 SCENARIO("Convert G20 / G21 ") 438 { 439 GIVEN("Starting in G20") 440 { 441 DECL_INIT_TEST_INTERP(); 442 REQUIRE_INTERP_OK(test_interp.execute("g20")); 443 REQUIRE_INTERP_OK(test_interp.execute("g0 x1 y2 z3 a4 b5 c6")); 444 445 CHECK_FUZZ(currentX(settings), 1); 446 CHECK_FUZZ(currentY(settings), 2); 447 CHECK_FUZZ(currentZ(settings), 3); 448 CHECK_FUZZ(currentA(settings), 4); 449 CHECK_FUZZ(currentB(settings), 5); 450 CHECK_FUZZ(currentC(settings), 6); 451 REQUIRE(settings->length_units == CANON_UNITS_INCHES); 452 WHEN("Convert current position to mm") { 453 REQUIRE_INTERP_OK(test_interp.execute("g21")); 454 REQUIRE(settings->length_units == CANON_UNITS_MM); 455 THEN("urrent position should be in new program units") { 456 CHECK_FUZZ(currentX(settings), 1 * 25.4); 457 CHECK_FUZZ(currentY(settings), 2 * 25.4); 458 CHECK_FUZZ(currentZ(settings), 3 * 25.4); 459 CHECK_FUZZ(currentA(settings), 4); 460 CHECK_FUZZ(currentB(settings), 5); 461 CHECK_FUZZ(currentC(settings), 6); 462 } 463 WHEN("Convert to back to inches") { 464 REQUIRE_INTERP_OK(test_interp.execute("g20")); 465 REQUIRE(settings->length_units == CANON_UNITS_INCHES); 466 THEN("current position returns to inch value") { 467 CHECK_FUZZ(currentX(settings), 1); 468 CHECK_FUZZ(currentY(settings), 2); 469 CHECK_FUZZ(currentZ(settings), 3); 470 CHECK_FUZZ(currentA(settings), 4); 471 CHECK_FUZZ(currentB(settings), 5); 472 CHECK_FUZZ(currentC(settings), 6); 473 } 474 } 475 } 476 477 WHEN("Switch to G21") { 478 REQUIRE_INTERP_OK(test_interp.execute("g10 L2 P1 X1 Y2 Z3 A4 B5 C6")); 479 REQUIRE_INTERP_OK(test_interp.execute("g54")); 480 REQUIRE_INTERP_OK(test_interp.execute("g0 x0.5 y0.5")); 481 REQUIRE_INTERP_OK(test_interp.execute("g21")); 482 REQUIRE(settings->length_units == CANON_UNITS_MM); 483 THEN("Current work offset in mm") { 484 CHECK_FUZZ(currentWorkOffsetX(settings), 1 * 25.4); 485 CHECK_FUZZ(currentWorkOffsetY(settings), 2 * 25.4); 486 CHECK_FUZZ(currentWorkOffsetZ(settings), 3 * 25.4); 487 CHECK_FUZZ(currentWorkOffsetA(settings), 4); 488 CHECK_FUZZ(currentWorkOffsetB(settings), 5); 489 CHECK_FUZZ(currentWorkOffsetC(settings), 6); 490 } 491 WHEN("Switch to back to G20") { 492 REQUIRE_INTERP_OK(test_interp.execute("g20")); 493 REQUIRE(settings->length_units == CANON_UNITS_INCHES); 494 THEN("current work offset returns to inches") { 495 CHECK_FUZZ(currentWorkOffsetX(settings), 1); 496 CHECK_FUZZ(currentWorkOffsetY(settings), 2); 497 CHECK_FUZZ(currentWorkOffsetZ(settings), 3); 498 CHECK_FUZZ(currentWorkOffsetA(settings), 4); 499 CHECK_FUZZ(currentWorkOffsetB(settings), 5); 500 CHECK_FUZZ(currentWorkOffsetC(settings), 6); 501 } 502 } 503 } 504 } 505 506 GIVEN("Starting in with an axis offset") 507 { 508 DECL_INIT_TEST_INTERP(); 509 REQUIRE_INTERP_OK(test_interp.execute("g20")); 510 REQUIRE_INTERP_OK(test_interp.execute("g92 x1 y2 z3 a4 b5 c6")); 511 512 THEN("Initial axis offsets should be in inches") { 513 CHECK_FUZZ(currentAxisOffsetX(settings), -1); 514 CHECK_FUZZ(currentAxisOffsetY(settings), -2); 515 CHECK_FUZZ(currentAxisOffsetZ(settings), -3); 516 CHECK_FUZZ(currentAxisOffsetA(settings), -4); 517 CHECK_FUZZ(currentAxisOffsetB(settings), -5); 518 CHECK_FUZZ(currentAxisOffsetC(settings), -6); 519 } 520 WHEN("Switch to G21") { 521 REQUIRE_INTERP_OK(test_interp.execute("g21")); 522 REQUIRE(settings->length_units == CANON_UNITS_MM); 523 THEN("Axis offsets in mm") { 524 CHECK_FUZZ(currentAxisOffsetX(settings), -1 * 25.4); 525 CHECK_FUZZ(currentAxisOffsetY(settings), -2 * 25.4); 526 CHECK_FUZZ(currentAxisOffsetZ(settings), -3 * 25.4); 527 CHECK_FUZZ(currentAxisOffsetA(settings), -4); 528 CHECK_FUZZ(currentAxisOffsetB(settings), -5); 529 CHECK_FUZZ(currentAxisOffsetC(settings), -6); 530 } 531 WHEN("Switch to back to G20") { 532 REQUIRE_INTERP_OK(test_interp.execute("g20")); 533 REQUIRE(settings->length_units == CANON_UNITS_INCHES); 534 THEN("Axis offsets in inches again") { 535 CHECK_FUZZ(currentAxisOffsetX(settings), -1); 536 CHECK_FUZZ(currentAxisOffsetY(settings), -2); 537 CHECK_FUZZ(currentAxisOffsetZ(settings), -3); 538 CHECK_FUZZ(currentAxisOffsetA(settings), -4); 539 CHECK_FUZZ(currentAxisOffsetB(settings), -5); 540 CHECK_FUZZ(currentAxisOffsetC(settings), -6); 541 } 542 } 543 } 544 } 545 } 546 547 SCENARIO("Applying a work offset while active") 548 { 549 GIVEN("A 45 deg rotated coordinate system with no offsets") 550 { 551 DECL_INIT_TEST_INTERP(); 552 REQUIRE_INTERP_OK(test_interp.execute("g20")); 553 REQUIRE(settings->length_units == CANON_UNITS_INCHES); 554 REQUIRE_INTERP_OK(test_interp.execute("g54")); 555 REQUIRE_INTERP_OK(test_interp.execute("g10 l2 p1 x0 y0 z0 r45")); 556 REQUIRE_INTERP_OK(test_interp.execute("g0 g53 x0 y0 z0")); 557 REQUIRE(currentX(settings) == 0.0); 558 REQUIRE(currentY(settings) == 0.0); 559 REQUIRE(currentZ(settings) == 0.0); 560 561 WHEN("Request L20 for an X offset") { 562 REQUIRE_INTERP_OK(test_interp.execute("g10 l20 p1 x-1")); 563 THEN("Actual work offsets are rotated") { 564 CHECK_FUZZ(currentWorkOffsetX(settings), sqrt(2)/2); 565 CHECK_FUZZ(currentWorkOffsetY(settings), sqrt(2)/2); 566 CHECK_FUZZ(currentWorkOffsetZ(settings), 0); 567 } 568 569 WHEN("Move to X0 and request a Y offset") { 570 REQUIRE_INTERP_OK(test_interp.execute("g0 x0")); 571 REQUIRE_INTERP_OK(test_interp.execute("g10 l20 p1 y-1")); 572 THEN("Actual work offsets are rotated") { 573 CHECK_FUZZ(currentWorkOffsetX(settings), 0.0); 574 CHECK_FUZZ(currentWorkOffsetY(settings), sqrt(2)); 575 CHECK_FUZZ(currentWorkOffsetZ(settings), 0); 576 } 577 } 578 } 579 } 580 } 581