00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 #ifndef __GNUC__
00084 #ifndef __attribute__
00085 #define __attribute__(x)
00086 #endif
00087 #endif
00088
00089 static char __attribute__((unused)) ident[] = "$Id: emccanon.cc,v 1.15 2001/07/14 17:32:54 paul_c Exp $";
00090
00091 #include <stdio.h>
00092 #include <stdarg.h>
00093 #include <math.h>
00094 #include <string.h>
00095 #include <ctype.h>
00096 #include "emc.hh"
00097 #include "canon.hh"
00098 #include "interpl.hh"
00099 #include "emcglb.h"
00100 #include "emcpos.h"
00101
00102 static PM_QUATERNION quat(1, 0, 0, 0);
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116 static CANON_POSITION programOrigin(0.0, 0.0, 0.0);
00117 static CANON_UNITS lengthUnits = CANON_UNITS_MM;
00118 static CANON_PLANE activePlane = CANON_PLANE_XY;
00119
00120
00121
00122
00123
00124 static CANON_POSITION canonEndPoint;
00125 static void canonUpdateEndPoint(double x, double y, double z, double a, double b, double c)
00126 {
00127 canonEndPoint.x = x;
00128 canonEndPoint.y = y;
00129 canonEndPoint.z = z;
00130 canonEndPoint.a = a;
00131 canonEndPoint.b = b;
00132 canonEndPoint.c = c;
00133 }
00134
00135
00136
00137 static CANON_MOTION_MODE canonMotionMode = 0;
00138
00139
00140 #define TO_EXT_LEN(mm) ((mm) * GET_EXTERNAL_LENGTH_UNITS())
00141 #define TO_EXT_ANG(deg) ((deg) * GET_EXTERNAL_ANGLE_UNITS())
00142
00143
00144 #define FROM_EXT_LEN(ext) ((ext) / GET_EXTERNAL_LENGTH_UNITS())
00145 #define FROM_EXT_ANG(ext) ((ext) / GET_EXTERNAL_ANGLE_UNITS())
00146
00147
00148 #define TO_PROG_LEN(mm) ((mm) / (lengthUnits == CANON_UNITS_INCHES ? 25.4 : lengthUnits == CANON_UNITS_CM ? 10.0 : 1.0))
00149 #define TO_PROG_ANG(deg) (deg)
00150
00151
00152 #define FROM_PROG_LEN(prog) ((prog) * (lengthUnits == CANON_UNITS_INCHES ? 25.4 : lengthUnits == CANON_UNITS_CM ? 10.0 : 1.0))
00153 #define FROM_PROG_ANG(prog) (prog)
00154
00155
00156
00157
00158 static double spindleSpeed = 0.0;
00159
00160
00161
00162
00163 static int preppedTool = 0;
00164
00165
00166
00167
00168
00169
00170 static double currentLinearFeedRate = 1.0;
00171 static double currentLinearTraverseRate = 1.0;
00172 static double currentAngularFeedRate = 1.0;
00173 static double currentAngularTraverseRate = 1.0;
00174
00175 static int pure_angular_move =0;
00176
00177
00178
00179
00180
00181 static double currentToolLengthOffset = 0.0;
00182
00183
00184
00185
00186
00187
00188
00189
00190 static double lastVelSet = -1;
00191
00192
00193 static int properVelocity(double vel)
00194 {
00195 EMC_TRAJ_SET_VELOCITY velMsg;
00196
00197 if (! pure_angular_move) {
00198 velMsg.velocity = TO_EXT_LEN(vel);
00199 }
00200 else {
00201 velMsg.velocity = TO_EXT_ANG(vel);
00202 }
00203
00204 if (velMsg.velocity != lastVelSet) {
00205 lastVelSet = velMsg.velocity;
00206 interp_list.append(velMsg);
00207 }
00208
00209 return 0;
00210 }
00211
00212
00213
00214 void SET_ORIGIN_OFFSETS(double x, double y, double z,
00215 double a, double b, double c)
00216 {
00217 EMC_TRAJ_SET_ORIGIN set_origin_msg;
00218
00219
00220 x = FROM_PROG_LEN(x);
00221 y = FROM_PROG_LEN(y);
00222 z = FROM_PROG_LEN(z);
00223
00224 programOrigin.x = x;
00225 programOrigin.y = y;
00226 programOrigin.z = z;
00227
00228
00229
00230 set_origin_msg.origin.tran.x = TO_EXT_LEN(programOrigin.x);
00231 set_origin_msg.origin.tran.y = TO_EXT_LEN(programOrigin.y);
00232 set_origin_msg.origin.tran.z = TO_EXT_LEN(programOrigin.z);
00233 set_origin_msg.origin.a = a;
00234 set_origin_msg.origin.b = b;
00235 set_origin_msg.origin.c = c;
00236
00237 interp_list.append(set_origin_msg);
00238 }
00239
00240 void USE_LENGTH_UNITS(CANON_UNITS in_unit)
00241 {
00242 lengthUnits = in_unit;
00243
00244 emcStatus->task.programUnits = in_unit;
00245 }
00246
00247
00248
00249 void SET_TRAVERSE_RATE(double rate)
00250 {
00251 double vmax;
00252
00253
00254
00255 rate /= 60.0;
00256
00257
00258 currentLinearTraverseRate = FROM_PROG_LEN(rate);
00259 currentAngularTraverseRate = FROM_PROG_ANG(rate);
00260
00261
00262
00263 vmax = FROM_EXT_LEN(TRAJ_MAX_VELOCITY);
00264 if (currentLinearTraverseRate > vmax) {
00265 currentLinearTraverseRate = vmax;
00266 }
00267
00268 }
00269
00270 void STRAIGHT_TRAVERSE(double x, double y, double z,
00271 double a, double b, double c)
00272 {
00273 EMC_TRAJ_LINEAR_MOVE linearMoveMsg;
00274 double dx, dy, dz, da, db, dc, dtot;
00275 double tx, ty, tz, ta, tb, tc, tmax;
00276 double vel;
00277
00278
00279 x = FROM_PROG_LEN(x);
00280 y = FROM_PROG_LEN(y);
00281 z = FROM_PROG_LEN(z);
00282 a = FROM_PROG_ANG(a);
00283 b = FROM_PROG_ANG(b);
00284 c = FROM_PROG_ANG(c);
00285
00286 x += programOrigin.x;
00287 y += programOrigin.y;
00288 z += programOrigin.z;
00289 a += programOrigin.a;
00290 b += programOrigin.b;
00291 c += programOrigin.c;
00292
00293 z += currentToolLengthOffset;
00294
00295
00296
00297 linearMoveMsg.end.tran.x = TO_EXT_LEN(x);
00298 linearMoveMsg.end.tran.y = TO_EXT_LEN(y);
00299 linearMoveMsg.end.tran.z = TO_EXT_LEN(z);
00300
00301
00302 linearMoveMsg.end.a = TO_EXT_ANG(a);
00303 linearMoveMsg.end.b = TO_EXT_ANG(b);
00304 linearMoveMsg.end.c = TO_EXT_ANG(c);
00305
00306
00307
00308 pure_angular_move = 0;
00309
00310 dx = x - canonEndPoint.x;
00311 dy = y - canonEndPoint.y;
00312 dz = z - canonEndPoint.z;
00313 da = a - canonEndPoint.a;
00314 db = b - canonEndPoint.b;
00315 dc = c - canonEndPoint.c;
00316 dtot = sqrt(dx*dx + dy*dy + dz*dz);
00317 if (dtot <= 0.0) {
00318 dtot = sqrt(da*da + db*db + dc*dc);
00319 if (dtot > 0.0) {
00320 pure_angular_move =1;
00321 }
00322 }
00323
00324 if (! pure_angular_move) {
00325 tx = fabs(dx / FROM_EXT_LEN(AXIS_MAX_VELOCITY[0]));
00326 ty = fabs(dy / FROM_EXT_LEN(AXIS_MAX_VELOCITY[1]));
00327 tz = fabs(dz / FROM_EXT_LEN(AXIS_MAX_VELOCITY[2]));
00328 tmax = tx > ty ? tx : ty;
00329 tmax = tz > tmax ? tz : tmax;
00330
00331 if (tmax <= 0.0) {
00332 vel = currentLinearTraverseRate;
00333 }
00334 else {
00335 vel = dtot/tmax;
00336 if (vel > currentLinearTraverseRate) {
00337 vel = currentLinearTraverseRate;
00338 }
00339 }
00340
00341 }
00342 else {
00343 ta = fabs(da / FROM_EXT_ANG(AXIS_MAX_VELOCITY[3]));
00344 tb = fabs(db / FROM_EXT_ANG(AXIS_MAX_VELOCITY[4]));
00345 tc = fabs(dc / FROM_EXT_ANG(AXIS_MAX_VELOCITY[5]));
00346 tmax = ta > tb ? ta : tb;
00347 tmax = tc > tmax ? tc : tmax;
00348
00349 if (tmax <= 0.0) {
00350 vel = currentAngularTraverseRate;
00351 }
00352 else {
00353 vel = dtot/tmax;
00354 if (vel > currentAngularTraverseRate) {
00355 vel = currentAngularTraverseRate;
00356 }
00357 }
00358
00359 }
00360
00361
00362 properVelocity(vel);
00363
00364 interp_list.append(linearMoveMsg);
00365
00366 canonUpdateEndPoint(x, y, z, a, b, c);
00367 }
00368
00369
00370
00371 void SET_FEED_RATE(double rate)
00372 {
00373 double vmax;
00374
00375
00376 rate /= 60.0;
00377
00378
00379 currentLinearFeedRate = FROM_PROG_LEN(rate);
00380 currentAngularFeedRate = FROM_PROG_ANG(rate);
00381
00382
00383
00384 vmax = FROM_EXT_LEN(TRAJ_MAX_VELOCITY);
00385 if (currentLinearFeedRate > vmax) {
00386 currentLinearFeedRate = vmax;
00387 }
00388 }
00389
00390 void SET_FEED_REFERENCE(CANON_FEED_REFERENCE reference)
00391 {
00392
00393 }
00394
00395 void SET_MOTION_CONTROL_MODE(CANON_MOTION_MODE mode)
00396 {
00397 EMC_TRAJ_SET_TERM_COND setTermCondMsg;
00398
00399 if (mode != canonMotionMode)
00400 {
00401 canonMotionMode = mode;
00402
00403 switch (mode)
00404 {
00405 case CANON_CONTINUOUS:
00406 setTermCondMsg.cond = EMC_TRAJ_TERM_COND_BLEND;
00407 break;
00408
00409 default:
00410 setTermCondMsg.cond = EMC_TRAJ_TERM_COND_STOP;
00411 break;
00412 }
00413
00414 interp_list.append(setTermCondMsg);
00415 }
00416 }
00417
00418 CANON_MOTION_MODE GET_MOTION_CONTROL_MODE()
00419 {
00420 return canonMotionMode;
00421 }
00422
00423 void SELECT_PLANE(CANON_PLANE in_plane)
00424 {
00425 activePlane = in_plane;
00426 }
00427
00428 void SET_CUTTER_RADIUS_COMPENSATION(double radius)
00429 {
00430
00431 }
00432
00433 void START_CUTTER_RADIUS_COMPENSATION(int side)
00434 {
00435
00436 }
00437
00438 void STOP_CUTTER_RADIUS_COMPENSATION()
00439 {
00440
00441 }
00442
00443 void START_SPEED_FEED_SYNCH()
00444 {
00445
00446 }
00447
00448 void STOP_SPEED_FEED_SYNCH()
00449 {
00450
00451 }
00452
00453 void SELECT_MOTION_MODE(CANON_MOTION_MODE mode)
00454 {
00455
00456 }
00457
00458
00459
00460
00461
00462 void ARC_FEED(double first_end, double second_end,
00463 double first_axis, double second_axis, int rotation,
00464 double axis_end_point,
00465 double a, double b, double c)
00466 {
00467 EmcPose end;
00468 PM_CARTESIAN center, normal;
00469 EMC_TRAJ_CIRCULAR_MOVE circularMoveMsg;
00470 EMC_TRAJ_LINEAR_MOVE linearMoveMsg;
00471 int full_circle_in_active_plane = 0;
00472 double v1, v2, vel;
00473
00474
00475 first_axis = FROM_PROG_LEN(first_axis);
00476 second_axis = FROM_PROG_LEN(second_axis);
00477 first_end = FROM_PROG_LEN(first_end);
00478 second_end = FROM_PROG_LEN(second_end);
00479 axis_end_point = FROM_PROG_LEN(axis_end_point);
00480
00481
00482 switch (activePlane) {
00483 case CANON_PLANE_XY:
00484
00485
00486 end.tran.x = first_end + programOrigin.x;
00487 end.tran.y = second_end + programOrigin.y;
00488 end.tran.z = axis_end_point + programOrigin.z;
00489 end.tran.z += currentToolLengthOffset;
00490 if (canonEndPoint.x == end.tran.x &&
00491 canonEndPoint.y == end.tran.y)
00492 {
00493 full_circle_in_active_plane = 1;
00494 }
00495 center.x = first_axis + programOrigin.x;
00496 center.y = second_axis + programOrigin.y;
00497 center.z = end.tran.z;
00498 normal.x = 0.0;
00499 normal.y = 0.0;
00500 normal.z = 1.0;
00501
00502
00503 vel = currentLinearFeedRate;
00504 v1 = FROM_EXT_LEN(AXIS_MAX_VELOCITY[0]);
00505 v2 = FROM_EXT_LEN(AXIS_MAX_VELOCITY[1]);
00506 if (vel > v1) {
00507 vel = v1;
00508 }
00509 if (vel > v2) {
00510 vel = v2;
00511 }
00512
00513 break;
00514
00515 case CANON_PLANE_YZ:
00516
00517
00518 end.tran.y = first_end + programOrigin.y;
00519 end.tran.z = second_end + programOrigin.z;
00520 end.tran.x = axis_end_point + programOrigin.x;
00521 end.tran.z += currentToolLengthOffset;
00522 if (canonEndPoint.z == end.tran.z &&
00523 canonEndPoint.y == end.tran.y) {
00524 full_circle_in_active_plane = 1;
00525 }
00526
00527 center.y = first_axis + programOrigin.y;
00528 center.z = second_axis + programOrigin.z;
00529 center.x = end.tran.x;
00530 normal.y = 0.0;
00531 normal.z = 0.0;
00532 normal.x = 1.0;
00533
00534
00535 vel = currentLinearFeedRate;
00536 v1 = FROM_EXT_LEN(AXIS_MAX_VELOCITY[1]);
00537 v2 = FROM_EXT_LEN(AXIS_MAX_VELOCITY[2]);
00538 if (vel > v1) {
00539 vel = v1;
00540 }
00541 if (vel > v2) {
00542 vel = v2;
00543 }
00544
00545 break;
00546
00547 case CANON_PLANE_XZ:
00548
00549
00550 end.tran.z = first_end + programOrigin.z;
00551 end.tran.x = second_end + programOrigin.x;
00552 end.tran.y = axis_end_point + programOrigin.y;
00553 end.tran.z += currentToolLengthOffset;
00554 if (canonEndPoint.x== end.tran.x &&
00555 canonEndPoint.z == end.tran.z)
00556 {
00557 full_circle_in_active_plane = 1;
00558 }
00559
00560 center.z = first_axis + programOrigin.z;
00561 center.x = second_axis + programOrigin.x;
00562 center.y = end.tran.y;
00563 normal.z = 0.0;
00564 normal.x = 0.0;
00565 normal.y = 1.0;
00566
00567
00568 vel = currentLinearFeedRate;
00569 v1 = FROM_EXT_LEN(AXIS_MAX_VELOCITY[0]);
00570 v2 = FROM_EXT_LEN(AXIS_MAX_VELOCITY[2]);
00571 if (vel > v1) {
00572 vel = v1;
00573 }
00574 if (vel > v2) {
00575 vel = v2;
00576 }
00577
00578 break;
00579 }
00580
00581
00582 properVelocity(vel);
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596 if (rotation == 0) {
00597
00598
00599 linearMoveMsg.end.tran.x = TO_EXT_LEN(end.tran.x);
00600 linearMoveMsg.end.tran.y = TO_EXT_LEN(end.tran.y);
00601 linearMoveMsg.end.tran.z = TO_EXT_LEN(end.tran.z);
00602
00603
00604 linearMoveMsg.end.a = a;
00605 linearMoveMsg.end.b = b;
00606 linearMoveMsg.end.c = c;
00607
00608
00609 interp_list.append(linearMoveMsg);
00610 }
00611 else if (rotation > 0) {
00612
00613 #if 0
00614
00615
00616
00617 if (full_circle_in_active_plane) {
00618 rotation++;
00619 }
00620 #endif
00621
00622 circularMoveMsg.end.tran.x = TO_EXT_LEN(end.tran.x);
00623 circularMoveMsg.end.tran.y = TO_EXT_LEN(end.tran.y);
00624 circularMoveMsg.end.tran.z = TO_EXT_LEN(end.tran.z);
00625
00626 circularMoveMsg.center.x = TO_EXT_LEN(center.x);
00627 circularMoveMsg.center.y = TO_EXT_LEN(center.y);
00628 circularMoveMsg.center.z = TO_EXT_LEN(center.z);
00629
00630 circularMoveMsg.normal.x = TO_EXT_LEN(normal.x);
00631 circularMoveMsg.normal.y = TO_EXT_LEN(normal.y);
00632 circularMoveMsg.normal.z = TO_EXT_LEN(normal.z);
00633
00634 circularMoveMsg.turn = rotation - 1;
00635
00636
00637 circularMoveMsg.end.a = a;
00638 circularMoveMsg.end.b = b;
00639 circularMoveMsg.end.c = c;
00640
00641
00642 interp_list.append(circularMoveMsg);
00643 }
00644 else {
00645
00646
00647 #if 0
00648
00649
00650
00651 if (full_circle_in_active_plane) {
00652 rotation--;
00653 }
00654 #endif
00655 circularMoveMsg.end.tran.x = TO_EXT_LEN(end.tran.x);
00656 circularMoveMsg.end.tran.y = TO_EXT_LEN(end.tran.y);
00657 circularMoveMsg.end.tran.z = TO_EXT_LEN(end.tran.z);
00658
00659 circularMoveMsg.center.x = TO_EXT_LEN(center.x);
00660 circularMoveMsg.center.y = TO_EXT_LEN(center.y);
00661 circularMoveMsg.center.z = TO_EXT_LEN(center.z);
00662
00663 circularMoveMsg.normal.x = TO_EXT_LEN(normal.x);
00664 circularMoveMsg.normal.y = TO_EXT_LEN(normal.y);
00665 circularMoveMsg.normal.z = TO_EXT_LEN(normal.z);
00666
00667 circularMoveMsg.turn = rotation;
00668
00669
00670
00671 circularMoveMsg.end.a = a;
00672 circularMoveMsg.end.b = b;
00673 circularMoveMsg.end.c = c;
00674
00675 interp_list.append(circularMoveMsg);
00676 }
00677
00678
00679
00680 canonUpdateEndPoint(end.tran.x, end.tran.y, end.tran.z, a, b, c);
00681 }
00682
00683 void STRAIGHT_FEED(double x, double y, double z, double a, double b, double c)
00684 {
00685 EMC_TRAJ_LINEAR_MOVE linearMoveMsg;
00686 double dx, dy, dz, da, db, dc, dtot;
00687 double tx, ty, tz, ta, tb, tc, tmax;
00688 double vel;
00689
00690
00691 x = FROM_PROG_LEN(x);
00692 y = FROM_PROG_LEN(y);
00693 z = FROM_PROG_LEN(z);
00694 a = FROM_PROG_ANG(a);
00695 b = FROM_PROG_ANG(b);
00696 c = FROM_PROG_ANG(c);
00697
00698 x += programOrigin.x;
00699 y += programOrigin.y;
00700 z += programOrigin.z;
00701 a += programOrigin.a;
00702 b += programOrigin.b;
00703 c += programOrigin.c;
00704
00705 z += currentToolLengthOffset;
00706
00707
00708
00709 linearMoveMsg.end.tran.x = TO_EXT_LEN(x);
00710 linearMoveMsg.end.tran.y = TO_EXT_LEN(y);
00711 linearMoveMsg.end.tran.z = TO_EXT_LEN(z);
00712
00713
00714 linearMoveMsg.end.a = TO_EXT_ANG(a);
00715 linearMoveMsg.end.b = TO_EXT_ANG(b);
00716 linearMoveMsg.end.c = TO_EXT_ANG(c);
00717
00718
00719
00720 pure_angular_move = 0;
00721
00722 dx = x - canonEndPoint.x;
00723 dy = y - canonEndPoint.y;
00724 dz = z - canonEndPoint.z;
00725 da = a - canonEndPoint.a;
00726 db = b - canonEndPoint.b;
00727 dc = c - canonEndPoint.c;
00728 dtot = sqrt(dx*dx + dy*dy + dz*dz);
00729 if (dtot <= 0.0) {
00730 dtot = sqrt(da*da + db*db + dc*dc);
00731 if (dtot > 0.0) {
00732 pure_angular_move =1;
00733 }
00734 }
00735
00736 if (!pure_angular_move) {
00737 tx = fabs(dx / FROM_EXT_LEN(AXIS_MAX_VELOCITY[0]));
00738 ty = fabs(dy / FROM_EXT_LEN(AXIS_MAX_VELOCITY[1]));
00739 tz = fabs(dz / FROM_EXT_LEN(AXIS_MAX_VELOCITY[2]));
00740 tmax = tx > ty ? tx : ty;
00741 tmax = tz > tmax ? tz : tmax;
00742
00743 if (tmax <= 0.0) {
00744 vel = currentLinearFeedRate;
00745 }
00746 else {
00747 vel = dtot/tmax;
00748 if (vel > currentLinearFeedRate) {
00749 vel = currentLinearFeedRate;
00750 }
00751 }
00752
00753 }
00754 else {
00755 ta = fabs(da / FROM_EXT_ANG(AXIS_MAX_VELOCITY[3]));
00756 tb = fabs(db / FROM_EXT_ANG(AXIS_MAX_VELOCITY[4]));
00757 tc = fabs(dc / FROM_EXT_ANG(AXIS_MAX_VELOCITY[5]));
00758 tmax = ta > tb ? ta : tb;
00759 tmax = tc > tmax ? tc : tmax;
00760
00761 if (tmax <= 0.0) {
00762 vel = currentAngularFeedRate;
00763 }
00764 else {
00765 vel = dtot/tmax;
00766 if (vel > currentAngularFeedRate) {
00767 vel = currentAngularFeedRate;
00768 }
00769 }
00770 }
00771
00772
00773 properVelocity(vel);
00774
00775 interp_list.append(linearMoveMsg);
00776
00777 canonUpdateEndPoint(x, y, z, a, b, c);
00778 }
00779
00780
00781
00782
00783
00784 void STRAIGHT_PROBE(double x, double y, double z, double a, double b, double c)
00785 {
00786 EMC_TRAJ_PROBE probeMsg;
00787 double dx, dy, dz, dtot;
00788 double tx, ty, tz, tmax;
00789 double vel;
00790
00791
00792 x = FROM_PROG_LEN(x);
00793 y = FROM_PROG_LEN(y);
00794 z = FROM_PROG_LEN(z);
00795
00796 x += programOrigin.x;
00797 y += programOrigin.y;
00798 z += programOrigin.z;
00799
00800 z += currentToolLengthOffset;
00801
00802
00803
00804 probeMsg.pos.tran.x = TO_EXT_LEN(x);
00805 probeMsg.pos.tran.y = TO_EXT_LEN(y);
00806 probeMsg.pos.tran.z = TO_EXT_LEN(z);
00807
00808
00809
00810 dx = x - canonEndPoint.x;
00811 dy = y - canonEndPoint.y;
00812 dz = z - canonEndPoint.z;
00813 dtot = sqrt(dx*dx + dy*dy + dz*dz);
00814
00815 tx = fabs(dx / FROM_EXT_LEN(AXIS_MAX_VELOCITY[0]));
00816 ty = fabs(dy / FROM_EXT_LEN(AXIS_MAX_VELOCITY[1]));
00817 tz = fabs(dz / FROM_EXT_LEN(AXIS_MAX_VELOCITY[2]));
00818 tmax = tx > ty ? tx : ty;
00819 tmax = tz > tmax ? tz : tmax;
00820
00821 if (tmax <= 0.0) {
00822 vel = currentLinearFeedRate;
00823 }
00824 else {
00825 vel = dtot/tmax;
00826 if (vel > currentLinearFeedRate) {
00827 vel = currentLinearFeedRate;
00828 }
00829 }
00830
00831
00832 properVelocity(vel);
00833
00834
00835 probeMsg.pos.a = a;
00836 probeMsg.pos.b = b;
00837 probeMsg.pos.c = c;
00838
00839 interp_list.append(probeMsg);
00840
00841 canonUpdateEndPoint(x, y, z, a, b,c);
00842 }
00843
00844 void DWELL(double seconds)
00845 {
00846 EMC_TRAJ_DELAY delayMsg;
00847
00848 delayMsg.delay = seconds;
00849
00850 interp_list.append(delayMsg);
00851 }
00852
00853
00854 void SPINDLE_RETRACT_TRAVERSE()
00855 {
00856
00857 }
00858
00859
00860 static int spindleOn = 0;
00861
00862 void START_SPINDLE_CLOCKWISE()
00863 {
00864 EMC_SPINDLE_ON emc_spindle_on_msg;
00865
00866 emc_spindle_on_msg.speed = spindleSpeed;
00867
00868 interp_list.append(emc_spindle_on_msg);
00869
00870 spindleOn = 1;
00871 }
00872
00873 void START_SPINDLE_COUNTERCLOCKWISE()
00874 {
00875 EMC_SPINDLE_ON emc_spindle_on_msg;
00876
00877 emc_spindle_on_msg.speed = - spindleSpeed;
00878
00879 interp_list.append(emc_spindle_on_msg);
00880
00881 spindleOn = -1;
00882 }
00883
00884 void SET_SPINDLE_SPEED(double r)
00885 {
00886
00887 spindleSpeed = r;
00888
00889
00890 if (spindleOn == 1)
00891 {
00892 START_SPINDLE_CLOCKWISE();
00893 }
00894 else if (spindleOn == -1)
00895 {
00896 START_SPINDLE_COUNTERCLOCKWISE();
00897 }
00898 }
00899
00900 void STOP_SPINDLE_TURNING()
00901 {
00902 EMC_SPINDLE_OFF emc_spindle_off_msg;
00903
00904 interp_list.append(emc_spindle_off_msg);
00905
00906 spindleOn = 0;
00907 }
00908
00909 void SPINDLE_RETRACT()
00910 {
00911
00912 }
00913
00914 void ORIENT_SPINDLE(double orientation, CANON_DIRECTION direction)
00915 {
00916
00917 }
00918
00919 void USE_NO_SPINDLE_FORCE()
00920 {
00921
00922 }
00923
00924
00925
00926
00927
00928
00929
00930 void USE_TOOL_LENGTH_OFFSET(double length)
00931 {
00932 EMC_TRAJ_SET_OFFSET set_offset_msg;
00933
00934
00935 currentToolLengthOffset = FROM_PROG_LEN(length);
00936
00937
00938
00939 set_offset_msg.offset.tran.x = 0.0;
00940 set_offset_msg.offset.tran.y = 0.0;
00941 set_offset_msg.offset.tran.z = TO_EXT_LEN(currentToolLengthOffset);
00942 set_offset_msg.offset.a = 0.0;
00943 set_offset_msg.offset.b = 0.0;
00944 set_offset_msg.offset.c = 0.0;
00945
00946 interp_list.append(set_offset_msg);
00947 }
00948
00949 void CHANGE_TOOL(int slot)
00950 {
00951 EMC_TOOL_LOAD load_tool_msg;
00952
00953 interp_list.append(load_tool_msg);
00954 }
00955
00956 void SELECT_TOOL(int slot)
00957 {
00958 EMC_TOOL_PREPARE prep_for_tool_msg;
00959
00960 prep_for_tool_msg.tool = slot;
00961
00962 interp_list.append(prep_for_tool_msg);
00963 }
00964
00965
00966
00967 void CLAMP_AXIS(CANON_AXIS axis)
00968 {
00969
00970 }
00971
00972
00973
00974
00975
00976
00977 static char * setString(char *dst, const char *src, int maxlen)
00978 {
00979 dst[0] = 0;
00980 strncat(dst, src, maxlen - 1);
00981 dst[maxlen - 1] = 0;
00982 return dst;
00983 }
00984
00985 static char * addString(char *dst, const char *src, int maxlen)
00986 {
00987 int dstlen = strlen(dst);
00988 int srclen = strlen(src);
00989 int actlen;
00990
00991 if (srclen >= maxlen - dstlen) {
00992 actlen = maxlen - dstlen - 1;
00993 dst[maxlen - 1] = 0;
00994 }
00995 else {
00996 actlen = srclen;
00997 }
00998
00999 strncat(dst, src, actlen);
01000
01001 return dst;
01002 }
01003
01004
01005
01006
01007
01008
01009
01010 static FILE *probefile = NULL;
01011
01012 void COMMENT(char *comment)
01013 {
01014
01015
01016 #define MSGLEN 256
01017 char msg[MSGLEN];
01018 char probefilename[MSGLEN];
01019 char *ptr;
01020
01021
01022 if (!strncmp(comment, "RPY", strlen("RPY"))) {
01023 PM_RPY rpy;
01024
01025 if (3 != sscanf(comment, "%*s %lf %lf %lf", &rpy.r, &rpy.p, &rpy.y)) {
01026
01027 printf("rpy = %f %f %f, quat = %f %f %f %f\n",
01028 rpy.r, rpy.p, rpy.y,
01029 quat.s, quat.x, quat.y, quat.z);
01030 }
01031 else {
01032
01033 quat = rpy;
01034 printf("rpy = %f %f %f, quat = %f %f %f %f\n",
01035 rpy.r, rpy.p, rpy.y,
01036 quat.s, quat.x, quat.y, quat.z);
01037 }
01038 return;
01039 }
01040
01041
01042 if (!strncmp(comment, "PROBEOPEN", strlen("PROBEOPEN"))) {
01043
01044 ptr = &comment[strlen("PROBEOPEN")];
01045
01046 while (isspace(*ptr)) {
01047 ptr++;
01048 }
01049 setString(probefilename, ptr, MSGLEN);
01050 if (NULL == (probefile = fopen(probefilename, "w"))) {
01051
01052 setString(msg, "can't open probe file ", MSGLEN);
01053 addString(msg, probefilename, MSGLEN);
01054 MESSAGE(msg);
01055 probefile = NULL;
01056 }
01057 return;
01058 }
01059
01060
01061 if (!strncmp(comment, "PROBECLOSE", strlen("PROBECLOSE"))) {
01062 if (probefile != NULL) {
01063 fclose(probefile);
01064 probefile = NULL;
01065 }
01066 return;
01067 }
01068
01069 return;
01070 }
01071
01072 void DISABLE_FEED_OVERRIDE()
01073 {
01074
01075 }
01076
01077 void DISABLE_SPEED_OVERRIDE()
01078 {
01079
01080 }
01081
01082 void ENABLE_FEED_OVERRIDE()
01083 {
01084
01085 }
01086
01087 void ENABLE_SPEED_OVERRIDE()
01088 {
01089
01090 }
01091
01092 void FLOOD_OFF()
01093 {
01094 EMC_COOLANT_FLOOD_OFF flood_off_msg;
01095
01096 interp_list.append(flood_off_msg);
01097 }
01098
01099 void FLOOD_ON()
01100 {
01101 EMC_COOLANT_FLOOD_ON flood_on_msg;
01102
01103 interp_list.append(flood_on_msg);
01104 }
01105
01106 void MESSAGE(char *s)
01107 {
01108 EMC_OPERATOR_DISPLAY operator_display_msg;
01109
01110 operator_display_msg.id = 0;
01111 strncpy(operator_display_msg.display, s, EMC_OPERATOR_DISPLAY_LEN);
01112 operator_display_msg.display[EMC_OPERATOR_DISPLAY_LEN - 1] = 0;
01113
01114 interp_list.append(operator_display_msg);
01115 }
01116
01117 void MIST_OFF()
01118 {
01119 EMC_COOLANT_MIST_OFF mist_off_msg;
01120
01121 interp_list.append(mist_off_msg);
01122 }
01123
01124 void MIST_ON()
01125 {
01126 EMC_COOLANT_MIST_ON mist_on_msg;
01127
01128 interp_list.append(mist_on_msg);
01129 }
01130
01131 void PALLET_SHUTTLE()
01132 {
01133
01134 }
01135
01136 void TURN_PROBE_OFF()
01137 {
01138
01139 }
01140
01141 void TURN_PROBE_ON()
01142 {
01143 EMC_TRAJ_CLEAR_PROBE_TRIPPED_FLAG clearMsg;
01144
01145 interp_list.append(clearMsg);
01146 }
01147
01148 void UNCLAMP_AXIS(CANON_AXIS axis)
01149 {
01150
01151 }
01152
01153
01154
01155 void PROGRAM_STOP()
01156 {
01157
01158
01159
01160 EMC_TASK_PLAN_PAUSE pauseMsg;
01161
01162 interp_list.append(pauseMsg);
01163 }
01164
01165 void OPTIONAL_PROGRAM_STOP()
01166 {
01167
01168 PROGRAM_STOP();
01169 }
01170
01171 void PROGRAM_END()
01172 {
01173 EMC_TASK_PLAN_END endMsg;
01174
01175 interp_list.append(endMsg);
01176 }
01177
01178
01179 CANON_VECTOR GET_PROGRAM_ORIGIN()
01180 {
01181 CANON_VECTOR origin;
01182
01183
01184 origin.x = TO_PROG_LEN(programOrigin.x);
01185 origin.y = TO_PROG_LEN(programOrigin.y);
01186 origin.z = TO_PROG_LEN(programOrigin.z);
01187
01188 return origin;
01189 }
01190
01191
01192 CANON_UNITS GET_LENGTH_UNITS()
01193 {
01194 return lengthUnits;
01195 }
01196
01197 CANON_PLANE GET_PLANE()
01198 {
01199 return activePlane;
01200 }
01201
01202 double GET_TOOL_LENGTH_OFFSET()
01203 {
01204 return TO_EXT_LEN(currentToolLengthOffset);
01205 }
01206
01207
01208
01209
01210
01211
01212 void INIT_CANON()
01213 {
01214
01215 programOrigin.x = 0.0;
01216 programOrigin.y = 0.0;
01217 programOrigin.z = 0.0;
01218 programOrigin.a = 0.0;
01219 programOrigin.b = 0.0;
01220 programOrigin.c = 0.0;
01221 activePlane = CANON_PLANE_XY;
01222 canonEndPoint.x = 0.0;
01223 canonEndPoint.y = 0.0;
01224 canonEndPoint.z = 0.0;
01225 canonEndPoint.a = 0.0;
01226 canonEndPoint.b = 0.0;
01227 canonEndPoint.c = 0.0;
01228 SET_MOTION_CONTROL_MODE(CANON_CONTINUOUS);
01229 spindleSpeed = 0.0;
01230 preppedTool = 0;
01231 currentLinearFeedRate = FROM_EXT_LEN(TRAJ_DEFAULT_VELOCITY);
01232 currentLinearTraverseRate = FROM_EXT_LEN(TRAJ_MAX_VELOCITY);
01233 currentAngularFeedRate = 0.0;
01234 currentAngularTraverseRate = 0.0;
01235 currentToolLengthOffset = 0.0;
01236 lengthUnits = CANON_UNITS_MM;
01237 }
01238
01239
01240 void CANON_ERROR(const char *fmt, ...)
01241 {
01242 va_list ap;
01243 EMC_OPERATOR_ERROR operator_error_msg;
01244
01245 operator_error_msg.id = 0;
01246 if (fmt != NULL) {
01247 va_start(ap, fmt);
01248 vsprintf(operator_error_msg.error, fmt, ap);
01249 va_end(ap);
01250 }
01251 else {
01252 operator_error_msg.error[0] = 0;
01253 }
01254
01255 interp_list.append(operator_error_msg);
01256 }
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268 CANON_TOOL_TABLE GET_EXTERNAL_TOOL_TABLE(int pocket)
01269 {
01270 CANON_TOOL_TABLE retval;
01271
01272 if (pocket < 0 || pocket >= CANON_TOOL_MAX) {
01273 retval.id = 0;
01274 retval.length = 0.0;
01275 retval.diameter = 0.0;
01276 }
01277 else {
01278 retval = emcStatus->io.tool.toolTable[pocket];
01279
01280
01281 retval.length = TO_PROG_LEN(FROM_EXT_LEN(retval.length));
01282 retval.diameter = TO_PROG_LEN(FROM_EXT_LEN(retval.diameter));
01283 }
01284
01285 return retval;
01286 }
01287
01288 CANON_POSITION GET_EXTERNAL_POSITION()
01289 {
01290 CANON_POSITION position;
01291 EmcPose pos;
01292
01293 pos = emcStatus->motion.traj.position;
01294
01295
01296 canonEndPoint.x = FROM_EXT_LEN(pos.tran.x) - programOrigin.x;
01297 canonEndPoint.y = FROM_EXT_LEN(pos.tran.y) - programOrigin.y;
01298 canonEndPoint.z = FROM_EXT_LEN(pos.tran.z) - programOrigin.z;
01299 canonEndPoint.z = FROM_EXT_LEN(pos.tran.z) - programOrigin.z;
01300 canonEndPoint.z -= currentToolLengthOffset;
01301
01302
01303 canonEndPoint.a = FROM_EXT_ANG(pos.a) - programOrigin.a;
01304 canonEndPoint.b = FROM_EXT_ANG(pos.b) - programOrigin.b;
01305 canonEndPoint.c = FROM_EXT_ANG(pos.c) - programOrigin.c;
01306
01307
01308
01309
01310 position.x = TO_PROG_LEN(canonEndPoint.x);
01311 position.y = TO_PROG_LEN(canonEndPoint.y);
01312 position.z = TO_PROG_LEN(canonEndPoint.z);
01313 position.z -= TO_PROG_LEN(currentToolLengthOffset);
01314
01315
01316 position.a = TO_PROG_ANG(canonEndPoint.a);
01317 position.b = TO_PROG_ANG(canonEndPoint.b);
01318 position.c = TO_PROG_ANG(canonEndPoint.c);
01319
01320 return position;
01321 }
01322
01323 CANON_POSITION GET_EXTERNAL_PROBE_POSITION()
01324 {
01325 CANON_POSITION position;
01326 EmcPose pos;
01327 static CANON_POSITION last_probed_position;
01328
01329 pos = emcStatus->motion.traj.probedPosition;
01330
01331
01332 canonEndPoint.x = FROM_EXT_LEN(pos.tran.x) - programOrigin.x;
01333 canonEndPoint.y = FROM_EXT_LEN(pos.tran.y) - programOrigin.y;
01334 canonEndPoint.z = FROM_EXT_LEN(pos.tran.z) - programOrigin.z;
01335 canonEndPoint.z -= currentToolLengthOffset;
01336
01337 canonEndPoint.a = FROM_EXT_ANG(pos.a) - programOrigin.a;
01338 canonEndPoint.b = FROM_EXT_ANG(pos.b) - programOrigin.b;
01339 canonEndPoint.c = FROM_EXT_ANG(pos.c) - programOrigin.c;
01340
01341
01342 position.x = TO_PROG_LEN(canonEndPoint.x);
01343 position.y = TO_PROG_LEN(canonEndPoint.y);
01344 position.z = TO_PROG_LEN(canonEndPoint.z);
01345 position.z -= TO_PROG_LEN(currentToolLengthOffset);
01346
01347 position.a = TO_PROG_ANG(canonEndPoint.a);
01348 position.b = TO_PROG_ANG(canonEndPoint.b);
01349 position.c = TO_PROG_ANG(canonEndPoint.c);
01350
01351
01352 if (probefile != NULL) {
01353 if (last_probed_position.x != position.x ||
01354 last_probed_position.y != position.y ||
01355 last_probed_position.z != position.z) {
01356 fprintf(probefile, "%f %f %f\n", position.x, position.y, position.z);
01357 last_probed_position = position;
01358 }
01359 }
01360
01361 return position;
01362 }
01363
01364 double GET_EXTERNAL_PROBE_VALUE()
01365 {
01366
01367 return 0.0;
01368 }
01369
01370 int IS_EXTERNAL_QUEUE_EMPTY()
01371 {
01372 return emcStatus->motion.traj.queue == 0 ? 1 : 0;
01373 }
01374
01375
01376 double GET_EXTERNAL_FEED_RATE()
01377 {
01378 double feed;
01379
01380
01381 feed = TO_PROG_LEN(FROM_EXT_LEN(emcStatus->motion.traj.velocity));
01382
01383
01384 feed *= 60.0;
01385
01386 return feed;
01387 }
01388
01389
01390 double GET_EXTERNAL_TRAVERSE_RATE()
01391 {
01392 double traverse;
01393
01394
01395 traverse = TO_PROG_LEN(FROM_EXT_LEN(emcStatus->motion.traj.maxVelocity));
01396
01397
01398 traverse *= 60.0;
01399
01400 return traverse;
01401 }
01402
01403 double GET_EXTERNAL_LENGTH_UNITS()
01404 {
01405 double u;
01406
01407 u = emcStatus->motion.traj.linearUnits;
01408
01409 if (u == 0) {
01410 CANON_ERROR("external length units are zero");
01411 return 1.0;
01412 }
01413 else {
01414 return u;
01415 }
01416 }
01417
01418 double GET_EXTERNAL_ANGLE_UNITS()
01419 {
01420 double u;
01421
01422 u = emcStatus->motion.traj.angularUnits;
01423
01424 if (u == 0) {
01425 CANON_ERROR("external angle units are zero");
01426 return 1.0;
01427 }
01428 else {
01429 return u;
01430 }
01431 }
01432
01433 int GET_EXTERNAL_TOOL()
01434 {
01435 return emcStatus->io.tool.toolInSpindle;
01436 }
01437
01438 int GET_EXTERNAL_MIST()
01439 {
01440 return emcStatus->io.coolant.mist;
01441 }
01442
01443 int GET_EXTERNAL_FLOOD()
01444 {
01445 return emcStatus->io.coolant.flood;
01446 }
01447
01448 int GET_EXTERNAL_POCKET()
01449 {
01450 return emcStatus->io.tool.toolPrepped;
01451 }
01452
01453 double GET_EXTERNAL_SPEED()
01454 {
01455
01456 return emcStatus->io.spindle.speed;
01457 }
01458
01459 CANON_DIRECTION GET_EXTERNAL_SPINDLE()
01460 {
01461 if (emcStatus->io.spindle.speed == 0)
01462 {
01463 return CANON_STOPPED;
01464 }
01465
01466 if (emcStatus->io.spindle.speed >= 0.0)
01467 {
01468 return CANON_CLOCKWISE;
01469 }
01470
01471 return CANON_COUNTERCLOCKWISE;
01472 }
01473
01474 int GET_EXTERNAL_TOOL_MAX()
01475 {
01476 return CANON_TOOL_MAX;
01477 }
01478
01479
01480
01481 #ifdef NEW_INTERPRETER
01482
01483 char _parameter_file_name[PARAMETER_FILE_NAME_LENGTH];
01484
01485 void GET_EXTERNAL_PARAMETER_FILE_NAME(
01486 char * file_name,
01487 int max_size)
01488 {
01489
01490 if( 0 == file_name )
01491 return;
01492
01493 if(max_size < 0)
01494 return;
01495
01496 if (strlen(_parameter_file_name) < ((size_t )max_size))
01497 strcpy(file_name, _parameter_file_name);
01498 else
01499 file_name[0] = 0;
01500 }
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522 #include "inifile.h"
01523
01524 int rs274ngc_ini_load(const char *filename)
01525 {
01526 INIFILE inifile;
01527 const char *inistring;
01528
01529
01530 if (-1 == inifile.open(filename))
01531 {
01532 return -1;
01533 }
01534
01535 if (NULL != (inistring = inifile.find("PARAMETER_FILE", "RS274NGC")))
01536 {
01537
01538 strncpy(_parameter_file_name, inistring,PARAMETER_FILE_NAME_LENGTH);
01539 }
01540 else
01541 {
01542
01543 }
01544
01545
01546 inifile.close();
01547
01548 return 0;
01549 }
01550
01551
01552 double GET_EXTERNAL_POSITION_X(void)
01553 {
01554 CANON_POSITION position;
01555 position = GET_EXTERNAL_POSITION();
01556 return position.x;
01557 }
01558
01559 double GET_EXTERNAL_POSITION_Y(void)
01560 {
01561 CANON_POSITION position;
01562 position = GET_EXTERNAL_POSITION();
01563 return position.y;
01564 }
01565
01566 double GET_EXTERNAL_POSITION_Z(void)
01567 {
01568 CANON_POSITION position;
01569 position = GET_EXTERNAL_POSITION();
01570 return position.z;
01571 }
01572
01573
01574 double GET_EXTERNAL_POSITION_A(void)
01575 {
01576 CANON_POSITION position;
01577 position = GET_EXTERNAL_POSITION();
01578 return position.a;
01579 }
01580
01581
01582 double GET_EXTERNAL_POSITION_B(void)
01583 {
01584 CANON_POSITION position;
01585 position = GET_EXTERNAL_POSITION();
01586 return position.b;
01587 }
01588
01589
01590 double GET_EXTERNAL_POSITION_C(void)
01591 {
01592 CANON_POSITION position;
01593 position = GET_EXTERNAL_POSITION();
01594 return position.c;
01595 }
01596
01597
01598
01599 double GET_EXTERNAL_PROBE_POSITION_X(void)
01600 {
01601 CANON_POSITION position;
01602 position = GET_EXTERNAL_PROBE_POSITION();
01603 return position.x;
01604 }
01605
01606 double GET_EXTERNAL_PROBE_POSITION_Y(void)
01607 {
01608 CANON_POSITION position;
01609 position = GET_EXTERNAL_PROBE_POSITION();
01610 return position.y;
01611 }
01612
01613 double GET_EXTERNAL_PROBE_POSITION_Z(void)
01614 {
01615 CANON_POSITION position;
01616 position = GET_EXTERNAL_PROBE_POSITION();
01617 return position.z;
01618 }
01619
01620 double GET_EXTERNAL_PROBE_POSITION_A(void)
01621 {
01622 CANON_POSITION position;
01623 position = GET_EXTERNAL_PROBE_POSITION();
01624 return position.a;
01625 }
01626
01627 double GET_EXTERNAL_PROBE_POSITION_B(void)
01628 {
01629 CANON_POSITION position;
01630 position = GET_EXTERNAL_PROBE_POSITION();
01631 return position.b;
01632 }
01633
01634 double GET_EXTERNAL_PROBE_POSITION_C(void)
01635 {
01636 CANON_POSITION position;
01637 position = GET_EXTERNAL_PROBE_POSITION();
01638 return position.c;
01639 }
01640
01641
01642 CANON_MOTION_MODE GET_EXTERNAL_MOTION_CONTROL_MODE()
01643 {
01644 return canonMotionMode;
01645 }
01646
01647 CANON_UNITS GET_EXTERNAL_LENGTH_UNIT_TYPE()
01648 {
01649 return lengthUnits;
01650 }
01651
01652 int GET_EXTERNAL_QUEUE_EMPTY(void)
01653 {
01654 return emcStatus->motion.traj.queue == 0 ? 1 : 0;
01655 }
01656
01657 int GET_EXTERNAL_TOOL_SLOT()
01658 {
01659 return emcStatus->io.tool.toolInSpindle;
01660 }
01661
01662 CANON_PLANE GET_EXTERNAL_PLANE()
01663 {
01664 return activePlane;
01665 }
01666
01667
01668 #endif // NEW_INTERPRETER