controller.cpp
Go to the documentation of this file.
00001 /*
00002  * Software License Agreement (BSD License)
00003  *
00004  * Copyright (c) 2011, Southwest Research Institute
00005  * All rights reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted provided that the following conditions are met:
00009  *
00010  *      * Redistributions of source code must retain the above copyright
00011  *      notice, this list of conditions and the following disclaimer.
00012  *      * Redistributions in binary form must reproduce the above copyright
00013  *      notice, this list of conditions and the following disclaimer in the
00014  *      documentation and/or other materials provided with the distribution.
00015  *      * Neither the name of the Southwest Research Institute, nor the names
00016  *      of its contributors may be used to endorse or promote products derived
00017  *      from this software without specific prior written permission.
00018  *
00019  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00020  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00021  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00022  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00023  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00024  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00025  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00026  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00027  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00028  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00029  * POSSIBILITY OF SUCH DAMAGE.
00030  */
00031  
00032  #include "controller.h"
00033  #include "log_wrapper.h"
00034  #include "ros_conversion.h"
00035  
00036 namespace motoman
00037 {
00038 namespace controller
00039 {
00040 
00041 // Global variable (to this source file) for storing cached robot parameters.
00042 // This used to be a static variable within the Controller class, but the motoman
00043 // controller would crash on loading.  It appears that a structure cannot be a
00044 // static variable.  The easiest fix was to move the variable here and use it as
00045 // a global.
00046 const int MAX_CTRL_GROUPS = 8;
00047 ctrl_grp_param_t ctrl_grp_parameters_[MAX_CTRL_GROUPS];
00048 sys_param_t sys_parameters_;
00049 
00050 int Controller::active_ctrl_grp_ = 0;  // assume default control group is #1
00051 
00052 Controller::Controller()
00053 {
00054   this->jobStarted = false;
00055   this->motionEnabled = false;
00056 }
00057 
00058 Controller::~Controller()
00059 {
00060   this->disableMotion();
00061   // TODO: The current job should probably be unloaded.
00062 }
00063 
00064 bool Controller::initParameters(int ctrl_grp)
00065 {
00066   if (!is_valid_ctrl_grp(ctrl_grp)) return false;
00067   setCtrlGroup(ctrl_grp);
00068 
00069   UINT16 dummyUInt;
00070   int dummyInt, dummyIntAry[MAX_PULSE_AXES];
00071   float dummyFloat, dummyFloatAry[MAX_PULSE_AXES];
00072   FB_AXIS_CORRECTION dummyPulseCorrAry[MAX_PULSE_AXES];
00073 
00074   // call each read-parameter function, to save values into cache.
00075   // Ignore the results here; later calls will read cached values.
00076   bool rslt = true;
00077   rslt &= getNumRobotAxes(ctrl_grp, &dummyInt);
00078   rslt &= getPulsesPerRadian(ctrl_grp, dummyFloatAry);
00079   rslt &= getFBPulseCorrection(ctrl_grp, dummyPulseCorrAry);
00080   rslt &= getNumTasks(&dummyInt, &dummyInt, &dummyInt);
00081   rslt &= getInterpPeriod(&dummyUInt);
00082   rslt &= getMaxIncrPerCycle(ctrl_grp, dummyIntAry);
00083   rslt &= getIncrMotionLimit(ctrl_grp, &dummyFloat);
00084   
00085   ctrl_grp_param_t& cp = ctrl_grp_parameters_[ctrl_grp];
00086   sys_param_t& sp = sys_parameters_;
00087 
00088   LOG_DEBUG("Controller Parameters retrieved for group #%d", ctrl_grp+1);
00089   LOG_DEBUG("  numAxes: %d", cp.num_axes);
00090   LOG_DEBUG("  pulse_per_rad: %8g", cp.pulses_per_rad[0]);
00091   for (int i=1; i<cp.num_axes; ++i)
00092     LOG_DEBUG(", %8g", cp.pulses_per_rad[i]);
00093     
00094   for (int i=0; i<MAX_PULSE_AXES; ++i)
00095   {
00096         FB_AXIS_CORRECTION& corr = cp.pulse_correction[i];
00097     if (!corr.bValid) continue;
00098 
00099     LOG_DEBUG("  pulseCorr[%d]: %d, %d, %8g", i, corr.ulSourceAxis, corr.ulCorrectionAxis, corr.fCorrectionRatio);
00100   }
00101   
00102   LOG_DEBUG("  numTasks: %d normal, %d highPrio, %d outFiles", sp.tasks.qtyOfNormalPriorityTasks,
00103             sp.tasks.qtyOfHighPriorityTasks, sp.tasks.qtyOfOutFiles);
00104   LOG_DEBUG("  interpPeriod: %d msec", sp.interp_period);
00105   LOG_DEBUG("  maxIncrPerCycle: %8g", cp.max_incr_per_cycle[0]);
00106   for (int i=01; i<cp.num_axes; ++i)
00107     LOG_DEBUG(", %8g", cp.max_incr_per_cycle[i]);
00108   LOG_DEBUG("  incrMotionLimit: %8g", cp.incr_motion_limit);
00109 
00110   return rslt;
00111 }
00112 
00113 void Controller::setInteger(int index, int value)
00114 {
00115         MP_VAR_DATA data;
00116         
00117         data.usType = MP_RESTYPE_VAR_I;
00118         data.usIndex = index;
00119         data.ulValue = value;
00120         
00121         while (mpPutVarData ( &data, 1 ) == MP_ERROR) 
00122         {
00123         LOG_ERROR("Failed to set integer varaible, index: %d, value: %d, retrying...", 
00124             data.usIndex, data.ulValue);
00125         mpTaskDelay(VAR_POLL_DELAY_);
00126     }
00127 }
00128 
00129 int Controller::getInteger(int index)
00130 {
00131     
00132         MP_VAR_INFO info;
00133         LONG rtn;
00134         
00135         info.usType = MP_RESTYPE_VAR_I;
00136         info.usIndex = index;
00137         
00138         while (mpGetVarData ( &info, &rtn, 1 ) == MP_ERROR) 
00139         {
00140         LOG_ERROR("Failed to retreive integer variable index: %d, retrying...", info.usIndex);
00141         mpTaskDelay(VAR_POLL_DELAY_);
00142     }
00143     return rtn;
00144 }
00145 
00146 bool Controller::setJointPositionVar(int index, industrial::joint_data::JointData ros_joints)
00147 {
00148     // convert ROS joint-order to MP joint-order
00149     float mp_joints_radians[MAX_PULSE_AXES];
00150     ros_conversion::toMpJoint(ros_joints, mp_joints_radians);
00151 
00152     // get conversion scaling   
00153     float pulses_per_rad[MAX_PULSE_AXES];
00154     if (!getPulsesPerRadian(pulses_per_rad)) return false;
00155 
00156     // convert radians to pulses
00157     LONG mp_joints_pulses[MAX_PULSE_AXES];
00158         for (int i=0; i<MAX_PULSE_AXES; ++i)
00159         mp_joints_pulses[i] = (long)floor(mp_joints_radians[i] * pulses_per_rad[i]);
00160     
00161     // convert to MP_POSVAR_DATA structure
00162     const int MP_POSVAR_SIZE = 10;  // hardcoded in MP_POSVAR_DATA (not set to MAX_PULSE_AXES+2)
00163         MP_POSVAR_DATA local_posvar;
00164         local_posvar.usType = MP_RESTYPE_VAR_ROBOT;  // assume ROBOT position (not BASE or STATION)
00165         local_posvar.usIndex = index;
00166         local_posvar.ulValue[0] = 0;   // 0 => Pulse (joint) position
00167         for (int i=0; i<MP_POSVAR_SIZE-2 && i<MAX_PULSE_AXES; ++i)
00168           local_posvar.ulValue[i+2] = mp_joints_pulses[i];  // First two values in ulValue are reserved
00169         
00170         // copy position data to controller data-list
00171         bool result = (mpPutPosVarData ( &local_posvar, 1 ) == OK);
00172         
00173         return result;
00174 }
00175 
00176 
00177  bool Controller::getStatus(industrial::robot_status::RobotStatus & status)
00178  {
00179         status.init();  //reintializes status (sets all to unknown)
00180     status.setInMotion(getInMotionStatus());
00181  return true;
00182  }
00183  
00184  
00185  industrial::robot_status::TriState Controller::getInMotionStatus()
00186  {
00187           industrial::robot_status::TriState rtn = 
00188                 industrial::robot_status::TriStates::TS_UNKNOWN;
00189         
00190           
00191           LONG status = 0;
00192           MP_CTRL_GRP_SEND_DATA sData;
00193           MP_FB_SPEED_RSP_DATA pulse_speed;
00194           const int SPEED_THRESHOLD = 150; //pulses/sec
00195           
00196           // get raw (uncorrected/unscaled) joint positions
00197           sData.sCtrlGrp = getCtrlGroup();
00198           status = mpGetFBSpeed (&sData,&pulse_speed);
00199           if (MP_ERROR == status)
00200           {
00201             LOG_ERROR("Failed to get pulse feedback speed: %u", status);
00202           }
00203           else
00204           {
00205                   // Assume we are not in motion.  If any of the joint speeds are
00206                   // greater than the threshold, then set in motion (quit early).
00207                   rtn = industrial::robot_status::TriStates::TS_FALSE;
00208                   
00209                   for (int i=0; i<MAX_PULSE_AXES; ++i)
00210                   {
00211                     if( abs(pulse_speed.lSpeed[i]) > SPEED_THRESHOLD )
00212                     {
00213                         LOG_DEBUG("Speed detected, joint speed: %d and threshold: %d", 
00214                                         pulse_speed.lSpeed[i], SPEED_THRESHOLD);
00215                         rtn = industrial::robot_status::TriStates::TS_TRUE;
00216                         break;
00217                     }
00218                   }
00219            }
00220           return rtn;
00221   }
00222 
00223 
00224 void Controller::enableMotion(void)
00225 {
00226   
00227   LOG_INFO("Enabling motion");
00228   this->motionEnabled = false;
00229 
00230   servo_power_data.sServoPower = ON;
00231   while(mpSetServoPower(&servo_power_data, &servo_power_error) == MP_ERROR)
00232   {
00233     LOG_ERROR("Failed to turn on servo power, error: %d, retrying...", servo_power_error.err_no);
00234     mpTaskDelay(this->VAR_POLL_DELAY_);
00235   };
00236   
00237   hold_data.sHold = OFF;
00238   while(mpHold(&hold_data, &hold_error) == MP_ERROR)
00239   {
00240     LOG_ERROR("Failed to turn off hold, error: %d, retrying...", hold_error.err_no);
00241     mpTaskDelay(this->VAR_POLL_DELAY_);
00242   };
00243   
00244   this->motionEnabled = true;
00245 }
00246 
00247 
00248 void Controller::disableMotion(void)
00249 {
00250   LOG_INFO("Disabling motion");
00251   servo_power_data.sServoPower = OFF;
00252   while(mpSetServoPower(&servo_power_data, &servo_power_error) == MP_ERROR)
00253   {
00254     LOG_ERROR("Failed to turn off servo power, error: %d, retrying...", servo_power_error.err_no);
00255     mpTaskDelay(this->VAR_POLL_DELAY_);
00256   };
00257   
00258   this->motionEnabled = false;
00259 }
00260 
00261 void Controller::startMotionJob(char* job_name)
00262 {
00263 
00264   this->jobStarted = false;
00265   
00266   this->enableMotion();
00267   
00268   // Set up job variables
00269   job_start_data.sTaskNo = 0;
00270   strcpy(job_start_data.cJobName, job_name);
00271  
00272   
00273   LOG_INFO("Starting motion job");
00274   while(mpStartJob(&job_start_data, &job_error) == ERROR)
00275   {
00276     LOG_ERROR("Failed to start job, error: %d, retrying...", job_error.err_no);
00277     mpTaskDelay(this->VAR_POLL_DELAY_);
00278   }; 
00279   
00280   this->jobStarted = true;
00281 }
00282 
00283 
00284 void Controller::stopMotionJob(char* job_name)
00285 {  
00286   LOG_INFO("Stopping motion job");
00287   this->disableMotion();
00288   
00289   // delete task
00290   strcpy(job_delete_data.cJobName, job_name);
00291   
00292   while(mpDeleteJob(&job_delete_data, &job_error) == MP_ERROR)
00293   {
00294     LOG_ERROR("Failed to delete job, error: %d, retrying...", job_error.err_no);
00295     mpTaskDelay(this->VAR_POLL_DELAY_);
00296   };
00297   
00298   this->jobStarted = false;
00299 }       
00300 
00301 
00302 #define FILE_NAM_BUFFER_SIZE 100
00303 bool Controller::writeJob(char* path, char* job)
00304 {
00305     bool rtn = false;
00306     int fd = this->MP_ERROR;
00307     int status = this->MP_ERROR;
00308     char filename[FILE_NAM_BUFFER_SIZE];  //should be big enough to hold a file name and DRAM drive name
00309     
00310     memset(filename, '\0', FILE_NAM_BUFFER_SIZE);  //not sure this is needed, strcpy below also does this.
00311     strcpy(filename, "MPRAM1:\\");
00312     strcat(filename, path);
00313     
00314     LOG_DEBUG("writeJob: %s", filename);
00315     
00316     // Remove the file, if it exists
00317     LOG_DEBUG("Trying to remove file, if it exists");
00318     status = mpRemove( filename );
00319     if (this->MP_ERROR == status)
00320     {
00321         LOG_WARN("Failed to remove job file: %s", filename);
00322     }
00323     
00324     
00325     // Create the file and write the job
00326     fd = mpCreate( filename, O_WRONLY );
00327     if (this->MP_ERROR != fd)
00328     {
00329         status = mpWrite( fd, job, strlen(job) );
00330         if ( this->MP_ERROR != status )
00331         {
00332             LOG_INFO("Successfully loaded file: %s, bytes written: %d", filename, status);
00333             rtn = true;
00334         }
00335         else
00336         {
00337             LOG_ERROR("Failed to write file: %s", filename);
00338             rtn = false;
00339         }
00340         
00341         
00342         // Checking file status
00343         /*
00344             struct stat pStat;
00345             status = mpFstat(fd, &pStat);
00346             {
00347                         LOG_DEBUG("mpFstat Complete");
00348                         LOG_DEBUG("st_dev = %u", pStat.st_dev);
00349                         LOG_DEBUG("st_ino = %u", pStat.st_ino);
00350                         LOG_DEBUG("st_mode = %u", pStat.st_mode);
00351                         LOG_DEBUG("st_nlink = %d", pStat.st_nlink);
00352                         LOG_DEBUG("st_uid = %d", pStat.st_uid);
00353                         LOG_DEBUG("st_gid = %d", pStat.st_gid);
00354                         LOG_DEBUG("st_rdev = %u", pStat.st_rdev);
00355                         LOG_DEBUG("st_size = %u", pStat.st_size);
00356                         LOG_DEBUG("st_atime = %u", pStat.st_atime);
00357                         LOG_DEBUG("st_mtime = %u", pStat.st_mtime);
00358                         LOG_DEBUG("st_ctime = %u", pStat.st_ctime);
00359                         LOG_DEBUG("st_blksize = %u", pStat.st_blksize);
00360                         LOG_DEBUG("st_blocks = %u", pStat.st_blocks);
00361                         LOG_DEBUG("st_attrib = %u", pStat.st_attrib);
00362                 }
00363                 */
00364                 
00365         // close file descriptor
00366             status = mpClose(fd);
00367             if (this->MP_ERROR == status)
00368             {
00369                 LOG_WARN("Failed to close file: %s, ignoring failure", filename);
00370             }
00371     }
00372     else
00373     {
00374         LOG_ERROR("Failed to create job file: %s", filename);
00375         rtn = false;
00376     }
00377     
00378     
00379     return rtn;
00380 }
00381 #undef FILE_NAM_BUFFER_SIZE
00382 
00383 
00384 bool Controller::loadJob(char* path, char * job)
00385 {
00386     bool rtn = false;
00387     int status;    
00388     
00389     LOG_DEBUG("Refreshing file list");
00390     status = mpRefreshFileList(MP_EXT_ID_JBI);
00391     if (this->MP_OK != status)
00392     {
00393         LOG_WARN("Failed to refresh file list: %d, ignoring failure", status);
00394     }
00395     LOG_DEBUG("File count before file load: %d", mpGetFileCount());
00396     
00397     LOG_DEBUG("Attempting to load file, path: %s, job: %s", path, job);
00398     status = mpLoadFile (MP_DRV_ID_DRAM, path, job );
00399     if (this->MP_OK == status)
00400     {
00401         LOG_INFO("Loaded job file %s", job);
00402         rtn = true;
00403     }
00404     else
00405     {
00406         LOG_ERROR("Failed to load job file: %s, path: %s, returned error code: %d",
00407                     job, path, status);
00408         rtn = false;
00409     }
00410     
00411     LOG_DEBUG("Refreshing file list");
00412     status = mpRefreshFileList(MP_EXT_ID_JBI);
00413     if (this->MP_OK != status)
00414     {
00415         LOG_WARN("Failed to refresh file list: %d, ignoring failure", status);
00416     }
00417     LOG_DEBUG("File count after file load: %d", mpGetFileCount());
00418     
00419     return rtn;
00420 
00421 }
00422 
00423 
00424 void Controller::setDigitalOut(int bit_offset, bool value)
00425 {
00426   LOG_DEBUG("Setting digital out, Bit offset: %d, value: %d", bit_offset, value);
00427   if ( (bit_offset < this->UNIV_IO_DATA_SIZE_) && 
00428        ( bit_offset > 0) )
00429   {  
00430     MP_IO_DATA data;
00431     data.ulAddr = this->UNIV_OUT_DATA_START_ + bit_offset;
00432     data.ulValue = value;
00433     //TODO: The return result of mpWriteIO is not checked
00434     mpWriteIO(&data, 1);
00435   }
00436   else
00437   {
00438     LOG_ERROR("Bit offset: %d, is greater than size: %d", bit_offset, this->UNIV_IO_DATA_SIZE_);
00439   }
00440 }
00441 
00442  void Controller::waitDigitalIn(int bit_offset, bool wait_value)
00443  {
00444    LOG_DEBUG("Waiting for digital in, Bit offset: %d, Wait value: %d", bit_offset, wait_value);
00445    if ( (bit_offset < this->UNIV_IO_DATA_SIZE_) && 
00446        ( bit_offset > 0) )
00447   { 
00448     MP_IO_INFO info;
00449     info.ulAddr = this->UNIV_IN_DATA_START_ + bit_offset;
00450     
00451     USHORT readValue;
00452     do
00453     {
00454       readValue = !wait_value;  
00455       //TODO: The return result of mpReadIO is not checked
00456       mpReadIO (&info, &readValue, 1);
00457       mpTaskDelay(VAR_POLL_DELAY_);
00458     } while ( ((bool)readValue) != wait_value);
00459   }
00460   else
00461   {
00462     LOG_ERROR("Bit offset: %d, is greater than size: %d", bit_offset, this->UNIV_IO_DATA_SIZE_);
00463   }
00464  }
00465  
00466 bool Controller::getActJointPos(float* pos)
00467 {
00468   int num_axes;
00469   LONG status = 0;
00470   MP_CTRL_GRP_SEND_DATA sData;
00471   MP_FB_PULSE_POS_RSP_DATA pulse_data;
00472   FB_AXIS_CORRECTION pulse_corr[MAX_PULSE_AXES];
00473   float pulses_per_rad[MAX_PULSE_AXES];
00474 
00475   memset(pos, 0, MAX_PULSE_AXES*sizeof(float));  // clear result, in case of error
00476   
00477   // get parameters for currently-active ctrl_grp
00478   if (!getFBPulseCorrection(pulse_corr)) return false;
00479   if (!getNumRobotAxes(&num_axes)) return false;
00480   if (!getPulsesPerRadian(pulses_per_rad)) return false;
00481   
00482   // get raw (uncorrected/unscaled) joint positions
00483   sData.sCtrlGrp = getCtrlGroup();
00484   status = mpGetFBPulsePos (&sData,&pulse_data);
00485   if (0 != status)
00486   {
00487     LOG_ERROR("Failed to get pulse feedback position: %u", status);
00488     return false;
00489   }
00490   
00491   // apply correction to account for cross-axis coupling
00492   for (int i=0; i<MAX_PULSE_AXES; ++i)
00493   {
00494     FB_AXIS_CORRECTION corr = pulse_corr[i];
00495     if (corr.bValid)
00496     {
00497       int src_axis = corr.ulSourceAxis;
00498       int dest_axis = corr.ulCorrectionAxis;
00499       pulse_data.lPos[dest_axis] -= (int)(pulse_data.lPos[src_axis] * corr.fCorrectionRatio);
00500     }
00501   }
00502   
00503   // apply scaling (pulse->radians)
00504   for (int i=0; i<num_axes; ++i)
00505     pos[i] = pulse_data.lPos[i] / pulses_per_rad[i];
00506     
00507   return true;
00508 }
00509 
00510 bool Controller::is_valid_ctrl_grp(int ctrl_grp)
00511 {
00512   bool valid = ((ctrl_grp >= 0) && (ctrl_grp < MAX_CTRL_GROUPS));
00513   if (!valid)
00514     LOG_ERROR("Invalid ctrl_grp (%d)", ctrl_grp);
00515   return valid;
00516 }
00517 
00518 bool Controller::getNumRobotAxes(int ctrl_grp, int* numAxes)
00519 {
00520   if (!is_valid_ctrl_grp(ctrl_grp)) return false;
00521  
00522   ctrl_grp_param_t& p = ctrl_grp_parameters_[ctrl_grp];
00523   
00524   // read parameters from controller, if not already cached
00525   if (!is_bit_set(p.initialized, GP_GETNUMBEROFAXES))
00526   {
00527     p.num_axes = GP_getNumberOfAxes(ctrl_grp);
00528     set_bit(&p.initialized, GP_GETNUMBEROFAXES);
00529   }
00530 
00531   *numAxes = p.num_axes;
00532   return (*numAxes >= 0);
00533 }
00534 
00535 bool Controller::getPulsesPerRadian(int ctrl_grp, float* pulses_per_radian)
00536 {
00537   if (!is_valid_ctrl_grp(ctrl_grp)) return false;
00538 
00539   ctrl_grp_param_t& p = ctrl_grp_parameters_[ctrl_grp];
00540   
00541   // read parameters from controller, if not already cached
00542   if (!is_bit_set(p.initialized, GP_GETPULSETORAD))
00543   {
00544     GB_PULSE_TO_RAD rData;
00545 
00546     if (GP_getPulseToRad(ctrl_grp, &rData) != OK)
00547     {
00548       LOG_ERROR("Failed to retrieve PulseToRadian parameters.");
00549       return false;
00550     }
00551     
00552     for (int i=0; i<MAX_PULSE_AXES; ++i)
00553       p.pulses_per_rad[i] = rData.PtoR[i];
00554     set_bit(&p.initialized, GP_GETPULSETORAD);
00555   }
00556 
00557   for (int i=0; i<MAX_PULSE_AXES; ++i)
00558     pulses_per_radian[i] = p.pulses_per_rad[i];
00559 
00560   return true;
00561 }
00562 
00563 bool Controller::getFBPulseCorrection(int ctrl_grp, FB_AXIS_CORRECTION* pulse_correction)
00564 {
00565   if (!is_valid_ctrl_grp(ctrl_grp)) return false;
00566 
00567   ctrl_grp_param_t& p = ctrl_grp_parameters_[ctrl_grp];
00568 
00569   // read parameters from controller, if not already cached
00570   if (!is_bit_set(p.initialized, GP_GETFBPULSECORRECTION))
00571   {
00572     FB_PULSE_CORRECTION_DATA rData;
00573 
00574     if (GP_getFBPulseCorrection(ctrl_grp, &rData) != OK)
00575     {
00576       LOG_ERROR("Failed to retrieve FBPulseCorrection parameters.");
00577       return false;
00578     }
00579     
00580     for (int i=0; i<MAX_PULSE_AXES; ++i)
00581       p.pulse_correction[i] = rData.correction[i];
00582     set_bit(&p.initialized, GP_GETFBPULSECORRECTION);
00583   }
00584 
00585   for (int i=0; i<MAX_PULSE_AXES; ++i)
00586     pulse_correction[i] = p.pulse_correction[i];
00587 
00588   return true;
00589 }
00590 
00591 bool Controller::getNumTasks(int* num_normal_tasks, int* num_highPrio_tasks, int* num_out_files)
00592 {
00593   sys_param_t& p = sys_parameters_;
00594 
00595   // read parameters from controller, if not already cached
00596   if (!is_bit_set(p.initialized, GP_GETQTYOFALLOWEDTASKS))
00597   {
00598     TASK_QTY_INFO rData;
00599 
00600     if (GP_getQtyOfAllowedTasks(&rData) != OK)
00601     {
00602       LOG_ERROR("Failed to retrieve QtyOfAllowedTasks parameters.");
00603       return false;
00604     }
00605     
00606     p.tasks = rData;
00607     set_bit(&p.initialized, GP_GETQTYOFALLOWEDTASKS);
00608   }
00609 
00610   *num_normal_tasks   = p.tasks.qtyOfNormalPriorityTasks;
00611   *num_highPrio_tasks = p.tasks.qtyOfHighPriorityTasks;
00612   *num_out_files      = p.tasks.qtyOfOutFiles;
00613 
00614   return true;
00615 }
00616 
00617 bool Controller::getInterpPeriod(UINT16* interp_period)
00618 {
00619   sys_param_t& p = sys_parameters_;
00620 
00621   // read parameters from controller, if not already cached
00622   if (!is_bit_set(p.initialized, GP_GETINTERPOLATIONPERIOD))
00623   {
00624     if (GP_getInterpolationPeriod(&(p.interp_period)) != OK)
00625     {
00626       LOG_ERROR("Failed to retrieve InterpolationPeriod parameters.");
00627       return false;
00628     }
00629     
00630     set_bit(&p.initialized, GP_GETINTERPOLATIONPERIOD);
00631   }
00632 
00633   *interp_period = p.interp_period;
00634   return true;
00635 }
00636 
00637 bool Controller::getMaxIncrPerCycle(int ctrl_grp, int* max_incr)
00638 {
00639   if (!is_valid_ctrl_grp(ctrl_grp)) return false;
00640 
00641   ctrl_grp_param_t& p = ctrl_grp_parameters_[ctrl_grp];
00642 
00643   // read parameters from controller, if not already cached
00644   if (!is_bit_set(p.initialized, GP_GETMAXINCPERIPCYCLE))
00645   {
00646     MAX_INCREMENT_INFO rData;
00647     UINT16 interp_period;
00648     if (!getInterpPeriod(&interp_period)) return false;
00649 
00650     if (GP_getMaxIncPerIpCycle(ctrl_grp, interp_period, &rData) != OK)
00651     {
00652       LOG_ERROR("Failed to retrieve MaxIncPerIpCycle parameters.");
00653       return false;
00654     }
00655     
00656     for (int i=0; i<MAX_PULSE_AXES; ++i)
00657       p.max_incr_per_cycle[i] = rData.maxIncrement[i];
00658     set_bit(&p.initialized, GP_GETMAXINCPERIPCYCLE);
00659   }
00660 
00661   for (int i=0; i<MAX_PULSE_AXES; ++i)
00662     max_incr[i] = p.max_incr_per_cycle[i];
00663 
00664   return true;
00665 }
00666 
00667 bool Controller::getIncrMotionLimit(int ctrl_grp, float* limit)
00668 {
00669   if (!is_valid_ctrl_grp(ctrl_grp)) return false;
00670 
00671   ctrl_grp_param_t& p = ctrl_grp_parameters_[ctrl_grp];
00672 
00673   // read parameters from controller, if not already cached
00674   if (!is_bit_set(p.initialized, GP_GETGOVFORINCMOTION))
00675   {
00676     p.incr_motion_limit = GP_getGovForIncMotion(ctrl_grp);
00677     set_bit(&p.initialized, GP_GETGOVFORINCMOTION);
00678   }
00679 
00680   *limit = p.incr_motion_limit;
00681   return (*limit >= 0);
00682 }
00683 
00684 
00685 } //controller
00686 } //motoman


dx100
Author(s): Shaun Edwards (Southwest Research Institute)
autogenerated on Mon Oct 6 2014 02:25:33