CtrlGroup.c
Go to the documentation of this file.
00001 // CtrlGroup.c
00002 //
00003 /*
00004 * Software License Agreement (BSD License) 
00005 *
00006 * Copyright (c) 2013, Yaskawa America, Inc.
00007 * All rights reserved.
00008 *
00009 * Redistribution and use in binary form, with or without modification,
00010 * is permitted provided that the following conditions are met:
00011 *
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 Yaskawa America, Inc., 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 "MotoPlus.h"
00033 #include "ParameterExtraction.h"
00034 #include "CtrlGroup.h"
00035 #include "SimpleMessage.h"
00036 #include "Controller.h"
00037 
00038 //-----------------------
00039 // Function Declarations
00040 //-----------------------
00041 MP_GRP_ID_TYPE Ros_CtrlGroup_FindGrpId(int groupNo);
00042 CtrlGroup* Ros_CtrlGroup_Create(int groupNo, float interpolPeriod);
00043 BOOL Ros_CtrlGroup_GetPulsePosCmd(CtrlGroup* ctrlGroup, long pulsePos[MAX_PULSE_AXES]);
00044 BOOL Ros_CtrlGroup_GetFBPulsePos(CtrlGroup* ctrlGroup, long pulsePos[MAX_PULSE_AXES]);
00045 void Ros_CtrlGroup_ConvertToRosPos(CtrlGroup* ctrlGroup, long pulsePos[MAX_PULSE_AXES], 
00046                                                                         float radPos[MAX_PULSE_AXES]);
00047 void Ros_CtrlGroup_ConvertToMotoPos(CtrlGroup* ctrlGroup, float radPos[MAX_PULSE_AXES], 
00048                                                                         long pulsePos[MAX_PULSE_AXES]);
00049 UCHAR Ros_CtrlGroup_GetAxisConfig(CtrlGroup* ctrlGroup);
00050 BOOL Ros_CtrlGroup_IsRobot(CtrlGroup* ctrlGroup);
00051 
00052 //-----------------------
00053 // Function implementation
00054 //-----------------------
00055 
00056 //-------------------------------------------------------------------
00057 // Search through the control group to find the GroupId that matches 
00058 // the group number
00059 //-------------------------------------------------------------------
00060 MP_GRP_ID_TYPE Ros_CtrlGroup_FindGrpId(int groupNo)
00061 {
00062         MP_GRP_ID_TYPE grp_id;
00063         
00064         for(grp_id = MP_R1_GID; grp_id < MP_S3_GID; grp_id++)
00065         {
00066                 if(groupNo == mpCtrlGrpId2GrpNo(grp_id))
00067                         return grp_id;
00068         }
00069         
00070         return -1;
00071 }
00072 
00073 //-------------------------------------------------------------------
00074 // Create a CtrlGroup data structure for existing group otherwise 
00075 // return NULL
00076 //-------------------------------------------------------------------
00077 CtrlGroup* Ros_CtrlGroup_Create(int groupNo, float interpolPeriod)
00078 {
00079         CtrlGroup* ctrlGroup;
00080         int numAxes;
00081         int i;
00082 #ifdef DX100            
00083         float speedCap;
00084 #endif
00085         long maxSpeedPulse[MP_GRP_AXES_NUM];
00086         STATUS status;
00087         BOOL bInitOk;
00088         
00089         // Check if group is defined
00090         numAxes = GP_getNumberOfAxes(groupNo);
00091         if(numAxes > 0)
00092         {
00093                 bInitOk = TRUE;
00094                 // Allocate and initialize memory
00095                 ctrlGroup = mpMalloc(sizeof(CtrlGroup));
00096                 memset(ctrlGroup, 0x00, sizeof(CtrlGroup));
00097 
00098                 // Populate values
00099                 ctrlGroup->groupNo = groupNo;
00100                 ctrlGroup->numAxes = numAxes;
00101                 ctrlGroup->groupId = Ros_CtrlGroup_FindGrpId(groupNo);
00102                 
00103                 status = GP_getPulseToRad(groupNo, &ctrlGroup->pulseToRad);
00104                 if(status!=OK)
00105                         bInitOk = FALSE;
00106 
00107                 status = GP_getFBPulseCorrection(groupNo, &ctrlGroup->correctionData);
00108                 if(status!=OK)
00109                         bInitOk = FALSE;
00110 
00111                 status = GP_getMaxIncPerIpCycle(groupNo, interpolPeriod , &ctrlGroup->maxInc);
00112                 if(status!=OK)
00113                         bInitOk = FALSE;
00114 
00115                 memset(&ctrlGroup->inc_q, 0x00, sizeof(Incremental_q));
00116                 ctrlGroup->inc_q.q_lock = mpSemBCreate(SEM_Q_FIFO, SEM_FULL);
00117 
00118 #ifdef DX100            
00119                 speedCap = GP_getGovForIncMotion(groupNo);
00120                 if(speedCap != -1)
00121                 {
00122                         for(i=0; i<numAxes; i++)
00123                                 ctrlGroup->maxInc.maxIncrement[i] *= speedCap;
00124                 }
00125                 else
00126                         bInitOk = FALSE;
00127 #endif
00128 
00129                 // Calculate maximum speed in radian per second
00130                 memset(maxSpeedPulse, 0x00, sizeof(maxSpeedPulse));
00131                 for(i=0; i<numAxes; i++)
00132                         maxSpeedPulse[i] = ctrlGroup->maxInc.maxIncrement[i] * 1000.0 / interpolPeriod; 
00133                 Ros_CtrlGroup_ConvertToRosPos(ctrlGroup, maxSpeedPulse, ctrlGroup->maxSpeedRad); 
00134 
00135                 printf("maxInc: %d, %d, %d, %d, %d, %d, %d\r\n", 
00136                         ctrlGroup->maxInc.maxIncrement[0],ctrlGroup->maxInc.maxIncrement[1],ctrlGroup->maxInc.maxIncrement[2],
00137                         ctrlGroup->maxInc.maxIncrement[3],ctrlGroup->maxInc.maxIncrement[4],ctrlGroup->maxInc.maxIncrement[5],
00138                         ctrlGroup->maxInc.maxIncrement[6]);
00139                 printf("maxSpeedRad: %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f\r\n", 
00140                         ctrlGroup->maxSpeedRad[0],ctrlGroup->maxSpeedRad[1],ctrlGroup->maxSpeedRad[2],
00141                         ctrlGroup->maxSpeedRad[3],ctrlGroup->maxSpeedRad[4],ctrlGroup->maxSpeedRad[5],
00142                         ctrlGroup->maxSpeedRad[6]);
00143 
00144                 ctrlGroup->tidAddToIncQueue = INVALID_TASK;
00145                 
00146                 if(bInitOk == FALSE)
00147                 {
00148                         mpFree(ctrlGroup);
00149                         ctrlGroup = NULL;
00150                 }
00151         }
00152         else
00153         {
00154                 ctrlGroup = NULL;
00155         }
00156         
00157         return ctrlGroup;
00158 }
00159 
00160 
00161 //-------------------------------------------------------------------
00162 // Get the commanded pulse position in pulse
00163 //-------------------------------------------------------------------
00164 BOOL Ros_CtrlGroup_GetPulsePosCmd(CtrlGroup* ctrlGroup, long pulsePos[MAX_PULSE_AXES])
00165 {
00166         LONG status = 0;
00167         MP_CTRL_GRP_SEND_DATA sData;
00168         MP_PULSE_POS_RSP_DATA pulse_data;
00169         int i;
00170 
00171         memset(pulsePos, 0, MAX_PULSE_AXES*sizeof(long));  // clear result, in case of error
00172 
00173         // Set the control group
00174         switch(ctrlGroup->groupId)
00175         {
00176                 case MP_R1_GID: sData.sCtrlGrp = 0; break;
00177                 case MP_R2_GID: sData.sCtrlGrp = 1; break;
00178                 case MP_B1_GID: sData.sCtrlGrp = 8; break;
00179                 case MP_B2_GID: sData.sCtrlGrp = 9; break;
00180                 case MP_S1_GID: sData.sCtrlGrp = 16; break;
00181                 case MP_S2_GID: sData.sCtrlGrp = 17; break;
00182                 case MP_S3_GID: sData.sCtrlGrp = 18; break;
00183                 default: 
00184                         printf("Failed to get pulse feedback position\nInvalid groupId: %d", ctrlGroup->groupId);
00185                         return FALSE;
00186         }
00187         
00188         // get the command joint positions
00189         status = mpGetPulsePos (&sData,&pulse_data);
00190         if (0 != status)
00191         {
00192         printf("Failed to get pulse position (command): %u", status);
00193         return FALSE;
00194         }
00195                 
00196         // assign return value
00197         for (i=0; i<ctrlGroup->numAxes; ++i)
00198         pulsePos[i] = pulse_data.lPos[i];
00199     
00200         return TRUE;    
00201 }
00202 
00203 
00204 //-------------------------------------------------------------------
00205 // Get the corrected feedback pulse position in pulse
00206 //-------------------------------------------------------------------
00207 BOOL Ros_CtrlGroup_GetFBPulsePos(CtrlGroup* ctrlGroup, long pulsePos[MAX_PULSE_AXES])
00208 {
00209         LONG status = 0;
00210         MP_CTRL_GRP_SEND_DATA sData;
00211         MP_FB_PULSE_POS_RSP_DATA pulse_data;
00212         int i;
00213 
00214         memset(pulsePos, 0, MAX_PULSE_AXES*sizeof(long));  // clear result, in case of error
00215 
00216         // Set the control group
00217         switch(ctrlGroup->groupId)
00218         {
00219                 case MP_R1_GID: sData.sCtrlGrp = 0; break;
00220                 case MP_R2_GID: sData.sCtrlGrp = 1; break;
00221                 case MP_B1_GID: sData.sCtrlGrp = 8; break;
00222                 case MP_B2_GID: sData.sCtrlGrp = 9; break;
00223                 case MP_S1_GID: sData.sCtrlGrp = 16; break;
00224                 case MP_S2_GID: sData.sCtrlGrp = 17; break;
00225                 case MP_S3_GID: sData.sCtrlGrp = 18; break;
00226                 default: 
00227                         printf("Failed to get pulse feedback position\nInvalid groupId: %d", ctrlGroup->groupId);
00228                         return FALSE;
00229         }
00230         
00231         // get raw (uncorrected/unscaled) joint positions
00232         status = mpGetFBPulsePos (&sData,&pulse_data);
00233         if (0 != status)
00234         {
00235         printf("Failed to get pulse feedback position: %u", status);
00236         return FALSE;
00237         }
00238         
00239          // apply correction to account for cross-axis coupling
00240          // Note: this is only required for feedback position
00241          // controller handles this correction internally when 
00242          // dealing with command positon.
00243         for (i=0; i<MAX_PULSE_AXES; ++i)
00244         {
00245         FB_AXIS_CORRECTION *corr = &ctrlGroup->correctionData.correction[i];
00246         if (corr->bValid)
00247         {
00248                     int src_axis = corr->ulSourceAxis;
00249                     int dest_axis = corr->ulCorrectionAxis;
00250                     pulse_data.lPos[dest_axis] -= (int)(pulse_data.lPos[src_axis] * corr->fCorrectionRatio);
00251         }
00252         }
00253         
00254         // assign return value
00255         for (i=0; i<ctrlGroup->numAxes; ++i)
00256         pulsePos[i] = pulse_data.lPos[i];
00257     
00258         return TRUE;    
00259 }
00260 
00261 //-------------------------------------------------------------------
00262 // Convert Motoman position in pulse to Ros position in radian
00263 // In the case of a 7 axis robot, adjust the order to match 
00264 // the physical axis sequence
00265 //-------------------------------------------------------------------
00266 void Ros_CtrlGroup_ConvertToRosPos(CtrlGroup* ctrlGroup, long pulsePos[MAX_PULSE_AXES], 
00267                                                                         float radPos[MAX_PULSE_AXES])
00268 {
00269         int i;
00270                 
00271         // Adjust joint order for 7 axis robot
00272         if((ctrlGroup->groupId >= MP_R1_GID) && (ctrlGroup->groupId <= MP_R4_GID) && (ctrlGroup->numAxes == 7))
00273         {
00274                 for(i=0; i<ctrlGroup->numAxes; i++)
00275                 {
00276                         if(i<2)
00277                                 radPos[i] = pulsePos[i] / ctrlGroup->pulseToRad.PtoR[i];
00278                         else if(i==2)
00279                                 radPos[2] = pulsePos[6] / ctrlGroup->pulseToRad.PtoR[6];
00280                         else
00281                                 radPos[i] = pulsePos[i-1] / ctrlGroup->pulseToRad.PtoR[i-1];            
00282                 }
00283         }
00284         else
00285         {
00286                 for(i=0; i<ctrlGroup->numAxes; i++)
00287                         radPos[i] = pulsePos[i] / ctrlGroup->pulseToRad.PtoR[i];
00288         }
00289 }
00290 
00291 //-------------------------------------------------------------------
00292 // Convert Ros position in radian to Motoman position in pulse
00293 // In the case of a 7 axis robot, adjust the order to match 
00294 // the motoman axis sequence
00295 //-------------------------------------------------------------------
00296 void Ros_CtrlGroup_ConvertToMotoPos(CtrlGroup* ctrlGroup, float radPos[MAX_PULSE_AXES], 
00297                                                                         long pulsePos[MAX_PULSE_AXES])
00298 {
00299         int i;
00300         
00301         // Initilize memory space
00302         memset(pulsePos, 0x00, sizeof(long)*MAX_PULSE_AXES);
00303         
00304         // Adjust joint order for 7 axis robot
00305         if((ctrlGroup->groupId >= MP_R1_GID) && (ctrlGroup->groupId <= MP_R4_GID) && (ctrlGroup->numAxes == 7))
00306         {
00307                 for(i=0; i<ctrlGroup->numAxes; i++)
00308                 {
00309                         if(i<2)
00310                                 pulsePos[i] = (int)(radPos[i] * ctrlGroup->pulseToRad.PtoR[i]);
00311                         else if(i==2)
00312                                 pulsePos[6] = (int)(radPos[2] * ctrlGroup->pulseToRad.PtoR[6]);
00313                         else
00314                                 pulsePos[i-1] = (int)(radPos[i] * ctrlGroup->pulseToRad.PtoR[i-1]);
00315                 }
00316         }
00317         else
00318         {
00319                 // Convert to pulse
00320                 for(i=0; i<ctrlGroup->numAxes; i++)
00321                          pulsePos[i] = (int)(radPos[i] * ctrlGroup->pulseToRad.PtoR[i]);        
00322         }
00323 }
00324 
00325 //-------------------------------------------------------------------
00326 // Returns a bit wise axis configuration
00327 // Note: This may need to be reviewed in the case of 4 or 5 axis robots
00328 //       where configuration is SLU--T or SLU-BT?? 
00329 //-------------------------------------------------------------------
00330 UCHAR Ros_CtrlGroup_GetAxisConfig(CtrlGroup* ctrlGroup)
00331 {
00332         int i;
00333         int axisConfig = 0;
00334         
00335         for(i=0; i<ctrlGroup->numAxes; i++)
00336                 axisConfig |= (0x01 << i);
00337                 
00338         return (UCHAR)axisConfig;
00339 }
00340 
00341 //-------------------------------------------------------------------
00342 // Returns TRUE is the specified group is defined as a robot
00343 //-------------------------------------------------------------------
00344 BOOL Ros_CtrlGroup_IsRobot(CtrlGroup* ctrlGroup)
00345 {
00346         return((ctrlGroup->groupId == MP_R1_GID) || (ctrlGroup->groupId == MP_R2_GID));
00347 }


motoman_driver
Author(s): Jeremy Zoss (Southwest Research Institute)
autogenerated on Wed Aug 26 2015 12:37:33