Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

world.cpp

Go to the documentation of this file.
00001 #include "stdafx.h"
00002 
00003 #include "ippdme/world.h"
00004 
00005 #include "ippdme/Command/commands.h"
00006 #include "ippdme/Property/ippOnePropertyAlignment.h"
00007 #include "ippdme/ippPtMeasPars.h"
00008 #include "ippdme/ippGoToPars.h"
00009 #include "ippdme/assert.h"
00010 
00011 
00012 #include <stdio.h>
00013 
00014 
00015 #ifdef _DEBUG
00016 #define new DEBUG_NEW
00017 #undef THIS_FILE
00018 static char THIS_FILE[] = __FILE__;
00019 #endif
00020 
00021 
00022 
00023 
00024  
00025 
00026 
00027 
00028 /*******************************************************************/
00029 
00030 /* world::getCurrentAlignment
00031 
00032 This makes a OnePropertyAlignment and returns a pointer to it. The
00033 OnePropertyAlignment is made from alignment1 and alignment2 (which
00034 belong to the world's toolChanger) converted into the current
00035 coordinate system (which belongs to the world). This function is
00036 defined to make it easy to construct a response to a
00037 GetProp(Tool.Alignment()) command.
00038 
00039 */
00040 
00041 ippOnePropertyAlignmentPtr world::getCurrentAlignment() 
00042 {
00043   double i1;             /* i1 of OnePropertyAlignment in current csy  */
00044   double j1;             /* j1 of OnePropertyAlignment in current csy  */
00045   double k1;             /* k1 of OnePropertyAlignment in current csy  */
00046   double i2;             /* i2 of OnePropertyAlignment in current csy  */
00047   double j2;             /* j2 of OnePropertyAlignment in current csy  */
00048   double k2;             /* k2 of OnePropertyAlignment in current csy  */
00049   bool has2;             /* has2 of OnePropertyAlignment               */
00050    ippCsyTransform * theSys; /* current coordinate system transform        */
00051   double mi;             /* i component in machine coordinates         */
00052   double mj;             /* j component in machine coordinates         */
00053   double mk;             /* k component in machine coordinates         */
00054 
00055   theSys = ((_Csy == MoveableMachineCsy) ? &_csyMoveable :
00056       (_Csy == MultipleArmCsy) ? &_csyMultiple :
00057       (_Csy == PartCsy) ? &_csyPart :
00058       NULL); /* for MachineCsy */
00059   mi = getTools()->getAlignment1().getI();
00060   mk = getTools()->getAlignment1().getJ();
00061   mj = getTools()->getAlignment1().getK();
00062 
00063   if (theSys)
00064     {
00065       i1 = theSys->fwdDirectionX(mi, mj, mk);
00066       j1 = theSys->fwdDirectionY(mi, mj, mk);
00067       k1 = theSys->fwdDirectionZ(mi, mj, mk);
00068     }
00069   else
00070     {
00071       i1 = mi;
00072       j1 = mj;
00073       k1 = mk;
00074     }
00075   mi = getTools()->getAlignment2().getI();
00076   mk = getTools()->getAlignment2().getJ();
00077   mj = getTools()->getAlignment2().getK();
00078 
00079   ippOnePropertyAlignmentPtr prop;
00080   if ((mi == 0) && (mj == 0) && (mk == 0))
00081     {
00082       has2 = false;
00083       i2 = 0.0;
00084       j2 = 0.0;
00085       k2 = 0.0;
00086       prop = new ippOnePropertyAlignment(Tool,i1, j1, k1);
00087     }
00088   else if (theSys)
00089     {
00090       has2 = true;
00091       i2 = theSys->fwdDirectionX(mi, mj, mk);
00092       j2 = theSys->fwdDirectionY(mi, mj, mk);
00093       k2 = theSys->fwdDirectionZ(mi, mj, mk);
00094       prop = new ippOnePropertyAlignment(Tool,i1, j1, k1, i2, j2, k2);
00095     }
00096   else
00097     {
00098       has2 = true;
00099       i2 = mi;
00100       j2 = mj;
00101       k2 = mk;
00102        prop = new ippOnePropertyAlignment(Tool,i1, j1, k1, i2, j2, k2);
00103    }
00104   return prop;
00105 }
00106 
00107 /*******************************************************************/
00108 
00109 /* world::inWorkVolume
00110 
00111 This returns true if point (x,y,z) is in the work volume of the
00112 machine and false if not. The point (x,y,z) is given in terms of the
00113 current coordinate system.
00114 
00115 This is not currently correcting for the tool offset. That should be
00116 added. A long tool offset may put the CMM mechanism out of bounds
00117 while the tool tip is still in bounds (or vice versa).
00118 
00119 */
00120 
00121 bool world::inWorkVolume(
00122  double x,
00123  double y,
00124  double z) const
00125 {
00126   const ippCsyTransform * theSys; /* current coordinate system transform */
00127   double mx;             /* current X in machine coordinates    */
00128   double my;             /* current Y in machine coordinates    */
00129   double mz;             /* current Z in machine coordinates    */
00130 
00131   theSys = ((_Csy == MoveableMachineCsy) ? &_csyMoveable :
00132       (_Csy == MultipleArmCsy) ? &_csyMultiple :
00133       (_Csy == PartCsy) ? &_csyPart :
00134       NULL); /* for MachineCsy */
00135   if (theSys)
00136     {
00137       mx = theSys->invPointX(x, y, z);
00138       my = theSys->invPointY(x, y, z);
00139       mz = theSys->invPointZ(x, y, z);
00140     }
00141   else
00142     {
00143       mx = x;
00144       my = y;
00145       mz = z;
00146     }
00147   return (bool)((mx > _limitLowerX) && (mx < _limitUpperX) &&
00148     (my > _limitLowerY) && (my < _limitUpperY) &&
00149     (mz > _limitLowerZ) && (mz < _limitUpperZ));
00150 }
00151 
00152 /*******************************************************************/
00153 
00154 /* world::update
00155 
00156 This update function updates the world model to what it should be
00157 after the ippCommand (that is the argument to update) is fully executed.
00158 This is a crude simulation, since every command appears to execute
00159 instantaneously. For better simulations, for example when commands
00160 that take time (all motion commands) are executed, the simulation
00161 program should either (1) not call update until the motion is ended
00162 or (2) not call update at all if the simulation is updating the
00163 world gradually itself.
00164 
00165 If the modifications to the world model are simple, this function
00166 updates the model itself. If the modifications are not simple, this
00167 calls a subordinate function to do the updating.
00168 
00169 The userEnabled flag is set to false only by a DisableUser command.
00170 It is not clear in the discussion on pages 39, 42, 44 of the spec
00171 whether the flag should also be set to false in other situations
00172 (such as GoTo or PtMeas being executed).
00173 
00174 This is assuming ChangeTool does not change the FoundTool.
00175 
00176 This assumes that if ChangeTool is called and the named tool is not
00177 known, nothing will change. An alternative is to remove the current
00178 tool but replace it with nothing (in which case the active tool would
00179 be NoTool after the command was executed).
00180 
00181 This assumes that if FindTool is called and the named tool is not
00182 found, nothing will change. An alternative is to have the found tool
00183 be NoTool after the command is executed.
00184 
00185 Executing AbortE should flush the slow command queue, but that is
00186 not implemented here on the assumption that the queue is being
00187 moved out of the world into the server.
00188 
00189 Changing the Tool will normally change the location of the controlled
00190 point, but this is not being modeled here.
00191 
00192 The AlignPart command should probably update currentR, but it is not
00193 clear how this should be done, and it is not currently being done.
00194 
00195 In the case of CenterPart, the spec (page 96) says the relationship
00196 between machine coordinates and part coordinates is lost. Here, we
00197 are not updating the world in any way when CenterPart is executed.
00198 TiltCenterPart and TiltPart also do not change the world.
00199 
00200 */
00201 
00202 void world::update(
00203  ippCommandConstPtr aCommand
00204 )
00205 {
00206   _outOfRangeFlag = false;
00207   switch (aCommand->getCommandName())
00208     {
00209     case AbortE:
00210       _readiness = aborted;
00211       break;
00212     case AlignPart:
00213       break;
00214     case AlignTool:
00215       updateAlignTool(static_cast<const ippAlignToolCommand*>(aCommand.get()));
00216       break;
00217     case CenterPart:
00218       break;
00219     case ChangeTool:
00220       updateChangeTool(static_cast<const ippChangeToolCommand *>(aCommand.get()));
00221       break;
00222     case ClearAllErrors:
00223       _readiness = ready;
00224       break;
00225     case DisableUser:
00226       _userEnabled = false;
00227       break;
00228     case EnableUser:
00229       _userEnabled = true;
00230       break;
00231     case EndSession:
00232       updateEndSession();
00233       break;
00234     case EnumAllProp:
00235       break;
00236     case EnumProp:
00237       break;
00238     case EnumTools:
00239       break;
00240     case FindTool:
00241       {
00242         const ippFindToolCommand * theFind =
00243           static_cast<const ippFindToolCommand *>(aCommand.get());
00244         getTools()->setFoundTool(getTools()->findTool(theFind->getToolName()));
00245       }
00246       break;
00247     case Get:
00248       break;
00249     case GetChangeToolAction:
00250       break;
00251     case GetCoordSystem:
00252       break;
00253     case GetCsyTransformation:
00254       break;
00255     case GetDMEVersion:
00256       break;
00257     case ipp::GetErrorInfo:
00258       break;
00259     case GetErrStatusE:
00260       break;
00261     case GetMachineClass:
00262       break;
00263     case ipp::GetProp:
00264       break;
00265     case GetPropE:
00266       break;
00267     case GetXtdErrStatus:
00268       break;
00269     case GoTo:
00270       { 
00271         const ippGoToCommand * theGoTo = static_cast<const ippGoToCommand*>(aCommand.get());
00272         if (theGoTo->getHasX()) {
00273           _currentX = theGoTo->getX();
00274         }
00275         if (theGoTo->getHasY()) {
00276           _currentY = theGoTo->getY();
00277         }
00278         if (theGoTo->getHasZ()){
00279           _currentZ = theGoTo->getZ();
00280         }
00281       } break;
00282 
00283     case Home:
00284       updateHome();
00285       break;
00286     case IsHomed:
00287       break;
00288     case IsUserEnabled:
00289       break;
00290     case LockAxis:
00291       updateLockAxis(static_cast<const ippLockAxisCommand*>(aCommand.get()));
00292       break;
00293     case OnMoveReportE:
00294       updateOnMoveReportE(static_cast<const ippOnMoveReportECommand*>(aCommand.get()));
00295       break;
00296     case OnPtMeasReport:
00297       updateOnPtMeasReport(static_cast<const ippOnPtMeasReportCommand*>(aCommand.get()));
00298       break;
00299     case OnScanReport:
00300       updateOnScanReport(static_cast<const ippOnScanReportCommand*>(aCommand.get()));
00301       break;
00302     case PtMeas:
00303       updatePtMeas(static_cast<const ippPtMeasCommand*>(aCommand.get()));
00304       break;
00305     case ReQualify:
00306       if ((getTools()->getActiveTool() != getTools()->getUnDefTool()) &&
00307         (getTools()->getActiveTool() != getTools()->getNoTool())) {
00308           getTools()->getActiveTool()->setIsQualified(true);
00309         }
00310       break;
00311     case ScanInCylEndIsPlane:
00312       updateScanInCylEndIsPlane(static_cast<const ippScanInCylEndIsPlaneCommand*>(aCommand.get()));
00313       break;
00314 
00315     case ScanInCylEndIsSphere:
00316       updateScanInCylEndIsSphere(static_cast<const ippScanInCylEndIsSphereCommand*>(aCommand.get()));
00317       break;
00318 
00319     case ScanInPlaneEndIsCyl:
00320       updateScanInPlaneEndIsCyl(static_cast<const ippScanInPlaneEndIsCylCommand*>(aCommand.get()));
00321 
00322       break;
00323     case ScanInPlaneEndIsPlane:
00324       updateScanInPlaneEndIsPlane(static_cast<const ippScanInPlaneEndIsPlaneCommand*>(aCommand.get()));
00325       break;
00326     case ScanInPlaneEndIsSphere:
00327       updateScanInPlaneEndIsSphere(static_cast<const ippScanInPlaneEndIsSphereCommand*>(aCommand.get()));
00328       break;
00329     case ScanOnCircle:
00330       updateScanOnCircle(static_cast<const ippScanOnCircleCommand*>(aCommand.get()));
00331       break;
00332     case ScanOnCircleHint:
00333       break;
00334     case ScanOnLine:
00335       updateScanOnLine(static_cast<const ippScanOnLineCommand*>(aCommand.get()));
00336       break;
00337     case ScanOnLineHint:
00338       break;
00339     case ScanUnknownHint:
00340       break;
00341     case SetCoordSystem:
00342       updateSetCoordSystem(static_cast<const ippSetCoordSystemCommand *>(aCommand.get()));
00343       break;
00344     case SetCsyTransformation:
00345       updateSetCsyTransformation(static_cast<const ippSetCsyTransformationCommand *>(aCommand.get()));
00346       break;
00347     case ipp::SetProp:
00348       updateSetProp(static_cast<const ippSetPropCommand *>(aCommand.get()));
00349       break;
00350     case SetTool:
00351       {
00352         const ippSetToolCommand * theSet = static_cast<const ippSetToolCommand *>(aCommand.get());
00353         getTools()->setActiveTool(getTools()->findTool(theSet->getToolName()));
00354       } break;
00355 
00356     case StartSession:
00357       updateStartSession();
00358       break;
00359     case StopAllDaemons:
00360       IPP_ASSERT_FAIL("not expected");
00361       break;
00362     case StopDaemon:
00363       IPP_ASSERT_FAIL("not expected");
00364       break;
00365     case TiltCenterPart:
00366       break;
00367     case TiltPart:
00368       break;
00369     default: // should never get here
00370       IPP_ASSERT_FAIL("Bug in update - unknown command\n");
00371       break;
00372     }
00373 }
00374 
00375 /*******************************************************************/
00376 
00377 /* world::updateAlignTool
00378 
00379 This sets the alignment of the current tool (in the getTools()). This
00380 does not set any angles of the current tool because its geometry is
00381 unknown.
00382 
00383 The command gives the alignment in the current coordinate system, but
00384 the data is stored in machine coordinates, so the data is transformed
00385 (if necessary) before being stored.
00386 
00387 */
00388 
00389 void world::updateAlignTool(
00390  const ippAlignToolCommand * theAlignTool
00391 )
00392 {
00393   double i;              /* i component in current csy          */
00394   double j;              /* j component in current csy          */
00395   double k;              /* k component in current csy          */
00396   ippCsyTransform * theSys; /* current coordinate system transform */
00397   double mi;             /* i component in machine coordinates  */
00398   double mj;             /* j component in machine coordinates  */
00399   double mk;             /* k component in machine coordinates  */
00400 
00401   theSys = ((_Csy == MoveableMachineCsy) ? &_csyMoveable :
00402       (_Csy == MultipleArmCsy) ? &_csyMultiple :
00403       (_Csy == PartCsy) ? &_csyPart :
00404       NULL); /* for MachineCsy */
00405   i = theAlignTool->getVector1i();
00406   j = theAlignTool->getVector1j();
00407   k = theAlignTool->getVector1k();
00408   if (theSys)
00409     {
00410       mi = theSys->invDirectionX(i, j, k);
00411       mj = theSys->invDirectionY(i, j, k);
00412       mk = theSys->invDirectionZ(i, j, k);
00413       getTools()->getAlignment1().setValues(mi, mj, mk);
00414     }
00415   else
00416     getTools()->getAlignment1().setValues(i, j, k);
00417   if (theAlignTool->getHas2())
00418     {
00419       i = theAlignTool->getVector2i();
00420       j = theAlignTool->getVector2j();
00421       k = theAlignTool->getVector2k();
00422       if (theSys)
00423   {
00424     mi = theSys->invDirectionX(i, j, k);
00425     mj = theSys->invDirectionY(i, j, k);
00426     mk = theSys->invDirectionZ(i, j, k);
00427     getTools()->getAlignment2().setValues(mi, mj, mk);
00428   }
00429       else
00430   getTools()->getAlignment2().setValues(i, j, k);
00431     }
00432 }
00433 
00434 /*******************************************************************/
00435 
00436 /* world::updateChangeTool
00437 
00438 Executing ChangeTool changes the tool and unlocks all axes (see
00439 page 98 concerning locking axes). It also resets alignment1 of the
00440 world's toolChanger to (0, 0, 1) and alignment2 to (0, 0, 0).
00441 
00442 */
00443 
00444 void world::updateChangeTool(
00445  const ippChangeToolCommand * theChangeTool)
00446 {
00447   getTools()->setActiveTool(getTools()->findTool(theChangeTool->getToolName()));
00448   _lockedC = false;
00449   _lockedPhi = false;
00450   _lockedR = false;
00451   _lockedX = false;
00452   _lockedY = false;
00453   _lockedZ= false;
00454   getTools()->getAlignment1().setValues(0, 0, 1);
00455   getTools()->getAlignment2().setValues(0, 0, 0);
00456 }
00457 
00458 /*******************************************************************/
00459 
00460 /* world::updateEndSession
00461 
00462 This:
00463 1. kills any on-move daemon (by setting onMoveTagNumber to zero).
00464 2. resets all the onMove items to false (spec does not say what to do)
00465 3. sets onPtmeasHasX, onPtmeasHasY, and onPtmeasHasZ to true
00466    and all other onPtmeas items to false (see page 41).
00467 4. set onScanHasQ, onScanHasX, onScanHasY, and onScanHasZ to true
00468    and all other onScan items to false (see page 41).
00469 5. sets inSession to false.
00470 6. sets isHomed to false (but we may want to change this).
00471 
00472 This does NOT change:
00473 1. readiness.
00474 2. userEnabled.
00475 3. locking of axes (see page 98, which does not say what to do).
00476 
00477 It probably is not actually necessary to reset anything except
00478 inSession, since StartSession does the same things this does, except
00479 for the way it sets inSession. 
00480 
00481 */
00482 
00483 void world::updateEndSession()
00484 {
00485   _isHomed = false;
00486   
00487   stopAllDaemons();
00488   _OnScanReportCmd = 0;
00489   _OnPtMeasReportCmd = 0;
00490   
00491 }
00492 
00493 /*******************************************************************/
00494 
00495 /* world::updateHome
00496 
00497 The spec says the Home command results in moving to a fixed home
00498 location. Here we assume the Home command leaves the controlled point
00499 for NoTool at (homeX, homeY, homeZ) in the machine coordinate system. The
00500 values in the current coordinate system are calculated and stored in
00501 currentX, currentY, and currentZ. This really should also be
00502 adjusted for the offset of the current tool, but that is not being
00503 done here.
00504 
00505 */
00506 
00507 void world::updateHome()
00508 {
00509   ippCsyTransform * theSys;
00510 
00511   _isHomed = true;
00512   theSys = ((_Csy == MoveableMachineCsy) ? &_csyMoveable :
00513       (_Csy == MultipleArmCsy) ? &_csyMultiple :
00514       (_Csy == PartCsy) ? &_csyPart :
00515       NULL); /* for MachineCsy */
00516   if (theSys)
00517     {
00518       _currentX = theSys->fwdPointX(_homeX, _homeY, _homeZ);
00519       _currentY = theSys->fwdPointY(_homeX, _homeY, _homeZ);
00520       _currentZ = theSys->fwdPointZ(_homeX, _homeY, _homeZ);
00521     }
00522   else
00523     {
00524       _currentX = _homeX;
00525       _currentY = _homeY;
00526       _currentZ = _homeZ;
00527     }
00528 }
00529 
00530 /*******************************************************************/
00531 
00532 /* world::updateLockAxis
00533 
00534 The LockAxis command is described on page 98. It has the following
00535 problems, which are handled has described here. The basic approach is
00536 to set the axis to locked if any LockAxis command locks it, to unlock
00537 all axes when a tool is changed, and otherwise to ignore whether an
00538 axis is locked or not.
00539 
00540 1. The only way to unlock an axis is with a ChangeTool ippCommand.
00541 This seems unwise.
00542 
00543 2. The spec does not say whether the axis being locked is an actual
00544 hardware axis, which would normally be an MCS axis, or whether the
00545 axis being locked is an axis in the current coordinate system (which
00546 would be implemented in software). Here, it does not matter, since
00547 locking axes has no effect except to change lockedness.
00548 
00549 3. The spec says axis motion on locked axes will be disabled even
00550 for those commands that explicitly move the axis, and no error should
00551 be reported in this case. This seems very risky. For commands like
00552 PtMeas, what to do if an axis is locked is not specified, so that the
00553 spec is ambiguous. Here, all motion commands are executed the same
00554 whether axes are locked or not.
00555 
00556 4. The spec does not say whether the lockedness of an axis persists
00557 between sessions. Here it does persist.
00558 
00559 5. The spec includes locking a Phi axis. The Phi axis is not defined
00560 anywhere.
00561 
00562 6. The spec says "Locking Phi() will only enable moves in R, Z, and C."
00563 It is not clear whether this is intended to mean that locking Phi
00564 also locks X and Y. It is not clear whether locking Phi unlocks R, Z
00565 and C. Here, locking Phi only locks Phi; it does not lock or unlock any
00566 other axis.
00567 
00568 */
00569 
00570 void world::updateLockAxis(
00571  const ippLockAxisCommand * theLockAxis
00572 )
00573 {
00574   if (theLockAxis->getHasC())
00575     _lockedC = true;
00576   if (theLockAxis->getHasPhi())
00577     _lockedPhi = true;
00578   if (theLockAxis->getHasR())
00579     _lockedR = true;
00580   _lockedX = false;
00581   _lockedY = false;
00582   _lockedZ= false;
00583 }
00584 
00585 /*******************************************************************/
00586 
00587 /* world::updateOnMoveReportE
00588 
00589 */
00590 
00591 void world::updateOnMoveReportE(
00592  const ippOnMoveReportECommand * theOnMove)
00593 {
00594   addDaemon(theOnMove);
00595 }
00596 
00597 /*******************************************************************/
00598 
00599 /* world::updateOnPtMeasReport
00600 
00601 */
00602 
00603 void world::updateOnPtMeasReport(
00604  const ippOnPtMeasReportCommand * theOnPtMeas
00605 )
00606 {
00607   _OnPtMeasReportCmd = const_cast<ippOnPtMeasReportCommand*>(theOnPtMeas);
00608 }
00609 
00610 ippOnPtMeasReportCommandConstPtr world::getOnPtMeasReportCommand() const
00611 {
00612   return _OnPtMeasReportCmd;
00613 }
00614 
00615 /*******************************************************************/
00616 
00617 /* world::updateOnScanReport
00618 
00619 */
00620 
00621 void world::updateOnScanReport(
00622  const ippOnScanReportCommand * theOnScan
00623 )
00624 {
00625   _OnScanReportCmd = const_cast<ippOnScanReportCommand*>(theOnScan);
00626 }
00627 
00628 ippOnScanReportCommandConstPtr world::getOnScanReportCommand() const
00629 {
00630   return _OnScanReportCmd;
00631 }
00632 
00633 
00634 /*******************************************************************/
00635 
00636 /* world::updatePtMeas
00637 
00638 For each of X, Y, and Z specified in the PtMeas, this sets the
00639 measuredX1, measuredY1, or measuredZ1 to the value specified by the
00640 PtMeas. If any of X, Y, or Z is not specified in the PtMeas, the
00641 corresponding measured coordinate continues to have its current
00642 value. The effect of this is that the 1st measured point is reported
00643 to be exactly at the nominal point. This sets pointTag to the tag
00644 number of the tag of the PtMeas to indicate that a point was found
00645 during execution of the PtMeas.
00646 
00647 As specified on page 43 of the spec, if the retract distance for the
00648 current tool is negative, this sets the current location after the
00649 PtMeas to be at the approach point. If the retract distance is not
00650 negative, this sets the current location to be one retract distance
00651 in the IJK direction from the nominal point.
00652 
00653 The details of this are a little messy because IJK may or may not be
00654 specified in the PtMeas, and the function is written so it will not
00655 crash the system in case of two errors (1) the active tool is NoTool
00656 or UnDefTool or (2) the nominal point is the current point. Both of
00657 these errors should be detected earlier and never occur here, but
00658 it is best to be prepared. If either error occurs, the current
00659 location after the PtMeas is set to the nominal point.
00660 
00661 */
00662 
00663 void world::updatePtMeas(
00664  const ippPtMeasCommand * thePtMeas
00665 )
00666 {
00667   double i;
00668   double j;
00669   double k;
00670   double length; /* length of IJK */
00671   double move;   /* how far to move away after PtMeas */
00672 
00673   _measuredX1 = ((thePtMeas->getHasX()) ? thePtMeas->getX() : _currentX);
00674   _measuredY1 = ((thePtMeas->getHasY()) ? thePtMeas->getY() : _currentY);
00675   _measuredZ1 = ((thePtMeas->getHasZ()) ? thePtMeas->getZ() : _currentZ);
00676   _pointTag = thePtMeas->getTag().getTagNumber();
00677   if ((getTools()->getActiveTool() == getTools()->getUnDefTool()) ||
00678       (getTools()->getActiveTool() == getTools()->getNoTool()))
00679     move = 0;
00680   else
00681     move = getTools()->getActiveTool()->getPtMeasPar()->getActRetract();
00682   if (move < 0)
00683     move = getTools()->getActiveTool()->getPtMeasPar()->getActApproach();
00684   if (thePtMeas->getHasIJK())
00685     {
00686       i = thePtMeas->getI();
00687       j = thePtMeas->getJ();
00688       k = thePtMeas->getK();
00689     }
00690   else
00691     {
00692       i = (_currentX - _measuredX1);
00693       j = (_currentY - _measuredY1);
00694       k = (_currentZ - _measuredZ1);
00695     }
00696   length = sqrt((i * i) + (j * j) + (k * k));
00697   if (length == 0)
00698     {
00699       _currentX = _measuredX1;
00700       _currentY = _measuredY1;
00701       _currentZ = _measuredZ1;
00702     }
00703   else
00704     {
00705       _currentX = (_measuredX1 + (move * (i/length)));
00706       _currentY = (_measuredY1 + (move * (j/length)));
00707       _currentZ = (_measuredZ1 + (move * (k/length)));
00708     }
00709 }
00710 
00711 /*******************************************************************/
00712 
00713 /* world::updateScanInCylEndIsPlane
00714 
00715 This sets:
00716 1st measured point to the start point of the scan
00717 2nd measured point to the direction point of the scan
00718 3rd measured point to the defining point of the stop plane
00719 current point to the defining point of the stop plane
00720 
00721 The three measured points can be used to construct a data response.
00722 
00723 The definition of the scan does not provide an end point, so the
00724 point on the plane is used instead. This is the least bad of the
00725 several bad choices available for updating the current point.
00726 
00727 */
00728 
00729 void world::updateScanInCylEndIsPlane(
00730  const ippScanInCylEndIsPlaneCommand * theScan
00731 )
00732 {
00733   _measuredX1 = theScan->getSx();
00734   _measuredY1 = theScan->getSy();
00735   _measuredZ1 = theScan->getSz();
00736   _measuredX2 = theScan->getDx();
00737   _measuredY2 = theScan->getDy();
00738   _measuredZ2 = theScan->getDz();
00739   _measuredX3 = theScan->getPx();
00740   _measuredY3 = theScan->getPy();
00741   _measuredZ3 = theScan->getPz();
00742   _currentX = theScan->getPx();
00743   _currentY = theScan->getPy();
00744   _currentZ = theScan->getPz();
00745 }
00746 
00747 
00748 /*******************************************************************/
00749 
00750 /* world::updateScanInCylEndIsSphere
00751 
00752 This sets:
00753 1st measured point to the start point of the scan
00754 2nd measured point to the direction point of the scan
00755 3rd measured point to the center point of the stop sphere
00756 current point to the center point of the stop sphere
00757 
00758 The three measured points can be used to construct a data response.
00759 
00760 The definition of the scan does not provide an end point, so the
00761 center point of the stop sphere is used instead. This is probably
00762 a reasonable point to use, even though it is not necessarily the
00763 end point of the scan.
00764 
00765 */
00766 
00767 void world::updateScanInCylEndIsSphere(
00768  const ippScanInCylEndIsSphereCommand * theScan
00769 )
00770 {
00771   _measuredX1 = theScan->getSx();
00772   _measuredY1 = theScan->getSy();
00773   _measuredZ1 = theScan->getSz();
00774   _measuredX2 = theScan->getDx();
00775   _measuredY2 = theScan->getDy();
00776   _measuredZ2 = theScan->getDz();
00777   _measuredX3 = theScan->getEx();
00778   _measuredY3 = theScan->getEy();
00779   _measuredZ3 = theScan->getEz();
00780   _currentX = theScan->getEx();
00781   _currentY = theScan->getEy();
00782   _currentZ = theScan->getEz();
00783 }
00784 
00785 /*******************************************************************/
00786 
00787 /* world::updateScanInPlaneEndIsCyl
00788 
00789 This sets:
00790 1st measured point to the start point of the scan
00791 2nd measured point to the direction point of the scan
00792 3rd measured point to the axis point of the stop cylinder
00793 current point to the axis point of the stop cylinder
00794 
00795 The three measured points can be used to construct a data response.
00796 
00797 The definition of the scan does not provide an end point, so the
00798 center point of the stop cylinder is used instead. This is the least
00799 bad choice.
00800 
00801 */
00802 
00803 void world::updateScanInPlaneEndIsCyl(
00804  const ippScanInPlaneEndIsCylCommand * theScan
00805 )
00806 {
00807   _measuredX1 = theScan->getSx();
00808   _measuredY1 = theScan->getSy();
00809   _measuredZ1 = theScan->getSz();
00810   _measuredX2 = theScan->getDx();
00811   _measuredY2 = theScan->getDy();
00812   _measuredZ2 = theScan->getDz();
00813   _measuredX3 = theScan->getCx();
00814   _measuredY3 = theScan->getCy();
00815   _measuredZ3 = theScan->getCz();
00816   _currentX = theScan->getCx();
00817   _currentY = theScan->getCy();
00818   _currentZ = theScan->getCz();
00819 }
00820 
00821 /*******************************************************************/
00822 
00823 /* world::updateScanInPlaneEndIsPlane
00824 
00825 This sets:
00826 1st measured point to the start point of the scan
00827 2nd measured point to the direction point of the scan
00828 3rd measured point to the definition point of the stop plane
00829 current point to the definition point of the stop plane
00830 
00831 The three measured points can be used to construct a data response.
00832 
00833 The definition of the scan does not provide an end point, so the
00834 definition point of the stop plane is used instead. This is the least
00835 bad choice.
00836 
00837 */
00838 
00839 void world::updateScanInPlaneEndIsPlane(
00840  const ippScanInPlaneEndIsPlaneCommand * theScan
00841 )
00842 {
00843   _measuredX1 = theScan->getSx();
00844   _measuredY1 = theScan->getSy();
00845   _measuredZ1 = theScan->getSz();
00846   _measuredX2 = theScan->getDx();
00847   _measuredY2 = theScan->getDy();
00848   _measuredZ2 = theScan->getDz();
00849   _measuredX3 = theScan->getPx();
00850   _measuredY3 = theScan->getPy();
00851   _measuredZ3 = theScan->getPz();
00852   _currentX = theScan->getPx();
00853   _currentY = theScan->getPy();
00854   _currentZ = theScan->getPz();
00855 }
00856 
00857 /*******************************************************************/
00858 
00859 /* world::updateScanInPlaneEndIsSphere
00860 
00861 This sets:
00862 1st measured point to the start point of the scan
00863 2nd measured point to the direction point of the scan
00864 3rd measured point to the end point of the scan
00865 current point to the end point of the scan
00866 
00867 The three measured points can be used to construct a data response.
00868 
00869 */
00870 
00871 void world::updateScanInPlaneEndIsSphere(
00872  const ippScanInPlaneEndIsSphereCommand * theScan
00873 )
00874 {
00875   _measuredX1 = theScan->getSx();
00876   _measuredY1 = theScan->getSy();
00877   _measuredZ1 = theScan->getSz();
00878   _measuredX2 = theScan->getDx();
00879   _measuredY2 = theScan->getDy();
00880   _measuredZ2 = theScan->getDz();
00881   _measuredX3 = theScan->getEx();
00882   _measuredY3 = theScan->getEy();
00883   _measuredZ3 = theScan->getEz();
00884   _currentX = theScan->getEx();
00885   _currentY = theScan->getEy();
00886   _currentZ = theScan->getEz();
00887 }
00888 
00889 /*******************************************************************/
00890 
00891 /* world::updateScanOnCircle
00892 
00893 This sets:
00894 1st measured point to the start point of the scan
00895 2nd measured point to the direction point of the scan
00896 3rd measured point to the end point of the scan
00897 current point to the end point of the scan
00898 
00899 The three measured points can be used to construct a data response.
00900 
00901 The end point of the scan is not given and must be calculated from
00902 the given data. The calculation is based on the usual method of
00903 converting translated polar coordinates to cartesian coordinates
00904 in the XY plane.
00905 P = C + ((r * cos(angle))X + (r * sin(angle))Y)
00906 where C is the translation, X is the unit vector on the X-axis and
00907 Y is the unit vector on the Y-axis.
00908 
00909 Here, X is replaced by the vector R from the center of the circle to
00910 the start point, and Y is replaced by V = NxR normalized, (cross product)
00911 where N is the normal to the plane of the circle.
00912 
00913 This is not checking for R or N being zero. That is done by the
00914 command checker, and the command checker should have been run before
00915 this is called.
00916 
00917 
00918 */
00919 
00920 void world::updateScanOnCircle(
00921  const ippScanOnCircleCommand * theScan
00922 )
00923 {
00924   double Rx;
00925   double Ry;
00926   double Rz;
00927   double Nx;
00928   double Ny;
00929   double Nz;
00930   double Vx;
00931   double Vy;
00932   double Vz;
00933   double Dx;
00934   double Dy;
00935   double Dz;
00936   double Ex;
00937   double Ey;
00938   double Ez;
00939   double r;
00940   double n;
00941   double angle;
00942 
00943   Rx = (theScan->getSx() - theScan->getCx());
00944   Ry = (theScan->getSy() - theScan->getCy());
00945   Rz = (theScan->getSz() - theScan->getCz());
00946   r = sqrt((Rx * Rx) + (Ry * Ry) + (Rz * Rz));
00947   Rx = (Rx / r);
00948   Ry = (Ry / r);
00949   Rz = (Rz / r);
00950   Nx = theScan->getI();
00951   Ny = theScan->getJ();
00952   Nz = theScan->getK();
00953   n = sqrt((Nx * Nx) + (Ny * Ny) + (Nz * Nz));
00954   Nx = (Nx / n);
00955   Ny = (Ny / n);
00956   Nz = (Nz / n);
00957   Vx = ((Ny * Rz) - (Ry * Nz));
00958   Vy = ((Nz * Rx) - (Rz * Nx));
00959   Vz = ((Nx * Ry) - (Rx * Ny));
00960   angle = ((IPP_PI / 180) * theScan->getDelta());
00961   Ex = (theScan->getCx() + (r * ((Rx * cos(angle)) + (Vx * sin(angle)))));
00962   Ey = (theScan->getCy() + (r * ((Ry * cos(angle)) + (Vy * sin(angle)))));
00963   Ez = (theScan->getCz() + (r * ((Rz * cos(angle)) + (Vz * sin(angle)))));
00964   angle = ((IPP_PI / 180) * theScan->getStepW());
00965   Dx = (theScan->getCx() + (r * ((Rx * cos(angle)) + (Vx * sin(angle)))));
00966   Dy = (theScan->getCy() + (r * ((Ry * cos(angle)) + (Vy * sin(angle)))));
00967   Dz = (theScan->getCz() + (r * ((Rz * cos(angle)) + (Vz * sin(angle)))));
00968   _measuredX1 = theScan->getSx();
00969   _measuredY1 = theScan->getSy();
00970   _measuredZ1 = theScan->getSz();
00971   _measuredX2 = Dx;
00972   _measuredY2 = Dy;
00973   _measuredZ2 = Dz;
00974   _measuredX3 = Ex;
00975   _measuredY3 = Ey;
00976   _measuredZ3 = Ez;
00977   _currentX = Ex;
00978   _currentY = Ey;
00979   _currentZ = Ez;
00980 }
00981 
00982 /*******************************************************************/
00983 
00984 void world::updateScanOnLine(
00985  const ippScanOnLineCommand * theScan
00986 )
00987 {
00988   double Ex;
00989   double Ey;
00990   double Ez;
00991   double Sx;
00992   double Sy;
00993   double Sz;
00994   double dx;
00995   double dy;
00996   double dz;
00997   double f;
00998 
00999   Ex = theScan->getEx();
01000   Ey = theScan->getEy();
01001   Ez = theScan->getEz();
01002   Sx = theScan->getSx();
01003   Sy = theScan->getSy();
01004   Sz = theScan->getSz();
01005   dx = (Ex - Sx);
01006   dy = (Ey - Sy);
01007   dz = (Ez - Sz);
01008   f = (theScan->getStepW() / sqrt((dx * dx) + (dy * dy) + (dz * dz)));
01009   _measuredX1 = Sx;
01010   _measuredY1 = Sy;
01011   _measuredZ1 = Sz;
01012   _measuredX2 = (Sx + (f * dx));
01013   _measuredY2 = (Sy + (f * dy));
01014   _measuredZ2 = (Sz + (f * dz));
01015   _measuredX3 = Ex;
01016   _measuredY3 = Ey;
01017   _measuredZ3 = Ez;
01018   _currentX = Ex;
01019   _currentY = Ey;
01020   _currentZ = Ez;
01021 }
01022 
01023 /*******************************************************************/
01024 
01025 /* world::updateSetCoordSystem
01026 
01027 This takes a SetCoordSystemCommand and, if the coordinate system given
01028 by the command is not the currently active coordinate system, updates
01029 the current coordinate system and the location of the controlled point.
01030 
01031 Setting the system for MachineCsy to &csyPart is not a bug; it
01032 just has to be something valid and non-NULL in this case.
01033 
01034 */
01035 
01036 void world::updateSetCoordSystem(
01037  const ippSetCoordSystemCommand * theSet
01038 )
01039 {
01040   ippCoordSysType theNewSysType;
01041   ippCsyTransform * theNewSys;
01042   ippCsyTransform * theOldSys;
01043   double x;
01044   double y;
01045   double z;
01046 
01047   theNewSysType = theSet->getCsyType();
01048   if (theNewSysType != _Csy)
01049     {
01050       theNewSys = ((theNewSysType == MoveableMachineCsy) ? &_csyMoveable :
01051        (theNewSysType == MultipleArmCsy) ? &_csyMultiple :
01052        (theNewSysType == PartCsy) ? &_csyPart :
01053        (theNewSysType == MachineCsy) ? &_csyPart : NULL);
01054       theOldSys = ((_Csy == MoveableMachineCsy) ? &_csyMoveable :
01055        (_Csy == MultipleArmCsy) ? &_csyMultiple :
01056        (_Csy == PartCsy) ? &_csyPart :
01057        (_Csy == MachineCsy) ? &_csyPart : NULL);
01058       if (theNewSys && (_Csy != MachineCsy))
01059   {
01060     x = _currentX;
01061     y = _currentY;
01062     z = _currentZ;
01063     _currentX = theOldSys->invPointX(x, y, z);
01064     _currentY = theOldSys->invPointY(x, y, z);
01065     _currentZ = theOldSys->invPointZ(x, y, z);
01066   }
01067       if (theNewSys && (theNewSysType != MachineCsy))
01068   {
01069     x = _currentX;
01070     y = _currentY;
01071     z = _currentZ;
01072     _currentX = theNewSys->fwdPointX(x, y, z);
01073     _currentY = theNewSys->fwdPointY(x, y, z);
01074     _currentZ = theNewSys->fwdPointZ(x, y, z);
01075   }
01076       _Csy = theNewSysType;
01077     }
01078 }
01079 
01080 /*******************************************************************/
01081 
01082 /* world::updateSetCsyTransformation
01083 
01084 This takes a SetCsyTransformationCommand and updates the given
01085 coordinate system. If the given coordinate system is the currently
01086 active coordinate system, this also updates the location of the
01087 controlled point.
01088 
01089 */
01090 
01091 void world::updateSetCsyTransformation(
01092  const ippSetCsyTransformationCommand * theSet
01093 )
01094 {
01095   ippCoordSysType theSysType;
01096   ippCsyTransform * theSys;
01097   double x;
01098   double y;
01099   double z;
01100 
01101   theSysType = theSet->getCoordSys();
01102   theSys = ((theSysType == JogDisplayCsy) ? &_csyJogDisplay :
01103       (theSysType == JogMoveCsy) ? &_csyJogMove :
01104       (theSysType == MultipleArmCsy) ? &_csyMultiple :
01105       (theSysType == PartCsy) ? &_csyPart :
01106       (theSysType == SensorCsy) ? &_csySensor : NULL);
01107   if (theSys)
01108     {
01109       if (theSysType == _Csy)
01110   { /* if theSys in use, convert current location to machine coords */
01111     x = _currentX;
01112     y = _currentY;
01113     z = _currentZ;
01114     _currentX = theSys->invPointX(x, y, z);
01115     _currentY = theSys->invPointY(x, y, z);
01116     _currentZ = theSys->invPointZ(x, y, z);
01117   }
01118       theSys->update(theSet->getX0(), theSet->getY0(), theSet->getZ0(),
01119          theSet->getTheta(), theSet->getPsi(), theSet->getPhi());
01120       if (theSysType == _Csy)
01121   { /* if theSys in use, convert current location from machine coords */
01122     x = _currentX;
01123     y = _currentY;
01124     z = _currentZ;
01125     _currentX = theSys->fwdPointX(x, y, z);
01126     _currentY = theSys->fwdPointY(x, y, z);
01127     _currentZ = theSys->fwdPointZ(x, y, z);
01128   }
01129     }
01130 }
01131 
01132 /*******************************************************************/
01133 
01134 /* world::updateSetProp
01135 
01136 SetProp updates PtMeas parameters or GoTo parameters of a tool.  A
01137 parameter has a maximum, a minimum, a default value, and an actual
01138 value. Only the actual value can be set. The parser signals an error
01139 and does not parse the command if the command is a SetProp that tries
01140 to set the maximum, minimum, or default. Thus, when the SetProp
01141 command is executed only the actual value of a property being set is
01142 considered. If an argument has four keywords, the only thing the
01143 fourth keyword can be is "Act". The spec (version 1.4.0) implies that
01144 both forms Tool.ippPtMeasPars.Speed() and Tool.ippPtMeasPars.Speed.Act()
01145 are allowed, and they mean the same thing. In version 1.4.1, this is
01146 stated explicitly. The same rule applies to all other parameters.
01147 Thus, in updateSetProp, we do not look at the fourth keyword.
01148 
01149 If the SetProp cannot be executed for one reason or another, this
01150 does nothing.
01151 
01152 If the tool is UnDefTool, SetProp cannot be executed.
01153 
01154 If the tool is NoTool, SetProp of PtMeas parameters cannot be
01155 executed.
01156 
01157 In _toolCollection->h, if an attempt is made (by calling any of the set methods
01158 used here) to set a parameter value greater than the maximum, the
01159 value is set to the maximum, and if an attempt is made to set the
01160 value less than the minimum, the value is set to the minimum.
01161 
01162 In addition to what _toolCollection->h does, this function sets the world's
01163 outOfRangeFlag to true if a value specified in an argument to SetProp
01164 is greater than the allowed maximum or less than the allowed minimum.
01165 The outOfRangeFlag is set back to false (by world::update()) just
01166 before this function runs. After this function runs, the
01167 outOfRangeFlag stays unchanged until the next time world::update()
01168 is called.
01169 
01170 It is clear from the spec that maxima and minima of properties are not
01171 settable by SetProp, so that is not allowed here.
01172 
01173 Note that, because of the way this behaves, the effect of a SetProp
01174 may not be what is expected. To find out what SetProp did, it
01175 can be followed by a GetProp.
01176 
01177 */
01178 
01179 void world::updateSetProp(
01180  const ippSetPropCommand * theSet
01181 )
01182 {
01183   ippKToolConstPtr theTool;
01184   ippGoToParsPtr pars1 = NULL;
01185   ippPtMeasParsPtr pars2;
01186   int n;
01187   int numberProps;
01188   double requested;
01189 
01190   numberProps = theSet->getNumberProps();
01191   
01192   for (n = 0; n < numberProps; n++) {
01193     
01194     requested = theSet->getValue(n);
01195 
01196     if (theSet->getProp(n).getKey1() == Tool) {
01197       theTool = getTools()->getActiveTool();
01198     
01199     } else if (theSet->getProp(n).getKey1() == FoundTool) {
01200       theTool = getTools()->getFoundTool();
01201     
01202     } else {
01203       theTool = NULL;
01204       if (!(theTool)) { 
01205       } else if (theTool == getTools()->getUnDefTool()){
01206       } else if (theSet->getProp(n).getKey2() == GoToPar) {
01207         pars1 = theTool->getGoToPar();
01208 
01209         switch (theSet->getProp(n).getKey3()) {
01210           case Speed:
01211             if ((pars1->getMaxSpeed() < requested) ||
01212               (pars1->getMinSpeed() > requested)){
01213               _outOfRangeFlag = true;
01214             }
01215             pars1->setActSpeed(requested);
01216             break;
01217           case Accel:
01218             if ((pars1->getMaxAccel() < requested) ||
01219               (pars1->getMinAccel() > requested)) {
01220                 _outOfRangeFlag = true;
01221             }
01222             pars1->setActAccel(requested);
01223             break;
01224           default:
01225             break;
01226         }
01227       } else if (theTool == getTools()->getNoTool()) {
01228 
01229       } else if (theSet->getProp(n).getKey2() == PtMeasPar) {
01230        
01231         pars2 = theTool->getPtMeasPar();
01232        
01233         switch (theSet->getProp(n).getKey3()) {
01234           case Speed:
01235             if ((pars2->getMaxSpeed() < requested) ||
01236               (pars2->getMinSpeed() > requested)){
01237               _outOfRangeFlag = true;
01238             }
01239             pars2->setActSpeed(requested);
01240           break;
01241           case Accel:
01242             if ((pars2->getMaxAccel() < requested) ||
01243               (pars2->getMinAccel() > requested)){
01244               _outOfRangeFlag = true;
01245             }
01246             pars2->setActAccel(requested);
01247             break;
01248           case Approach:
01249             if ((pars2->getMaxApproach() < requested) ||
01250               (pars2->getMinApproach() > requested)) {
01251               _outOfRangeFlag = true;
01252             }
01253             pars2->setActApproach(requested);
01254             break;
01255       case Retract:
01256           if ((pars2->getMaxRetract() < requested) ||
01257             (pars2->getMinRetract() > requested)) {
01258             _outOfRangeFlag = true;
01259           }
01260           pars2->setActRetract(requested);
01261           break;
01262       case Search:
01263         if ((pars2->getMaxSearch() < requested) ||
01264           (pars2->getMinSearch() > requested)) {
01265             _outOfRangeFlag = true;
01266         }
01267         pars2->setActSearch(requested);
01268         break;
01269       default:
01270         break;
01271     }
01272    }
01273  }
01274   }
01275 }
01276 
01277 /*******************************************************************/
01278 
01279 /* world::updateStartSession
01280 
01281 This:
01282 1. sets readiness to ready.
01283 2. sets inSession to true.
01284 3. sets onPtmeasHasX, onPtmeasHasY, and onPtmeasHasZ to true
01285    and all other onPtmeas items to false (see page 41).
01286 4. sets onScanHasQ, onScanHasX, onScanHasY, and onScanHasZ to true
01287    and all other onScan items to false (see page 41).
01288 5. resets all the onMove items to false (spec does not say what to do).
01289 6. kills any on-move daemon (by setting onMoveTagNumber to zero).
01290 
01291 This does NOT change:
01292 1. userEnabled.
01293 2. locking of axes (see page 98, which does not say what to do)
01294 
01295 */
01296 
01297 void world::updateStartSession()
01298 {
01299   stopAllDaemons();
01300 
01301   // by default, and according to the i++ specfication
01302   // OnPtMeasReport should report X,Y,Z
01303   _OnPtMeasReportCmd =  new  ippOnPtMeasReportCommand(0);
01304   _OnPtMeasReportCmd->setDefault();
01305 
01306   // by default, and according to the i++ specfication
01307   // OnScanReport should report X,Y,Z and Q
01308   _OnScanReportCmd = new ippOnScanReportCommand(0);
01309   _OnScanReportCmd->setDefault();
01310 
01311   _readiness = ready;
01312 }
01313 
01314 
01315 
01316 
01317 
01318 /*******************************************************************/
01319 
01320 /* world::world
01321 
01322 This is the constructor for the world class.
01323 
01324 */
01325 
01326 world::world()
01327 {
01328   _toolCollection = new ippToolChanger;
01329 
01330   _Csy = MachineCsy;
01331   // csyJogDisplay initialized automatically by the csyTransform constructor.
01332   // csyJogMove    initialized automatically by the csyTransform constructor.
01333   // csyMoveable   initialized automatically by the csyTransform constructor.
01334   // csyMultiple   initialized automatically by the csyTransform constructor.
01335   // csyPart       initialized automatically by the csyTransform constructor.
01336   // csySensor     initialized automatically by the csyTransform constructor.
01337 
01338 
01339   _currentR = 0;
01340   _currentX = 0;
01341   _currentY = 0;
01342   _currentZ = 0;
01343   
01344   _currentQ = 1.0;
01345   _IJKAct =  1;
01346 
01347   _homeX = 0.0;
01348   _homeY = 0.0;
01349   _homeZ = 0.0;
01350   _isHomed = false;
01351 
01352 
01353 
01354   _limitLowerX = -1500;
01355   _limitLowerY = -1500;
01356   _limitLowerZ = -1500;
01357   _limitUpperX = 1500;
01358   _limitUpperY = 1500;
01359   _limitUpperZ = 1500;
01360 
01361 
01362   _lockedC   = false;
01363   _lockedPhi = false;
01364   _lockedR   = false;
01365   _lockedX   = false;
01366   _lockedY   = false;
01367   _lockedZ   = false;
01368 
01369   _machineClass = CartCMMWithRotaryTable;
01370 
01371   _measuredX1 = 0;
01372   _measuredY1 = 0;
01373   _measuredZ1 = 0;
01374   _measuredX2 = 0;
01375   _measuredY2 = 0;
01376   _measuredZ2 = 0;
01377   _measuredX3 = 0;
01378   _measuredY3 = 0;
01379   _measuredZ3 = 0;
01380 
01381   stopAllDaemons();
01382 
01383 
01384 
01385   _OnPtMeasReportCmd =  new  ippOnPtMeasReportCommand(0);
01386   _OnPtMeasReportCmd->setDefault();
01387 
01388   _outOfRangeFlag = false;
01389 
01390   _pointTag = 0;
01391   _readiness = ready;
01392 
01393   // _toolCollection initialized automatically by the ToolChanger constructor.
01394   _userEnabled = false;
01395 }
01396 
01397 
01398 void world::putCurrentQ(double quality_factor)
01399 //
01400 // Q is the quality factor for the contact point. it is used by PtMeas 
01401 // and Scan commands.
01402 //
01403 // I++ v1.5 6.3.2.4 : 
01404 //          11.1.2
01405 //   0.00  : means high quality
01406 // 100.00  : means poor quality.
01407 {
01408   IPP_ASSERT_MSG(quality_factor>=0.0 && quality_factor<=100.0,
01409            "quality factor should be between 0..100 according to the I++ specification"); 
01410   
01411   if (quality_factor<0) { 
01412         this->_currentQ =0.0;
01413   } else if (quality_factor>100) {
01414         this->_currentQ =100.0;
01415   } else {
01416         this->_currentQ = quality_factor;
01417   }
01418 }
01419 
01420 
01421 
01422 
01423 /* world::daemonExists
01424 
01425 Note: the world object is capable of managing more than one daemon
01426       but the I++ is ambiguous.
01427 
01428 There is only one daemon in the world that may be alive some of the
01429 time.  That is the onMoveReportE daemon. 
01430 There is no need for an OnPtMeasReport daemon or an OnScanReport daemon. In those cases a
01431 point is reported whenever it is taken. What gets reported is
01432 controlled by whatever the last OnPtMeasReport or OnScanReport command
01433 specified.
01434 
01435 The spec creates the impression that many daemons may be alive in the
01436 world at the same time, but there is no need for this. On page 21 the
01437 spec suggests a daemon should come alive while an Event command is
01438 being executed and then die immediately, but that seems pointless
01439 since the daemon does not do anything while it is alive.
01440 
01441 */
01442 
01443 
01444 int  world::daemonCount() const
01445 {
01446    return _daemons.size();
01447 }
01448 
01449 void world::stopDaemon(int daemon_tag)
01450 {
01451   std::map<int,ippDaemonConstPtr>::iterator it = _daemons.find(daemon_tag);
01452   IPP_ASSERT(it!=_daemons.end());
01453   _daemons.erase(it);
01454 }
01455 
01456 
01457 bool world::daemonExists(int tag) const
01458 {
01459   return _daemons.find(tag) != _daemons.end();
01460 }
01461 
01462 void world::stopAllDaemons()
01463 {
01464   _daemons.clear();
01465 }
01466 #include "ippdme/ippDaemon.h"
01467 void world::addDaemon(const ippOnMoveReportECommand* cmd)
01468 {
01469   int daemon_tag = cmd->getTag().getTagNumber();
01470   IPP_ASSERT(!daemonExists(daemon_tag));
01471   _daemons[daemon_tag] = new ippDaemon(daemon_tag,cmd);
01472 }
01473 
01474 ippDaemonConstPtr world::getDaemon() const {
01475   IPP_ASSERT(daemonCount()>=0);
01476   return _daemons.begin()->second;
01477 }
01478 
01479 world::~world()
01480 {
01481 
01482 }
01483 
01484 

Generated on Wed Nov 8 00:20:07 2006 for IPPDME by  doxygen 1.4.1