CtrlGroup.c
Go to the documentation of this file.
1 // CtrlGroup.c
2 //
3 /*
4 * Software License Agreement (BSD License)
5 *
6 * Copyright (c) 2013, Yaskawa America, Inc.
7 * All rights reserved.
8 *
9 * Redistribution and use in binary form, with or without modification,
10 * is permitted provided that the following conditions are met:
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * * Neither the name of the Yaskawa America, Inc., nor the names
16 * of its contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31 
32 #include "MotoROS.h"
33 
34 //-----------------------
35 // Function implementation
36 //-----------------------
37 
38 //-------------------------------------------------------------------
39 // Search through the control group to find the GroupId that matches
40 // the group number
41 //-------------------------------------------------------------------
42 MP_GRP_ID_TYPE Ros_CtrlGroup_FindGrpId(int groupNo)
43 {
44  MP_GRP_ID_TYPE grp_id;
45 
46  for(grp_id = MP_R1_GID; grp_id < MP_S3_GID; grp_id++)
47  {
48  if(groupNo == mpCtrlGrpId2GrpNo(grp_id))
49  return grp_id;
50  }
51 
52  return -1;
53 }
54 
55 //-------------------------------------------------------------------
56 // Create a CtrlGroup data structure for existing group otherwise
57 // return NULL
58 //-------------------------------------------------------------------
59 CtrlGroup* Ros_CtrlGroup_Create(int groupNo, BOOL bIsLastGrpToInit, float interpolPeriod)
60 {
61  CtrlGroup* ctrlGroup;
62  int numAxes;
63  int i;
64 #ifdef DX100
65  float speedCap;
66 #endif
67  long maxSpeedPulse[MP_GRP_AXES_NUM];
68  STATUS status;
69  BOOL bInitOk;
70  BOOL slaveAxis;
71 
72  // Check if group is defined
73  numAxes = GP_getNumberOfAxes(groupNo);
74 #ifdef DEBUG
75  printf("Group %d: Num Axes %d\n", groupNo, numAxes);
76 #endif
77  if(numAxes > 0)
78  {
79  bInitOk = TRUE;
80  // Allocate and initialize memory
81  ctrlGroup = mpMalloc(sizeof(CtrlGroup));
82  memset(ctrlGroup, 0x00, sizeof(CtrlGroup));
83 
84  // Populate values
85  ctrlGroup->groupNo = groupNo;
86  ctrlGroup->numAxes = numAxes;
87  ctrlGroup->groupId = Ros_CtrlGroup_FindGrpId(groupNo);
88  ctrlGroup->tool = 0;
89 
90  status = GP_getAxisMotionType(groupNo, &ctrlGroup->axisType);
91  if (status != OK)
92  bInitOk = FALSE;
93 
94  status = GP_getPulseToRad(groupNo, &ctrlGroup->pulseToRad);
95  if (status != OK)
96  bInitOk = FALSE;
97 
98  status = GP_getPulseToMeter(groupNo, &ctrlGroup->pulseToMeter);
99  if (status != OK)
100  bInitOk = FALSE;
101 
102  status = GP_getFBPulseCorrection(groupNo, &ctrlGroup->correctionData);
103  if(status!=OK)
104  bInitOk = FALSE;
105 
106  status = GP_getMaxIncPerIpCycle(groupNo, interpolPeriod, &ctrlGroup->maxInc);
107  if (status != OK)
108  bInitOk = FALSE;
109 
110  status = GP_isBaxisSlave(groupNo, &slaveAxis);
111  if (status != OK)
112  bInitOk = FALSE;
113 
114  status = GP_getFeedbackSpeedMRegisterAddresses(groupNo, //zero based index of the control group
115  TRUE, //If the register-speed-feedback is not enabled, automatically modify the SC.PRM file to enable this feature.
116  bIsLastGrpToInit, //If activating the reg-speed-feedback feature, delay the alarm until all the groups have been processed.
117  &ctrlGroup->speedFeedbackRegisterAddress); //[OUT] Index of the M registers containing the feedback speed values.
118  if (status != OK)
119  {
121  }
122 
123  ctrlGroup->bIsBaxisSlave = (numAxes == 5) && slaveAxis;
124 
125  //adjust the axisType field to account for robots with non-contiguous axes (such as delta or palletizing which use SLU--T axes)
126  for (i = 0; i < MP_GRP_AXES_NUM; i += 1)
127  {
128  if (ctrlGroup->maxInc.maxIncrement[i] == 0) //if the axis can't move, then I assume it's invalid
129  ctrlGroup->axisType.type[i] = AXIS_INVALID;
130  }
131 
132  memset(&ctrlGroup->inc_q, 0x00, sizeof(Incremental_q));
133  ctrlGroup->inc_q.q_lock = mpSemBCreate(SEM_Q_FIFO, SEM_FULL);
134 
135 #ifdef DX100
136  speedCap = GP_getGovForIncMotion(groupNo);
137  if(speedCap != -1)
138  {
139  for(i=0; i<MP_GRP_AXES_NUM; i++)
140  ctrlGroup->maxInc.maxIncrement[i] *= speedCap;
141  }
142  else
143  bInitOk = FALSE;
144 #endif
145 
146  // Calculate maximum speed in radian per second
147  memset(maxSpeedPulse, 0x00, sizeof(maxSpeedPulse));
148  for(i=0; i<MP_GRP_AXES_NUM; i++)
149  maxSpeedPulse[i] = ctrlGroup->maxInc.maxIncrement[i] * 1000.0 / interpolPeriod;
150  Ros_CtrlGroup_ConvertToRosPos(ctrlGroup, maxSpeedPulse, ctrlGroup->maxSpeed);
151 
152  printf("axisType[%d]: ", groupNo);
153  for (i = 0; i < MP_GRP_AXES_NUM; i++)
154  {
155  if (ctrlGroup->axisType.type[i] == AXIS_LINEAR)
156  printf("Lin\t");
157  else if (ctrlGroup->axisType.type[i] == AXIS_ROTATION)
158  printf("Rot\t");
159  else
160  {
161  printf("---\t");
162  //motoRosAssert(FALSE, SUBCODE_INVALID_AXIS_TYPE, "Grp%d Axs%d type invalid", groupNo, i);
163  }
164  }
165  printf(";\r\n");
166 
167  printf("pulse->unit[%d]: ", groupNo);
168  for (i = 0; i < MP_GRP_AXES_NUM; i++)
169  {
170  if (ctrlGroup->axisType.type[i] == AXIS_LINEAR)
171  printf("%.4f\t", ctrlGroup->pulseToMeter.PtoM[i]);
172  else if (ctrlGroup->axisType.type[i] == AXIS_ROTATION)
173  printf("%.4f\t", ctrlGroup->pulseToRad.PtoR[i]);
174  else
175  printf("--\t");
176  }
177  printf(";\r\n");
178 
179  printf("maxInc[%d] (in motoman joint order): %d, %d, %d, %d, %d, %d, %d\r\n",
180  groupNo,
181  ctrlGroup->maxInc.maxIncrement[0],ctrlGroup->maxInc.maxIncrement[1],ctrlGroup->maxInc.maxIncrement[2],
182  ctrlGroup->maxInc.maxIncrement[3],ctrlGroup->maxInc.maxIncrement[4],ctrlGroup->maxInc.maxIncrement[5],
183  ctrlGroup->maxInc.maxIncrement[6]);
184 
185  printf("maxSpeed[%d] (in ros joint order): %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f\r\n",
186  groupNo,
187  ctrlGroup->maxSpeed[0],ctrlGroup->maxSpeed[1],ctrlGroup->maxSpeed[2],
188  ctrlGroup->maxSpeed[3],ctrlGroup->maxSpeed[4],ctrlGroup->maxSpeed[5],
189  ctrlGroup->maxSpeed[6]);
190 
191  ctrlGroup->tidAddToIncQueue = INVALID_TASK;
192 
193  if(bInitOk == FALSE)
194  {
195  mpFree(ctrlGroup);
196  ctrlGroup = NULL;
197  }
198  }
199  else
200  {
201  ctrlGroup = NULL;
202  }
203 
204  return ctrlGroup;
205 }
206 
207 
208 //-------------------------------------------------------------------
209 // Get the commanded pulse position in pulse (in motoman joint order)
210 // Used for MOTION SERVER connection for positional planning calculations.
211 //-------------------------------------------------------------------
212 BOOL Ros_CtrlGroup_GetPulsePosCmd(CtrlGroup* ctrlGroup, long pulsePos[MAX_PULSE_AXES])
213 {
214  LONG status = 0;
215  MP_CTRL_GRP_SEND_DATA sData;
216  MP_PULSE_POS_RSP_DATA pulse_data;
217  float rosAnglePos[MP_GRP_AXES_NUM]; //temporary storage for B axis compensation
218  int i;
219 
220  memset(pulsePos, 0, MAX_PULSE_AXES*sizeof(long)); // clear result, in case of error
221 
222  // Set the control group
223  switch(ctrlGroup->groupId)
224  {
225  case MP_R1_GID: sData.sCtrlGrp = 0; break;
226  case MP_R2_GID: sData.sCtrlGrp = 1; break;
227  case MP_R3_GID: sData.sCtrlGrp = 2; break;
228  case MP_R4_GID: sData.sCtrlGrp = 3; break;
229  case MP_B1_GID: sData.sCtrlGrp = 8; break;
230  case MP_B2_GID: sData.sCtrlGrp = 9; break;
231  case MP_B3_GID: sData.sCtrlGrp = 10; break;
232  case MP_B4_GID: sData.sCtrlGrp = 11; break;
233  case MP_S1_GID: sData.sCtrlGrp = 16; break;
234  case MP_S2_GID: sData.sCtrlGrp = 17; break;
235  case MP_S3_GID: sData.sCtrlGrp = 18; break;
236  default:
237  printf("Failed to get pulse feedback position\nInvalid groupId: %d\n", ctrlGroup->groupId);
238  return FALSE;
239  }
240 
241  // get the command joint positions
242  status = mpGetPulsePos (&sData,&pulse_data);
243  if (0 != status)
244  {
245  printf("Failed to get pulse position (command): %u\n", status);
246  return FALSE;
247  }
248 
249  // assign return value
250  for (i=0; i<MAX_PULSE_AXES; ++i)
251  pulsePos[i] = pulse_data.lPos[i];
252 
253  // For MPL80/100 robot type (SLUBT): Controller automatically moves the B-axis
254  // to maintain orientation as other axes are moved.
255  if (ctrlGroup->bIsBaxisSlave)
256  {
257  //B axis compensation works on the ROS ANGLE positions, not on MOTO PULSE positions
258  Ros_CtrlGroup_ConvertToRosPos(ctrlGroup, pulsePos, rosAnglePos);
259  rosAnglePos[3] += -rosAnglePos[1] + rosAnglePos[2];
260  Ros_CtrlGroup_ConvertToMotoPos(ctrlGroup, rosAnglePos, pulsePos);
261  }
262 
263  return TRUE;
264 }
265 
266 
267 //-------------------------------------------------------------------
268 // Get the corrected feedback pulse position in pulse.
269 // Used exclusively for STATE SERVER connection to report position.
270 //-------------------------------------------------------------------
271 BOOL Ros_CtrlGroup_GetFBPulsePos(CtrlGroup* ctrlGroup, long pulsePos[MAX_PULSE_AXES])
272 {
273  LONG status = 0;
274  MP_CTRL_GRP_SEND_DATA sData;
275 #ifndef DUMMY_SERVO_MODE
276  MP_FB_PULSE_POS_RSP_DATA pulse_data;
277 #else
278  MP_PULSE_POS_RSP_DATA pulse_data;
279 #endif
280  int i;
281 
282  memset(pulsePos, 0, MAX_PULSE_AXES*sizeof(long)); // clear result, in case of error
283 
284  // Set the control group
285  switch(ctrlGroup->groupId)
286  {
287  case MP_R1_GID: sData.sCtrlGrp = 0; break;
288  case MP_R2_GID: sData.sCtrlGrp = 1; break;
289  case MP_R3_GID: sData.sCtrlGrp = 2; break;
290  case MP_R4_GID: sData.sCtrlGrp = 3; break;
291  case MP_B1_GID: sData.sCtrlGrp = 8; break;
292  case MP_B2_GID: sData.sCtrlGrp = 9; break;
293  case MP_B3_GID: sData.sCtrlGrp = 10; break;
294  case MP_B4_GID: sData.sCtrlGrp = 11; break;
295  case MP_S1_GID: sData.sCtrlGrp = 16; break;
296  case MP_S2_GID: sData.sCtrlGrp = 17; break;
297  case MP_S3_GID: sData.sCtrlGrp = 18; break;
298  default:
299  printf("Failed to get pulse feedback position\nInvalid groupId: %d\n", ctrlGroup->groupId);
300  return FALSE;
301  }
302 
303 #ifndef DUMMY_SERVO_MODE
304  // get raw (uncorrected/unscaled) joint positions
305  status = mpGetFBPulsePos (&sData,&pulse_data);
306  if (0 != status)
307  {
308  printf("Failed to get pulse feedback position: %u\n", status);
309  return FALSE;
310  }
311 
312  // apply correction to account for cross-axis coupling
313  // Note: this is only required for feedback position
314  // controller handles this correction internally when
315  // dealing with command positon.
316  for (i=0; i<MAX_PULSE_AXES; ++i)
317  {
318  FB_AXIS_CORRECTION *corr = &ctrlGroup->correctionData.correction[i];
319  if (corr->bValid)
320  {
321  int src_axis = corr->ulSourceAxis;
322  int dest_axis = corr->ulCorrectionAxis;
323  pulse_data.lPos[dest_axis] -= (int)(pulse_data.lPos[src_axis] * corr->fCorrectionRatio);
324  }
325  }
326 #else
327  mpGetPulsePos(&sData, &pulse_data);
328 #endif
329 
330  // assign return value
331  for (i=0; i<MAX_PULSE_AXES; ++i)
332  pulsePos[i] = pulse_data.lPos[i];
333 
334  //--------------------------------------------------------------------
335  //NOTE: Do NOT apply any B axis compensation here.
336  // This is actual feedback which is reported to the state server.
337  //--------------------------------------------------------------------
338 
339  return TRUE;
340 }
341 
342 //-------------------------------------------------------------------
343 // Get the corrected feedback pulse speed in pulse for each axis.
344 //-------------------------------------------------------------------
345 BOOL Ros_CtrlGroup_GetFBServoSpeed(CtrlGroup* ctrlGroup, long pulseSpeed[MAX_PULSE_AXES])
346 {
347  int i;
348 
349 #ifndef DUMMY_SERVO_MODE
350 #if (DX100 || FS100) //Use mpSvsGetVelTrqFb for older controller models
351  MP_GRP_AXES_T dst_vel;
352  LONG status;
353 
354  if (ctrlGroup->groupNo >= MAX_CONTROLLABLE_GROUPS)
355  return FALSE;
356 
357  memset(&dst_vel, 0x00, sizeof(MP_GRP_AXES_T));
358 
359  status = mpSvsGetVelTrqFb(dst_vel, NULL); //units are 0.1 pulse/sec
360  if (status != OK)
361  return FALSE;
362 
363  for (i = 0; i < MAX_PULSE_AXES; i += 1)
364  {
365  pulseSpeed[i] = dst_vel[ctrlGroup->groupNo][i] * 0.1;
366  }
367 
368  // Apply correction to account for cross-axis coupling.
369  // Note: This is only required for feedback.
370  // Controller handles this correction internally when
371  // dealing with command positon.
372  for (i = 0; i< MAX_PULSE_AXES; ++i)
373  {
374  FB_AXIS_CORRECTION *corr = &ctrlGroup->correctionData.correction[i];
375  if (corr->bValid)
376  {
377  int src_axis = corr->ulSourceAxis;
378  int dest_axis = corr->ulCorrectionAxis;
379  pulseSpeed[dest_axis] -= (int)(pulseSpeed[src_axis] * corr->fCorrectionRatio);
380  }
381  }
382 
383 #else //DX200 and newer supports the M-register analog feedback (higher precision feedback)
384  LONG status;
385  MP_IO_INFO registerInfo[MAX_PULSE_AXES * 2]; //values are 4 bytes, which consumes 2 registers
386  USHORT registerValues[MAX_PULSE_AXES * 2];
387  UINT32 registerValuesLong[MAX_PULSE_AXES * 2];
388  double dblRegister;
389 
391  return FALSE;
392 
393  for (i = 0; i < MAX_PULSE_AXES; i += 1)
394  {
395  registerInfo[i * 2].ulAddr = ctrlGroup->speedFeedbackRegisterAddress.cioAddressForAxis[i][0];
396  registerInfo[(i * 2) + 1].ulAddr = ctrlGroup->speedFeedbackRegisterAddress.cioAddressForAxis[i][1];
397  }
398 
399  // get raw (uncorrected/unscaled) joint speeds
400  status = mpReadIO(registerInfo, registerValues, MAX_PULSE_AXES * 2);
401  if (status != OK)
402  {
403  printf("Failed to get pulse feedback speed: %u\n", status);
404  return FALSE;
405  }
406 
407  for (i = 0; i < MAX_PULSE_AXES; i += 1)
408  {
409  //move to 32 bit storage
410  registerValuesLong[i * 2] = registerValues[i * 2];
411  registerValuesLong[(i * 2) + 1] = registerValues[(i * 2) + 1];
412 
413  //combine both registers into single 4 byte value (0.0001 deg/sec or 1 um/sec)
414  dblRegister = (registerValuesLong[(i * 2) + 1] << 16) | registerValuesLong[i * 2];
415 
416  //convert to pulse/sec
417  if (ctrlGroup->axisType.type[i] == AXIS_ROTATION)
418  {
419  dblRegister /= 1.0E4; //deg/sec
420  dblRegister *= RAD_PER_DEGREE; //rad/sec
421  dblRegister *= ctrlGroup->pulseToRad.PtoR[i]; //pulse/sec
422  }
423  else if (ctrlGroup->axisType.type[i] == AXIS_LINEAR)
424  {
425  dblRegister /= 1.0E6; //m/sec
426  dblRegister *= ctrlGroup->pulseToMeter.PtoM[i]; //pulse/sec
427  }
428 
429  pulseSpeed[i] = (long)dblRegister;
430  }
431 #endif
432 
433 #else //dummy-servo mode for testing
434  MP_CTRL_GRP_SEND_DATA sData;
435  MP_SERVO_SPEED_RSP_DATA pulse_data;
436 
437  mpGetServoSpeed(&sData, &pulse_data);
438 
439  // assign return value
440  for (i = 0; i<MAX_PULSE_AXES; ++i)
441  pulseSpeed[i] = pulse_data.lSpeed[i];
442 #endif
443 
444  return TRUE;
445 }
446 
447 //-------------------------------------------------------------------
448 // Retrieves the absolute value (Nm) of the maximum current servo torque.
449 //-------------------------------------------------------------------
450 BOOL Ros_CtrlGroup_GetTorque(CtrlGroup* ctrlGroup, double torqueValues[MAX_PULSE_AXES])
451 {
452  MP_GRP_AXES_T dst_vel;
453  MP_TRQ_CTL_VAL dst_trq;
454  LONG status = 0;
455  int i;
456 
457  memset(torqueValues, 0, sizeof(torqueValues)); // clear result, in case of error
458  memset(dst_trq.data, 0, sizeof(MP_TRQCTL_DATA));
459  dst_trq.unit = TRQ_NEWTON_METER; //request data in Nm
460 
461  memset(&dst_vel, 0x00, sizeof(MP_GRP_AXES_T));
462 
463  status = mpSvsGetVelTrqFb(dst_vel, &dst_trq);
464  if (status != OK)
465  return FALSE;
466 
467  for (i = 0; i < MAX_PULSE_AXES; i += 1)
468  {
469  torqueValues[i] = (double)dst_trq.data[ctrlGroup->groupId][i] * 0.000001; //Use double. Float only good for 6 sig digits.
470  }
471 
472  return TRUE;
473 }
474 
475 // Convert Motoman position in pulse to Ros position in radian/meters
476 // In the case of a 7, 4, or 5 axis robot, adjust the order to match
477 // the physical axis sequence
478 //-------------------------------------------------------------------
479 void Ros_CtrlGroup_ConvertToRosPos(CtrlGroup* ctrlGroup, long motopulsePos[MAX_PULSE_AXES],
480  float rosPos[MAX_PULSE_AXES])
481 {
482  int i;
483  float conversion = 1;
484  int rpi = 0; //rosPos index
485  int mpi = 0; //motopos index
486 
487  if ((ctrlGroup->numAxes == 7) && Ros_CtrlGroup_IsRobot(ctrlGroup)) //is robot, and is 7 axis
488  {
489  // Adjust joint order for 7 axis robot (SLURBTE > SLEURBT); All rotary axes
490 
491  for (i = 0; i < ctrlGroup->numAxes; i++)
492  {
493  if (i < 2)
494  rosPos[i] = motopulsePos[i] / ctrlGroup->pulseToRad.PtoR[i];
495  else if (i == 2)
496  rosPos[2] = motopulsePos[6] / ctrlGroup->pulseToRad.PtoR[6];
497  else
498  rosPos[i] = motopulsePos[i - 1] / ctrlGroup->pulseToRad.PtoR[i - 1];
499  }
500  }
501  else if (Ros_CtrlGroup_IsRobot(ctrlGroup) && ctrlGroup->numAxes < 6)
502  {
503  //Delta: (SLU--T- > SLUT---) All rotary axes
504  //Scara: (SLUR--- > SLUR---) U-axis is linear
505  //Large Palletizing: (SLU--T- > SLUT---) All rotary axes
506  //High Speed Picking: (SLU-BT- > SLUBT--) All rotary axes
507 
508  for (i = rpi = mpi = 0; i < ctrlGroup->numAxes; i += 1, rpi += 1, mpi += 1)
509  {
510  while (ctrlGroup->axisType.type[mpi] == AXIS_INVALID)
511  {
512  mpi += 1;
513  if (mpi >= MAX_PULSE_AXES)
514  return;
515  }
516 
517  if (ctrlGroup->axisType.type[mpi] == AXIS_ROTATION)
518  conversion = ctrlGroup->pulseToRad.PtoR[mpi];
519  else if (ctrlGroup->axisType.type[mpi] == AXIS_LINEAR)
520  conversion = ctrlGroup->pulseToMeter.PtoM[mpi];
521  else
522  conversion = 1.0;
523 
524  rosPos[rpi] = motopulsePos[mpi] / conversion;
525  }
526  }
527  else
528  {
529  for (i = 0; i < MAX_PULSE_AXES; i++)
530  {
531  if (ctrlGroup->axisType.type[i] == AXIS_ROTATION)
532  conversion = ctrlGroup->pulseToRad.PtoR[i];
533  else if (ctrlGroup->axisType.type[i] == AXIS_LINEAR)
534  conversion = ctrlGroup->pulseToMeter.PtoM[i];
535  else
536  conversion = 1.0;
537 
538  rosPos[i] = motopulsePos[i] / conversion;
539  }
540  }
541 }
542 
543 //-------------------------------------------------------------------
544 // Convert Ros position in radian to Motoman position in pulse
545 // In the case of a 7 or 4 axis robot, adjust the order to match
546 // the motoman axis sequence
547 //-------------------------------------------------------------------
548 void Ros_CtrlGroup_ConvertToMotoPos(CtrlGroup* ctrlGroup, float radPos[MAX_PULSE_AXES], long motopulsePos[MAX_PULSE_AXES])
549 {
550  int i;
551  float conversion = 1;
552  int rpi = 0; //radpos index
553  int mpi = 0; //motopos index
554 
555  // Initialize memory space
556  memset(motopulsePos, 0x00, sizeof(long)*MAX_PULSE_AXES);
557 
558  if ((ctrlGroup->numAxes == 7) && Ros_CtrlGroup_IsRobot(ctrlGroup))
559  {
560  // Adjust joint order for 7 axis robot (SLEURBT > SLURBTE); All rotary axes
561 
562  for (i = 0; i < ctrlGroup->numAxes; i++)
563  {
564  if (i < 2)
565  motopulsePos[i] = (int)(radPos[i] * ctrlGroup->pulseToRad.PtoR[i]);
566  else if (i == 2)
567  motopulsePos[6] = (int)(radPos[2] * ctrlGroup->pulseToRad.PtoR[6]);
568  else
569  motopulsePos[i - 1] = (int)(radPos[i] * ctrlGroup->pulseToRad.PtoR[i - 1]);
570  }
571  }
572  else if (Ros_CtrlGroup_IsRobot(ctrlGroup) && ctrlGroup->numAxes < 6)
573  {
574  //Delta: (SLUT--- > SLU--T-) All rotary axes
575  //Scara: (SLUR--- > SLUR---) U-axis is linear
576  //Large Palletizing: (SLUT--- > SLU--T-) All rotary axes
577  //High Speed Picking: (SLUBT-- > SLU-BT-) All rotary axes
578 
579  for (i = rpi = mpi = 0; i < ctrlGroup->numAxes; i += 1, rpi += 1, mpi += 1)
580  {
581  while (ctrlGroup->axisType.type[mpi] == AXIS_INVALID)
582  {
583  mpi += 1;
584  if (mpi >= MAX_PULSE_AXES)
585  return;
586  }
587 
588  if (ctrlGroup->axisType.type[mpi] == AXIS_ROTATION)
589  conversion = ctrlGroup->pulseToRad.PtoR[mpi];
590  else if (ctrlGroup->axisType.type[mpi] == AXIS_LINEAR)
591  conversion = ctrlGroup->pulseToMeter.PtoM[mpi];
592  else
593  conversion = 1.0;
594 
595  motopulsePos[mpi] = (int)(radPos[rpi] * conversion);
596  }
597  }
598  else
599  {
600  // Convert to pulse
601  for (i = 0; i < MAX_PULSE_AXES; i++)
602  {
603  if (ctrlGroup->axisType.type[i] == AXIS_ROTATION)
604  conversion = ctrlGroup->pulseToRad.PtoR[i];
605  else if (ctrlGroup->axisType.type[i] == AXIS_LINEAR)
606  conversion = ctrlGroup->pulseToMeter.PtoM[i];
607  else
608  conversion = 1.0;
609 
610  motopulsePos[i] = (int)(radPos[i] * conversion);
611  }
612  }
613 }
614 
615 //-------------------------------------------------------------------
616 // Returns a bit wise axis configuration for the increment move API
617 //-------------------------------------------------------------------
619 {
620  int i;
621  int axisConfig = 0;
622 
623  for (i = 0; i < MAX_PULSE_AXES; i++)
624  {
625  if (ctrlGroup->axisType.type[i] != AXIS_INVALID)
626  axisConfig |= (0x01 << i);
627  }
628 
629  return (UCHAR)axisConfig;
630 }
631 
632 //-------------------------------------------------------------------
633 // Returns TRUE is the specified group is defined as a robot
634 //-------------------------------------------------------------------
636 {
637  return((ctrlGroup->groupId >= MP_R1_GID) && (ctrlGroup->groupId <= MP_R4_GID));
638 }
MP_GRP_ID_TYPE groupId
Definition: CtrlGroup.h:84
int GP_getNumberOfAxes(int ctrlGrp)
AXIS_TYPE type[MAX_PULSE_AXES]
STATUS GP_getMaxIncPerIpCycle(int ctrlGrp, int interpolationPeriodInMilliseconds, MAX_INCREMENT_INFO *mip)
#define INVALID_TASK
Definition: Controller.h:68
#define MAX_CONTROLLABLE_GROUPS
Definition: Controller.h:64
BOOL Ros_CtrlGroup_GetPulsePosCmd(CtrlGroup *ctrlGroup, long pulsePos[MAX_PULSE_AXES])
Definition: CtrlGroup.c:212
JOINT_FEEDBACK_SPEED_ADDRESSES speedFeedbackRegisterAddress
Definition: CtrlGroup.h:105
Incremental_q inc_q
Definition: CtrlGroup.h:92
BOOL bIsBaxisSlave
Definition: CtrlGroup.h:103
int groupNo
float PtoR[MAX_PULSE_AXES]
BOOL Ros_CtrlGroup_GetFBPulsePos(CtrlGroup *ctrlGroup, long pulsePos[MAX_PULSE_AXES])
Definition: CtrlGroup.c:271
STATUS GP_getFBPulseCorrection(int ctrlGrp, FB_PULSE_CORRECTION_DATA *correctionData)
STATUS GP_isBaxisSlave(int ctrlGrp, BOOL *bBaxisIsSlave)
float PtoM[MAX_PULSE_AXES]
SEM_ID q_lock
Definition: CtrlGroup.h:60
float maxSpeed[MP_GRP_AXES_NUM]
Definition: CtrlGroup.h:89
PULSE_TO_RAD pulseToRad
Definition: CtrlGroup.h:85
void Ros_CtrlGroup_ConvertToMotoPos(CtrlGroup *ctrlGroup, float radPos[MAX_PULSE_AXES], long motopulsePos[MAX_PULSE_AXES])
Definition: CtrlGroup.c:548
STATUS
ULONG cioAddressForAxis[MAX_PULSE_AXES][2]
STATUS GP_getAxisMotionType(int ctrlGrp, AXIS_MOTION_TYPE *axisType)
int tidAddToIncQueue
Definition: CtrlGroup.h:98
BOOL Ros_CtrlGroup_GetTorque(CtrlGroup *ctrlGroup, double torqueValues[MAX_PULSE_AXES])
Definition: CtrlGroup.c:450
UCHAR Ros_CtrlGroup_GetAxisConfig(CtrlGroup *ctrlGroup)
Definition: CtrlGroup.c:618
STATUS GP_getPulseToMeter(int ctrlGrp, PULSE_TO_METER *PulseToMeter)
int tool
Definition: CtrlGroup.h:90
int groupNo
Definition: CtrlGroup.h:82
STATUS GP_getPulseToRad(int ctrlGrp, PULSE_TO_RAD *PulseToRad)
MP_GRP_ID_TYPE Ros_CtrlGroup_FindGrpId(int groupNo)
Definition: CtrlGroup.c:42
BOOL Ros_CtrlGroup_GetFBServoSpeed(CtrlGroup *ctrlGroup, long pulseSpeed[MAX_PULSE_AXES])
Definition: CtrlGroup.c:345
int numAxes
Definition: CtrlGroup.h:83
BOOL Ros_CtrlGroup_IsRobot(CtrlGroup *ctrlGroup)
Definition: CtrlGroup.c:635
STATUS GP_getFeedbackSpeedMRegisterAddresses(int ctrlGrp, BOOL bActivateIfNotEnabled, BOOL bForceRebootAfterActivation, JOINT_FEEDBACK_SPEED_ADDRESSES *registerAddresses)
#define RAD_PER_DEGREE
Definition: CtrlGroup.h:47
MAX_INCREMENT_INFO maxInc
Definition: CtrlGroup.h:88
UINT32 maxIncrement[MAX_PULSE_AXES]
FB_AXIS_CORRECTION correction[MAX_PULSE_AXES]
AXIS_MOTION_TYPE axisType
Definition: CtrlGroup.h:101
FB_PULSE_CORRECTION_DATA correctionData
Definition: CtrlGroup.h:87
PULSE_TO_METER pulseToMeter
Definition: CtrlGroup.h:86
CtrlGroup * Ros_CtrlGroup_Create(int groupNo, BOOL bIsLastGrpToInit, float interpolPeriod)
Definition: CtrlGroup.c:59
float GP_getGovForIncMotion(int ctrlGrp)
void Ros_CtrlGroup_ConvertToRosPos(CtrlGroup *ctrlGroup, long motopulsePos[MAX_PULSE_AXES], float rosPos[MAX_PULSE_AXES])
Definition: CtrlGroup.c:479


motoman_driver
Author(s): Jeremy Zoss (Southwest Research Institute), Ted Miller (MotoROS) (Yaskawa Motoman), Eric Marcil (MotoROS) (Yaskawa Motoman)
autogenerated on Sat May 8 2021 02:27:43