PowerCubeCtrl.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2017 Fraunhofer Institute for Manufacturing Engineering and Automation (IPA)
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9 
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 
18 // ROS includes
19 #include <ros/ros.h>
20 
21 // own includes
23 
24 #define PCTRL_CHECK_INITIALIZED() \
25  if (isInitialized() == false) \
26  { \
27  m_ErrorMessage.assign("Manipulator not initialized."); \
28  return false; \
29  }
30 
31 #define Ready4MoveStep 4638
32 
33 /*
34  * \brief Constructor
35  */
37 {
38  m_mutex = PTHREAD_MUTEX_INITIALIZER;
39 
40  m_CANDeviceOpened = false;
41  m_Initialized = false;
42 
43  m_params = params;
44 
45  m_horizon = 0.01; // sec
46 
48 
50 }
51 
52 /*
53  * \brief Destructor
54  */
56 {
57  // stop all components
58  Stop();
59 
60  // close CAN device
62  {
63  pthread_mutex_lock(&m_mutex);
65  pthread_mutex_unlock(&m_mutex);
66  }
67 }
68 
70 
76 {
77  int ret = 0;
78  int DOF = m_params->GetDOF();
79  std::string CanModule = m_params->GetCanModule();
80  std::string CanDevice = m_params->GetCanDevice();
81  std::vector<int> ModulIDs = m_params->GetModuleIDs();
82  int CanBaudrate = m_params->GetBaudrate();
83  std::vector<double> MaxVel = m_params->GetMaxVel();
84  std::vector<double> MaxAcc = m_params->GetMaxAcc();
85  std::vector<double> Offsets = m_params->GetOffsets();
86  std::vector<double> LowerLimits = m_params->GetLowerLimits();
87  std::vector<double> UpperLimits = m_params->GetUpperLimits();
88 
90  std::cout << " D O F :" << DOF << std::endl;
91  m_status.resize(DOF);
92  m_ModuleTypes.resize(DOF);
93  m_version.resize(DOF);
94  m_dios.resize(DOF);
95  m_positions.resize(DOF);
96  m_velocities.resize(DOF);
97 
98  std::cout << "=========================================================================== " << std::endl;
99  std::cout << "PowerCubeCtrl:Init: Trying to initialize with the following parameters: " << std::endl;
100  std::cout << "DOF: " << DOF << std::endl;
101  std::cout << "CanModule: " << CanModule << std::endl;
102  std::cout << "CanDevice: " << CanDevice << std::endl;
103  std::cout << "CanBaudrate: " << CanBaudrate << std::endl;
104  std::cout << "ModulIDs: ";
105  for (int i = 0; i < DOF; i++)
106  {
107  std::cout << ModulIDs[i] << " ";
108  }
109  std::cout << std::endl;
110 
111  std::cout << std::endl << "maxVel: ";
112  for (int i = 0; i < DOF; i++)
113  {
114  std::cout << MaxVel[i] << " ";
115  }
116 
117  std::cout << std::endl << "maxAcc: ";
118  for (int i = 0; i < DOF; i++)
119  {
120  std::cout << MaxAcc[i] << " ";
121  }
122 
123  std::cout << std::endl << "upperLimits: ";
124  for (int i = 0; i < DOF; i++)
125  {
126  std::cout << UpperLimits[i] << " ";
127  }
128 
129  std::cout << std::endl << "lowerLimits: ";
130  for (int i = 0; i < DOF; i++)
131  {
132  std::cout << LowerLimits[i] << " ";
133  }
134 
135  std::cout << std::endl << "offsets: ";
136  for (int i = 0; i < DOF; i++)
137  {
138  std::cout << Offsets[i] << " ";
139  }
140 
141  std::cout << std::endl << "=========================================================================== " << std::endl;
142  std::ostringstream InitStr;
143  InitStr << CanModule << ":" << CanDevice << "," << CanBaudrate;
144  std::cout << "initstring = " << InitStr.str().c_str() << std::endl;
145 
147  pthread_mutex_lock(&m_mutex);
148  ret = PCube_openDevice(&m_DeviceHandle, InitStr.str().c_str());
149  pthread_mutex_unlock(&m_mutex);
150  if (ret != 0)
151  {
152  std::ostringstream errorMsg;
153  errorMsg << "Could not open device " << CanDevice << ", m5api error code: " << ret;
154  m_ErrorMessage = errorMsg.str();
155  return false;
156  }
157 
158  m_CANDeviceOpened = true;
159 
161  int max_tries = 3;
162  for (int i = 0; i < DOF; i++)
163  {
164  for (int reset_try = 0; reset_try < max_tries; reset_try++)
165  {
166  pthread_mutex_lock(&m_mutex);
167  ret = PCube_resetModule(m_DeviceHandle, ModulIDs.at(i));
168  pthread_mutex_unlock(&m_mutex);
169 
170  if (ret == 0)
171  {
172  break;
173  }
174  else if ((ret != 0) && (reset_try == (max_tries - 1)))
175  {
176  std::ostringstream errorMsg;
177  errorMsg << "Could not reset module " << ModulIDs.at(i) << " during init. Errorcode during reset: " << ret << " Try to init once more.";
178  m_ErrorMessage = errorMsg.str();
179  return false;
180  }
181  else
182  {
183  // little break
184  usleep(1500000);
185  }
186  }
187  }
188  std::cout << "number of moduleIDs" << ModulIDs.size() << std::endl;
189 
191  pthread_mutex_lock(&m_mutex);
192  int number_of_modules = PCube_getModuleCount(m_DeviceHandle);
193  pthread_mutex_unlock(&m_mutex);
194  std::cout << "found " << number_of_modules << " modules." << std::endl;
195 
197  for (int i = 0; i < DOF; i++)
198  {
199  unsigned long serNo;
200  unsigned short verNo;
201  unsigned long defConfig;
202  std::vector<std::string> Module_Types;
203 
205  pthread_mutex_lock(&m_mutex);
206  ret = PCube_getModuleSerialNo(m_DeviceHandle, ModulIDs[i], &serNo);
207  pthread_mutex_unlock(&m_mutex);
208  if (ret != 0)
209  {
210  std::ostringstream errorMsg;
211  errorMsg << "Could not find Module with ID " << ModulIDs[i] << ", m5api error code: " << ret;
212  m_ErrorMessage = errorMsg.str();
213  return false;
214  }
215 
217  pthread_mutex_lock(&m_mutex);
218  ret = PCube_getModuleVersion(m_DeviceHandle, ModulIDs[i], &verNo);
219  pthread_mutex_unlock(&m_mutex);
220  if (ret != 0)
221  {
222  std::ostringstream errorMsg;
223  errorMsg << "Could not find Module with ID " << ModulIDs[i] << ", m5api error code: " << ret;
224  m_ErrorMessage = errorMsg.str();
225  return false;
226  }
227  else
228  {
229  m_version[i] = verNo;
230  }
231 
233  float gear_ratio;
234  pthread_mutex_lock(&m_mutex);
235  ret = PCube_getDefGearRatio(m_DeviceHandle, ModulIDs[i], &gear_ratio);
236  pthread_mutex_unlock(&m_mutex);
237  if (ret != 0)
238  {
239  std::ostringstream errorMsg;
240  errorMsg << "Could not get Module type with ID " << ModulIDs[i] << ", m5api error code: " << ret;
241  m_ErrorMessage = errorMsg.str();
242  return false;
243  }
244  else
245  {
246  if (true)
247  {
248  std::cout << "gear ratio: " << gear_ratio << std::endl;
249  // return false;
250  }
251  }
252 
254  unsigned char type;
255  pthread_mutex_lock(&m_mutex);
256  ret = PCube_getModuleType(m_DeviceHandle, ModulIDs[i], &type);
257  pthread_mutex_unlock(&m_mutex);
258  if (ret != 0)
259  {
260  std::ostringstream errorMsg;
261  errorMsg << "Could not get Module type with ID " << ModulIDs[i] << ", m5api error code: " << ret;
262  m_ErrorMessage = errorMsg.str();
263  return false;
264  }
265  else
266  {
267  if (type != TYPEID_MOD_ROTARY)
268  {
269  std::cout << "wrong module type configured. Type must be rotary axis. Use Windows configuration software to change type." << std::endl;
270  return false;
271  }
272  }
273 
275  // the typ -if PW or PRL- can be distinguished by the typ of encoder.
276  pthread_mutex_lock(&m_mutex);
277  ret = PCube_getDefSetup(m_DeviceHandle, ModulIDs[i], &defConfig);
278  pthread_mutex_unlock(&m_mutex);
279 
280  ROS_DEBUG("module type check: %li (std::dec)", defConfig);
281 
282  if (ret != 0)
283  {
284  std::ostringstream errorMsg;
285  errorMsg << "Error on communication with module " << ModulIDs[i] << ", m5api error code: " << ret;
286  m_ErrorMessage = errorMsg.str();
287  return false;
288  }
289 
290  // Firmware version 4634 of PRL modules replies ABSOULTE_FEEDBACK, firmware 4638 replies RESOLVER_FEEDBACK.
291  // Both means the same: Module is PRL. PW modules have encoders (ENCODER_FEEDBACK, s.M5API), but this bit is not set
292  // is DefConfig word.
293  // For new firmware versions this needs to be evaluated.
294  if (((defConfig & CONFIG_ABSOLUTE_FEEDBACK) == CONFIG_ABSOLUTE_FEEDBACK) ||
295  ((defConfig & CONFIG_RESOLVER_FEEDBACK) == CONFIG_RESOLVER_FEEDBACK))
296  {
297  m_ModuleTypes[i] = "PRL";
298  ROS_DEBUG("Module %i is from type: PRL", i);
299  }
300  else
301  {
302  m_ModuleTypes[i] = "PW";
303  ROS_DEBUG("Module %i is from type: PW", i);
304  }
305 
307  std::cout << "Found module " << std::dec << ModulIDs[i] << " Serial: " << serNo << " Version: " << std::hex << verNo << std::endl;
308  }
309 
310  // modules should be initialized now
312  m_Initialized = true;
313 
315  std::vector<std::string> errorMessages;
316  PC_CTRL_STATUS status;
317 
318  // update status variables
319  updateStates();
320 
321  // grep updated status
322  getStatus(status, errorMessages);
323 
324  // homing dependant on moduletype and if already homed
325  bool successful = false;
326  successful = doHoming();
327  if (!successful)
328  {
329  std::cout << "PowerCubeCtrl:Init: homing not successful, aborting ...\n";
330  return false;
331  }
332 
333  // All modules initialized successfully
335  return true;
336 }
337 
342 {
343  if (m_CANDeviceOpened)
344  {
345  m_Initialized = false;
346  m_CANDeviceOpened = false;
347 
348  pthread_mutex_lock(&m_mutex);
350  pthread_mutex_unlock(&m_mutex);
351 
352  return true;
353  }
354 
355  else
356  {
357  return false;
358  }
359 }
360 
366 bool PowerCubeCtrl::MoveJointSpaceSync(const std::vector<double>& target_pos)
367 {
369 
370  unsigned int DOF = m_params->GetDOF();
371  std::vector<int> ModulIDs = m_params->GetModuleIDs();
372 
373  std::vector<double> m_maxVel = m_params->GetMaxVel();
374  std::vector<double> m_maxAcc = m_params->GetMaxAcc();
375 
376  std::cout << "Starting MoveJointSpaceSync(Jointd Angle) ... " << std::endl;
377 
378  // Questions about method: Felix.Geibel@gmx.de
379  std::vector<double> acc(DOF);
380  std::vector<double> vel(DOF);
381  std::vector<double> posnow(DOF);
382  std::vector<double> velnow(DOF);
383  double TG = 0;
384 
385  try
386  {
387  // Calcute the joint which need longest time to the goal
388  if (!getJointAngles(posnow))
389  {
390  return false;
391  }
392 
393  if (!getJointVelocities(velnow))
394  {
395  return false;
396  }
397 
398  std::vector<double> times(DOF);
399  for (int i = 0; i < DOF; i++)
400  {
401  RampCommand rm(posnow[i], velnow[i], target_pos[i], m_maxAcc[i], m_maxVel[i]);
402  times[i] = rm.getTotalTime();
403  }
404 
405  // determine the joint index that has the greates value for time
406  int furthest = 0;
407  double max = times[0];
408  for (int i = 1; i < DOF; i++)
409  {
410  if (times[i] > max)
411  {
412  max = times[i];
413  furthest = i;
414  }
415  }
416 
417  RampCommand rm_furthest(posnow[furthest], velnow[furthest], target_pos[furthest], m_maxAcc[furthest], m_maxVel[furthest]);
418 
419  double T1 = rm_furthest.T1();
420  double T2 = rm_furthest.T2();
421  double T3 = rm_furthest.T3();
422  // Sum of times:
423  TG = T1 + T2 + T3;
424 
425  acc[furthest] = m_maxAcc[furthest]; //maximal acceleration for furthest
426  vel[furthest] = m_maxVel[furthest]; //maximal speed for furthest
427 
428  for (int i = 0; i < DOF; i++)
429  {
430  if (i != furthest)
431  {
432  double a;
433  double v;
434  // a und v berechnen:
435  RampCommand::calculateAV( //TODO Berechnungsfehler! In dieser Methode wird die Geschw. und Beschl. falsch berechnet!
436  posnow[i],
437  velnow[i],
438  target_pos[i],
439  TG, T3,
440  m_maxAcc[i],
441  m_maxVel[i],
442  a,
443  v);
444 
445  acc[i] = a;
446  vel[i] = v;
447  // printf("i_a: %f \n", acc[i]);
448  // printf("i_v: %f \n", vel[i]);
449  }
450  }
451  }
452  catch (...)
453  {
454  return false;
455  }
456 
457  // Send motion commands to hardware
458  std::ostringstream errorMsg;
459  int ret = 0;
460  bool ok = true;
461 
462  //PCube_setDeviceDebug(m_Dev, 1, 2, -1);
463  for (int i = 0; i < DOF; i++)
464  {
465  if (fabs(posnow[i] - target_pos[i]) > 1e-3)
466  {
467  double v = fabs(vel[i]);
468  double a = fabs(acc[i]);
469  ret = PCube_moveRamp(m_DeviceHandle, ModulIDs[i], target_pos[i], v, a);
470  if (ret != 0)
471  {
472  errorMsg << "Module " << ModulIDs[i] << " PCube_moveRamp returned " << ret << std::endl;
473  m_ErrorMessage = errorMsg.str();
474  ok = false;
475  }
476  }
477  }
478 
480  if (ret != 0)
481  {
482  errorMsg << "PCube_startMotionAll returned " << ret << std::endl;
483  m_ErrorMessage = errorMsg.str();
484  ok = false;
485  }
486 
487  return ok;
488 }
489 
490 /*
491  * \brief Move joints with calculated velocities
492  *
493  * Calculating positions and times by desired value of the cob_trajectory_controller
494  * \param velocities Vector
495  */
496 bool PowerCubeCtrl::MoveVel(const std::vector<double>& vel)
497 {
499 
500  //== init var ==================================================
501 
503  unsigned int DOF = m_params->GetDOF();
504  std::vector<int> ModulIDs = m_params->GetModuleIDs();
505 
506  std::vector<double> velocities;
507  velocities.resize(DOF);
508  velocities = vel; // temp var for velocity because of const reference of the function
509 
510  std::ostringstream errorMsg; // temp error msg for being copied to m_errorMessage
511 
512  std::vector<std::string> errorMessages; // temp error msg for call of getStatus()
513  PC_CTRL_STATUS status; // PowerCube Ctrl status variable
514 
515  std::vector<float> delta_pos; // traviling distance for next command
516  std::vector<float> delta_pos_horizon;
517  delta_pos.resize(DOF);
518  delta_pos_horizon.resize(DOF);
519 
520  std::vector<float> target_pos; // absolute target postion that is desired with this command
521  std::vector<float> target_pos_horizon;
522 
523  target_pos.resize(DOF);
524  target_pos_horizon.resize(DOF);
525  float target_time; // time in milliseconds
526  float target_time_horizon = 0;
527 
528  float delta_t; // time from the last moveVel cmd to now
529 
531  std::vector<double> LowerLimits = m_params->GetLowerLimits();
532  std::vector<double> UpperLimits = m_params->GetUpperLimits();
533  std::vector<double> maxVels = m_params->GetMaxVel();
534 
536  std::vector<double> Offsets = m_params->GetOffsets();
537 
538  int ret; // temp return value holder
539  float pos; // temp position variable for PCube_move.. cmds
540 
541  //== calculate destination position ============================
542  // needed for limit handling and MoveStep command
543 
544  delta_t = ros::Time::now().toSec() - m_last_time_pub.toSec();
545 
547 
548  std::vector<double> pos_temp;
549  pos_temp.resize(DOF);
550 
551  for (unsigned int i = 0; i < DOF; i++)
552  {
553  // limit step time to 50msec
554  // TODO: set value 0.05 as parameter
555  if (delta_t >= 0.050)
556  {
557  target_time = 0.050; // sec
558  }
559  else
560  {
561  target_time = delta_t; // sec
562  }
563 
564  // add horizon to time before calculation of target position, to influence both time and position at the same time
565  target_time_horizon = target_time + (float)m_horizon; // sec
566  // calculate travel distance
567  delta_pos_horizon[i] = target_time_horizon * velocities[i];
568  delta_pos[i] = target_time * velocities[i];
569 
570  ROS_DEBUG("delta_pos[%i]: %f target_time: %f velocitiy[%i]: %f", i, delta_pos[i], target_time, i, velocities[i]);
571 
572  // calculate target position
573  target_pos_horizon[i] = m_positions[i] + delta_pos_horizon[i] - Offsets[i];
574  ROS_DEBUG("target_pos[%i]: %f m_position[%i]: %f", i, target_pos[i], i, m_positions[i]);
575  }
576 
577  //== check input parameter =====================================
578 
580  if (velocities.size() != DOF)
581  {
582  m_ErrorMessage = "Skipping command: Commanded velocities and DOF are not same dimension.";
583  return false;
584  }
585 
586  for (unsigned int i = 0; i < DOF; i++)
587  {
589  if (velocities[i] > maxVels[i])
590  {
591  // set velocities command to max value
592  velocities[i] = maxVels[i];
593 
594  // TODO: add ros_warn
595 
596  ROS_INFO("Velocity %f exceeds limit %f for axis %i. moving with max velocity %f instead", velocities[i], maxVels[i], i, maxVels[i]);
597  }
598 
600  // TODO: add second limit "safty limit"
601  // if target position is outer limits and the command velocity is in in direction away from working range, skip
602  // command
603  if ((target_pos[i] < LowerLimits[i] + Offsets[i]) && (velocities[i] < 0))
604  {
605  ROS_INFO("Skipping command: %f Target position exceeds lower limit (%f).", target_pos[i], LowerLimits[i]);
606  // target position is set to actual position and velocity to Null. So only movement in the non limit direction is possible.
607 
608  pthread_mutex_lock(&m_mutex);
609  PCube_haltModule(m_DeviceHandle, ModulIDs.at(i));
610  pthread_mutex_unlock(&m_mutex);
611 
612  return true;
613  }
614 
615  // if target position is outer limits and the command velocity is in in direction away from working range, skip command
616  if ((target_pos[i] > UpperLimits[i] + Offsets[i]) && (velocities[i] > 0))
617  {
618  ROS_INFO("Skipping command: %f Target position exceeds upper limit (%f).", target_pos[i], UpperLimits[i]);
619  // target position is set to actual position. So only movement in the non limit direction is possible.
620 
621  pthread_mutex_lock(&m_mutex);
622  PCube_haltModule(m_DeviceHandle, ModulIDs.at(i));
623  pthread_mutex_unlock(&m_mutex);
624 
625  return true;
626  }
627  }
628 
629  //== check system status ======================================
630 
631  getStatus(status, errorMessages);
632 
633  if ((status != PC_CTRL_OK))
634  {
635  m_ErrorMessage.assign("");
636  for (unsigned int i = 0; i < DOF; i++)
637  {
638  m_ErrorMessage.append(errorMessages[i]);
639  }
640  ROS_INFO("Error during movement. Status: %i \n", status);
641  return false;
642  }
643 
644  //== send velocity cmd to modules ==============================
645 
646  // convert the time to int in [ms]
647  unsigned short time4motion = (unsigned short)((target_time_horizon)*1000.0);
648 
649  for (unsigned int i = 0; i < DOF; i++)
650  {
651  // check module type sending command (PRL-Modules can be driven with moveStepExtended(), PW-Modules can only be driven with less safe moveVelExtended())
652  if ((m_ModuleTypes.at(i) == "PRL") && (m_version[i] >= Ready4MoveStep) && !m_params->GetUseMoveVel())
653  {
654  // ROS_DEBUG("Modul_id = %i, ModuleType: %s, step=%f, time=%f", m_params->GetModuleID(i), m_ModuleTypes[i].c_str(), target_pos[i], target_time);
655 
656  // ROS_INFO("Modul_id = %i, ModuleType: %s, step=%f, time4motion=%i [ms], target_time=%f, horizon: %f", m_params->GetModuleID(i), m_ModuleTypes[i].c_str(), delta_pos[i], time4motion, target_time, m_horizon);
657 
658  pthread_mutex_lock(&m_mutex);
659  ret = PCube_moveStepExtended(m_DeviceHandle, m_params->GetModuleID(i), target_pos_horizon[i], time4motion, &m_status[i], &m_dios[i], &pos);
660  pthread_mutex_unlock(&m_mutex);
661  }
662  else
663  {
664  pthread_mutex_lock(&m_mutex);
665  ret = PCube_moveVelExtended(m_DeviceHandle, m_params->GetModuleID(i), velocities[i], &m_status[i], &m_dios[i], &pos);
666  pthread_mutex_unlock(&m_mutex);
667  }
668 
670  if (ret != 0)
671  {
672  ROS_DEBUG("Com Error: %i", ret);
673  pos = m_positions[i];
674  // m_pc_status = PC_CTRL_ERR;
675  // TODO: add error msg for diagnostics if error occours often
676  }
677 
678  // !!! Position in pos is position before moveStep movement, to get the expected position after the movement
679  // (required as input to the next moveStep command) we add the delta position (cmd_pos) !!!
680  m_positions[i] = (double)pos + delta_pos[i] + Offsets[i];
681 
682  pos_temp[i] = (double)pos;
683  // ROS_INFO("After cmd (%X) :m_positions[%i] %f = pos: %f + delta_pos[%i]: %f",m_status[i], i, m_positions[i], pos, i, delta_pos[i]);
684  }
685 
686  updateVelocities(pos_temp, delta_t);
687 
688  // std::cout << "vel_com: " << velocities[1] << " vel_hori: " << delta_pos_horizon[1]/target_time_horizon << " vel_real[1]: " << m_velocities.at(1) << std::endl;
689 
690  pthread_mutex_lock(&m_mutex);
692  pthread_mutex_unlock(&m_mutex);
693 
694  return true;
695 }
696 
697 // Calculation of velocities based on vel = 1/(6*dt) * (-pos(t-3) - 3*pos(t-2) + 3*pos(t-1) + pos(t))
698 void PowerCubeCtrl::updateVelocities(std::vector<double> pos_temp, double delta_t)
699 {
700  unsigned int DOF = m_params->GetDOF();
701 
702  if (m_cached_pos.empty())
703  {
704  std::vector<double> null;
705  for (unsigned int i = 0; i < DOF; i++)
706  {
707  null.push_back(0);
708  }
709 
710  m_cached_pos.push_back(null);
711  m_cached_pos.push_back(null);
712  m_cached_pos.push_back(null);
713  m_cached_pos.push_back(null);
714  }
715 
716  m_cached_pos.push_back(pos_temp);
717  m_cached_pos.pop_front();
718 
719  std::vector<double> last_pos = m_cached_pos.front();
720 
721  for (unsigned int i = 0; i < DOF; i++)
722  {
723  m_velocities[i] = 1 / (6 * delta_t) * (-m_cached_pos[0][i] - (3 * m_cached_pos[1][i]) + (3 * m_cached_pos[2][i]) + m_cached_pos[3][i]);
724  // m_velocities[i] = (m_cached_pos[3][i] - m_cached_pos[2][i])/delta_t;
725  // m_velocities[i] = (pos_temp.at(i)-last_pos.at(i))/delta_t;
726  }
727 }
728 
733 {
735  unsigned int DOF = m_params->GetDOF();
736  std::vector<int> ModulIDs = m_params->GetModuleIDs();
737 
739 
740  for (unsigned int i = 0; i < DOF; i++)
741  {
742  pthread_mutex_lock(&m_mutex);
743  int ret = PCube_haltModule(m_DeviceHandle, ModulIDs.at(i));
744  pthread_mutex_unlock(&m_mutex);
745  if (ret != 0)
746  {
747  std::ostringstream errorMsg;
748  errorMsg << "Could not reset all modules, m5api error code: " << ret;
749  m_ErrorMessage = errorMsg.str();
750  return false;
751  }
752  }
753 
755  usleep(500000);
756 
758  for (unsigned int i = 0; i < DOF; i++)
759  {
760  pthread_mutex_lock(&m_mutex);
761  int ret = PCube_resetModule(m_DeviceHandle, ModulIDs.at(i));
762  pthread_mutex_unlock(&m_mutex);
763  if (ret != 0)
764  {
765  std::ostringstream errorMsg;
766  errorMsg << "Could not reset all modules, m5api error code: " << ret;
767  m_ErrorMessage = errorMsg.str();
768  return false;
769  }
770  }
771  return true;
772 }
773 
778 {
779  unsigned int DOF = m_params->GetDOF();
780  std::vector<int> ModulIDs = m_params->GetModuleIDs();
781  std::vector<double> MaxVel = m_params->GetMaxVel();
782  std::vector<double> MaxAcc = m_params->GetMaxAcc();
783  std::vector<double> Offsets = m_params->GetOffsets();
784 
785  std::vector<std::string> errorMessages;
786  PC_CTRL_STATUS status;
787 
788  unsigned long state = PC_CTRL_OK;
789  unsigned char dio;
790  float position;
791  int ret = 0;
792 
793  // check for each module if reset is necessary
794  for (unsigned int i = 0; i < DOF; i++)
795  {
796  pthread_mutex_lock(&m_mutex);
797  ret = getPositionAndStatus(i, &state, &dio, &position);
798  pthread_mutex_unlock(&m_mutex);
799  if (ret != 0)
800  {
802  std::cout << "State: Error com with Module: " << i << " Time: " << ros::Time::now() << std::endl;
803  return false;
804  }
805 
806  // if module is in error state --> reset
807  if (state & STATEID_MOD_ERROR)
808  {
809  pthread_mutex_lock(&m_mutex);
811  pthread_mutex_unlock(&m_mutex);
812  if (ret != 0)
813  {
815  std::cout << "State: Error com with Module: " << i << " Time: " << ros::Time::now() << std::endl;
816  return false;
817  }
818  }
819  }
820 
821  // time for reboot
822  usleep(500000);
823 
824  // check is everything is ok now
825  updateStates();
826 
828  {
829  if (!doHoming())
830  {
831  return false;
832  }
833  }
834 
835  usleep(500000);
836 
837  // modules should be recovered now
839 
840  updateStates();
841  // check if modules are really back to normal state
842  getStatus(status, errorMessages);
843 
844  if ((status != PC_CTRL_OK))
845  {
846  m_ErrorMessage.assign("");
847  for (int i = 0; i < m_params->GetDOF(); i++)
848  {
849  m_ErrorMessage.append(errorMessages[i]);
850  }
851  return false;
852  }
853 
856  return true;
857 }
858 
864 bool PowerCubeCtrl::setMaxVelocity(double maxVelocity)
865 {
866  std::vector<int> ModulIDs = m_params->GetModuleIDs();
867 
869  for (int i = 0; i < m_params->GetDOF(); i++)
870  {
871  pthread_mutex_lock(&m_mutex);
872  int ret = PCube_setMaxVel(m_DeviceHandle, m_params->GetModuleID(i), maxVelocity);
873  pthread_mutex_unlock(&m_mutex);
874  if (ret != 0)
875  {
876  std::ostringstream errorMsg;
877  errorMsg << "Could not set MaxVelocity in Module ID: " << ModulIDs[i] << ", m5api error code: " << ret;
878  m_ErrorMessage = errorMsg.str();
879  return false;
880  }
881 
882  std::vector<double> maxVelocities(maxVelocity);
883  m_params->SetMaxVel(maxVelocities);
884  }
885 
886  return true;
887 }
888 
892 bool PowerCubeCtrl::setMaxVelocity(const std::vector<double>& maxVelocities)
893 {
895 
896  std::vector<int> ModulIDs = m_params->GetModuleIDs();
897 
898  for (int i = 0; i < m_params->GetDOF(); i++)
899  {
900  pthread_mutex_lock(&m_mutex);
901  // std::cout << "------------------------------> PCube_setMaxVel()" << std::endl;
902  int ret = PCube_setMaxVel(m_DeviceHandle, m_params->GetModuleID(i), maxVelocities[i]);
903  pthread_mutex_unlock(&m_mutex);
904  if (ret != 0)
905  {
906  std::ostringstream errorMsg;
907  errorMsg << "Could not set MaxVelocity in Module ID: " << ModulIDs[i] << ", m5api error code: " << ret;
908  m_ErrorMessage = errorMsg.str();
909  return false;
910  }
911 
912  m_params->SetMaxVel(maxVelocities);
913  }
914 
915  return true;
916 }
917 
923 bool PowerCubeCtrl::setMaxAcceleration(double maxAcceleration)
924 {
926 
927  std::vector<int> ModulIDs = m_params->GetModuleIDs();
928 
929  for (int i = 0; i < m_params->GetDOF(); i++)
930  {
931  pthread_mutex_lock(&m_mutex);
932  // std::cout << "------------------------------> PCube_setMaxAcc()" << std::endl;
933  int ret = PCube_setMaxAcc(m_DeviceHandle, m_params->GetModuleID(i), maxAcceleration);
934  pthread_mutex_unlock(&m_mutex);
935  if (ret != 0)
936  {
937  std::ostringstream errorMsg;
938  errorMsg << "Could not set MaxAcceleration in Module ID: " << ModulIDs[i] << ", m5api error code: " << ret;
939  m_ErrorMessage = errorMsg.str();
940  return false;
941  }
942 
943  std::vector<double> maxAccelerations(maxAcceleration);
944  m_params->SetMaxAcc(maxAccelerations);
945  }
946 
947  return true;
948 }
949 
953 bool PowerCubeCtrl::setMaxAcceleration(const std::vector<double>& maxAccelerations)
954 {
956 
957  std::vector<int> ModulIDs = m_params->GetModuleIDs();
958 
959  for (int i = 0; i < m_params->GetDOF(); i++)
960  {
961  pthread_mutex_lock(&m_mutex);
962  int ret = PCube_setMaxAcc(m_DeviceHandle, m_params->GetModuleID(i), maxAccelerations[i]);
963  pthread_mutex_unlock(&m_mutex);
964  if (ret != 0)
965  {
966  std::ostringstream errorMsg;
967  errorMsg << "Could not set MaxAcceleration in Module ID: " << ModulIDs[i] << ", m5api error code: " << ret;
968  m_ErrorMessage = errorMsg.str();
969  return false;
970  }
971 
972  m_params->SetMaxAcc(maxAccelerations);
973  }
974 
975  return true;
976 }
977 
984 bool PowerCubeCtrl::setHorizon(double horizon)
985 {
986  m_horizon = horizon;
987 
988  return true;
989 }
990 
998 {
999  return m_horizon;
1000 }
1001 
1008 {
1009  std::vector<int> ModulIDs = m_params->GetModuleIDs();
1010 
1011  if (m_CANDeviceOpened)
1012  {
1013  for (int i = 0; i < m_params->GetDOF(); i++)
1014  {
1015  unsigned long confword;
1016 
1018  pthread_mutex_lock(&m_mutex);
1020  pthread_mutex_unlock(&m_mutex);
1021 
1023  pthread_mutex_lock(&m_mutex);
1025  pthread_mutex_unlock(&m_mutex);
1026  if (ret != 0)
1027  {
1028  std::ostringstream errorMsg;
1029  errorMsg << "Could not set SyncMotion in Module ID: " << ModulIDs[i] << ", m5api error code: " << ret;
1030  m_ErrorMessage = errorMsg.str();
1031  return false;
1032  }
1033  }
1034  return true;
1035  }
1036  else
1037  {
1038  return false;
1039  }
1040 }
1047 {
1048  if (m_CANDeviceOpened)
1049  {
1050  for (int i = 0; i < m_params->GetDOF(); i++)
1051  {
1052  unsigned long confword;
1053 
1055  pthread_mutex_lock(&m_mutex);
1057  pthread_mutex_unlock(&m_mutex);
1058 
1060  pthread_mutex_lock(&m_mutex);
1062  pthread_mutex_unlock(&m_mutex);
1063  }
1064  return true;
1065  }
1066 
1067  else
1068  {
1069  return false;
1070  }
1071 }
1076 {
1078 
1079  unsigned int DOF = m_params->GetDOF();
1080  unsigned long state;
1081  PC_CTRL_STATUS pc_status = PC_CTRL_ERR;
1082  std::vector<std::string> ErrorMessages;
1083  std::vector<double> Offsets = m_params->GetOffsets();
1084  std::ostringstream errorMsg;
1085 
1086  unsigned char dio;
1087  float position;
1088  int ret = 0;
1089 
1090  for (unsigned int i = 0; i < DOF; i++)
1091  {
1092  state = m_status[i];
1093  pthread_mutex_lock(&m_mutex);
1094  ret = getPositionAndStatus(i, &state, &dio, &position);
1095  pthread_mutex_unlock(&m_mutex);
1096 
1097  if (ret != 0)
1098  {
1099  // m_pc_status = PC_CTRL_ERR;
1100  ROS_DEBUG("Error on com in UpdateStates");
1101  return true;
1102  // errorMsg << "State: Error com with Module [" << i << "]";
1103  // ErrorMessages[i] = errorMsg.str();
1104  }
1105  else
1106  {
1107  ROS_DEBUG("Module %i, State: %li, Time: %f", i, state, ros::Time::now().toSec());
1108 
1109  m_status[i] = state;
1110  m_dios[i] = dio;
1111  m_positions[i] = position + Offsets[i];
1112  }
1113  }
1114 
1115  /*
1116  double delta_t = ros::Time::now().toSec() - m_last_time_pub.toSec();
1117  m_last_time_pub = ros::Time::now();
1118 
1119  updateVelocities(m_positions, delta_t);
1120  */
1121 
1122  // evaluate state for translation for diagnostics msgs
1123  getStatus(pc_status, ErrorMessages);
1124 
1125  for (unsigned int i = 0; i < ErrorMessages.size(); i++)
1126  {
1127  m_ErrorMessage.clear();
1128  m_ErrorMessage.assign("");
1129  m_ErrorMessage.append(ErrorMessages[i]);
1130  }
1131 
1132  return true;
1133 }
1134 
1138 bool PowerCubeCtrl::getStatus(PC_CTRL_STATUS& status, std::vector<std::string>& errorMessages)
1139 {
1140  unsigned int DOF = m_params->GetDOF();
1141  std::vector<int> ModuleIDs = m_params->GetModuleIDs();
1142 
1143  std::vector<PC_CTRL_STATUS> StatusArray;
1144  StatusArray.resize(DOF);
1145 
1146  errorMessages.clear();
1147  errorMessages.resize(DOF);
1148 
1149  status = PC_CTRL_OK;
1150 
1151  for (unsigned int i = 0; i < DOF; i++)
1152  {
1153  std::ostringstream errorMsg;
1154 
1156  {
1158  {
1159  errorMsg << "Error in Module " << ModuleIDs[i] << ": ";
1160  errorMsg << "Motor voltage below minimum value! Check Emergency Stop!";
1161  errorMessages[i] = errorMsg.str();
1162  }
1163  else if (m_status[i] & STATEID_MOD_POW_FET_TEMP)
1164  {
1165  errorMsg << "Error in Module " << ModuleIDs[i] << ": ";
1166  errorMsg << "Overheated power transitors! Power must be switched of to reset this error.";
1167  errorMessages[i] = errorMsg.str();
1168  }
1169  else if (m_status[i] & STATEID_MOD_POW_INTEGRALERR)
1170  {
1171  errorMsg << "Error in Module " << ModuleIDs[i] << ": ";
1172  errorMsg << "The drive has been overloaded and the servo loop has been disabled. Power must be switched off to reset this error.";
1173  errorMessages[i] = errorMsg.str();
1174  }
1175  StatusArray[i] = PC_CTRL_POW_VOLT_ERR;
1176  }
1177  else if (m_status[i] & STATEID_MOD_TOW_ERROR)
1178  {
1179  errorMsg << "Error in Module " << ModuleIDs[i] << ": ";
1180  errorMsg << "The servo loop was not able to follow the target position!";
1181  errorMessages[i] = errorMsg.str();
1182  StatusArray[i] = PC_CTRL_ERR;
1183  }
1184  else if (m_status[i] & STATEID_MOD_ERROR)
1185  {
1186  // STOP the motion for each module
1187  pthread_mutex_lock(&m_mutex);
1189  pthread_mutex_unlock(&m_mutex);
1190 
1191  errorMsg << "Error in Module " << ModuleIDs[i];
1192  errorMsg << " : Status code: " << std::hex << m_status[i];
1193  errorMessages[i] = errorMsg.str();
1194  StatusArray[i] = PC_CTRL_ERR;
1195  }
1196  else if (m_pc_status & PC_CTRL_ERR)
1197  {
1198  Stop(); // stop all motion
1199  errorMsg << "PowerCubeCtrl is in global error state";
1200  errorMessages[i] = errorMsg.str();
1201  StatusArray[i] = PC_CTRL_ERR;
1202  }
1203  else
1204  {
1205  errorMsg << "Module with Id " << ModuleIDs[i];
1206  errorMsg << ": Status OK.";
1207  errorMessages[i] = errorMsg.str();
1208  StatusArray[i] = PC_CTRL_OK;
1209  }
1210  }
1211 
1212  // search for worst status
1213  for (unsigned int i = 0; i < DOF; i++)
1214  {
1215  if ((int)StatusArray[i] <= (int)status)
1216  {
1217  status = StatusArray[i];
1218  }
1219  }
1220 
1221  m_pc_status = status;
1222 
1223  return true;
1224 }
1225 
1229 std::vector<unsigned long> PowerCubeCtrl::getVersion()
1230 {
1231  return m_version;
1232 }
1237 {
1239 
1240  for (int i = 0; i < m_params->GetDOF(); i++)
1241  {
1242  if (m_status[i] & STATEID_MOD_MOTION)
1243  return true;
1244  }
1245  return false;
1246 }
1247 
1251 std::vector<double> PowerCubeCtrl::getPositions()
1252 {
1253  return m_positions;
1254 }
1255 
1259 std::vector<double> PowerCubeCtrl::getVelocities()
1260 {
1262  return m_velocities;
1263 }
1264 
1268 std::vector<double> PowerCubeCtrl::getAccelerations()
1269 {
1271  return m_accelerations;
1272 }
1273 
1277 bool PowerCubeCtrl::getJointAngles(std::vector<double>& result)
1278 {
1280 
1281  std::vector<int> ModulIDs = m_params->GetModuleIDs();
1282 
1283  int ret = 0;
1284  float pos;
1285 
1286  for (int i = 0; i < m_params->GetDOF(); i++)
1287  {
1288  pthread_mutex_lock(&m_mutex);
1289  ret = PCube_getPos(m_DeviceHandle, ModulIDs[i], &pos);
1290  pthread_mutex_unlock(&m_mutex);
1291  if (ret != 0)
1292  {
1293  std::cout << "PCubeCtrl::getConfig(): getPos(" << ModulIDs[i] << ") return " << ret << std::endl;
1294  return false;
1295  }
1296  result[i] = pos;
1297  }
1298 
1299  return true;
1300 }
1301 
1305 bool PowerCubeCtrl::getJointVelocities(std::vector<double>& result)
1306 {
1308 
1309  std::vector<int> ModulIDs = m_params->GetModuleIDs();
1310 
1311  int ret = 0;
1312  float vel;
1313 
1314  for (int i = 0; i < m_params->GetDOF(); i++)
1315  {
1316  pthread_mutex_lock(&m_mutex);
1317  ret = PCube_getVel(m_DeviceHandle, ModulIDs[i], &vel);
1318  pthread_mutex_unlock(&m_mutex);
1319  if (ret != 0)
1320  {
1321  std::cout << "PCubeCtrl::getConfig(): getVel(" << ModulIDs[i] << ") return " << ret << std::endl;
1322  return false;
1323  }
1324  result[i] = vel;
1325  }
1326 
1327  return true;
1328 }
1329 
1336 {
1337  unsigned int DOF = m_params->GetDOF();
1338  std::vector<int> ModuleIDs = m_params->GetModuleIDs();
1339  std::vector<double> LowerLimits = m_params->GetLowerLimits();
1340  std::vector<double> UpperLimits = m_params->GetUpperLimits();
1341 
1343  std::vector<double> Offsets = m_params->GetOffsets();
1344 
1346  double max_homing_time = 15.0; // seconds
1347  double homing_time = 999.0; // set to 0 if any module is homed
1348  double intervall = 0.1;
1349 
1350  unsigned long state = PC_CTRL_ERR;
1351  unsigned char dio;
1352  float position;
1353  int ret = 0;
1354 
1356  for (unsigned int i = 0; i < DOF; i++)
1357  {
1358  pthread_mutex_lock(&m_mutex);
1359  ret = getPositionAndStatus(i, &state, &dio, &position);
1360  pthread_mutex_unlock(&m_mutex);
1361 
1362  // check and init m_position variable for trajectory controller
1363  if ((position > UpperLimits[i] + Offsets[i]) || (position < LowerLimits[i] + Offsets[i]))
1364  {
1365  std::ostringstream errorMsg;
1366  errorMsg << "Module " << ModuleIDs[i] << " has position " << position << " that is outside limits (" << UpperLimits[i] + Offsets[i] << " <-> " << LowerLimits[i] + Offsets[i] << std::endl;
1367  if ((m_ModuleTypes.at(i) == "PW") || (m_ModuleTypes.at(i) == "other"))
1368  {
1369  std::cout << "Position error for PW-Module. Init is aborted. Try to reboot the robot." << std::endl;
1370  m_ErrorMessage = errorMsg.str();
1372  return false;
1373  }
1374  else if (m_ModuleTypes.at(i) == "PRL")
1375  {
1376  ROS_INFO("Position of Module %i is outside limits. Module can only be moved in opposite direction.", i);
1377  ROS_INFO("Homing for Module: %i not necessary", m_params->GetModuleID(i));
1378  }
1379  else
1380  {
1381  ROS_INFO("Module type incorrect. (in func. PowerCubeCtrl::doHoming();)");
1382  return false;
1383  }
1384  }
1385  else
1386  {
1387  m_positions[i] = position + Offsets[i];
1388  }
1389 
1390  // check module type before homing (PRL-Modules need not to be homed by ROS)
1391  if ((m_ModuleTypes.at(i) == "PW") || (m_ModuleTypes.at(i) == "other"))
1392  {
1393  pthread_mutex_lock(&m_mutex);
1394  ret = getPositionAndStatus(i, &state, &dio, &position);
1395  pthread_mutex_unlock(&m_mutex);
1396 
1397  if (ret != 0)
1398  {
1399  ROS_INFO("Error on communication with Module: %i.", m_params->GetModuleID(i));
1401  return false;
1402  }
1403 
1404  // only do homing when necessary
1405  if (!(state & STATEID_MOD_HOME))
1406  {
1407  // homing timer
1408  homing_time = 0.0;
1409 
1410  pthread_mutex_lock(&m_mutex);
1411  ret = PCube_homeModule(m_DeviceHandle, ModuleIDs[i]);
1412  pthread_mutex_unlock(&m_mutex);
1413 
1414  ROS_INFO("Homing started at: %f", ros::Time::now().toSec());
1415 
1416  if (ret != 0)
1417  {
1418  ROS_INFO("Error while sending homing command to Module: %i. I try to reset the module.", i);
1419 
1420  // reset module with the hope that homing works afterwards
1421  pthread_mutex_lock(&m_mutex);
1422  ret = PCube_resetModule(m_DeviceHandle, ModuleIDs[i]);
1423  pthread_mutex_unlock(&m_mutex);
1424  if (ret != 0)
1425  {
1426  std::ostringstream errorMsg;
1427  errorMsg << "Can't reset module after homing error" << ModuleIDs[i] << ", m5api error code: " << ret;
1428  m_ErrorMessage = errorMsg.str();
1429  }
1430 
1431  // little break for reboot
1432  usleep(200000);
1433 
1434  pthread_mutex_lock(&m_mutex);
1435  ret = PCube_homeModule(m_DeviceHandle, ModuleIDs[i]);
1436  pthread_mutex_unlock(&m_mutex);
1437  if (ret != 0)
1438  {
1439  std::ostringstream errorMsg;
1440  errorMsg << "Can't start homing for module " << ModuleIDs[i] << ", tried reset with no success, m5api error code: " << ret;
1441  m_ErrorMessage = errorMsg.str();
1442  return false;
1443  }
1444  }
1445  }
1446  else
1447  {
1448  ROS_INFO("Homing for Module: %i not necessary", m_params->GetModuleID(i));
1449  }
1450  }
1451  else
1452  {
1453  ROS_INFO("Homing for PRL-Module %i not necessary", m_params->GetModuleID(i));
1454  }
1455  }
1456 
1457  for (unsigned int i = 0; i < DOF; i++)
1458  {
1459  unsigned long int help;
1460  do
1461  {
1462  pthread_mutex_lock(&m_mutex);
1463  PCube_getModuleState(m_DeviceHandle, ModuleIDs[i], &help);
1464  pthread_mutex_unlock(&m_mutex);
1465  ROS_DEBUG("Homing active for Module: %i State: %li", ModuleIDs.at(i), help);
1466 
1468  usleep(intervall * 1000000); // convert sec to usec
1469  homing_time += intervall;
1470  if (homing_time >= max_homing_time)
1471  {
1472  Stop();
1473  break;
1474  }
1475 
1476  } while ((help & STATEID_MOD_HOME) == 0);
1477 
1478  m_status[i] = help;
1479  ROS_DEBUG("State of Module %i : %li", ModuleIDs.at(i), help);
1480  }
1481 
1482  for (unsigned int i = 0; i < DOF; i++)
1483  {
1485  if (!(m_status[i] & STATEID_MOD_HOME) || (m_status[i] & STATEID_MOD_ERROR))
1486  {
1487  std::cout << "Homing failed: Error in Module " << ModuleIDs[i] << std::endl;
1489  return false;
1490  }
1491 
1492  ROS_INFO("Homing for Modul %i done.", ModuleIDs.at(i));
1493  }
1494 
1495  // modules successfully homed
1497  return true;
1498 }
1499 
1500 bool PowerCubeCtrl::getPositionAndStatus(int i, unsigned long* state, unsigned char* dio, float* position)
1501 {
1502  int ret = 0;
1503 
1504  if (m_version[i] > VERSION_ELECTR3_FIRST or
1506  {
1507  ret = PCube_getStateDioPos(m_DeviceHandle, m_params->GetModuleID(i), state, dio, position);
1508  }
1509  else
1510  {
1511  ret = PCube_getPos(m_DeviceHandle, m_params->GetModuleID(i), position);
1513  unsigned long puiValue;
1514  ret |= PCube_getDioData(m_DeviceHandle, m_params->GetModuleID(i), &puiValue);
1515  *dio = (unsigned char)puiValue;
1516  }
1517 
1518  return ret;
1519 }
1520 
1524 bool m_TranslateError2Diagnosics(std::ostringstream* errorMsg)
1525 {
1526  return true;
1527 }
bool setHorizon(double horizon)
Sets the horizon (sec).
std::vector< double > getPositions()
Gets the current positions.
std::vector< double > m_accelerations
bool getJointVelocities(std::vector< double > &result)
get the current joint velocities (Rad/s)
M5DLL_API int WINAPI PCube_getVel(int iDeviceId, int iModuleId, float *pfVel)
std::string GetCanModule()
Gets the CAN Module.
M5DLL_API int WINAPI PCube_getModuleSerialNo(int iDeviceId, int iModuleId, unsigned long *puiValue)
std::vector< unsigned char > m_dios
M5DLL_API int WINAPI PCube_resetModule(int iDeviceId, int iModuleId)
std::string m_ErrorMessage
std::vector< double > m_positions
std::vector< double > GetLowerLimits()
Gets the lower angular limits (rad) for the joints.
bool MoveVel(const std::vector< double > &velocities)
Moves all cubes by the given velocities.
M5DLL_API int WINAPI PCube_homeModule(int iDeviceId, int iModuleId)
bool m_CANDeviceOpened
M5DLL_API int WINAPI PCube_getModuleState(int iDeviceId, int iModuleId, unsigned long *puiState)
std::vector< unsigned long > m_status
#define STATEID_MOD_POW_INTEGRALERR
#define STATEID_MOD_POW_VOLT_ERR
bool getStatus(PC_CTRL_STATUS &status, std::vector< std::string > &errorMessages)
Gets the status of the modules.
#define STATEID_MOD_MOTION
PC_CTRL_STATUS m_pc_status
#define VERSION_ELECTR2_FIRST
Definition: PowerCubeCtrl.h:23
M5DLL_API int WINAPI PCube_getModuleVersion(int iDeviceId, int iModuleId, unsigned short *puiValue)
bool setSyncMotion()
Configure powercubes to start all movements synchronously.
~PowerCubeCtrl()
Destructor.
M5DLL_API int WINAPI PCube_getDefGearRatio(int iDeviceId, int iModuleId, float *pfValue)
pthread_mutex_t m_mutex
M5DLL_API int WINAPI PCube_getModuleCount(int iDeviceId)
#define VERSION_ELECTR2_LAST
Definition: PowerCubeCtrl.h:22
std::vector< unsigned long > m_version
virtual double T3()
Definition: moveCommand.h:163
bool Init(PowerCubeCtrlParams *params)
Initializing.
std::vector< double > GetMaxAcc()
Gets the max. angular accelerations (rad/s^2) for the joints.
bool getJointAngles(std::vector< double > &result)
get the current joint angles
bool setMaxAcceleration(double acceleration)
Sets the maximum angular velocity (rad/s) for the Joints, use with care!
bool Recover()
Recovery after emergency stop or power supply failure.
M5DLL_API int WINAPI PCube_closeDevice(int iDeviceId)
virtual double getTotalTime()
returns the planned total time for the movement (in seconds)
M5DLL_API int WINAPI PCube_moveVelExtended(int iDeviceId, int iModuleId, float fCur, unsigned long *puiState, unsigned char *pucDio, float *pfPos)
M5DLL_API int WINAPI PCube_setMaxVel(int iDeviceId, int iModuleId, float fValue)
#define CONFIGID_MOD_SYNC_MOTION
std::vector< double > getAccelerations()
Gets the current accelerations.
M5DLL_API int WINAPI PCube_haltModule(int iDeviceId, int iModuleId)
M5DLL_API int WINAPI PCube_getModuleType(int iDeviceId, int iModuleId, unsigned char *pucValue)
#define Ready4MoveStep
std::deque< std::vector< double > > m_cached_pos
std::vector< double > getVelocities()
Gets the current velcities.
#define PCTRL_CHECK_INITIALIZED()
M5DLL_API int WINAPI PCube_getStateDioPos(int iDeviceId, int iModuleId, unsigned long *puiState, unsigned char *pucDio, float *pfPos)
ros::Time m_last_time_pub
M5DLL_API int WINAPI PCube_moveStepExtended(int iDeviceId, int iModuleId, float fPos, unsigned short uiTime, unsigned long *puiState, unsigned char *pucDio, float *pfPos)
int GetModuleID(int no)
Gets the ModuleID.
M5DLL_API int WINAPI PCube_moveRamp(int iDeviceId, int iModuleId, float fPos, float fVel, float fAcc)
#define ROS_INFO(...)
M5DLL_API int WINAPI PCube_setConfig(int iDeviceId, int iModuleId, unsigned long puiValue)
M5DLL_API int WINAPI PCube_getDefSetup(int iDeviceId, int iModuleId, unsigned long *puiValue)
static void calculateAV(double x0, double v0, double xtarget, double time, double T3, double amax, double vmax, double &a, double &v)
Calculate the necessary a and v of a rampmove, so that the move will take the desired time...
ROSCPP_DECL bool ok()
std::string GetCanDevice()
Gets the CAN Device.
bool setMaxVelocity(double velocity)
Sets the maximum angular velocity (rad/s) for the Joints, use with care!
#define CONFIG_RESOLVER_FEEDBACK
#define VERSION_ELECTR3_FIRST
Definition: PowerCubeCtrl.h:21
M5DLL_API int WINAPI PCube_openDevice(int *piDeviceId, const char *acInitString)
int GetDOF()
Gets the DOF value.
M5DLL_API int WINAPI PCube_getDioData(int iDeviceId, int iModuleId, unsigned long *puiValue)
#define STATEID_MOD_TOW_ERROR
bool getPositionAndStatus(int module_id, unsigned long *state, unsigned char *dio, float *position)
#define TYPEID_MOD_ROTARY
int SetMaxAcc(std::vector< double > MaxAcc)
Sets the max. angular accelerations (rad/s^2) for the joints.
void updateVelocities(std::vector< double > pos_temp, double delta_t)
#define STATEID_MOD_POW_FET_TEMP
bool statusMoving()
Returns true if any of the Joints are still moving.
M5DLL_API int WINAPI PCube_setMaxAcc(int iDeviceId, int iModuleId, float fValue)
std::vector< double > m_velocities
virtual double T1()
Return the times of the different phases of the ramp move.
Definition: moveCommand.h:155
bool doHoming()
Waits until all Modules are homed.
bool updateStates()
Returns the state of all modules.
bool Close()
Close.
std::vector< std::string > m_ModuleTypes
M5DLL_API int WINAPI PCube_getPos(int iDeviceId, int iModuleId, float *pfPos)
int SetMaxVel(std::vector< double > MaxVel)
Sets the max. angular velocities (rad/s) for the joints.
PowerCubeCtrlParams * m_params
virtual double T2()
Definition: moveCommand.h:159
std::vector< double > GetOffsets()
Gets the offset angulars (rad) for the joints.
#define STATEID_MOD_HOME
int GetBaudrate()
Gets the Baudrate.
#define STATEID_MOD_ERROR
static Time now()
std::vector< double > GetMaxVel()
Gets the max. angular velocities (rad/s) for the joints.
#define STATEID_MOD_POWERFAULT
std::vector< double > GetUpperLimits()
Gets the upper angular limits (rad) for the joints.
bool Stop()
Stops the Manipulator immediately.
std::vector< unsigned long > getVersion()
Gets the firmware version of the modules.
M5DLL_API int WINAPI PCube_startMotionAll(int iDeviceId)
bool m_TranslateError2Diagnosics(std::ostringstream *errorMsg)
Setup errors for diagnostics.
bool setASyncMotion()
Configure powercubes to start all movements asynchronously.
int GetUseMoveVel()
Gets UseMoveVel.
PowerCubeCtrl(PowerCubeCtrlParams *params)
Constructor.
#define CONFIG_ABSOLUTE_FEEDBACK
M5DLL_API int WINAPI PCube_getConfig(int iDeviceId, int iModuleId, unsigned long *puiValue)
double getHorizon()
Gets the horizon (sec).
Parameters for cob_powercube_chain.
bool MoveJointSpaceSync(const std::vector< double > &angles)
Send position goals to powercubes, the final angles will be reached simultaneously.
std::string help()
std::vector< int > GetModuleIDs()
Gets the Module IDs.
#define ROS_DEBUG(...)


schunk_powercube_chain
Author(s): Florian Weisshardt
autogenerated on Mon Nov 25 2019 03:48:21