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

ippCommandChecker.cpp

Go to the documentation of this file.
00001 // 
00002 // DISCLAIMER: 
00003 //  This software was produced by the National Institute of Standards 
00004 //  and Technology (NIST), an agency of the U.S. government, and by statute is 
00005 //  not subject to copyright in the United States.  Recipients of this 
00006 //  software assume all responsibility associated with its operation,
00007 //  modification,maintenance, and subsequent redistribution. 
00008 //
00009 //  See NIST Administration Manual 4.09.07 b and Appendix I. 
00010 //
00011 
00012 #include "stdafx.h"
00013 
00014 /* ippCommandCheckerBase.cc
00015 
00016   This defines functions in the ippCommandCheckerBase class.
00017 
00018   Functions named checkXXX (where XXX is a command name) are used to
00019   check each type of command in context. The checkXXX functions are
00020   called by checkCommand, which does some checks before calling.  The
00021   documentation for each checkXXX function gives the rules that it is
00022   enforcing and gives one or more references to pages of version 1.4 of
00023   the spec. The error code generated if a rule is broken is given after
00024   each rule.
00025 
00026   The arguments to each command are assumed to have passed the checks
00027   performed by the command parser. If this checker is used without the
00028   checks performed by the command parser having been made previously, the
00029   checker may crash or give wrong results.
00030 
00031   Several semantic checks are made in this checker that could be made in
00032   the command parser (because context is not required). For example, the
00033   check that a direction vector is not (0, 0, 0). These are identified
00034   here as semantic checks.
00035 
00036   The reference pages reference both text and examples. Text references
00037   are given in parentheses. Example references are given in brackets.
00038   Other references are not enclosed.
00039 
00040   Example: Reference pages: 23 26 (39) [40] 85
00041   This means there is relevant text on page 39 and an example on page 40.
00042 
00043   Page 17 is not referenced because the print is too small. Page 25 is not
00044   referenced since everything on it appears identically elsewhere.
00045               
00046 */
00047 
00048 #include "ippdme/Checker/ippCommandChecker.h"
00049 #include "ippdme/world.h"
00050 
00051 #include "ippdme/Command/commands.h"
00052 #include "ippdme/ippErrorNameType.h"
00053 #include "ippdme/assert.h"
00054 
00055 
00056 
00057 
00058 /*******************************************************************/
00059 
00060 /* ippCommandCheckerBase::getIppErr
00061 
00062   Returned Value: int (the number of the I++ error corresponding to the
00063   "code" argument)
00064 
00065   Called By:
00066   external functions
00067   main (in stand-alone command checker)
00068 
00069   Rules: None.
00070 
00071   For attempting to do anything with UNDEFTOOL, the IppErr is always
00072   ToolNotDefined.
00073 
00074   For attempting to do illegal things with NOTOOL, the IppErr is always
00075   IllegalCommand.
00076           
00077 */
00078 #ifdef _DEBUG
00079 #define new DEBUG_NEW
00080 #undef THIS_FILE
00081 static char THIS_FILE[] = __FILE__;
00082 #endif
00083 
00084 #define CHECKER_ENUMERATION \
00085   CHECKER_ENUM(CHECKER_OK                                  ,GenericError            ,"OK") \
00086   CHECKER_ENUM(AXIS_DIRECTION_VECTOR_HAS_ZERO_LENGTH       ,VectorHasNoNorm         ,"AXIS DIRECTION VECTOR HAS ZERO LENGTH")\
00087   CHECKER_ENUM(BAD_ERROR_NUMBER                            ,ArgumentOutOfRange      ,"BAD ERROR NUMBER")\
00088   CHECKER_ENUM(CAN_NOT_CHANGE_TOOL_TO_UNDEFTOOL            ,ToolNotDefined          ,"CAN NOT CHANGE TOOL TO UNDEFTOOL")\
00089   CHECKER_ENUM(CAN_NOT_ENUMALLPROP_NOTOOL_PTMEASPAR        ,IllegalCommand          ,"CAN NOT ENUMALLPROP NOTOOL PTMEASPAR")\
00090   CHECKER_ENUM(CAN_NOT_ENUMALLPROP_UNDEFTOOL_GOTOPAR       ,ToolNotDefined          ,"CAN NOT ENUMALLPROP UNDEFTOOL GOTOPAR")\
00091   CHECKER_ENUM(CAN_NOT_ENUMALLPROP_UNDEFTOOL_PTMEASPAR     ,ToolNotDefined          ,"CAN NOT ENUMALLPROP UNDEFTOOL PTMEASPAR")\
00092   CHECKER_ENUM(CAN_NOT_ENUMPROP_NOTOOL_PTMEASPAR           ,IllegalCommand          ,"CAN NOT ENUMPROP NOTOOL PTMEASPAR")\
00093   CHECKER_ENUM(CAN_NOT_ENUMPROP_UNDEFTOOL_GOTOPAR          ,ToolNotDefined          ,"CAN NOT ENUMPROP UNDEFTOOL GOTOPAR")\
00094   CHECKER_ENUM(CAN_NOT_ENUMPROP_UNDEFTOOL_PTMEASPAR        ,ToolNotDefined          ,"CAN NOT ENUMPROP UNDEFTOOL PTMEASPAR")\
00095   CHECKER_ENUM(CAN_NOT_GETPROP_PTMEASPARS_OF_NOTOOL        ,IllegalCommand          ,"CAN NOT GETPROP PTMEASPARS OF NOTOOL")\
00096   CHECKER_ENUM(CAN_NOT_GETPROP_UNDEFTOOL                   ,ToolNotDefined          ,"CAN NOT GETPROP UNDEFTOOL")\
00097   CHECKER_ENUM(CAN_NOT_GETPROPE_PTMEASPARS_OF_NOTOOL       ,IllegalCommand          ,"CAN NOT GETPROPE PTMEASPARS OF NOTOOL")\
00098   CHECKER_ENUM(CAN_NOT_GETPROPE_UNDEFTOOL                  ,ToolNotDefined          ,"CAN NOT GETPROPE UNDEFTOOL")\
00099   CHECKER_ENUM(CAN_NOT_GOTO_USING_UNDEFTOOL                ,IllegalCommand          ,"CAN NOT GOTO USING UNDEFTOOL")\
00100   CHECKER_ENUM(CAN_NOT_PTMEAS_USING_NOTOOL                 ,IllegalCommand          ,"CAN NOT PTMEAS USING NOTOOL")\
00101   CHECKER_ENUM(CAN_NOT_PTMEAS_USING_UNDEFTOOL              ,ToolNotDefined          ,"CAN NOT PTMEAS USING UNDEFTOOL")\
00102   CHECKER_ENUM(CAN_NOT_REQUALIFY_NOTOOL                    ,IllegalCommand          ,"CAN_NOT_REQUALIFY_NOTOOL")\
00103   CHECKER_ENUM(CAN_NOT_REQUALIFY_UNDEFTOOL                 ,ToolNotDefined          ,"CAN_NOT_REQUALIFY_UNDEFTOOL")\
00104   CHECKER_ENUM(CAN_NOT_SCAN_USING_NOTOOL                   ,IllegalCommand          ,"CAN NOT SCAN USING NOTOOL")\
00105   CHECKER_ENUM(CAN_NOT_SCAN_USING_UNDEFTOOL                ,ToolNotDefined          ,"CAN NOT SCAN USING UNDEFTOOL")\
00106   CHECKER_ENUM(CAN_NOT_SET_TOOL_TO_UNDEFTOOL               ,ToolNotDefined          ,"CAN NOT SET TOOL TO UNDEFTOOL")\
00107   CHECKER_ENUM(CAN_NOT_SETPROP_PTMEASPARS_OF_NOTOOL        ,IllegalCommand          ,"CAN NOT SETPROP PTMEASPARS OF NOTOOL")\
00108   CHECKER_ENUM(CAN_NOT_SETPROP_UNDEFTOOL                   ,ToolNotDefined          ,"CAN NOT SETPROP UNDEFTOOL")\
00109   CHECKER_ENUM(DAEMON_TO_STOP_DOES_NOT_EXIST               ,DaemonDoesNotExist      ,"DAEMON TO STOP DOES NOT EXIST")\
00110   CHECKER_ENUM(DIRECTION_VECTOR_HAS_ZERO_LENGTH            ,VectorHasNoNorm         ,"DIRECTION VECTOR HAS ZERO LENGTH")\
00111   CHECKER_ENUM(DIS_ARGUMENT_MUST_BE_POSITIVE               ,BadProperty             ,"DIS ARGUMENT MUST BE POSITIVE")\
00112   CHECKER_ENUM(FIRST_VECTOR_NOT_NORMALIZED                 ,IncorrectArguments      ,"FIRST VECTOR NOT NORMALIZED")\
00113   CHECKER_ENUM(MUST_STOP_EXISTING_DAEMON_BEFORE_STARTING_ANOTHER,DaemonAlreadyExists, "MUST STOP EXISTING DAEMON BEFORE STARTING ANOTHER")\
00114   CHECKER_ENUM(NOT_HOMED_CAN_NOT_EXECUTE_COMMAND           ,IllegalCommand          ,"NOT HOMED CAN NOT EXECUTE COMMAND")\
00115   CHECKER_ENUM(RADIUS_MUST_BE_PERPENDICULAR_TO_NORMAL      ,IllegalCommand          ,"RADIUS MUST BE PERPENDICULAR TO NORMAL")\
00116   CHECKER_ENUM(RADIUS_MUST_HAVE_POSITIVE_LENGTH            ,IncorrectArguments      ,"RADIUS MUST HAVE POSITIVE LENGTH")\
00117   CHECKER_ENUM(READINESS_ABORTED_CAN_NOT_EXECUTE_COMMAND   ,UseClearAllErrorsToCont ,"READINESS ABORTED CAN NOT EXECUTE COMMAND")\
00118   CHECKER_ENUM(READINESS_ERRED_CAN_NOT_EXECUTE_COMMAND     ,UseClearAllErrorsToCont ,"READINESS ERRED CAN NOT EXECUTE COMMAND")\
00119   CHECKER_ENUM(SCAN_POINT_MUST_BE_IN_WORK_VOLUME           ,ArgumentOutOfRange      ,"SCAN POINT MUST BE IN WORK VOLUME")\
00120   CHECKER_ENUM(SECOND_VECTOR_NOT_NORMALIZED                ,IncorrectArguments      ,"SECOND VECTOR NOT NORMALIZED")\
00121   CHECKER_ENUM(START_POINT_MUST_DIFFER_FROM_DIRECTION_POINT,IncorrectArguments      ,"START POINT MUST DIFFER FROM DIRECTION POINT")\
00122   CHECKER_ENUM(START_POINT_MUST_DIFFER_FROM_END_POINT      ,IncorrectArguments      ,"START POINT MUST DIFFER FROM END POINT")\
00123   CHECKER_ENUM(START_POINT_MUST_NOT_BE_ON_CYLINDER_AXIS    ,IncorrectArguments      ,"START POINT MUST NOT BE ON CYLINDER AXIS")\
00124   CHECKER_ENUM(TARGET_POINT_OUT_OF_WORK_VOLUME             ,TargetPosOutOfMachVol   ,"TARGET POINT OUT OF WORK VOLUME")\
00125   CHECKER_ENUM(THETA_MUST_NOT_BE_NEGATIVE_OR_MORE_THAN_180 ,ThetaOutOfRange         ,"THETA MUST NOT BE NEGATIVE OR MORE THAN 180")\
00126   CHECKER_ENUM(TIME_ARGUMENT_MUST_NOT_BE_LESS_THAN_A_TENTH ,BadProperty             ,"TIME ARGUMENT MUST NOT BE LESS THAN A TENTH")\
00127   CHECKER_ENUM(UNKNOWN_TOOL                                ,ToolNotFound            ,"UNKNOWN TOOL")\
00128 
00129 
00130 ippErrorNameType ippCommandCheckerBase::getIppErr(ippCheckerErrorId code)
00131 {
00132     switch(code){
00133 #define CHECKER_ENUM(enumValue,IPPError,c) case enumValue: return IPPError;
00134       CHECKER_ENUMERATION
00135 #undef CHECKER_ENUM
00136     }
00137     return GenericError;
00138 }
00139 
00140 /*******************************************************************/
00141 
00142 /* ippCommandCheckerBase::getErrorMessageString
00143 
00144   Returned Value: std::string
00145   If there is a problem with providing a string, this returns an empty string.
00146   Otherwise, it returns the full text of the message
00147 
00148   Called By:
00149   external functions
00150   main (in stand-alone command checker)
00151 
00152   Rules: None.
00153 
00154   This copies an error message into the buffer, preceded by the name
00155   of the command being checked when the error was found.
00156 
00157   The symbol for each error code is the same as the text of the error
00158   message, except that the symbol has underscores. The symbol serves as
00159   an index into the array of strings defined here. The symbols are
00160   defined in ippCommandChecker.h.
00161           
00162 */
00163 
00164 std::string ippCommandCheckerBase::getErrorMessageString() const
00165 {
00166   std::string error_string;
00167   if ((_commandName > -1) && (_commandName < ippCOMMANDNAMETYPE_MAXIMUM)) {
00168     
00169     error_string.append(getCommandNameString(_commandName));
00170     error_string.append(" : ");
00171   }
00172 
00173   switch(_errorCode){
00174     #define CHECKER_ENUM(x,b,c) case x: error_string.append(c); break;
00175       CHECKER_ENUMERATION
00176     #undef CHECKER_ENUM
00177   }
00178 
00179   return error_string.c_str();
00180 }
00181 
00182 ippCommandCheckerBase::ippCommandCheckerBase()
00183 {
00184 }
00185 /*******************************************************************/
00186 
00187 /* ippCommandChecker::checkAbortE 1
00188 
00189   Returned Value: None.
00190   
00191   Called By: ippCommandChecker::checkCommand
00192 
00193   Rules: None.
00194 
00195   Reference pages: 9 24 26 (42) [43] 99
00196         
00197 */
00198 
00199 void ippCommandChecker::checkAbortE(
00200   ippCommandConstPtr aCommand
00201 )
00202 {
00203   
00204 }
00205 
00206 /*******************************************************************/
00207 
00208 /* ippCommandChecker::checkAlignPart 2
00209 
00210   Returned Value: None.
00211 
00212   Called By: ippCommandChecker::checkCommand
00213 
00214   Rules:
00215   1. The system must be homed (see p. 48)
00216   NOT_HOMED_CAN_NOT_EXECUTE_COMMAND
00217 
00218   Reference pages: 24 28 63 (95) 105
00219         
00220 */
00221 
00222 void ippCommandChecker::checkAlignPart( ippCommandConstPtr aCommand)
00223 {
00224   if (!(_world->getIsHomed())) {
00225     _errorCode = NOT_HOMED_CAN_NOT_EXECUTE_COMMAND;
00226   }
00227 }
00228 
00229 /*******************************************************************/
00230 
00231 /* ippCommandChecker::checkAlignTool 3
00232 
00233     Returned Value: None.
00234 
00235     Called By: ippCommandChecker::checkCommand
00236 
00237     Rules:
00238     1. Vector1 must be a unit vector.
00239     FIRST_VECTOR_NOT_NORMALIZED
00240     2. If vector2 is set, it must be a unit vector.
00241     SECOND_VECTOR_NOT_NORMALIZED
00242     3. The system must be homed (see p. 48)
00243     NOT_HOMED_CAN_NOT_EXECUTE_COMMAND
00244 
00245     Reference pages: 24 27 29 (55) 66 70 102 107
00246 
00247     The first two rules are semantic checks.
00248 
00249     Might add not allowing AlignTool using UnDefTool or NoTool.
00250 
00251 */
00252 
00253 void ippCommandChecker::checkAlignTool( ippCommandConstPtr aCommand)
00254 {
00255   const ippAlignToolCommand* theAlign = static_cast<const ippAlignToolCommand*>(aCommand.get());
00256 
00257   double i;
00258   double j;
00259   double k;
00260   
00261 
00262   i = theAlign->getVector1i();
00263   j = theAlign->getVector1j();
00264   k = theAlign->getVector1k();
00265   if (fabs(sqrt((i*i)+(j*j)+(k*k)) - 1.0) > IPP_NORMAL_ERROR)
00266     _errorCode = FIRST_VECTOR_NOT_NORMALIZED;
00267   if ((_errorCode == CHECKER_OK) && (theAlign->getHas2()))
00268   {
00269     i = theAlign->getVector2i();
00270     j = theAlign->getVector2j();
00271     k = theAlign->getVector2k();
00272     if (fabs(sqrt((i*i)+(j*j)+(k*k)) - 1.0) > IPP_NORMAL_ERROR)
00273       _errorCode = SECOND_VECTOR_NOT_NORMALIZED;
00274   }
00275   if ((_errorCode == CHECKER_OK) && (!(_world->getIsHomed())))
00276     _errorCode = NOT_HOMED_CAN_NOT_EXECUTE_COMMAND;
00277 }
00278 
00279 /*******************************************************************/
00280 
00281 /* ippCommandCheckerBase:: checkCenterPart 4
00282 
00283   Returned Value: None.
00284 
00285   Called By: ippCommandChecker::checkCommand
00286 
00287   Rules:
00288   1.The system must be homed (see p. 48)
00289   NOT_HOMED_CAN_NOT_EXECUTE_COMMAND
00290 
00291   Reference pages: 24 27 (96) 102
00292         
00293 */
00294 
00295 void ippCommandChecker::checkCenterPart( ippCommandConstPtr aCommand)
00296 {
00297   if (!_world->getIsHomed()) {
00298     _errorCode = NOT_HOMED_CAN_NOT_EXECUTE_COMMAND;
00299   }
00300 }
00301 
00302 /*******************************************************************/
00303 
00304 /* ippCommandChecker::checkChangeTool 5
00305 
00306   Returned Value: None.
00307 
00308   Called By: ippCommandChecker::checkCommand
00309 
00310   Rules:
00311   1. The name of the tool must not be "UnDefTool".
00312   CAN_NOT_CHANGE_TOOL_TO_UNDEFTOOL
00313   2. The tool must be one of the tools known to the toolchanger.
00314   UNKNOWN_TOOL
00315 
00316   Reference pages: 24 27 29 (54) (57) (58) (78) 98 102 106
00317 
00318   Rule 2 above is not explicit in the spec, but seems implicit. It also
00319   seems implicit that it should be possible to change to "NoTool",
00320   "BaseTool" or "RefTool". Rule 2 is a semantic check.
00321 
00322   This is not currently requiring that the machine be homed, since it may
00323   be possible to change tools without moving the machine on some machines.
00324             
00325 */
00326 
00327 void ippCommandChecker::checkChangeTool( ippCommandConstPtr aCommand)
00328 {
00329   const ippChangeToolCommand * theChange = static_cast<const ippChangeToolCommand *>(aCommand.get());
00330 
00331   if (strcmp("UnDefTool", theChange->getToolName()) == 0) {
00332     _errorCode = CAN_NOT_CHANGE_TOOL_TO_UNDEFTOOL;
00333   } else if (_world->getTools()->findTool(theChange->getToolName()).get() == NULL) {
00334     _errorCode = UNKNOWN_TOOL;
00335   } 
00336 }
00337 
00338 /*******************************************************************/
00339 
00340 /* ippCommandChecker::checkClearAllErrors 6
00341 
00342   Returned Value: None.
00343 
00344   Called By: ippCommandChecker::checkCommand
00345 
00346   Rules: None.
00347 
00348   Reference pages: 24 26 [38] (40) (41) (42) (43) [44] (47) (75) 76 99
00349         
00350 */
00351 
00352 void ippCommandChecker::checkClearAllErrors( ippCommandConstPtr aCommand)
00353 {
00354   
00355 }
00356 
00357 /*******************************************************************/
00358 
00359 /* ippCommandChecker::checkDisableUser 7
00360 
00361   Returned Value: None.
00362 
00363   Called By: ippCommandChecker::checkCommand
00364 
00365   Rules: None.
00366 
00367   Reference pages: 24 27 (48) (51) (53) 102
00368 
00369 */
00370 
00371 void ippCommandChecker::checkDisableUser( ippCommandConstPtr aCommand)
00372 {
00373   
00374 }
00375 
00376 /*******************************************************************/
00377 
00378 /* ippCommandChecker::checkEnableUser 8
00379 
00380   Returned Value: None.
00381 
00382   Called By: ippCommandChecker::checkCommand
00383 
00384   Rules: None.
00385 
00386   Reference pages: 24 27 [39] (48) (51) 102
00387         
00388 */
00389 
00390 void ippCommandChecker::checkEnableUser( ippCommandConstPtr aCommand)
00391 {
00392   
00393 }
00394 
00395 /*******************************************************************/
00396 
00397 /* ippCommandChecker::checkEndSession 9
00398 
00399     Returned Value: None.
00400 
00401     Called By: ippCommandChecker::checkCommand
00402 
00403     Rules: None.
00404 
00405     Reference pages: 18 20 24 26 (41) (77) 99
00406         
00407 */
00408 
00409 void ippCommandChecker::checkEndSession( ippCommandConstPtr aCommand)
00410 {
00411   
00412 }
00413 
00414 /*******************************************************************/
00415 
00416 /* ippCommandChecker::checkEnumAllProp 10
00417 
00418   Returned Value: None.
00419 
00420   Called By: ippCommandChecker::checkCommand
00421 
00422   The parser requires that the argument have one of the following patterns.
00423   key1()
00424   key1.key2()
00425   key1.key2.key3()
00426   key1.key2.key3.key4()
00427   where key1 must be FoundTool or Tool and key2 must be GoToPar or PtMeasPar.
00428 
00429   Rules:
00430   1. If the value found by key1 is UnDefTool, there must be no key2.
00431   CAN_NOT_ENUMALLPROP_UNDEFTOOL_PTMEASPAR
00432   CAN_NOT_ENUMALLPROP_UNDEFTOOL_GOTOPAR
00433   2. If the value found by key1 is NoTool, key2 must not be PtMeasPar.
00434   CAN_NOT_ENUMALLPROP_NOTOOL_PTMEASPAR
00435 
00436   Reference pages: 24 26 45 (46) [74] 99
00437 
00438   These rules are not explicit in the spec, but seem implicit. The rules
00439   are consistent with the rules for EnumProp, GetProp, and GetPropE.
00440             
00441 */
00442 typedef boost::intrusive_ptr<ippEnumAllPropCommand> ippEnumAllPropCommandPtr;
00443 typedef boost::intrusive_ptr<const ippEnumAllPropCommand> ippEnumAllPropCommandConstPtr;
00444 
00445 void ippCommandChecker::checkEnumAllProp(ippCommandConstPtr aCommand)
00446 {
00447   const ippEnumAllPropCommand* theEnum =
00448      static_cast<const ippEnumAllPropCommand*>(aCommand.get());
00449 
00450   ippKToolPtr theTool;
00451   
00452   if (theEnum->getProp().getKey1() == Tool){                  
00453     theTool = _world->getTools()->getActiveTool();
00454 
00455   } else if (theEnum->getProp().getKey1() == FoundTool) {
00456     theTool = _world->getTools()->getFoundTool();
00457   } else{  // should never happen
00458     theTool = NULL;
00459   }
00460   if (theTool && (theTool == _world->getTools()->getUnDefTool()))
00461   {
00462     if (theEnum->getProp().getNumberKeys() > 1)
00463     {
00464       if (theEnum->getProp().getKey2() == PtMeasPar)
00465         _errorCode = CAN_NOT_ENUMALLPROP_UNDEFTOOL_PTMEASPAR;
00466       else // if (theEnum->getKey2() == GoToPar)
00467         _errorCode = CAN_NOT_ENUMALLPROP_UNDEFTOOL_GOTOPAR;
00468     }
00469   }
00470   else if (theTool && (theTool == _world->getTools()->getNoTool()))
00471   {
00472     if ((theEnum->getProp().getNumberKeys() > 1) && (theEnum->getProp().getKey2() == PtMeasPar))
00473       _errorCode = CAN_NOT_ENUMALLPROP_NOTOOL_PTMEASPAR;
00474   }
00475 }
00476 
00477 /*******************************************************************/
00478 
00479 /* ippCommandChecker::checkEnumProp 11
00480 
00481   Returned Value: None.
00482   
00483     Called By: ippCommandChecker::checkCommand
00484     
00485     The parser requires that the argument have one of the following patterns.
00486     key1()
00487     key1.key2()
00488     key1.key2.key3()
00489     key1.key2.key3.key4()
00490     where key1 must be FoundTool or Tool and key2 must be GoToPar or PtMeasPar.
00491 
00492     Rules:
00493     1. If the value found by key1 is UnDefTool, there must be no key2.
00494     CAN_NOT_ENUMPROP_UNDEFTOOL_PTMEASPAR
00495     CAN_NOT_ENUMPROP_UNDEFTOOL_GOTOPAR
00496     2. If the value found by key1 is NoTool, key2 must not be PtMeasPar.
00497     CAN_NOT_ENUMPROP_NOTOOL_PTMEASPAR
00498 
00499     Reference pages: 24 26 29 (45) [73] 99 108 109 110 111
00500 
00501     These rules are not explicit in the spec, but seem implicit. The rules
00502     are consistent with the rules for EnumAllProp, GetProp, and GetPropE.
00503             
00504 */
00505 
00506 void ippCommandChecker::checkEnumProp( ippCommandConstPtr aCommand)
00507 {
00508   const ippEnumPropCommand * theEnum= (const ippEnumPropCommand *)aCommand.get();
00509   
00510   ippKToolConstPtr theTool;
00511   
00512   const ippProp& prop = theEnum->getProp();
00513 
00514   if (prop.getKey1() == Tool) {
00515     theTool = _world->getTools()->getActiveTool();
00516 
00517   } else if (prop.getKey1() == FoundTool) {
00518     theTool = _world->getTools()->getFoundTool();
00519   } else {
00520     theTool = NULL;
00521   
00522   }
00523 
00524   if (theTool && (theTool == _world->getTools()->getUnDefTool()))
00525   {
00526     if (prop.getNumberKeys() > 1)
00527     {
00528       if (prop.getKey2() == PtMeasPar) {
00529         _errorCode = CAN_NOT_ENUMPROP_UNDEFTOOL_PTMEASPAR;
00530       }  else  { // if (theEnum->getKey2() == GoToPar)
00531         _errorCode = CAN_NOT_ENUMPROP_UNDEFTOOL_GOTOPAR;
00532       }
00533     }
00534   } else if (theTool && (theTool == _world->getTools()->getNoTool()))  {
00535     if ((prop.getNumberKeys() > 1) && (prop.getKey2() == PtMeasPar)) {
00536       _errorCode = CAN_NOT_ENUMPROP_NOTOOL_PTMEASPAR;
00537     }
00538   }
00539 }
00540 
00541 /*******************************************************************/
00542 
00543 /* ippCommandChecker::checkEnumTools 12
00544 
00545   Returned Value: None.
00546   
00547   Called By: ippCommandChecker::checkCommand
00548 
00549   Rules: None.
00550 
00551   Reference pages: 24 29 (53) (54) (56) 106
00552         
00553 */
00554 
00555 void ippCommandChecker::checkEnumTools( ippCommandConstPtr aCommand)
00556 {
00557   
00558 }
00559 
00560 /*******************************************************************/
00561 
00562 /* ippCommandChecker::checkFindTool 13
00563 
00564   Returned Value: None.
00565   
00566   Called By: ippCommandChecker::checkCommand
00567 
00568   Rules: None.
00569 
00570   Reference pages: 24 27 29 (54) [74] 102 106
00571 
00572   ipp1.4 This (unlike checkChangeTool) is allowing "UnDefTool". Thus, FoundTool
00573   can be UnDefTool. It might be better to make this illegal.
00574 
00575   ipp1.5 Has this changed ?
00576 
00577 */
00578 
00579 void ippCommandChecker::checkFindTool( ippCommandConstPtr aCommand)
00580 {
00581  // Etienne doesn't know if this test would be valid : 
00582  //xx const ippFindToolCommand * theFind = static_cast<const ippFindToolCommand *>(aCommand.get());
00583  //xx if (strcmp("UnDefTool", theFind->getToolName()) == 0) {
00584  //xx   _errorCode = CAN_NOT_CHANGE_TOOL_TO_UNDEFTOOL;
00585  //xx }  
00586 }
00587 
00588 /*******************************************************************/
00589 
00590 /* ippCommandChecker::checkGet 14
00591 
00592   Returned Value: None.
00593 
00594   Called By: ippCommandChecker::checkCommand
00595 
00596   Rules: None
00597 
00598   Reference pages: 24 27 [38] [44] (49) (51) 57 (61) (63) (66) (81) 102
00599         
00600 */
00601 
00602 void ippCommandChecker::checkGet( ippCommandConstPtr aCommand)
00603 {
00604   
00605 }
00606 
00607 /*******************************************************************/
00608 
00609 /* ippCommandCheckerBase:: checkGetChangeToolAction 15
00610 
00611   Returned Value: None.
00612 
00613   Called By: ippCommandChecker::checkCommand
00614 
00615   Rules:
00616   1. The name of the tool must not be "UnDefTool".
00617   CAN_NOT_CHANGE_TOOL_TO_UNDEFTOOL
00618   2. The tool must be one of the tools known to the toolchanger.
00619   UNKNOWN_TOOL
00620 
00621   Reference pages: 24 27 29 (57-58) 102 106
00622         
00623 */
00624 
00625 void ippCommandChecker::checkGetChangeToolAction( ippCommandConstPtr aCommand)
00626 {
00627   const ippGetChangeToolActionCommand* theChangeAction = 
00628       static_cast<const ippGetChangeToolActionCommand*>(aCommand.get());
00629 
00630   if (strcmp("UnDefTool", theChangeAction->getToolName()) == 0){
00631     
00632     _errorCode = CAN_NOT_CHANGE_TOOL_TO_UNDEFTOOL;
00633 
00634   } else if (_world->getTools()->findTool(theChangeAction->getToolName()).get()== NULL){
00635     
00636     _errorCode = UNKNOWN_TOOL;
00637 
00638   }
00639 }
00640 
00641 /*******************************************************************/
00642 
00643 /* ippCommandChecker::checkGetCoordSystem 16
00644 
00645   Returned Value: None.
00646 
00647   Called By: ippCommandChecker::checkCommand
00648 
00649   Rules: None.
00650 
00651   Reference pages: 24 28 (59) 103
00652         
00653 */
00654 
00655 void ippCommandChecker::checkGetCoordSystem( ippCommandConstPtr aCommand)
00656 {
00657   
00658 }
00659 
00660 /*******************************************************************/
00661 
00662 /* ippCommandChecker::checkGetCsyTransformation 17
00663 
00664   Returned Value: None.
00665 
00666   Called By: ippCommandChecker::checkCommand
00667 
00668   Rules: None.
00669 
00670   Reference pages: 24 28 (60) (80) 103
00671         
00672 */
00673 
00674 void ippCommandChecker::checkGetCsyTransformation( ippCommandConstPtr aCommand)
00675 {
00676   
00677 }
00678 
00679 /*******************************************************************/
00680 
00681 /* ippCommandCheckerBase:: checkGetDMEVersion 18
00682 
00683   Returned Value: None.
00684 
00685   Called By: ippCommandChecker::checkCommand
00686 
00687   Rules: None.
00688 
00689   Reference pages: 24 26 (46) [47] 99
00690         
00691 */
00692 
00693 void ippCommandChecker::checkGetDMEVersion( ippCommandConstPtr aCommand)
00694 {
00695   
00696 }
00697 
00698 /*******************************************************************/
00699 
00700 /* ippCommandChecker::checkGetErrorInfo 19
00701 
00702   Returned Value: None.
00703 
00704   Called By: ippCommandChecker::checkCommand
00705 
00706   Rules:
00707   1. The error number must be an allowed error number.
00708   BAD_ERROR_NUMBER
00709 
00710   Reference pages:  19 24 26 (43) 76 99
00711   Page 76 does not mention the command but gives allowable error numbers.
00712 
00713   The range 8000-9999 is provided for server-defined and client-defined
00714   errors, as given on page 75, but it is not clear how such error numbers
00715   are to be defined.
00716 
00717   Rule 1 is a semantic check.
00718 
00719 */
00720 
00721 void ippCommandChecker::checkGetErrorInfo(ippCommandConstPtr aCommand)
00722 {
00723   const ippGetErrorInfoCommand* theGetErrorInfo = 
00724     static_cast<const  ippGetErrorInfoCommand*>(aCommand.get());
00725 
00726   int error_number = theGetErrorInfo->getErrorNumber().asInteger();
00727 
00728   if (((error_number >=    0) && (error_number <=    8)) ||
00729     ((error_number >=  500) && (error_number <=  515)) ||
00730     ((error_number >= 1000) && (error_number <= 1010)) ||
00731     ((error_number >= 1500) && (error_number <= 1503)) ||
00732     ((error_number >= 2000) && (error_number <= 2002)) ||
00733     ((error_number >= 2500) && (error_number <= 2506)) ||
00734     ((error_number >= 8000) && (error_number <= 9999)));
00735   else
00736     _errorCode = BAD_ERROR_NUMBER;
00737 }
00738 
00739 /*******************************************************************/
00740 
00741 /* ippCommandChecker::checkGetErrStatusE 20
00742 
00743   Returned Value: None.
00744 
00745   Called By: ippCommandChecker::checkCommand
00746 
00747   Rules: None.
00748 
00749   Reference pages: 24 27 (50) 102
00750         
00751 */
00752 
00753 void ippCommandChecker::checkGetErrStatusE( ippCommandConstPtr aCommand)
00754 {
00755   
00756 }
00757 
00758 /*******************************************************************/
00759 
00760 /* ippCommandChecker::checkGetMachineClass 21
00761 
00762   Returned Value: None.
00763 
00764   Called By: ippCommandChecker::checkCommand
00765 
00766   Rules: None.
00767 
00768   Reference pages: 18 24 27 (50) 102
00769         
00770 */
00771 
00772 void ippCommandChecker::checkGetMachineClass( ippCommandConstPtr aCommand)
00773 {
00774   
00775 }
00776 
00777 /*******************************************************************/
00778 
00779 /* ippCommandChecker::checkGetProp 22
00780 
00781   Returned Value: None.
00782 
00783   Called By: ippCommandChecker::checkCommand
00784 
00785   Rules: 
00786   1. Properties of UnDefTool cannot be gotten by GetProp.
00787   CAN_NOT_GETPROP_UNDEFTOOL
00788   2. PtMeas parameters of NoTool cannot be gotten by GetProp.
00789   CAN_NOT_GETPROP_PTMEASPARS_OF_NOTOOL
00790 
00791   Reference pages: 24 26 29 (45) 66 67 [68] [69] 70 [73] [74] 77 79 99 108
00792 
00793   These rules are not explicit in the spec, but seem implicit. The rules
00794   are consistent with the rules for EnumAllProp, EnumProp, and GetPropE.
00795 
00796 */
00797 
00798 void ippCommandChecker::checkGetProp( ippCommandConstPtr aCommand)
00799 {
00800   const ippGetPropCommand* theGetProp  = 
00801    static_cast<const ippGetPropCommand*>(aCommand.get());
00802   
00803 
00804   ippKToolConstPtr theTool;
00805   int n;
00806   
00807   for (n = 0; ((_errorCode == CHECKER_OK) && (n < theGetProp->getNumberProps())); n++)
00808   {
00809     const ippProp& prop = theGetProp->getProp(n);
00810 
00811     if (theGetProp->getProp(n).getKey1() == Tool) {
00812       theTool = _world->getTools()->getActiveTool();
00813 
00814     } else if (theGetProp->getProp(n).getKey1() == FoundTool) {
00815       theTool = _world->getTools()->getFoundTool();
00816 
00817     } else { 
00818       theTool = NULL;
00819     }
00820     if (theTool && (theTool == _world->getTools()->getUnDefTool())) {
00821       _errorCode = CAN_NOT_GETPROP_UNDEFTOOL;
00822 
00823     } else if (theTool && (theGetProp->getProp(n).getKey2() == PtMeasPar) &&
00824       (theTool == _world->getTools()->getNoTool())) {
00825         _errorCode = CAN_NOT_GETPROP_PTMEASPARS_OF_NOTOOL;
00826     }
00827   }
00828 }
00829 
00830 /*******************************************************************/
00831 
00832 /* ippCommandChecker::checkGetPropE 23
00833 
00834     Returned Value: None.
00835 
00836     Called By: ippCommandChecker::checkCommand
00837 
00838     Rules:
00839     1. Properties of UnDefTool cannot be gotten by GetPropE.
00840     CAN_NOT_GETPROPE_UNDEFTOOL
00841     2. PtMeas parameters of NoTool cannot be gotten by GetPropE.
00842     CAN_NOT_GETPROPE_PTMEASPARS_OF_NOTOOL
00843 
00844     Reference pages: 24 26 29 (45) 99 108
00845 
00846     These rules are not explicit in the spec, but seem implicit. The rules
00847     are consistent with the rules for EnumAllProp, EnumProp, and GetProp.
00848           
00849 */
00850 
00851 void ippCommandChecker::checkGetPropE( ippCommandConstPtr aCommand)
00852 {
00853   const ippGetPropECommand * theGetPropE = 
00854     static_cast<const ippGetPropECommand*>(aCommand.get());
00855 
00856   ippKToolConstPtr theTool;
00857   int n;
00858   
00859   for (n = 0;
00860   ((_errorCode == CHECKER_OK) && (n < theGetPropE->getNumberProps()));
00861   n++)
00862   {
00863     if (theGetPropE->getProp(n).getKey1() == Tool) {
00864       theTool = _world->getTools()->getActiveTool();
00865     }  else if (theGetPropE->getProp(n).getKey1() == FoundTool){
00866       theTool = _world->getTools()->getFoundTool();
00867     } else{
00868       theTool = NULL;
00869     }
00870 
00871     if (theTool && (theTool == _world->getTools()->getUnDefTool())){
00872       _errorCode = CAN_NOT_GETPROPE_UNDEFTOOL;
00873     } else if (theTool && (theGetPropE->getProp(n).getKey2() == PtMeasPar) && 
00874       (theTool == _world->getTools()->getNoTool())) {
00875       _errorCode = CAN_NOT_GETPROPE_PTMEASPARS_OF_NOTOOL;
00876     }
00877   }
00878 }
00879 
00880 /*******************************************************************/
00881 
00882 /* ippCommandChecker::checkGetXtdErrStatus 24
00883 
00884   Returned Value: None.
00885 
00886   Called By: ippCommandChecker::checkCommand
00887 
00888   Rules: None.
00889 
00890   Reference pages: 24 27 (50) 102
00891 
00892 */
00893 
00894 void ippCommandChecker::checkGetXtdErrStatus( ippCommandConstPtr aCommand)
00895 {
00896   
00897 }
00898 
00899 /*******************************************************************/
00900 
00901 /* ippCommandChecker::checkGoTo 25
00902 
00903   Returned Value: None.
00904 
00905   Called By: ippCommandChecker::checkCommand
00906 
00907   Rules:
00908   1. The system must be homed (see page 48).
00909   NOT_HOMED_CAN_NOT_EXECUTE_COMMAND
00910   2. The active tool must not be UnDefTool.
00911   CAN_NOT_GOTO_USING_UNDEFTOOL
00912   3. The target point must be inside the work volume of the machine.
00913   TARGET_POINT_OUT_OF_WORK_VOLUME
00914 
00915   Reference pages: 24 27 [38] [43] (51 - 53) (58) (62) [71] [72] (78) (98) 102
00916         
00917 */
00918 
00919 void ippCommandChecker::checkGoTo( ippCommandConstPtr aCommand)
00920 {
00921   const ippGoToCommand * theGoTo = static_cast<const ippGoToCommand*>(aCommand.get());
00922 
00923   if (!(_world->getIsHomed())) {
00924     _errorCode = NOT_HOMED_CAN_NOT_EXECUTE_COMMAND;
00925 
00926   } else if (_world->getTools()->getActiveTool() == _world->getTools()->getUnDefTool()){
00927      _errorCode = CAN_NOT_GOTO_USING_UNDEFTOOL;
00928   } else if (!(_world->inWorkVolume
00929     ((theGoTo->getHasX() ? theGoTo->getX() : _world->getCurrentX()),
00930     (theGoTo->getHasY() ? theGoTo->getY() : _world->getCurrentY()),
00931     (theGoTo->getHasZ() ? theGoTo->getZ() : _world->getCurrentZ())))) {
00932       _errorCode = TARGET_POINT_OUT_OF_WORK_VOLUME;
00933     }
00934 }
00935 
00936 /*******************************************************************/
00937 
00938 /* ippCommandChecker::checkHome 26
00939 
00940   Returned Value: None.
00941 
00942   Called By: ippCommandChecker::checkCommand
00943 
00944   Rules: None.
00945 
00946     Reference pages: 24 27 [38] (48) 102
00947         
00948 */
00949 
00950 void ippCommandChecker::checkHome( ippCommandConstPtr aCommand)
00951 {
00952   
00953 }
00954 
00955 /*******************************************************************/
00956 
00957 /* ippCommandChecker::checkIsHomed 27
00958 
00959   Returned Value: None.
00960 
00961   Called By: ippCommandChecker::checkCommand
00962 
00963   Rules: None.
00964 
00965   Reference pages: 24 27 (48) 102 111
00966         
00967 */
00968 
00969 void ippCommandChecker::checkIsHomed( ippCommandConstPtr aCommand)
00970 {
00971   
00972 }
00973 
00974 /*******************************************************************/
00975 
00976 /* ippCommandChecker::checkIsUserEnabled 28
00977 
00978   Returned Value: None.
00979 
00980   Called By: ippCommandChecker::checkCommand
00981 
00982   Rules: None.
00983 
00984   Reference pages: 24 27 (49) 102
00985         
00986 */
00987 
00988 void ippCommandChecker::checkIsUserEnabled( ippCommandConstPtr aCommand)
00989 {
00990   
00991 }
00992 
00993 /*******************************************************************/
00994 
00995 /* ippCommandCheckerBase:: checkLockAxis 29
00996 
00997   Returned Value: None.
00998 
00999   Called By: ippCommandChecker::checkCommand
01000 
01001   Rules: None.
01002 
01003   Reference pages: 24 (97-98)
01004         
01005 */
01006 
01007 void ippCommandChecker::checkLockAxis( ippCommandConstPtr aCommand)
01008 {
01009   
01010 }
01011 
01012 /*******************************************************************/
01013 
01014 /* ippCommandChecker::checkOnMoveReportE 30
01015 
01016   Returned Value: None.
01017 
01018   Called By: ippCommandChecker::checkCommand
01019 
01020   Rules:
01021   1. If Time is included, the interval must not be less than 0.1.
01022   TIME_ARGUMENT_MUST_NOT_BE_LESS_THAN_A_TENTH
01023   2. If Dis is included, the interval must be positive.
01024   DIS_ARGUMENT_MUST_BE_POSITIVE
01025   3. An OnMoveReportE daemon must not already exist.
01026   MUST_STOP_EXISTING_DAEMON_BEFORE_STARTING_ANOTHER
01027 
01028   Reference pages: 19 24 27 [39] (49 - 50) 102
01029   This is referenced as "OnReport" on pages 56, 57, 61, 63, and 66.
01030 
01031   Rules 1 and 2 are semantic checks.
01032           
01033 */
01034 
01035 void ippCommandChecker::checkOnMoveReportE( ippCommandConstPtr aCommand)
01036 {
01037   const ippOnMoveReportECommand* theOn =
01038     static_cast<const ippOnMoveReportECommand*>(aCommand.get());
01039   
01040   if (theOn->getHasTime() && (theOn->getTheTime() < 0.1)) {
01041     _errorCode = TIME_ARGUMENT_MUST_NOT_BE_LESS_THAN_A_TENTH;
01042   } else if (theOn->getHasDis() && (theOn->getTheDis() <= 0)) {
01043     _errorCode = DIS_ARGUMENT_MUST_BE_POSITIVE;
01044   } else if (_world->daemonCount() != 0) {
01045     _errorCode = MUST_STOP_EXISTING_DAEMON_BEFORE_STARTING_ANOTHER;
01046   }
01047 }
01048 
01049 /*******************************************************************/
01050 
01051 /* ippCommandChecker::checkOnPtMeasReport 31
01052 
01053   Returned Value: None.
01054 
01055   Called By: ippCommandChecker::checkCommand
01056 
01057   Rules: None.
01058 
01059   Reference pages: 24 27 (41) (49) (52) (53) 61 [71] [72] (78) 102
01060         
01061 */
01062 
01063 void ippCommandChecker::checkOnPtMeasReport( ippCommandConstPtr aCommand)
01064 {
01065   
01066 }
01067 
01068 /*******************************************************************/
01069 
01070 /* ippCommandChecker::checkOnScanReport 32
01071 
01072     Returned Value: None.
01073 
01074     Called By: ippCommandChecker::checkCommand
01075 
01076     Rules: None.
01077 
01078     Reference pages: 24 27 (41) (81) 82 83 84 86 87 88 90 91 [93] 103
01079         
01080 */
01081 
01082 void ippCommandChecker::checkOnScanReport( ippCommandConstPtr aCommand)
01083 {
01084   
01085 }
01086 
01087 /*******************************************************************/
01088 
01089 /* ippCommandChecker::checkPtMeas 33
01090 
01091   
01092 */
01093 
01094 //=============================================================================
01095 void ippCommandChecker::checkPtMeas( ippCommandConstPtr aCommand)
01096 
01097 // Returned Value: None.
01098 //
01099 // Called By: ippCommandChecker::checkCommand
01100 //
01101 // Rules:
01102 // 1. If there is an IJK vector, its length must not be zero.
01103 //    DIRECTION_VECTOR_HAS_ZERO_LENGTH
01104 // 2. The system must be homed (see p. 48).
01105 //    NOT_HOMED_CAN_NOT_EXECUTE_COMMAND
01106 // 3. The target point must be inside the work volume of the machine.
01107 //    TARGET_POINT_OUT_OF_WORK_VOLUME
01108 // 4. The active tool must be an actual tool.
01109 //    CAN_NOT_PTMEAS_USING_UNDEFTOOL
01110 //    CAN_NOT_PTMEAS_USING_NOTOOL
01111 //
01112 //  Reference pages: 9 24 27 (41) (49) (52 - 53) (62) [71] [72] (78) 83 84 86
01113 //                 87 89 90 91 102
01114 {
01115   ippPtMeasCommandConstPtr thePtMeas =  boost::static_pointer_cast<const ippPtMeasCommand>(aCommand);
01116   
01117   if (!(_world->getIsHomed())) {
01118     
01119     _errorCode = NOT_HOMED_CAN_NOT_EXECUTE_COMMAND;
01120     
01121   }  else if ((thePtMeas->getHasIJK()) && (thePtMeas->getI() == 0) && (thePtMeas->getJ() == 0) && (thePtMeas->getK() == 0)) {
01122     
01123     _errorCode = DIRECTION_VECTOR_HAS_ZERO_LENGTH;
01124     
01125   } else if (!(_world->inWorkVolume(
01126     (thePtMeas->getHasX() ? thePtMeas->getX() : _world->getCurrentX()),
01127     (thePtMeas->getHasY() ? thePtMeas->getY() : _world->getCurrentY()),
01128     (thePtMeas->getHasZ() ? thePtMeas->getZ() : _world->getCurrentZ()))))
01129   {
01130     _errorCode = TARGET_POINT_OUT_OF_WORK_VOLUME;
01131     
01132     
01133   } else if (_world->getTools()->getActiveTool() == _world->getTools()->getUnDefTool()) {
01134     
01135     _errorCode = CAN_NOT_PTMEAS_USING_UNDEFTOOL;
01136     
01137   } else if (_world->getTools()->getActiveTool() == _world->getTools()->getNoTool()) {
01138     
01139     _errorCode = CAN_NOT_PTMEAS_USING_NOTOOL;
01140   }
01141 }
01142 
01143 /*******************************************************************/
01144 
01145 /* ippCommandChecker::checkReQualify 34
01146 
01147   Returned Value: None.
01148 
01149   Called By: ippCommandChecker::checkCommand
01150 
01151   Rules:
01152   1. The system must be homed (see p. 48).
01153   NOT_HOMED_CAN_NOT_EXECUTE_COMMAND
01154   2. The current tool must not be UnDefTool.
01155   CAN_NOT_REQUALIFY_UNDEFTOOL
01156   3. The current tool must not be NoTool.
01157   CAN_NOT_REQUALIFY_NOTOOL
01158 
01159   Reference pages: 24 29 (64) 106 107
01160   [This is called Qualify on pages 29 106 107]
01161 
01162   Rules 2 and 3 are not explicit in the spec, but it seems prudent not
01163   to attempt to qualify a non-existent tool or a tool whose identity and
01164   existence are unknown.
01165 
01166   It might be good to add not allowing Requalify when the tool is BaseTool,
01167   since that does not seem to be an actual tool.
01168             
01169 */
01170 
01171 void ippCommandChecker::checkReQualify( ippCommandConstPtr aCommand)
01172 {
01173   if (!(_world->getIsHomed()))
01174     _errorCode = NOT_HOMED_CAN_NOT_EXECUTE_COMMAND;
01175   else if (_world->getTools()->getActiveTool() ==
01176            _world->getTools()->getUnDefTool())
01177      _errorCode = CAN_NOT_REQUALIFY_UNDEFTOOL;
01178   else if (_world->getTools()->getActiveTool() ==
01179            _world->getTools()->getNoTool())
01180      _errorCode = CAN_NOT_REQUALIFY_NOTOOL;
01181 }
01182 
01183 /*******************************************************************/
01184 
01185 /* ippCommandChecker::checkScanInCylEndIsPlane 35
01186 
01187   Returned Value: None.
01188 
01189   Called By: ippCommandChecker::checkCommand
01190 
01191   Rules:
01192   1. The system must be homed (see p. 48).
01193   NOT_HOMED_CAN_NOT_EXECUTE_COMMAND
01194   2. The active tool must be an actual tool.
01195   CAN_NOT_SCAN_USING_UNDEFTOOL
01196   CAN_NOT_SCAN_USING_NOTOOL
01197   3. The direction vector of the axis of the cylinder must not have length 0.
01198   DIRECTION_VECTOR_HAS_ZERO_LENGTH
01199   4. The direction vector at the start point must not have length 0.
01200   DIRECTION_VECTOR_HAS_ZERO_LENGTH
01201   5. The direction vector of the stop plane must not have length 0.
01202   DIRECTION_VECTOR_HAS_ZERO_LENGTH
01203   6. The direction vector at the end point must not have length 0.
01204   DIRECTION_VECTOR_HAS_ZERO_LENGTH
01205   7. The start point must be in the work volume.
01206   SCAN_POINT_MUST_BE_IN_WORK_VOLUME
01207   8. The direction point must be in the work volume.
01208   SCAN_POINT_MUST_BE_IN_WORK_VOLUME
01209   9. The start point must differ from the direction point.
01210   START_POINT_MUST_DIFFER_FROM_DIRECTION_POINT
01211   10. The start point must not be on the cylinder axis.
01212   START_POINT_MUST_NOT_BE_ON_CYLINDER_AXIS
01213 
01214   Reference pages: 24 27 (90 - 91) 103
01215 
01216   Rules 3 - 6 are semantic checks.
01217 
01218   Rule 10 is explicit on page 91. The check is made by checking that the
01219   absolute value of the cosine of the angle between [the axis vector] and
01220   [the vector from the axis point to the start point] is less than one
01221   (actually, less than 0.9999, to account for rounding error).
01222 
01223 */
01224 
01225 void ippCommandChecker::checkScanInCylEndIsPlane( ippCommandConstPtr aCommand)
01226 {
01227   const ippScanInCylEndIsPlaneCommand * theScan = 
01228     static_cast<const ippScanInCylEndIsPlaneCommand*>(aCommand.get());
01229 
01230   double ci = theScan->getCI();
01231   double cj = theScan->getCJ();
01232   double ck = theScan->getCK();
01233   double vi = (theScan->getSx() - theScan->getCx());
01234   double vj = (theScan->getSy() - theScan->getCy());
01235   double vk = (theScan->getSz() - theScan->getCz());
01236 
01237   double lengthc = sqrt((ci * ci) + (cj * cj) + (ck * ck));
01238   double lengthv = sqrt((vi * vi) + (vj * vj) + (vk * vk));
01239 
01240   if (!(_world->getIsHomed())) {
01241     _errorCode = NOT_HOMED_CAN_NOT_EXECUTE_COMMAND;
01242 
01243   } else if (_world->getTools()->getActiveTool() ==  _world->getTools()->getUnDefTool()) {
01244      _errorCode = CAN_NOT_SCAN_USING_UNDEFTOOL;
01245 
01246   } else if (_world->getTools()->getActiveTool() == _world->getTools()->getNoTool()) {
01247      _errorCode = CAN_NOT_SCAN_USING_NOTOOL;
01248 
01249   }  else if (lengthc == 0) {
01250     _errorCode = AXIS_DIRECTION_VECTOR_HAS_ZERO_LENGTH;
01251 
01252   }  else if ((theScan->getSI() == 0) && (theScan->getSJ() == 0) && (theScan->getSK() == 0)) {
01253      _errorCode = DIRECTION_VECTOR_HAS_ZERO_LENGTH;
01254 
01255   }  else if ((theScan->getPI() == 0) && (theScan->getPJ() == 0) &&  (theScan->getPK() == 0)){
01256     _errorCode = DIRECTION_VECTOR_HAS_ZERO_LENGTH;
01257 
01258   }  else if ((theScan->getEI() == 0) && (theScan->getEJ() == 0) &&  (theScan->getEK() == 0)) {
01259      _errorCode = DIRECTION_VECTOR_HAS_ZERO_LENGTH;
01260 
01261   }  else if (!(_world->inWorkVolume(theScan->getSx(), theScan->getSy(), theScan->getSz()))) {
01262     _errorCode = SCAN_POINT_MUST_BE_IN_WORK_VOLUME;
01263 
01264   }  else if (!(_world->inWorkVolume(theScan->getDx(), theScan->getDy(), theScan->getDz()))) {
01265     _errorCode = SCAN_POINT_MUST_BE_IN_WORK_VOLUME;
01266 
01267   } else if ((theScan->getSx() == theScan->getDx()) && (theScan->getSy() == theScan->getDy()) &&  (theScan->getSz() == theScan->getDz())) {
01268      _errorCode = START_POINT_MUST_DIFFER_FROM_DIRECTION_POINT;
01269 
01270   }  else if ((lengthv == 0) ||  (fabs((((ci * vi) + (cj * vj) + (ck * vk)) / lengthc) / lengthv) > 0.9999)) {
01271       _errorCode = START_POINT_MUST_NOT_BE_ON_CYLINDER_AXIS;
01272   }
01273 }
01274 
01275 /*******************************************************************/
01276 
01277 /* ippCommandChecker::checkScanInCylEndIsSphere 36
01278 
01279   Returned Value: None.
01280 
01281   Called By: ippCommandChecker::checkCommand
01282 
01283   Rules: 
01284   1. The system must be homed (see p. 48).
01285   NOT_HOMED_CAN_NOT_EXECUTE_COMMAND
01286   2. The active tool must be an actual tool.
01287   CAN_NOT_SCAN_USING_UNDEFTOOL
01288   CAN_NOT_SCAN_USING_NOTOOL
01289   3. The direction vector of the axis of the cylinder must not have length 0.
01290   DIRECTION_VECTOR_HAS_ZERO_LENGTH
01291   4. The direction vector at the start point must not have length 0.
01292   DIRECTION_VECTOR_HAS_ZERO_LENGTH
01293   5. The direction vector at the end point must not have length 0.
01294   DIRECTION_VECTOR_HAS_ZERO_LENGTH
01295   6. The start point must be in the work volume.
01296   SCAN_POINT_MUST_BE_IN_WORK_VOLUME
01297   7. The direction point must be in the work volume.
01298   SCAN_POINT_MUST_BE_IN_WORK_VOLUME
01299   8. The start point must differ from the direction point.
01300   START_POINT_MUST_DIFFER_FROM_DIRECTION_POINT
01301   9. The start point must not be on the cylinder axis.
01302   START_POINT_MUST_NOT_BE_ON_CYLINDER_AXIS
01303 
01304   Reference pages: 24 27 (89 - 90) 103
01305 
01306   Rules 3 - 5 are semantic checks.
01307 
01308   Rule 9 is explicit on page 90. The check is made by checking that the
01309   absolute value of the cosine of the angle between [the axis vector] and
01310   [the vector from the axis point to the start point] is less than one
01311   (actually, less than 0.9999, to account for rounding error).
01312 
01313 */
01314 
01315 void ippCommandChecker::checkScanInCylEndIsSphere( ippCommandConstPtr aCommand)
01316 {
01317   const ippScanInCylEndIsSphereCommand * theScan =
01318     static_cast<const ippScanInCylEndIsSphereCommand*>(aCommand.get());
01319 
01320   double ci = theScan->getCI();
01321   double cj = theScan->getCJ();
01322   double ck = theScan->getCK();
01323   double vi = (theScan->getSx() - theScan->getCx());
01324   double vj = (theScan->getSy() - theScan->getCy());
01325   double vk = (theScan->getSz() - theScan->getCz());
01326   double lengthc = sqrt((ci * ci) + (cj * cj) + (ck * ck));
01327   double lengthv = sqrt((vi * vi) + (vj * vj) + (vk * vk));
01328 
01329   if (!(_world->getIsHomed())) {
01330     _errorCode = NOT_HOMED_CAN_NOT_EXECUTE_COMMAND;
01331 
01332   } else if (_world->getTools()->getActiveTool() == _world->getTools()->getUnDefTool()) {
01333      _errorCode = CAN_NOT_SCAN_USING_UNDEFTOOL;
01334 
01335   } else if (_world->getTools()->getActiveTool() == _world->getTools()->getNoTool()) {
01336      _errorCode = CAN_NOT_SCAN_USING_NOTOOL;
01337 
01338   } else if (lengthc == 0) {
01339     _errorCode = AXIS_DIRECTION_VECTOR_HAS_ZERO_LENGTH;
01340 
01341   } else if ((theScan->getSI() == 0) &&  (theScan->getSJ() == 0) && (theScan->getSK() == 0)){
01342      _errorCode = DIRECTION_VECTOR_HAS_ZERO_LENGTH;
01343 
01344   } else if ((theScan->getEI() == 0) &&(theScan->getEJ() == 0) && (theScan->getEK() == 0)) {
01345      _errorCode = DIRECTION_VECTOR_HAS_ZERO_LENGTH;
01346 
01347   } else if (!(_world->inWorkVolume(theScan->getSx(), theScan->getSy(), theScan->getSz()))) {
01348     _errorCode = SCAN_POINT_MUST_BE_IN_WORK_VOLUME;
01349 
01350   } else if (!(_world->inWorkVolume (theScan->getDx(), theScan->getDy(), theScan->getDz()))) {
01351     _errorCode = SCAN_POINT_MUST_BE_IN_WORK_VOLUME;
01352 
01353   } else if ((theScan->getSx() == theScan->getDx()) &&(theScan->getSy() == theScan->getDy()) && (theScan->getSz() == theScan->getDz())){
01354      _errorCode = START_POINT_MUST_DIFFER_FROM_DIRECTION_POINT;
01355 
01356   } else if ((lengthv == 0) ||(fabs((((ci * vi) + (cj * vj) + (ck * vk)) / lengthc) / lengthv)> 0.9999)) {
01357      _errorCode = START_POINT_MUST_NOT_BE_ON_CYLINDER_AXIS;
01358   }
01359 }
01360 
01361 /*******************************************************************/
01362 
01363 /* ippCommandChecker::checkScanInPlaneEndIsCyl 37
01364 
01365   Returned Value: None.
01366   
01367     Called By: ippCommandChecker::checkCommand
01368     
01369       Rules:
01370       1. The system must be homed (see p. 48).
01371       NOT_HOMED_CAN_NOT_EXECUTE_COMMAND
01372       2. The active tool must be an actual tool.
01373       CAN_NOT_SCAN_USING_UNDEFTOOL
01374       CAN_NOT_SCAN_USING_NOTOOL
01375       3. The direction vector of the axis of the cylinder must not have length 0.
01376       AXIS_DIRECTION_VECTOR_HAS_ZERO_LENGTH
01377       4. The direction vector at the start point must not have length 0.
01378       DIRECTION_VECTOR_HAS_ZERO_LENGTH
01379       5. The direction vector at the end point must not have length 0.
01380       DIRECTION_VECTOR_HAS_ZERO_LENGTH
01381       6. The start point must be in the work volume.
01382       SCAN_POINT_MUST_BE_IN_WORK_VOLUME
01383       7. The direction point must be in the work volume.
01384       SCAN_POINT_MUST_BE_IN_WORK_VOLUME
01385       8. The start point must differ from the direction point.
01386       START_POINT_MUST_DIFFER_FROM_DIRECTION_POINT
01387       
01388         Reference pages: 24 27 (88 - 89) 103
01389         
01390 */
01391 
01392 void ippCommandChecker::checkScanInPlaneEndIsCyl( ippCommandConstPtr aCommand)
01393 {
01394   const ippScanInPlaneEndIsCylCommand * theScan = 
01395     static_cast<const ippScanInPlaneEndIsCylCommand*>(aCommand.get());
01396   
01397   if (!(_world->getIsHomed())) {
01398     _errorCode = NOT_HOMED_CAN_NOT_EXECUTE_COMMAND;
01399 
01400   }  else if (_world->getTools()->getActiveTool() ==  _world->getTools()->getUnDefTool()){
01401      _errorCode = CAN_NOT_SCAN_USING_UNDEFTOOL;
01402 
01403   } else if (_world->getTools()->getActiveTool() == _world->getTools()->getNoTool()){
01404      _errorCode = CAN_NOT_SCAN_USING_NOTOOL;
01405 
01406   }  else if ((theScan->getCI() == 0) && (theScan->getCJ() == 0) && (theScan->getCK() == 0)){
01407      _errorCode = AXIS_DIRECTION_VECTOR_HAS_ZERO_LENGTH;
01408 
01409   } else if ((theScan->getSI() == 0) && (theScan->getSJ() == 0) && (theScan->getSK() == 0)) {
01410     _errorCode = DIRECTION_VECTOR_HAS_ZERO_LENGTH;
01411 
01412 
01413   } else if ((theScan->getEI() == 0) &&  (theScan->getEJ() == 0) && (theScan->getEK() == 0)){
01414      _errorCode = DIRECTION_VECTOR_HAS_ZERO_LENGTH;
01415 
01416   } else if (!(_world->inWorkVolume(theScan->getSx(), theScan->getSy(), theScan->getSz()))){
01417     _errorCode = SCAN_POINT_MUST_BE_IN_WORK_VOLUME;
01418 
01419   } else if (!(_world->inWorkVolume(theScan->getDx(), theScan->getDy(), theScan->getDz()))){
01420     _errorCode = SCAN_POINT_MUST_BE_IN_WORK_VOLUME;
01421   
01422   }else if ((theScan->getSx() == theScan->getDx()) &&(theScan->getSy() == theScan->getDy()) && (theScan->getSz() == theScan->getDz())){
01423      _errorCode = START_POINT_MUST_DIFFER_FROM_DIRECTION_POINT;
01424 
01425   }
01426 }
01427 
01428 /*******************************************************************/
01429 
01430 /* ippCommandChecker::checkScanInPlaneEndIsPlane 38
01431 
01432   Returned Value: None.
01433   
01434     Called By: ippCommandChecker::checkCommand
01435     
01436       Rules:
01437       1. The system must be homed (see p. 48).
01438       NOT_HOMED_CAN_NOT_EXECUTE_COMMAND
01439       2. The active tool must be an actual tool.
01440       CAN_NOT_SCAN_USING_UNDEFTOOL
01441       CAN_NOT_SCAN_USING_NOTOOL
01442       3. The direction vector at the start point must not have length 0.
01443       DIRECTION_VECTOR_HAS_ZERO_LENGTH
01444       4. The direction vector of the stop plane must not have length 0.
01445       DIRECTION_VECTOR_HAS_ZERO_LENGTH
01446       5. The direction vector at the end point must not have length 0.
01447       DIRECTION_VECTOR_HAS_ZERO_LENGTH
01448       6. The start point must be in the work volume.
01449       SCAN_POINT_MUST_BE_IN_WORK_VOLUME
01450       7. The direction point must be in the work volume.
01451       SCAN_POINT_MUST_BE_IN_WORK_VOLUME
01452       8. The start point must differ from the direction point.
01453       START_POINT_MUST_DIFFER_FROM_DIRECTION_POINT
01454       
01455         Reference pages: 24 27 (86 - 87) 103
01456         
01457 */
01458 
01459 void ippCommandChecker::checkScanInPlaneEndIsPlane( ippCommandConstPtr aCommand)
01460 {
01461   const ippScanInPlaneEndIsPlaneCommand* theScan= 
01462     static_cast<const ippScanInPlaneEndIsPlaneCommand*>(aCommand.get());
01463 
01464   
01465   if (!(_world->getIsHomed())) {
01466    _errorCode = NOT_HOMED_CAN_NOT_EXECUTE_COMMAND;
01467 
01468   } else if (_world->getTools()->getActiveTool() == _world->getTools()->getUnDefTool()) {
01469    _errorCode = CAN_NOT_SCAN_USING_UNDEFTOOL;
01470 
01471   } else if (_world->getTools()->getActiveTool() == _world->getTools()->getNoTool()){
01472    _errorCode = CAN_NOT_SCAN_USING_NOTOOL;
01473   
01474   } else if ((theScan->getSI() == 0) &&(theScan->getSJ() == 0) && (theScan->getSK() == 0)){
01475    _errorCode = DIRECTION_VECTOR_HAS_ZERO_LENGTH;
01476 
01477   }else if ((theScan->getPI() == 0) && (theScan->getPJ() == 0) &&(theScan->getPK() == 0)) {
01478     _errorCode = DIRECTION_VECTOR_HAS_ZERO_LENGTH;
01479 
01480   } else if ((theScan->getEI() == 0) &&(theScan->getEJ() == 0) &&(theScan->getEK() == 0)) {
01481     _errorCode = DIRECTION_VECTOR_HAS_ZERO_LENGTH;
01482 
01483   } else if (!(_world->inWorkVolume(theScan->getSx(), theScan->getSy(), theScan->getSz()))){
01484     _errorCode = SCAN_POINT_MUST_BE_IN_WORK_VOLUME;
01485 
01486   } else if (!(_world->inWorkVolume(theScan->getDx(), theScan->getDy(), theScan->getDz()))){
01487     _errorCode = SCAN_POINT_MUST_BE_IN_WORK_VOLUME;
01488 
01489   } else if ((theScan->getSx() == theScan->getDx()) &&(theScan->getSy() == theScan->getDy()) && (theScan->getSz() == theScan->getDz())) {
01490      _errorCode = START_POINT_MUST_DIFFER_FROM_DIRECTION_POINT;
01491 
01492   }
01493 }
01494 
01495 /*******************************************************************/
01496 
01497 /* ippCommandChecker::checkScanInPlaneEndIsSphere 39
01498 
01499   Returned Value: None.
01500   
01501     Called By: ippCommandChecker::checkCommand
01502     
01503       Rules:
01504       1. The system must be homed (see p. 48).
01505       NOT_HOMED_CAN_NOT_EXECUTE_COMMAND
01506       2. The active tool must be an actual tool.
01507       CAN_NOT_SCAN_USING_UNDEFTOOL
01508       CAN_NOT_SCAN_USING_NOTOOL
01509       3. The direction vector at the start point must not have length 0.
01510       DIRECTION_VECTOR_HAS_ZERO_LENGTH
01511       4.The direction vector at the end point must not have length 0.
01512       DIRECTION_VECTOR_HAS_ZERO_LENGTH
01513       5. The start point must be in the work volume.
01514       SCAN_POINT_MUST_BE_IN_WORK_VOLUME
01515       6. The end point must be in the work volume.
01516       SCAN_POINT_MUST_BE_IN_WORK_VOLUME
01517       7. The direction point must be in the work volume.
01518       SCAN_POINT_MUST_BE_IN_WORK_VOLUME
01519       8. The start point must differ from the direction point
01520       START_POINT_MUST_DIFFER_FROM_DIRECTION_POINT
01521       
01522         Reference pages: 24 27 (85 - 86) [94] 103
01523         
01524 */
01525 
01526 void ippCommandChecker::checkScanInPlaneEndIsSphere( ippCommandConstPtr aCommand)
01527 {
01528   const ippScanInPlaneEndIsSphereCommand * theScan = 
01529     static_cast<const ippScanInPlaneEndIsSphereCommand*>(aCommand.get());
01530   
01531   if (!(_world->getIsHomed()))  {
01532     _errorCode = NOT_HOMED_CAN_NOT_EXECUTE_COMMAND;
01533   
01534   } else if (_world->getTools()->getActiveTool() == _world->getTools()->getUnDefTool()){
01535      _errorCode = CAN_NOT_SCAN_USING_UNDEFTOOL;
01536 
01537   } else if (_world->getTools()->getActiveTool() == _world->getTools()->getNoTool()){
01538      _errorCode = CAN_NOT_SCAN_USING_NOTOOL;
01539 
01540   } else if ((theScan->getSI() == 0) && (theScan->getSJ() == 0) && (theScan->getSK() == 0)) {
01541     _errorCode = DIRECTION_VECTOR_HAS_ZERO_LENGTH;
01542   
01543   } else if ((theScan->getEI() == 0) && (theScan->getEJ() == 0) && (theScan->getEK() == 0)){
01544      _errorCode = DIRECTION_VECTOR_HAS_ZERO_LENGTH;
01545   
01546   } else if (!(_world->inWorkVolume(theScan->getSx(), theScan->getSy(), theScan->getSz()))){
01547     _errorCode = SCAN_POINT_MUST_BE_IN_WORK_VOLUME;
01548 
01549   } else if (!(_world->inWorkVolume(theScan->getDx(), theScan->getDy(), theScan->getDz()))){
01550     _errorCode = SCAN_POINT_MUST_BE_IN_WORK_VOLUME;
01551   
01552   } else if (!(_world->inWorkVolume(theScan->getEx(), theScan->getEy(), theScan->getEz()))){
01553     _errorCode = SCAN_POINT_MUST_BE_IN_WORK_VOLUME;
01554 
01555   } else if ((theScan->getSx() == theScan->getDx()) && (theScan->getSy() == theScan->getDy()) && (theScan->getSz() == theScan->getDz())){
01556      _errorCode = START_POINT_MUST_DIFFER_FROM_DIRECTION_POINT;
01557 
01558   }
01559 }
01560 
01561 /*******************************************************************/
01562 
01563 /* ippCommandChecker::checkScanOnCircle 40
01564 
01565   Returned Value: None.
01566   
01567     Called By: ippCommandChecker::checkCommand
01568     
01569       Rules:
01570       1. The system must be homed (see p. 48).
01571       NOT_HOMED_CAN_NOT_EXECUTE_COMMAND
01572       2. The active tool must be an actual tool.
01573       CAN_NOT_SCAN_USING_UNDEFTOOL
01574       CAN_NOT_SCAN_USING_NOTOOL
01575       3. The direction vector of the axis of the circle must not have length 0.
01576       DIRECTION_VECTOR_HAS_ZERO_LENGTH
01577       4. The radius of the circle must not have length 0.
01578       RADIUS_MUST_HAVE_POSITIVE_LENGTH
01579       5. The radius of the circle must be perpendicular to its normal
01580       RADIUS_MUST_BE_PERPENDICULAR_TO_NORMAL
01581       6. The start point must be in the work volume.
01582       SCAN_POINT_MUST_BE_IN_WORK_VOLUME
01583       
01584         Reference pages: 24 27 (82 - 83) [93] 103
01585         
01586           It would be useful to add:
01587           5. end point in work volume
01588           
01589 */
01590 
01591 void ippCommandChecker::checkScanOnCircle( ippCommandConstPtr aCommand)
01592 {
01593   const ippScanOnCircleCommand * theScan = 
01594     static_cast<const ippScanOnCircleCommand *>(aCommand.get());
01595 
01596   double i = theScan->getI();
01597   double j = theScan->getJ();
01598   double k = theScan->getK();
01599   double norml = sqrt((i * i) + (j * j) + (k * k));
01600   double radx = (theScan->getSx() - theScan->getCx());
01601   double rady = (theScan->getSy() - theScan->getCy());
01602   double radz = (theScan->getSz() - theScan->getCz());
01603   double radl = sqrt((radx * radx) + (rady * rady) + (radz * radz));
01604   
01605   if (!(_world->getIsHomed())) {
01606     _errorCode = NOT_HOMED_CAN_NOT_EXECUTE_COMMAND;
01607 
01608   } else if (_world->getTools()->getActiveTool() == _world->getTools()->getUnDefTool()){
01609      _errorCode = CAN_NOT_SCAN_USING_UNDEFTOOL;
01610 
01611   }  else if (_world->getTools()->getActiveTool() == _world->getTools()->getNoTool()) {
01612      _errorCode = CAN_NOT_SCAN_USING_NOTOOL;
01613 
01614   }  else if (norml == 0) {
01615     _errorCode = DIRECTION_VECTOR_HAS_ZERO_LENGTH;
01616 
01617   } else if (radl == 0) {
01618     _errorCode = RADIUS_MUST_HAVE_POSITIVE_LENGTH;
01619 
01620   }  else if (fabs(((i * radx) + (j * rady) + (k * radz)) / (norml * radl)) > IPP_NORMAL_ERROR) {
01621     _errorCode = RADIUS_MUST_BE_PERPENDICULAR_TO_NORMAL;
01622 
01623   }  else if (!(_world->inWorkVolume(theScan->getSx(), theScan->getSy(), theScan->getSz()))) {
01624     _errorCode = SCAN_POINT_MUST_BE_IN_WORK_VOLUME;
01625 
01626   }
01627 }
01628 
01629 /*******************************************************************/
01630 
01631 /* ippCommandChecker::checkScanOnCircleHint 41
01632 
01633   Returned Value: None.
01634   
01635     Called By: ippCommandChecker::checkCommand
01636     
01637       Rules: None
01638       
01639         Reference pages: 24 27 (82) [93] 103
01640         
01641 */
01642 
01643 void ippCommandChecker::checkScanOnCircleHint( ippCommandConstPtr aCommand)
01644 {
01645   
01646 }
01647 
01648 /*******************************************************************/
01649 
01650 /* ippCommandChecker::checkScanOnLine 42
01651 
01652   Returned Value: None.
01653   
01654     Called By: ippCommandChecker::checkCommand
01655     
01656       Rules:
01657       1. The system must be homed (see p. 48).
01658       NOT_HOMED_CAN_NOT_EXECUTE_COMMAND
01659       2. The active tool must be an actual tool.
01660       CAN_NOT_SCAN_USING_UNDEFTOOL
01661       CAN_NOT_SCAN_USING_NOTOOL
01662       3. The start point must differ from the end point.
01663       START_POINT_MUST_DIFFER_FROM_END_POINT
01664       4. The start point must be in the work volume.
01665       SCAN_POINT_MUST_BE_IN_WORK_VOLUME
01666       5. The end point must be in the work volume.
01667       SCAN_POINT_MUST_BE_IN_WORK_VOLUME
01668       
01669         Reference pages: 24 27 (83 - 84) 103
01670         
01671 */
01672 
01673 void ippCommandChecker::checkScanOnLine( ippCommandConstPtr aCommand)
01674 {
01675   const ippScanOnLineCommand* theScan =
01676    static_cast<const ippScanOnLineCommand *>(aCommand.get());
01677 
01678   if (!(_world->getIsHomed())) {
01679     _errorCode = NOT_HOMED_CAN_NOT_EXECUTE_COMMAND;
01680 
01681   } else if (_world->getTools()->getActiveTool() == _world->getTools()->getUnDefTool()){
01682      _errorCode = CAN_NOT_SCAN_USING_UNDEFTOOL;
01683 
01684   }  else if (_world->getTools()->getActiveTool() == _world->getTools()->getNoTool()){
01685      _errorCode = CAN_NOT_SCAN_USING_NOTOOL;
01686 
01687   }  else if ((theScan->getSx() == theScan->getEx()) && (theScan->getSy() == theScan->getEy()) &&(theScan->getSz() == theScan->getEz())){
01688      _errorCode = START_POINT_MUST_DIFFER_FROM_END_POINT;
01689 
01690   } else if (!(_world->inWorkVolume(theScan->getSx(), theScan->getSy(), theScan->getSz()))){
01691     _errorCode = SCAN_POINT_MUST_BE_IN_WORK_VOLUME;
01692 
01693   }  else if (!(_world->inWorkVolume(theScan->getEx(), theScan->getEy(), theScan->getEz()))){
01694     _errorCode = SCAN_POINT_MUST_BE_IN_WORK_VOLUME;
01695 
01696   }
01697 }
01698 
01699 /*******************************************************************/
01700 
01701 /* ippCommandChecker::checkScanOnLineHint 43
01702 
01703   Returned Value: None.
01704   
01705     Called By: ippCommandChecker::checkCommand
01706     
01707       Rules: None.
01708       
01709         Reference pages: 24 27 (83) 103
01710         
01711 */
01712 
01713 void ippCommandChecker::checkScanOnLineHint( ippCommandConstPtr aCommand)
01714 {
01715   
01716 }
01717 
01718 /*******************************************************************/
01719 
01720 /* ippCommandChecker::checkScanUnknownHint 44
01721 
01722   Returned Value: None.
01723   
01724     Called By: ippCommandChecker::checkCommand
01725     
01726       Rules: None.
01727       
01728         Reference pages: 24 27 (85) [93] 103
01729         
01730 */
01731 
01732 void ippCommandChecker::checkScanUnknownHint( ippCommandConstPtr aCommand)
01733 {
01734   
01735 }
01736 
01737 /*******************************************************************/
01738 
01739 /* ippCommandChecker::checkScanUnknownDensity 
01740 
01741          
01742 */
01743 
01744 void ippCommandChecker::checkScanUnknownDensity( ippCommandConstPtr aCommand)
01745 {
01746   
01747 }
01748 
01749 /*******************************************************************/
01750 
01751 /* ippCommandChecker::checkSetCoordSystem 45
01752 
01753   Returned Value: None.
01754   
01755     Called By: ippCommandChecker::checkCommand
01756     
01757       Rules: None.
01758       
01759         Reference pages: 24 28 58 (59) (67) [71] [72] 103
01760         
01761 */
01762 
01763 void ippCommandChecker::checkSetCoordSystem( ippCommandConstPtr aCommand)
01764 {
01765   
01766 }
01767 
01768 /*******************************************************************/
01769 
01770 /* ippCommandChecker::checkSetCsyTransformation 46
01771 
01772   Returned Value: None.
01773   
01774     Called By:
01775     ippCommandChecker::checkCommand
01776     Rules:
01777     1. Theta must not be negative or more than 180 degrees.
01778     THETA_MUST_NOT_BE_NEGATIVE_OR_MORE_THAN_180
01779     
01780       Reference pages: 24 28 59 (60) 67 [71] [72] (80) 103
01781       
01782         Rule 1 is a semantic check and is currently also done in the command
01783         parser.
01784         
01785 */
01786 
01787 void ippCommandChecker::checkSetCsyTransformation( ippCommandConstPtr aCommand)
01788 {
01789   const ippSetCsyTransformationCommand* theSetCsyTransformation =  
01790     static_cast<const ippSetCsyTransformationCommand *>(aCommand.get());
01791 
01792   if ((theSetCsyTransformation->getTheta() < 0) || (theSetCsyTransformation->getTheta() > 180)){
01793     _errorCode = THETA_MUST_NOT_BE_NEGATIVE_OR_MORE_THAN_180;
01794   }
01795 
01796 }
01797 
01798 /*******************************************************************/
01799 
01800 /* ippCommandChecker::checkSetProp 47
01801 
01802   Returned Value: None.
01803   
01804     Called By: ippCommandChecker::checkCommand
01805     
01806       Rules: 
01807       1. Properties of UnDefTool cannot be set by SetProp.
01808       CAN_NOT_SETPROP_UNDEFTOOL
01809       2. PtMeas parameters of NoTool cannot be set by SetProp.
01810       CAN_NOT_SETPROP_PTMEASPARS_OF_NOTOOL
01811       
01812         Reference pages: 24 26 29 (45) 65 [73] 77 (78) 99 108
01813         Also see the reference pages for GetProp, since several of those imply
01814         that certain properties cannot be set directly.
01815         
01816           These rules are not explicit in the spec, but seem implicit.
01817           
01818             This is not checking for attempting to cause an out-of-range condition
01819             or attempting to set an unsettable parameter. These checks might be
01820             added. The behavior of updateSetProp in world.cc, combined with the
01821             behavior of the Param class in tools.h handles these cases without error.
01822             
01823 */
01824 
01825 void ippCommandChecker::checkSetProp( ippCommandConstPtr aCommand)
01826 {
01827   const ippSetPropCommand * theSetProp = 
01828     static_cast<const ippSetPropCommand*>(aCommand.get());
01829 
01830   ippKToolConstPtr theTool;
01831   int n;
01832   
01833   for (n = 0;
01834   ((_errorCode == CHECKER_OK) && (n < theSetProp->getNumberProps()));
01835   n++)
01836   {
01837     if (theSetProp->getProp(n).getKey1() == Tool)
01838       theTool = _world->getTools()->getActiveTool();
01839     else if (theSetProp->getProp(n).getKey1() == FoundTool)
01840       theTool = _world->getTools()->getFoundTool();
01841     else
01842       theTool = NULL;
01843     if (theTool && (theTool == _world->getTools()->getUnDefTool()))
01844       _errorCode = CAN_NOT_SETPROP_UNDEFTOOL;
01845     else if (theTool && (theSetProp->getProp(n).getKey2() == PtMeasPar) &&
01846       (theTool == _world->getTools()->getNoTool()))
01847       _errorCode = CAN_NOT_SETPROP_PTMEASPARS_OF_NOTOOL;
01848   }
01849 }
01850 
01851 /*******************************************************************/
01852 
01853 /* ippCommandChecker::checkSetTool 48
01854 
01855   Returned Value: None.
01856   
01857     Called By: ippCommandChecker::checkCommand
01858     
01859       Rules: 
01860       1. The tool must be one of the tools known to the toolchanger.
01861       UNKNOWN_TOOL
01862       2. The name of the tool must not be "UnDefTool".
01863       CAN_NOT_SET_TOOL_TO_UNDEFTOOL
01864       
01865         Reference pages: 24 27 29 (54 - 55) 102 106
01866         
01867           Rule 2 above is not explicit in the spec, but seems implicit. It also
01868           seems implicit that it should be possible to set the tool to "NoTool",
01869           "BaseTool" or "RefTool". These are the same rules as used for ChangeTool.
01870           
01871 */
01872 
01873 void ippCommandChecker::checkSetTool( ippCommandConstPtr aCommand)
01874 {
01875   const ippSetToolCommand * theSet = 
01876     static_cast<const ippSetToolCommand*>(aCommand.get());
01877   
01878   if (strcmp("UnDefTool", theSet->getToolName()) == 0) {
01879     _errorCode = CAN_NOT_SET_TOOL_TO_UNDEFTOOL;
01880   } else if (!_world->getTools()->findTool(theSet->getToolName())) {
01881     _errorCode = UNKNOWN_TOOL;
01882   }
01883 }
01884 
01885 /*******************************************************************/
01886 
01887 /* ippCommandChecker::checkStartSession 49
01888 
01889   Returned Value: None.
01890   
01891     Called By: ippCommandChecker::checkCommand
01892     
01893       Rules:
01894       1. A session must not already be in progress.
01895       ALREADY_IN_SESSION
01896       
01897         Reference pages: 18 20 24 26 (38) (41) 49 [71] (77) 81 99
01898         
01899 */
01900 
01901 void ippCommandChecker::checkStartSession( ippCommandConstPtr aCommand)
01902 {
01903 }
01904 
01905 /*******************************************************************/
01906 
01907 /* ippCommandChecker::checkStopAllDaemons 50
01908 
01909   Returned Value: None.
01910   
01911     Called By: ippCommandChecker::checkCommand
01912     
01913       Rules: None.
01914       
01915         Reference pages: 24 26 (42) (50) 99
01916         
01917           The spec lists no errors. It is not an error to call this when no
01918           daemons exist.
01919           
01920 */
01921 
01922 void ippCommandChecker::checkStopAllDaemons( ippCommandConstPtr aCommand)
01923 {
01924   
01925 }
01926 
01927 /*******************************************************************/
01928 
01929 /* ippCommandChecker::checkStopDaemon 51
01930 
01931   Returned Value: None.
01932 
01933   Called By: ippCommandChecker::checkCommand
01934 
01935   Rules:
01936   1. The daemon identified in the command must exist.
01937   DAEMON_TO_STOP_DOES_NOT_EXIST
01938 
01939     Reference pages: 19 (22) 24 26 [40] (42) (50) 99
01940         
01941 */
01942 
01943 void ippCommandChecker::checkStopDaemon( ippCommandConstPtr aCommand)
01944 {
01945   const ippStopDaemonCommand * theStop = 
01946     static_cast<const ippStopDaemonCommand* >(aCommand.get());
01947 
01948   int tagNumber= theStop->getDaemonTag().getTagNumber();
01949   if (!(_world->daemonExists(tagNumber))) {
01950     _errorCode = DAEMON_TO_STOP_DOES_NOT_EXIST;
01951   }
01952 }
01953 
01954 /*******************************************************************/
01955 
01956 /* ippCommandCheckerBase:: checkTiltCenterPart 52
01957 
01958   Returned Value: None.
01959   
01960   Called By: ippCommandChecker::checkCommand
01961 
01962   Rules:
01963   1. The two circle centers must not be in the same place.
01964   AXIS_DIRECTION_VECTOR_HAS_ZERO_LENGTH
01965 
01966   Reference pages: 24 27 (97) 102
01967 
01968   If the circle centers are in the same place, the vector between them
01969   does not have a direction. This rule is not explicit in the spec, but
01970   if the direction does not exist, the distance to the axis (which is
01971   needed for determining whether the centers are within the limit) does
01972   not exist.
01973 
01974     Rule 1 is a semantic check.
01975             
01976 */
01977 
01978 void ippCommandChecker::checkTiltCenterPart( ippCommandConstPtr aCommand)
01979 {
01980   const ippTiltCenterPartCommand * theTiltCenter =
01981     static_cast<const ippTiltCenterPartCommand *>(aCommand.get());
01982   
01983   double vecX = (theTiltCenter->getPx1() - theTiltCenter->getPx2());
01984   double vecY = (theTiltCenter->getPy1() - theTiltCenter->getPy2());
01985   double vecZ = (theTiltCenter->getPz1() - theTiltCenter->getPz2());
01986   double length = sqrt((vecX * vecX) + (vecY * vecY) + (vecZ * vecZ));
01987   
01988   if (length == 0) {
01989     _errorCode = AXIS_DIRECTION_VECTOR_HAS_ZERO_LENGTH;
01990   }
01991 }
01992 
01993 /*******************************************************************/
01994 
01995 /* ippCommandCheckerBase:: checkTiltPart 53
01996 
01997   Returned Value: None.
01998   
01999   Called By: ippCommandChecker::checkCommand
02000 
02001   Rules:
02002   1. The length of the axis direction vector must not be 0.
02003   AXIS_DIRECTION_VECTOR_HAS_ZERO_LENGTH
02004 
02005   Reference pages: 24 27 (97) 102
02006 
02007   Rule 1 is not explicit in the spec, but if the direction vector has no
02008   length, it has no direction and cannot be used for the required
02009   comparison with the measured direction.
02010 
02011   Rule 1 is a semantic check.
02012             
02013 */
02014 
02015 void ippCommandChecker::checkTiltPart(ippCommandConstPtr aCommand)
02016 {
02017   const ippTiltPartCommand*  theTilt  = 
02018     static_cast<const ippTiltPartCommand *>(aCommand.get());
02019   
02020   double vecX = theTilt->getDx();
02021   double vecY = theTilt->getDy();
02022   double vecZ = theTilt->getDz();
02023   double length = sqrt((vecX * vecX) + (vecY * vecY) + (vecZ * vecZ));
02024   if (length == 0){
02025     _errorCode = AXIS_DIRECTION_VECTOR_HAS_ZERO_LENGTH;
02026   }
02027 }
02028 
02029 
02030 void ippCommandChecker::checkEnumToolCollection(ippCommandConstPtr aCommand)
02031 {
02032 
02033 }
02034 void ippCommandChecker::checkEnumAllToolCollections(ippCommandConstPtr aCommand)
02035 {
02036 
02037 }
02038 void ippCommandChecker::checkOpenToolCollection(ippCommandConstPtr aCommand)
02039 {
02040 
02041 }
02042 void ippCommandChecker::checkSaveActiveCoordSystem(ippCommandConstPtr aCommand)
02043 {
02044 
02045 }
02046 void ippCommandChecker::checkLoadCoordSystem(ippCommandConstPtr aCommand)
02047 {
02048 
02049 }
02050 void ippCommandChecker::checkDeleteCoordSystem(ippCommandConstPtr aCommand)
02051 {
02052 
02053 }
02054 void ippCommandChecker::checkEnumCoordSystems(ippCommandConstPtr aCommand)
02055 {
02056 
02057 }
02058 void ippCommandChecker::checkGetNamedCsyTransformation(ippCommandConstPtr aCommand)
02059 {
02060 
02061 }
02062 void ippCommandChecker::checkSaveNamedCsyTransformation(ippCommandConstPtr aCommand)
02063 {
02064 
02065 }
02066 void ippCommandChecker::checkScanOnCurveDensity(ippCommandConstPtr aCommand)
02067 {
02068 
02069 }
02070 void ippCommandChecker::checkScanOnCurve(ippCommandConstPtr aCommand)
02071 {
02072 
02073 }
02074 void ippCommandChecker::checkScanOnCurveHint(ippCommandConstPtr aCommand)
02075 {
02076 
02077 }
02078 void ippCommandChecker::checkScanOnHelix(ippCommandConstPtr aCommand)
02079 {
02080 
02081 }
02082 void ippCommandChecker::checkPtMeasSelfCenter(ippCommandConstPtr aCommand)
02083 {
02084 
02085 }
02086 void ippCommandChecker::checkPtMeasSelfCenterLocked(ippCommandConstPtr aCommand)
02087 {
02088 
02089 }
02090 
02091 /*******************************************************************/
02092 
02093 /* ippCommandChecker::checkCommand 54
02094 
02095   Returned Value: None.
02096 
02097   Called By:
02098   external functions
02099   main (in stand-alone command checker)
02100 
02101   Rules:
02102   1. If a session is not in progress, only StartSession and EndSession
02103   may be executed.
02104   NOT_IN_SESSION_CAN_NOT_EXECUTE_COMMAND
02105   2. If in session and readiness is erred, only GetErrStatusE,
02106   GetXtdErrStatus, or ClearAllErrors may be executed.
02107   READINESS_ERRED_CAN_NOT_EXECUTE_COMMAND
02108   3. If readiness is aborted, only GetErrStatusE,
02109   GetXtdErrStatus, or ClearAllErrors may be executed.
02110   READINESS_ABORTED_CAN_NOT_EXECUTE_COMMAND
02111 
02112   This is allowing AbortE if readiness is aborted or erred, but not if no
02113   session is in progress.
02114 
02115   StartSession has the effect of ClearAllErrors (in case an error occurs
02116   during the execution of StartSession).
02117 
02118   References:
02119   Rule 1 above: (41)
02120   AbortE: 9 24 26 (42) [43] 99
02121   ClearAllErrors: 24 26 [38] (40) (41) (42) (43) [44] (47) (75) 76 99
02122   StartSession: 18 20 24 26 (38) (41) 49 [71] (77) 81 99
02123 
02124   After checking the rules described above, the function calls a checker
02125   specific to the command.
02126 
02127   There is currently no command that can call for an abort while a
02128   StartSession command is being executed.
02129 
02130   Allowing GetErrStatusE and GetXtdErrStatus when in an error state or
02131   an aborted state (as done by Rules 2 and 3 above) is not currently
02132   supported by the spec, but it should be because otherwise
02133   GetErrStatusE and GetXtdErrStatus have no useful function. The spec
02134   actually says (page 43) that after AbortE, only ClearAllErrors is
02135   allowed, and (page 40) that after an error of severity 2 or greater,
02136   only ClearAllErrors is allowed.
02137 
02138   It seems prudent to allow AbortE at any time, even though the spec
02139   does not support that. It was allowed in previous versions of this
02140   command checker (1.0 to 2.1) but is not allowed in this version.
02141 
02142   The positions of functions in the checkers array correspond to the
02143   names in the commandNameType enumeration in IppCmdRes.h. The
02144   enumeration has no name for indexes 0 and 1. checkAbortE is
02145   used here in those positions. These indexes will never be used, so
02146   any of the checkXXX functions could have been used there.
02147 
02148 */
02149 ippCheckerErrorId ippCommandCheckerBase::checkCommand( ippCommandConstPtr aCommand)
02150 {
02151   _errorCode = CHECKER_OK;
02152   return _errorCode;
02153 }
02154 
02155 ippCommandChecker::ippCommandChecker(world& inWorld)
02156 : _world(&inWorld)
02157 {
02158 }
02159 
02160 ippCheckerErrorId ippCommandChecker::checkCommand( ippCommandConstPtr aCommand)
02161 {
02162 
02163   _errorCode = CHECKER_OK;
02164 
02165   _commandName = aCommand->getCommandName();
02166  
02167   if (_errorCode == CHECKER_OK) {
02168     
02169     if ((_world->getReadiness() == erred) && // we are in error state ...
02170                     (_commandName != GetErrStatusE)    && // and the command is not related
02171         (_commandName != GetXtdErrStatus)  && // to clearing or asking about the error
02172         (_commandName != ClearAllErrors)) { 
02173       
02174       // an error has been reported 
02175       // the client must send ClearAllErrors() 
02176       _errorCode = READINESS_ERRED_CAN_NOT_EXECUTE_COMMAND;
02177       
02178     } else if ((_world->getReadiness() == aborted) &&
02179       (_commandName != GetErrStatusE) &&
02180       (_commandName != GetXtdErrStatus) &&
02181       (_commandName != ClearAllErrors)) {
02182       
02183       _errorCode = READINESS_ABORTED_CAN_NOT_EXECUTE_COMMAND;
02184     }
02185   }
02186   if (_errorCode == CHECKER_OK) {
02187   
02188       switch(_commandName)
02189       {
02190         // this code is equivalent to 
02191         //  case IsHome : return executeIsHomed();
02192         // for all values defined in he COMMAND enumeration
02193 
02194   #define ENUM(value,function) case ipp::value: IPP_CONCAT(check,value)(aCommand); break;
02195       COMMAND_ENUMERATION
02196   #undef ENUM
02197       default:
02198         IPP_ASSERT_FAIL(" Unknown command");
02199 
02200       }
02201   }
02202   return _errorCode;
02203 
02204 }
02205 
02206 
02207 /*******************************************************************/
02208 

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