robotis_controller.cpp
Go to the documentation of this file.
1 /*******************************************************************************
2 * Copyright 2018 ROBOTIS CO., LTD.
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  * robotis_controller.cpp
19  *
20  * Created on: 2016. 1. 15.
21  * Author: zerom
22  */
23 
24 #include <ros/package.h>
25 #include <ros/callback_queue.h>
26 
28 
29 using namespace robotis_framework;
30 
32  : is_timer_running_(false),
33  stop_timer_(false),
34  init_pose_loaded_(false),
35  timer_thread_(0),
36  controller_mode_(MotionModuleMode),
37  DEBUG_PRINT(false),
38  robot_(0),
39  gazebo_mode_(false),
40  gazebo_robot_name_("robotis")
41 {
42  direct_sync_write_.clear();
43 }
44 
46 {
47  if (gazebo_mode_ == true)
48  return;
49 
50  //ROS_INFO("FIRST BULKREAD");
51  for (auto& it : port_to_bulk_read_)
52  it.second->txRxPacket();
53  for(auto& it : port_to_bulk_read_)
54  {
55  int error_count = 0;
56  int result = COMM_SUCCESS;
57  do
58  {
59  if (++error_count > 10)
60  {
61  ROS_ERROR("[RobotisController] first bulk read fail!!");
62  exit(-1);
63  }
64  usleep(10 * 1000);
65  result = it.second->txRxPacket();
66  } while (result != COMM_SUCCESS);
67  }
68  init_pose_loaded_ = true;
69  //ROS_INFO("FIRST BULKREAD END");
70 
71  // clear syncwrite param setting
72  for (auto& it : port_to_sync_write_position_)
73  {
74  if (it.second != NULL)
75  it.second->clearParam();
76  }
78  {
79  if (it.second != NULL)
80  it.second->clearParam();
81  }
83  {
84  if (it.second != NULL)
85  it.second->clearParam();
86  }
88  {
89  if (it.second != NULL)
90  it.second->clearParam();
91  }
92  for (auto& it : port_to_sync_write_velocity_)
93  {
94  if (it.second != NULL)
95  it.second->clearParam();
96  }
98  {
99  if (it.second != NULL)
100  it.second->clearParam();
101  }
102  for (auto& it : port_to_sync_write_velocity_i_gain_)
103  {
104  if (it.second != NULL)
105  it.second->clearParam();
106  }
107  for (auto& it : port_to_sync_write_velocity_d_gain_)
108  {
109  if (it.second != NULL)
110  it.second->clearParam();
111  }
112  for (auto& it : port_to_sync_write_current_)
113  {
114  if (it.second != NULL)
115  it.second->clearParam();
116  }
117 
118  // set init syncwrite param(from data of bulkread)
119  for (auto& it : robot_->dxls_)
120  {
121  std::string joint_name = it.first;
122  Dynamixel *dxl = it.second;
123 
124  for (int i = 0; i < dxl->bulk_read_items_.size(); i++)
125  {
126  uint32_t read_data = 0;
127  uint8_t sync_write_data[4];
128 
129  if (port_to_bulk_read_[dxl->port_name_]->isAvailable(dxl->id_,
130  dxl->bulk_read_items_[i]->address_,
131  dxl->bulk_read_items_[i]->data_length_) == true)
132  {
133  read_data = port_to_bulk_read_[dxl->port_name_]->getData(dxl->id_,
134  dxl->bulk_read_items_[i]->address_,
135  dxl->bulk_read_items_[i]->data_length_);
136 
137  sync_write_data[0] = DXL_LOBYTE(DXL_LOWORD(read_data));
138  sync_write_data[1] = DXL_HIBYTE(DXL_LOWORD(read_data));
139  sync_write_data[2] = DXL_LOBYTE(DXL_HIWORD(read_data));
140  sync_write_data[3] = DXL_HIBYTE(DXL_HIWORD(read_data));
141 
142  if ((dxl->present_position_item_ != 0) &&
143  (dxl->bulk_read_items_[i]->item_name_ == dxl->present_position_item_->item_name_))
144  {
145  dxl->dxl_state_->present_position_ = dxl->convertValue2Radian(read_data) - dxl->dxl_state_->position_offset_; // remove offset
147 
148  port_to_sync_write_position_[dxl->port_name_]->addParam(dxl->id_, sync_write_data);
149  }
150  else if ((dxl->position_p_gain_item_ != 0) &&
151  (dxl->bulk_read_items_[i]->item_name_ == dxl->position_p_gain_item_->item_name_))
152  {
153  dxl->dxl_state_->position_p_gain_ = read_data;
154  }
155  else if ((dxl->position_i_gain_item_ != 0) &&
156  (dxl->bulk_read_items_[i]->item_name_ == dxl->position_i_gain_item_->item_name_))
157  {
158  dxl->dxl_state_->position_i_gain_ = read_data;
159  }
160  else if ((dxl->position_d_gain_item_ != 0) &&
161  (dxl->bulk_read_items_[i]->item_name_ == dxl->position_d_gain_item_->item_name_))
162  {
163  dxl->dxl_state_->position_d_gain_ = read_data;
164  }
165  else if ((dxl->present_velocity_item_ != 0) &&
166  (dxl->bulk_read_items_[i]->item_name_ == dxl->present_velocity_item_->item_name_))
167  {
168  dxl->dxl_state_->present_velocity_ = dxl->convertValue2Velocity(read_data);
170  }
171  else if ((dxl->velocity_p_gain_item_ != 0) &&
172  (dxl->bulk_read_items_[i]->item_name_ == dxl->velocity_p_gain_item_->item_name_))
173  {
174  dxl->dxl_state_->velocity_p_gain_ = read_data;
175  }
176  else if ((dxl->velocity_i_gain_item_ != 0) &&
177  (dxl->bulk_read_items_[i]->item_name_ == dxl->velocity_i_gain_item_->item_name_))
178  {
179  dxl->dxl_state_->velocity_i_gain_ = read_data;
180  }
181  else if ((dxl->velocity_d_gain_item_ != 0) &&
182  (dxl->bulk_read_items_[i]->item_name_ == dxl->velocity_d_gain_item_->item_name_))
183  {
184  dxl->dxl_state_->velocity_d_gain_ = read_data;
185  }
186  else if ((dxl->present_current_item_ != 0) &&
187  (dxl->bulk_read_items_[i]->item_name_ == dxl->present_current_item_->item_name_))
188  {
189  dxl->dxl_state_->present_torque_ = dxl->convertValue2Torque(read_data);
191  }
192  }
193  }
194  }
195 }
196 
197 bool RobotisController::initialize(const std::string robot_file_path, const std::string init_file_path)
198 {
199  std::string dev_desc_dir_path = ros::package::getPath("robotis_device") + "/devices";
200 
201  // load robot info : port , device
202  robot_ = new Robot(robot_file_path, dev_desc_dir_path);
203 
204  if (gazebo_mode_ == true)
205  {
206  queue_thread_ = boost::thread(boost::bind(&RobotisController::msgQueueThread, this));
207  return true;
208  }
209 
210  for (auto& it : robot_->ports_)
211  {
212  std::string port_name = it.first;
213  dynamixel::PortHandler *port = it.second;
215 
216  if (port->setBaudRate(port->getBaudRate()) == false)
217  {
218  ROS_ERROR("PORT [%s] SETUP ERROR! (baudrate: %d)", port_name.c_str(), port->getBaudRate());
219  exit(-1);
220  }
221 
222  // get the default device info of the port
223  std::string default_device_name = robot_->port_default_device_[port_name];
224  auto dxl_it = robot_->dxls_.find(default_device_name);
225  auto sensor_it = robot_->sensors_.find(default_device_name);
226  if (dxl_it != robot_->dxls_.end())
227  {
228  Dynamixel *default_device = dxl_it->second;
229  default_pkt_handler = dynamixel::PacketHandler::getPacketHandler(default_device->protocol_version_);
230 
231  if (default_device->goal_position_item_ != 0)
232  {
234  = new dynamixel::GroupSyncWrite(port,
235  default_pkt_handler,
236  default_device->goal_position_item_->address_,
237  default_device->goal_position_item_->data_length_);
238  }
239 
240  if (default_device->position_p_gain_item_ != 0)
241  {
243  = new dynamixel::GroupSyncWrite(port,
244  default_pkt_handler,
245  default_device->position_p_gain_item_->address_,
246  default_device->position_p_gain_item_->data_length_);
247  }
248 
249  if (default_device->position_i_gain_item_ != 0)
250  {
252  = new dynamixel::GroupSyncWrite(port,
253  default_pkt_handler,
254  default_device->position_i_gain_item_->address_,
255  default_device->position_i_gain_item_->data_length_);
256  }
257 
258  if (default_device->position_d_gain_item_ != 0)
259  {
261  = new dynamixel::GroupSyncWrite(port,
262  default_pkt_handler,
263  default_device->position_d_gain_item_->address_,
264  default_device->position_d_gain_item_->data_length_);
265  }
266 
267  if (default_device->goal_velocity_item_ != 0)
268  {
270  = new dynamixel::GroupSyncWrite(port,
271  default_pkt_handler,
272  default_device->goal_velocity_item_->address_,
273  default_device->goal_velocity_item_->data_length_);
274  }
275 
276  if (default_device->velocity_p_gain_item_ != 0)
277  {
279  = new dynamixel::GroupSyncWrite(port,
280  default_pkt_handler,
281  default_device->velocity_p_gain_item_->address_,
282  default_device->velocity_p_gain_item_->data_length_);
283  }
284 
285  if (default_device->velocity_i_gain_item_ != 0)
286  {
288  = new dynamixel::GroupSyncWrite(port,
289  default_pkt_handler,
290  default_device->velocity_i_gain_item_->address_,
291  default_device->velocity_i_gain_item_->data_length_);
292  }
293 
294  if (default_device->velocity_d_gain_item_ != 0)
295  {
297  = new dynamixel::GroupSyncWrite(port,
298  default_pkt_handler,
299  default_device->velocity_d_gain_item_->address_,
300  default_device->velocity_d_gain_item_->data_length_);
301  }
302 
303  if (default_device->goal_current_item_ != 0)
304  {
305  port_to_sync_write_current_[port_name]
306  = new dynamixel::GroupSyncWrite(port,
307  default_pkt_handler,
308  default_device->goal_current_item_->address_,
309  default_device->goal_current_item_->data_length_);
310  }
311  }
312  else if (sensor_it != robot_->sensors_.end())
313  {
314  Sensor *_default_device = sensor_it->second;
315  default_pkt_handler = dynamixel::PacketHandler::getPacketHandler(_default_device->protocol_version_);
316  }
317 
318  port_to_bulk_read_[port_name] = new dynamixel::GroupBulkRead(port, default_pkt_handler);
319  }
320 
321  // (for loop) check all dxls are connected.
322  for (auto& it : robot_->dxls_)
323  {
324  std::string joint_name = it.first;
325  Dynamixel *dxl = it.second;
326 
327  if (ping(joint_name) != 0)
328  {
329  usleep(10 * 1000);
330  if (ping(joint_name) != 0)
331  ROS_ERROR("JOINT[%s] does NOT respond!!", joint_name.c_str());
332  }
333  }
334 
335  initializeDevice(init_file_path);
336 
337  queue_thread_ = boost::thread(boost::bind(&RobotisController::msgQueueThread, this));
338  return true;
339 }
340 
341 void RobotisController::initializeDevice(const std::string init_file_path)
342 {
343  // device initialize
344  if (DEBUG_PRINT)
345  ROS_WARN("INIT FILE LOAD");
346 
347  YAML::Node doc;
348  try
349  {
350  doc = YAML::LoadFile(init_file_path.c_str());
351 
352  for (YAML::const_iterator it_doc = doc.begin(); it_doc != doc.end(); it_doc++)
353  {
354  std::string joint_name = it_doc->first.as<std::string>();
355 
356  YAML::Node joint_node = doc[joint_name];
357  if (joint_node.size() == 0)
358  continue;
359 
360  Dynamixel *dxl = NULL;
361  auto dxl_it = robot_->dxls_.find(joint_name);
362  if (dxl_it != robot_->dxls_.end())
363  dxl = dxl_it->second;
364 
365  if (dxl == NULL)
366  {
367  ROS_WARN("Joint [%s] was not found.", joint_name.c_str());
368  continue;
369  }
370  if (DEBUG_PRINT)
371  ROS_INFO("JOINT_NAME: %s", joint_name.c_str());
372 
373  for (YAML::const_iterator it_joint = joint_node.begin(); it_joint != joint_node.end(); it_joint++)
374  {
375  std::string item_name = it_joint->first.as<std::string>();
376 
377  if (DEBUG_PRINT)
378  ROS_INFO(" ITEM_NAME: %s", item_name.c_str());
379 
380  uint32_t value = it_joint->second.as<uint32_t>();
381 
382  ControlTableItem *item = dxl->ctrl_table_[item_name];
383  if (item == NULL)
384  {
385  ROS_WARN("Control Item [%s] was not found.", item_name.c_str());
386  continue;
387  }
388 
389  if (item->memory_type_ == EEPROM)
390  {
391  uint8_t data8 = 0;
392  uint16_t data16 = 0;
393  uint32_t data32 = 0;
394 
395  switch (item->data_length_)
396  {
397  case 1:
398  read1Byte(joint_name, item->address_, &data8);
399  if (data8 == value)
400  continue;
401  break;
402  case 2:
403  read2Byte(joint_name, item->address_, &data16);
404  if (data16 == value)
405  continue;
406  break;
407  case 4:
408  read4Byte(joint_name, item->address_, &data32);
409  if (data32 == value)
410  continue;
411  break;
412  default:
413  break;
414  }
415  }
416 
417  switch (item->data_length_)
418  {
419  case 1:
420  write1Byte(joint_name, item->address_, (uint8_t) value);
421  break;
422  case 2:
423  write2Byte(joint_name, item->address_, (uint16_t) value);
424  break;
425  case 4:
426  write4Byte(joint_name, item->address_, value);
427  break;
428  default:
429  break;
430  }
431 
432  if (item->memory_type_ == EEPROM)
433  {
434  // Write to EEPROM -> delay is required (max delay: 55 msec per byte)
435  usleep(item->data_length_ * 55 * 1000);
436  }
437  }
438  }
439  } catch (const std::exception& e)
440  {
441  ROS_INFO("Dynamixel Init file not found.");
442  }
443 
444  // [ BulkRead ] StartAddress : Present Position , Length : 10 ( Position/Velocity/Current )
445  for (auto& it : robot_->ports_)
446  {
447  if (port_to_bulk_read_[it.first] != 0)
448  port_to_bulk_read_[it.first]->clearParam();
449  }
450  for (auto& it : robot_->dxls_)
451  {
452  std::string joint_name = it.first;
453  Dynamixel *dxl = it.second;
454 
455  if (dxl == NULL)
456  continue;
457 
458  int bulkread_start_addr = 0;
459  int bulkread_data_length = 0;
460 
461 // // bulk read default : present position
462 // if(dxl->present_position_item != 0)
463 // {
464 // bulkread_start_addr = dxl->present_position_item->address;
465 // bulkread_data_length = dxl->present_position_item->data_length;
466 // }
467 
468  // calculate bulk read start address & data length
469  auto indirect_addr_it = dxl->ctrl_table_.find(INDIRECT_ADDRESS_1);
470  if (indirect_addr_it != dxl->ctrl_table_.end()) // INDIRECT_ADDRESS_1 exist
471  {
472  if (dxl->bulk_read_items_.size() != 0)
473  {
474  uint16_t data16 = 0;
475 
476  bulkread_start_addr = dxl->bulk_read_items_[0]->address_;
477  bulkread_data_length = 0;
478 
479  // set indirect address
480  int indirect_addr = indirect_addr_it->second->address_;
481  for (int i = 0; i < dxl->bulk_read_items_.size(); i++)
482  {
483  int addr_leng = dxl->bulk_read_items_[i]->data_length_;
484 
485  bulkread_data_length += addr_leng;
486  for (int l = 0; l < addr_leng; l++)
487  {
488  // ROS_WARN("[%12s] INDIR_ADDR: %d, ITEM_ADDR: %d", joint_name.c_str(), indirect_addr, dxl->ctrl_table[dxl->bulk_read_items[i]->item_name]->address + _l);
489 
490  read2Byte(joint_name, indirect_addr, &data16);
491  if (data16 != dxl->ctrl_table_[dxl->bulk_read_items_[i]->item_name_]->address_ + l)
492  {
493  write2Byte(joint_name, indirect_addr, dxl->ctrl_table_[dxl->bulk_read_items_[i]->item_name_]->address_ + l);
494  }
495  indirect_addr += 2;
496  }
497  }
498  }
499  }
500  else // INDIRECT_ADDRESS_1 NOT exist
501  {
502  if (dxl->bulk_read_items_.size() != 0)
503  {
504  bulkread_start_addr = dxl->bulk_read_items_[0]->address_;
505  bulkread_data_length = 0;
506 
507  ControlTableItem *last_item = dxl->bulk_read_items_[0];
508 
509  for (int i = 0; i < dxl->bulk_read_items_.size(); i++)
510  {
511  int addr = dxl->bulk_read_items_[i]->address_;
512  if (addr < bulkread_start_addr)
513  bulkread_start_addr = addr;
514  else if (last_item->address_ < addr)
515  last_item = dxl->bulk_read_items_[i];
516  }
517 
518  bulkread_data_length = last_item->address_ - bulkread_start_addr + last_item->data_length_;
519  }
520  }
521 
522 // ROS_WARN("[%12s] start_addr: %d, data_length: %d", joint_name.c_str(), bulkread_start_addr, bulkread_data_length);
523  if (bulkread_start_addr != 0)
524  port_to_bulk_read_[dxl->port_name_]->addParam(dxl->id_, bulkread_start_addr, bulkread_data_length);
525 
526  // Torque ON
527  if (writeCtrlItem(joint_name, dxl->torque_enable_item_->item_name_, 1) != COMM_SUCCESS)
528  writeCtrlItem(joint_name, dxl->torque_enable_item_->item_name_, 1);
529  }
530 
531  for (auto& it : robot_->sensors_)
532  {
533  std::string sensor_name = it.first;
534  Sensor *sensor = it.second;
535 
536  if (sensor == NULL)
537  continue;
538 
539  int bulkread_start_addr = 0;
540  int bulkread_data_length = 0;
541 
542  // calculate bulk read start address & data length
543  auto indirect_addr_it = sensor->ctrl_table_.find(INDIRECT_ADDRESS_1);
544  if (indirect_addr_it != sensor->ctrl_table_.end()) // INDIRECT_ADDRESS_1 exist
545  {
546  if (sensor->bulk_read_items_.size() != 0)
547  {
548  uint16_t data16 = 0;
549 
550  bulkread_start_addr = sensor->bulk_read_items_[0]->address_;
551  bulkread_data_length = 0;
552 
553  // set indirect address
554  int indirect_addr = indirect_addr_it->second->address_;
555  for (int i = 0; i < sensor->bulk_read_items_.size(); i++)
556  {
557  int addr_leng = sensor->bulk_read_items_[i]->data_length_;
558 
559  bulkread_data_length += addr_leng;
560  for (int l = 0; l < addr_leng; l++)
561  {
562 // ROS_WARN("[%12s] INDIR_ADDR: %d, ITEM_ADDR: %d", sensor_name.c_str(), indirect_addr, sensor->ctrl_table[sensor->bulk_read_items[i]->item_name]->address + _l);
563  read2Byte(sensor_name, indirect_addr, &data16);
564  if (data16 != sensor->ctrl_table_[sensor->bulk_read_items_[i]->item_name_]->address_ + l)
565  {
566  write2Byte(sensor_name,
567  indirect_addr,
568  sensor->ctrl_table_[sensor->bulk_read_items_[i]->item_name_]->address_ + l);
569  }
570  indirect_addr += 2;
571  }
572  }
573  }
574  }
575  else // INDIRECT_ADDRESS_1 NOT exist
576  {
577  if (sensor->bulk_read_items_.size() != 0)
578  {
579  bulkread_start_addr = sensor->bulk_read_items_[0]->address_;
580  bulkread_data_length = 0;
581 
582  ControlTableItem *last_item = sensor->bulk_read_items_[0];
583 
584  for (int i = 0; i < sensor->bulk_read_items_.size(); i++)
585  {
586  int addr = sensor->bulk_read_items_[i]->address_;
587  if (addr < bulkread_start_addr)
588  bulkread_start_addr = addr;
589  else if (last_item->address_ < addr)
590  last_item = sensor->bulk_read_items_[i];
591  }
592 
593  bulkread_data_length = last_item->address_ - bulkread_start_addr + last_item->data_length_;
594  }
595  }
596 
597  //ROS_WARN("[%12s] start_addr: %d, data_length: %d", sensor_name.c_str(), bulkread_start_addr, bulkread_data_length);
598  if (bulkread_start_addr != 0)
599  port_to_bulk_read_[sensor->port_name_]->addParam(sensor->id_, bulkread_start_addr, bulkread_data_length);
600  }
601 }
602 
604 {
605  ros::Rate gazebo_rate(1000 / robot_->getControlCycle());
606 
607  while (!stop_timer_)
608  {
609  if (init_pose_loaded_ == true)
610  process();
611  gazebo_rate.sleep();
612  }
613 }
614 
616 {
617  ros::NodeHandle ros_node;
618  ros::CallbackQueue callback_queue;
619 
620  ros_node.setCallbackQueue(&callback_queue);
621 
622  /* subscriber */
623  ros::Subscriber write_control_table_sub = ros_node.subscribe("/robotis/write_control_table", 5,
625  ros::Subscriber sync_write_item_sub = ros_node.subscribe("/robotis/sync_write_item", 10,
627  ros::Subscriber joint_ctrl_modules_sub = ros_node.subscribe("/robotis/set_joint_ctrl_modules", 10,
629  ros::Subscriber enable_ctrl_module_sub = ros_node.subscribe("/robotis/enable_ctrl_module", 10,
631  ros::Subscriber control_mode_sub = ros_node.subscribe("/robotis/set_control_mode", 10,
633  ros::Subscriber joint_states_sub = ros_node.subscribe("/robotis/set_joint_states", 10,
635 
636  ros::Subscriber gazebo_joint_states_sub;
637  if (gazebo_mode_ == true)
638  gazebo_joint_states_sub = ros_node.subscribe("/" + gazebo_robot_name_ + "/joint_states", 10,
640 
641  /* publisher */
642  goal_joint_state_pub_ = ros_node.advertise<sensor_msgs::JointState>("/robotis/goal_joint_states", 10);
643  present_joint_state_pub_ = ros_node.advertise<sensor_msgs::JointState>("/robotis/present_joint_states", 10);
644  current_module_pub_ = ros_node.advertise<robotis_controller_msgs::JointCtrlModule>(
645  "/robotis/present_joint_ctrl_modules", 10);
646 
647  if (gazebo_mode_ == true)
648  {
649  for (auto& it : robot_->dxls_)
650  {
651  gazebo_joint_position_pub_[it.first] = ros_node.advertise<std_msgs::Float64>(
652  "/" + gazebo_robot_name_ + "/" + it.first + "_position/command", 1);
653  gazebo_joint_velocity_pub_[it.first] = ros_node.advertise<std_msgs::Float64>(
654  "/" + gazebo_robot_name_ + "/" + it.first + "_velocity/command", 1);
655  gazebo_joint_effort_pub_[it.first] = ros_node.advertise<std_msgs::Float64>(
656  "/" + gazebo_robot_name_ + "/" + it.first + "_effort/command", 1);
657  }
658  }
659 
660  /* service */
661  ros::ServiceServer get_joint_module_server = ros_node.advertiseService("/robotis/get_present_joint_ctrl_modules",
663  ros::ServiceServer set_joint_module_server = ros_node.advertiseService("/robotis/set_present_joint_ctrl_modules",
665  ros::ServiceServer set_module_server = ros_node.advertiseService("/robotis/set_present_ctrl_modules",
667 
668  ros::WallDuration duration(robot_->getControlCycle() / 1000.0);
669  while(ros_node.ok())
670  callback_queue.callAvailable(duration);
671 }
672 
674 {
675  RobotisController *controller = (RobotisController *) param;
676  static struct timespec next_time;
677  static struct timespec curr_time;
678 
679  ROS_DEBUG("controller::thread_proc started");
680 
681  clock_gettime(CLOCK_MONOTONIC, &next_time);
682 
683  while (!controller->stop_timer_)
684  {
685  next_time.tv_sec += (next_time.tv_nsec + controller->robot_->getControlCycle() * 1000000) / 1000000000;
686  next_time.tv_nsec = (next_time.tv_nsec + controller->robot_->getControlCycle() * 1000000) % 1000000000;
687 
688  controller->process();
689 
690  clock_gettime(CLOCK_MONOTONIC, &curr_time);
691  long delta_nsec = (next_time.tv_sec - curr_time.tv_sec) * 1000000000 + (next_time.tv_nsec - curr_time.tv_nsec);
692  if (delta_nsec < -100000)
693  {
694  if (controller->DEBUG_PRINT == true)
695  {
696  fprintf(stderr, "[RobotisController::ThreadProc] NEXT TIME < CURR TIME.. (%f)[%ld.%09ld / %ld.%09ld]",
697  delta_nsec / 1000000.0, (long )next_time.tv_sec, (long )next_time.tv_nsec,
698  (long )curr_time.tv_sec, (long )curr_time.tv_nsec);
699  }
700 
701  // next_time = curr_time + 3 msec
702  next_time.tv_sec = curr_time.tv_sec + (curr_time.tv_nsec + 3000000) / 1000000000;
703  next_time.tv_nsec = (curr_time.tv_nsec + 3000000) % 1000000000;
704  }
705 
706  clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &next_time, NULL);
707  }
708  return 0;
709 }
710 
712 {
713  if (this->is_timer_running_ == true)
714  return;
715 
716  if (this->gazebo_mode_ == true)
717  {
718  // create and start the thread
719  gazebo_thread_ = boost::thread(boost::bind(&RobotisController::gazeboTimerThread, this));
720  }
721  else
722  {
724 
725  for (auto& it : port_to_bulk_read_)
726  {
727  it.second->txPacket();
728  }
729 
730  usleep(8 * 1000);
731 
732  int error;
733  struct sched_param param;
734  pthread_attr_t attr;
735 
736  pthread_attr_init(&attr);
737 
738  error = pthread_attr_setschedpolicy(&attr, SCHED_RR);
739  if (error != 0)
740  ROS_ERROR("pthread_attr_setschedpolicy error = %d\n", error);
741  error = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
742  if (error != 0)
743  ROS_ERROR("pthread_attr_setinheritsched error = %d\n", error);
744 
745  memset(&param, 0, sizeof(param));
746  param.sched_priority = 31; // RT
747  error = pthread_attr_setschedparam(&attr, &param);
748  if (error != 0)
749  ROS_ERROR("pthread_attr_setschedparam error = %d\n", error);
750 
751  // create and start the thread
752  if ((error = pthread_create(&this->timer_thread_, &attr, this->timerThread, this)) != 0)
753  {
754  ROS_ERROR("Creating timer thread failed!!");
755  exit(-1);
756  }
757  }
758 
759  this->is_timer_running_ = true;
760 }
761 
763 {
764  int error = 0;
765 
766  // set the flag to stop the thread
767  if (this->is_timer_running_)
768  {
769  this->stop_timer_ = true;
770 
771  if (this->gazebo_mode_ == false)
772  {
773  // wait until the thread is stopped.
774  if ((error = pthread_join(this->timer_thread_, NULL)) != 0)
775  exit(-1);
776 
777  for (auto& it : port_to_bulk_read_)
778  {
779  if (it.second != NULL)
780  it.second->rxPacket();
781  }
782 
783  for (auto& it : port_to_sync_write_position_)
784  {
785  if (it.second != NULL)
786  it.second->clearParam();
787  }
788  for (auto& it : port_to_sync_write_position_p_gain_)
789  {
790  if (it.second != NULL)
791  it.second->clearParam();
792  }
793  for (auto& it : port_to_sync_write_position_i_gain_)
794  {
795  if (it.second != NULL)
796  it.second->clearParam();
797  }
798  for (auto& it : port_to_sync_write_position_d_gain_)
799  {
800  if (it.second != NULL)
801  it.second->clearParam();
802  }
803  for (auto& it : port_to_sync_write_velocity_)
804  {
805  if (it.second != NULL)
806  it.second->clearParam();
807  }
808  for (auto& it : port_to_sync_write_velocity_p_gain_)
809  {
810  if (it.second != NULL)
811  it.second->clearParam();
812  }
813  for (auto& it : port_to_sync_write_velocity_i_gain_)
814  {
815  if (it.second != NULL)
816  it.second->clearParam();
817  }
818  for (auto& it : port_to_sync_write_velocity_d_gain_)
819  {
820  if (it.second != NULL)
821  it.second->clearParam();
822  }
823  for (auto& it : port_to_sync_write_current_)
824  {
825  if (it.second != NULL)
826  it.second->clearParam();
827  }
828  }
829  else
830  {
831  // wait until the thread is stopped.
832  gazebo_thread_.join();
833  }
834 
835  this->stop_timer_ = false;
836  this->is_timer_running_ = false;
837  }
838 }
839 
841 {
842  return this->is_timer_running_;
843 }
844 
845 void RobotisController::loadOffset(const std::string path)
846 {
847  YAML::Node doc;
848  try
849  {
850  doc = YAML::LoadFile(path.c_str());
851  } catch (const std::exception& e)
852  {
853  ROS_ERROR("Fail to load offset yaml.");
854  return;
855  }
856 
857  YAML::Node offset_node = doc["offset"];
858  if (offset_node.size() == 0)
859  return;
860 
861  ROS_INFO("Load offsets...");
862  for (YAML::const_iterator it = offset_node.begin(); it != offset_node.end(); it++)
863  {
864  std::string joint_name = it->first.as<std::string>();
865  double offset = it->second.as<double>();
866 
867  auto dxl_it = robot_->dxls_.find(joint_name);
868  if (dxl_it != robot_->dxls_.end())
869  dxl_it->second->dxl_state_->position_offset_ = offset;
870  }
871 }
872 
874 {
875  // avoid duplicated function call
876  static bool is_process_running = false;
877  if (is_process_running == true)
878  return;
879  is_process_running = true;
880 
881  // ROS_INFO("Controller::Process()");
882 
883  ros::Time start_time;
884  ros::Duration time_duration;
885 
886  if (DEBUG_PRINT)
887  start_time = ros::Time::now();
888 
889  sensor_msgs::JointState goal_state;
890  sensor_msgs::JointState present_state;
891 
892  present_state.header.stamp = ros::Time::now();
893  goal_state.header.stamp = present_state.header.stamp;
894 
896  {
897  if (gazebo_mode_ == false)
898  {
899  // BulkRead Rx
900  for (auto& it : port_to_bulk_read_)
901  {
902  robot_->ports_[it.first]->setPacketTimeout(0.0);
903  it.second->rxPacket();
904  }
905 
906  // -> save to robot->dxls_[]->dxl_state_
907  if (robot_->dxls_.size() > 0)
908  {
909  for (auto& dxl_it : robot_->dxls_)
910  {
911  Dynamixel *dxl = dxl_it.second;
912  std::string port_name = dxl_it.second->port_name_;
913  std::string joint_name = dxl_it.first;
914 
915  if (dxl->bulk_read_items_.size() > 0)
916  {
917  bool updated = false;
918  uint32_t data = 0;
919  for (int i = 0; i < dxl->bulk_read_items_.size(); i++)
920  {
921  ControlTableItem *item = dxl->bulk_read_items_[i];
922  if (port_to_bulk_read_[port_name]->isAvailable(dxl->id_, item->address_, item->data_length_) == true)
923  {
924  updated = true;
925  data = port_to_bulk_read_[port_name]->getData(dxl->id_, item->address_, item->data_length_);
926 
927  // change dxl_state
928  if (dxl->present_position_item_ != 0 && item->item_name_ == dxl->present_position_item_->item_name_)
929  dxl->dxl_state_->present_position_ = dxl->convertValue2Radian(data) - dxl->dxl_state_->position_offset_; // remove offset
930  else if (dxl->present_velocity_item_ != 0 && item->item_name_ == dxl->present_velocity_item_->item_name_)
932  else if (dxl->present_current_item_ != 0 && item->item_name_ == dxl->present_current_item_->item_name_)
934  else if (dxl->goal_position_item_ != 0 && item->item_name_ == dxl->goal_position_item_->item_name_)
935  dxl->dxl_state_->goal_position_ = dxl->convertValue2Radian(data) - dxl->dxl_state_->position_offset_; // remove offset
936  else if (dxl->goal_velocity_item_ != 0 && item->item_name_ == dxl->goal_velocity_item_->item_name_)
938  else if (dxl->goal_current_item_ != 0 && item->item_name_ == dxl->goal_current_item_->item_name_)
939  dxl->dxl_state_->goal_torque_ = dxl->convertValue2Torque(data);
940 
941  dxl->dxl_state_->bulk_read_table_[item->item_name_] = data;
942  }
943  }
944 
945  // -> update time stamp to Robot->dxls[]->dynamixel_state.update_time_stamp
946  if (updated == true)
947  dxl->dxl_state_->update_time_stamp_ = TimeStamp(present_state.header.stamp.sec, present_state.header.stamp.nsec);
948  }
949  }
950  }
951 
952  // -> save to robot->sensors_[]->sensor_state_
953  if (robot_->sensors_.size() > 0)
954  {
955  for (auto& sensor_it : robot_->sensors_)
956  {
957  Sensor *sensor = sensor_it.second;
958  std::string port_name = sensor_it.second->port_name_;
959  std::string sensor_name = sensor_it.first;
960 
961  if (sensor->bulk_read_items_.size() > 0)
962  {
963  bool updated = false;
964  uint32_t data = 0;
965  for (int i = 0; i < sensor->bulk_read_items_.size(); i++)
966  {
967  ControlTableItem *item = sensor->bulk_read_items_[i];
968  if (port_to_bulk_read_[port_name]->isAvailable(sensor->id_, item->address_, item->data_length_) == true)
969  {
970  updated = true;
971  data = port_to_bulk_read_[port_name]->getData(sensor->id_, item->address_, item->data_length_);
972 
973  // change sensor_state
974  sensor->sensor_state_->bulk_read_table_[item->item_name_] = data;
975  }
976  }
977 
978  // -> update time stamp to Robot->dxls[]->dynamixel_state.update_time_stamp
979  if (updated == true)
980  sensor->sensor_state_->update_time_stamp_ = TimeStamp(present_state.header.stamp.sec, present_state.header.stamp.nsec);
981  }
982  }
983  }
984 
985  if (DEBUG_PRINT)
986  {
987  time_duration = ros::Time::now() - start_time;
988  fprintf(stderr, "(%2.6f) BulkRead Rx & update state \n", time_duration.nsec * 0.000001);
989  }
990 
991  // SyncWrite
992  queue_mutex_.lock();
993 
994  if (direct_sync_write_.size() > 0)
995  {
996  for (int i = 0; i < direct_sync_write_.size(); i++)
997  {
998  direct_sync_write_[i]->txPacket();
999  direct_sync_write_[i]->clearParam();
1000  }
1001  direct_sync_write_.clear();
1002  }
1003 
1004  if (port_to_sync_write_position_p_gain_.size() > 0)
1005  {
1006  for (auto& it : port_to_sync_write_position_p_gain_)
1007  {
1008  it.second->txPacket();
1009  it.second->clearParam();
1010  }
1011  }
1012  if (port_to_sync_write_position_i_gain_.size() > 0)
1013  {
1014  for (auto& it : port_to_sync_write_position_i_gain_)
1015  {
1016  it.second->txPacket();
1017  it.second->clearParam();
1018  }
1019  }
1020  if (port_to_sync_write_position_d_gain_.size() > 0)
1021  {
1022  for (auto& it : port_to_sync_write_position_d_gain_)
1023  {
1024  it.second->txPacket();
1025  it.second->clearParam();
1026  }
1027  }
1028  if (port_to_sync_write_velocity_p_gain_.size() > 0)
1029  {
1030  for (auto& it : port_to_sync_write_velocity_p_gain_)
1031  {
1032  it.second->txPacket();
1033  it.second->clearParam();
1034  }
1035  }
1036  if (port_to_sync_write_velocity_i_gain_.size() > 0)
1037  {
1038  for (auto& it : port_to_sync_write_velocity_i_gain_)
1039  {
1040  it.second->txPacket();
1041  it.second->clearParam();
1042  }
1043  }
1044  if (port_to_sync_write_velocity_d_gain_.size() > 0)
1045  {
1046  for (auto& it : port_to_sync_write_velocity_d_gain_)
1047  {
1048  it.second->txPacket();
1049  it.second->clearParam();
1050  }
1051  }
1052  for (auto& it : port_to_sync_write_position_)
1053  {
1054  if (it.second != NULL)
1055  it.second->txPacket();
1056  }
1057  for (auto& it : port_to_sync_write_velocity_)
1058  {
1059  if (it.second != NULL)
1060  it.second->txPacket();
1061  }
1062  for (auto& it : port_to_sync_write_current_)
1063  {
1064  if (it.second != NULL)
1065  it.second->txPacket();
1066  }
1067 
1068  queue_mutex_.unlock();
1069 
1070  // BulkRead Tx
1071  for (auto& it : port_to_bulk_read_)
1072  it.second->txPacket();
1073 
1074  if (DEBUG_PRINT)
1075  {
1076  time_duration = ros::Time::now() - start_time;
1077  fprintf(stderr, "(%2.6f) SyncWrite & BulkRead Tx \n", time_duration.nsec * 0.000001);
1078  }
1079  }
1080  else if (gazebo_mode_ == true)
1081  {
1082  for (auto module_it = motion_modules_.begin(); module_it != motion_modules_.end(); module_it++)
1083  {
1084  if ((*module_it)->getModuleEnable() == false)
1085  continue;
1086 
1087  std_msgs::Float64 joint_msg;
1088 
1089  for (auto& dxl_it : robot_->dxls_)
1090  {
1091  std::string joint_name = dxl_it.first;
1092  Dynamixel *dxl = dxl_it.second;
1093  DynamixelState *dxl_state = dxl_it.second->dxl_state_;
1094 
1095  if (dxl->ctrl_module_name_ == (*module_it)->getModuleName())
1096  {
1097  if ((*module_it)->getControlMode() == PositionControl)
1098  {
1099  joint_msg.data = dxl_state->goal_position_;
1100  gazebo_joint_position_pub_[joint_name].publish(joint_msg);
1101  }
1102  else if ((*module_it)->getControlMode() == VelocityControl)
1103  {
1104  joint_msg.data = dxl_state->goal_velocity_;
1105  gazebo_joint_velocity_pub_[joint_name].publish(joint_msg);
1106  }
1107  else if ((*module_it)->getControlMode() == TorqueControl)
1108  {
1109  joint_msg.data = dxl_state->goal_torque_;
1110  gazebo_joint_effort_pub_[joint_name].publish(joint_msg);
1111  }
1112  }
1113  }
1114  }
1115  }
1116  }
1117  else if (controller_mode_ == DirectControlMode)
1118  {
1119  if(gazebo_mode_ == false)
1120  {
1121  // BulkRead Rx
1122  for (auto& it : port_to_bulk_read_)
1123  {
1124  robot_->ports_[it.first]->setPacketTimeout(0.0);
1125  it.second->rxPacket();
1126  }
1127 
1128  // -> save to robot->dxls_[]->dxl_state_
1129  if (robot_->dxls_.size() > 0)
1130  {
1131  for (auto& dxl_it : robot_->dxls_)
1132  {
1133  Dynamixel *dxl = dxl_it.second;
1134  std::string port_name = dxl_it.second->port_name_;
1135  std::string joint_name = dxl_it.first;
1136 
1137  if (dxl->bulk_read_items_.size() > 0)
1138  {
1139  uint32_t data = 0;
1140  for (int i = 0; i < dxl->bulk_read_items_.size(); i++)
1141  {
1142  ControlTableItem *item = dxl->bulk_read_items_[i];
1143  if (port_to_bulk_read_[port_name]->isAvailable(dxl->id_, item->address_, item->data_length_) == true)
1144  {
1145  data = port_to_bulk_read_[port_name]->getData(dxl->id_, item->address_, item->data_length_);
1146 
1147  // change dxl_state
1148  if (dxl->present_position_item_ != 0 && item->item_name_ == dxl->present_position_item_->item_name_)
1149  dxl->dxl_state_->present_position_ = dxl->convertValue2Radian(data) - dxl->dxl_state_->position_offset_; // remove offset
1150  else if (dxl->present_velocity_item_ != 0 && item->item_name_ == dxl->present_velocity_item_->item_name_)
1152  else if (dxl->present_current_item_ != 0 && item->item_name_ == dxl->present_current_item_->item_name_)
1153  dxl->dxl_state_->present_torque_ = dxl->convertValue2Torque(data);
1154  else if (dxl->goal_position_item_ != 0 && item->item_name_ == dxl->goal_position_item_->item_name_)
1155  dxl->dxl_state_->goal_position_ = dxl->convertValue2Radian(data) - dxl->dxl_state_->position_offset_; // remove offset
1156  else if (dxl->goal_velocity_item_ != 0 && item->item_name_ == dxl->goal_velocity_item_->item_name_)
1157  dxl->dxl_state_->goal_velocity_ = dxl->convertValue2Velocity(data);
1158  else if (dxl->goal_current_item_ != 0 && item->item_name_ == dxl->goal_current_item_->item_name_)
1159  dxl->dxl_state_->goal_torque_ = dxl->convertValue2Torque(data);
1160 
1161  dxl->dxl_state_->bulk_read_table_[item->item_name_] = data;
1162  }
1163  }
1164 
1165  // -> update time stamp to Robot->dxls[]->dynamixel_state.update_time_stamp
1166  dxl->dxl_state_->update_time_stamp_ = TimeStamp(present_state.header.stamp.sec, present_state.header.stamp.nsec);
1167  }
1168  }
1169  }
1170 
1171  queue_mutex_.lock();
1172 
1173 // for (auto& it : port_to_sync_write_position_)
1174 // {
1175 // it.second->txPacket();
1176 // it.second->clearParam();
1177 // }
1178 
1179  if (direct_sync_write_.size() > 0)
1180  {
1181  for (int i = 0; i < direct_sync_write_.size(); i++)
1182  {
1183  direct_sync_write_[i]->txPacket();
1184  direct_sync_write_[i]->clearParam();
1185  }
1186  direct_sync_write_.clear();
1187  }
1188 
1189  queue_mutex_.unlock();
1190 
1191  // BulkRead Tx
1192  for (auto& it : port_to_bulk_read_)
1193  it.second->txPacket();
1194  }
1195  }
1196 
1197  // Call SensorModule Process()
1198  // -> for loop : call SensorModule list -> Process()
1199  if (sensor_modules_.size() > 0)
1200  {
1201  for (auto module_it = sensor_modules_.begin(); module_it != sensor_modules_.end(); module_it++)
1202  {
1203  (*module_it)->process(robot_->dxls_, robot_->sensors_);
1204 
1205  for (auto& it : (*module_it)->result_)
1206  sensor_result_[it.first] = it.second;
1207  }
1208  }
1209 
1210  if (DEBUG_PRINT)
1211  {
1212  time_duration = ros::Time::now() - start_time;
1213  fprintf(stderr, "(%2.6f) SensorModule Process() & save result \n", time_duration.nsec * 0.000001);
1214  }
1215 
1217  {
1218  // Call MotionModule Process()
1219  // -> for loop : call MotionModule list -> Process()
1220  if (motion_modules_.size() > 0)
1221  {
1222  queue_mutex_.lock();
1223 
1224  for (auto module_it = motion_modules_.begin(); module_it != motion_modules_.end(); module_it++)
1225  {
1226  if ((*module_it)->getModuleEnable() == false)
1227  continue;
1228 
1229  (*module_it)->process(robot_->dxls_, sensor_result_);
1230 
1231  // for loop : joint list
1232  for (auto& dxl_it : robot_->dxls_)
1233  {
1234  std::string joint_name = dxl_it.first;
1235  Dynamixel *dxl = dxl_it.second;
1236  DynamixelState *dxl_state = dxl_it.second->dxl_state_;
1237 
1238  if (dxl->ctrl_module_name_ == (*module_it)->getModuleName())
1239  {
1240  //do_sync_write = true;
1241  DynamixelState *result_state = (*module_it)->result_[joint_name];
1242 
1243  if (result_state == NULL)
1244  {
1245  ROS_ERROR("[%s] %s ", (*module_it)->getModuleName().c_str(), joint_name.c_str());
1246  continue;
1247  }
1248 
1249  // TODO: check update time stamp ?
1250 
1251  if ((*module_it)->getControlMode() == PositionControl)
1252  {
1253  dxl_state->goal_position_ = result_state->goal_position_;
1254 
1255  if (gazebo_mode_ == false)
1256  {
1257  // add offset
1258  uint32_t pos_data = dxl->convertRadian2Value(dxl_state->goal_position_ + dxl_state->position_offset_);
1259  uint8_t sync_write_data[4] = { 0 };
1260  sync_write_data[0] = DXL_LOBYTE(DXL_LOWORD(pos_data));
1261  sync_write_data[1] = DXL_HIBYTE(DXL_LOWORD(pos_data));
1262  sync_write_data[2] = DXL_LOBYTE(DXL_HIWORD(pos_data));
1263  sync_write_data[3] = DXL_HIBYTE(DXL_HIWORD(pos_data));
1264 
1265  if (port_to_sync_write_position_[dxl->port_name_] != NULL)
1266  port_to_sync_write_position_[dxl->port_name_]->changeParam(dxl->id_, sync_write_data);
1267 
1268  // if position p gain value is changed -> sync write
1269  if (dxl_state->position_p_gain_ != result_state->position_p_gain_)
1270  {
1271  dxl_state->position_p_gain_ = result_state->position_p_gain_;
1272  uint8_t sync_write_data[4] = { 0 };
1273  sync_write_data[0] = DXL_LOBYTE(DXL_LOWORD(dxl_state->position_p_gain_));
1274  sync_write_data[1] = DXL_HIBYTE(DXL_LOWORD(dxl_state->position_p_gain_));
1275  sync_write_data[2] = DXL_LOBYTE(DXL_HIWORD(dxl_state->position_p_gain_));
1276  sync_write_data[3] = DXL_HIBYTE(DXL_HIWORD(dxl_state->position_p_gain_));
1277 
1279  port_to_sync_write_position_p_gain_[dxl->port_name_]->addParam(dxl->id_, sync_write_data);
1280  }
1281 
1282  // if position i gain value is changed -> sync write
1283  if (dxl_state->position_i_gain_ != result_state->position_i_gain_)
1284  {
1285  dxl_state->position_i_gain_ = result_state->position_i_gain_;
1286  uint8_t sync_write_data[4] = { 0 };
1287  sync_write_data[0] = DXL_LOBYTE(DXL_LOWORD(dxl_state->position_i_gain_));
1288  sync_write_data[1] = DXL_HIBYTE(DXL_LOWORD(dxl_state->position_i_gain_));
1289  sync_write_data[2] = DXL_LOBYTE(DXL_HIWORD(dxl_state->position_i_gain_));
1290  sync_write_data[3] = DXL_HIBYTE(DXL_HIWORD(dxl_state->position_i_gain_));
1291 
1293  port_to_sync_write_position_i_gain_[dxl->port_name_]->addParam(dxl->id_, sync_write_data);
1294  }
1295 
1296  // if position d gain value is changed -> sync write
1297  if (dxl_state->position_d_gain_ != result_state->position_d_gain_)
1298  {
1299  dxl_state->position_d_gain_ = result_state->position_d_gain_;
1300  uint8_t sync_write_data[4] = { 0 };
1301  sync_write_data[0] = DXL_LOBYTE(DXL_LOWORD(dxl_state->position_d_gain_));
1302  sync_write_data[1] = DXL_HIBYTE(DXL_LOWORD(dxl_state->position_d_gain_));
1303  sync_write_data[2] = DXL_LOBYTE(DXL_HIWORD(dxl_state->position_d_gain_));
1304  sync_write_data[3] = DXL_HIBYTE(DXL_HIWORD(dxl_state->position_d_gain_));
1305 
1307  port_to_sync_write_position_d_gain_[dxl->port_name_]->addParam(dxl->id_, sync_write_data);
1308  }
1309  }
1310  }
1311  else if ((*module_it)->getControlMode() == VelocityControl)
1312  {
1313  dxl_state->goal_velocity_ = result_state->goal_velocity_;
1314 
1315  if (gazebo_mode_ == false)
1316  {
1317  uint32_t vel_data = dxl->convertVelocity2Value(dxl_state->goal_velocity_);
1318  uint8_t sync_write_data[4] = { 0 };
1319  sync_write_data[0] = DXL_LOBYTE(DXL_LOWORD(vel_data));
1320  sync_write_data[1] = DXL_HIBYTE(DXL_LOWORD(vel_data));
1321  sync_write_data[2] = DXL_LOBYTE(DXL_HIWORD(vel_data));
1322  sync_write_data[3] = DXL_HIBYTE(DXL_HIWORD(vel_data));
1323 
1324  if (port_to_sync_write_velocity_[dxl->port_name_] != NULL)
1325  port_to_sync_write_velocity_[dxl->port_name_]->changeParam(dxl->id_, sync_write_data);
1326 
1327  // if velocity p gain gain value is changed -> sync write
1328  if (dxl_state->velocity_p_gain_ != result_state->velocity_p_gain_)
1329  {
1330  dxl_state->velocity_p_gain_ = result_state->velocity_p_gain_;
1331  uint8_t sync_write_data[4] = { 0 };
1332  sync_write_data[0] = DXL_LOBYTE(DXL_LOWORD(dxl_state->velocity_p_gain_));
1333  sync_write_data[1] = DXL_HIBYTE(DXL_LOWORD(dxl_state->velocity_p_gain_));
1334  sync_write_data[2] = DXL_LOBYTE(DXL_HIWORD(dxl_state->velocity_p_gain_));
1335  sync_write_data[3] = DXL_HIBYTE(DXL_HIWORD(dxl_state->velocity_p_gain_));
1336 
1338  port_to_sync_write_velocity_p_gain_[dxl->port_name_]->addParam(dxl->id_, sync_write_data);
1339  }
1340 
1341  // if velocity i gain value is changed -> sync write
1342  if (dxl_state->velocity_i_gain_ != result_state->velocity_i_gain_)
1343  {
1344  dxl_state->velocity_i_gain_ = result_state->velocity_i_gain_;
1345  uint8_t sync_write_data[4] = { 0 };
1346  sync_write_data[0] = DXL_LOBYTE(DXL_LOWORD(dxl_state->velocity_i_gain_));
1347  sync_write_data[1] = DXL_HIBYTE(DXL_LOWORD(dxl_state->velocity_i_gain_));
1348  sync_write_data[2] = DXL_LOBYTE(DXL_HIWORD(dxl_state->velocity_i_gain_));
1349  sync_write_data[3] = DXL_HIBYTE(DXL_HIWORD(dxl_state->velocity_i_gain_));
1350 
1352  port_to_sync_write_velocity_i_gain_[dxl->port_name_]->addParam(dxl->id_, sync_write_data);
1353  }
1354 
1355  // if velocity d gain value is changed -> sync write
1356  if (dxl_state->velocity_d_gain_ != result_state->velocity_d_gain_)
1357  {
1358  dxl_state->velocity_d_gain_ = result_state->velocity_d_gain_;
1359  uint8_t sync_write_data[4] = { 0 };
1360  sync_write_data[0] = DXL_LOBYTE(DXL_LOWORD(dxl_state->velocity_d_gain_));
1361  sync_write_data[1] = DXL_HIBYTE(DXL_LOWORD(dxl_state->velocity_d_gain_));
1362  sync_write_data[2] = DXL_LOBYTE(DXL_HIWORD(dxl_state->velocity_d_gain_));
1363  sync_write_data[3] = DXL_HIBYTE(DXL_HIWORD(dxl_state->velocity_d_gain_));
1364 
1366  port_to_sync_write_velocity_d_gain_[dxl->port_name_]->addParam(dxl->id_, sync_write_data);
1367  }
1368  }
1369  }
1370  else if ((*module_it)->getControlMode() == TorqueControl)
1371  {
1372  dxl_state->goal_torque_ = result_state->goal_torque_;
1373 
1374  if (gazebo_mode_ == false)
1375  {
1376  uint32_t curr_data = dxl->convertTorque2Value(dxl_state->goal_torque_);
1377  uint8_t sync_write_data[2] = { 0 };
1378  sync_write_data[0] = DXL_LOBYTE(curr_data);
1379  sync_write_data[1] = DXL_HIBYTE(curr_data);
1380 
1381  if (port_to_sync_write_current_[dxl->port_name_] != NULL)
1382  port_to_sync_write_current_[dxl->port_name_]->changeParam(dxl->id_, sync_write_data);
1383  }
1384  }
1385  }
1386  }
1387  }
1388 
1389  queue_mutex_.unlock();
1390  }
1391 
1392  if (DEBUG_PRINT)
1393  {
1394  time_duration = ros::Time::now() - start_time;
1395  fprintf(stderr, "(%2.6f) MotionModule Process() & save result \n", time_duration.nsec * 0.000001);
1396  }
1397  }
1398 
1399  // publish present & goal position
1400  for (auto& dxl_it : robot_->dxls_)
1401  {
1402  std::string joint_name = dxl_it.first;
1403  Dynamixel *dxl = dxl_it.second;
1404 
1405  present_state.name.push_back(joint_name);
1406  present_state.position.push_back(dxl->dxl_state_->present_position_);
1407  present_state.velocity.push_back(dxl->dxl_state_->present_velocity_);
1408  present_state.effort.push_back(dxl->dxl_state_->present_torque_);
1409 
1410  goal_state.name.push_back(joint_name);
1411  goal_state.position.push_back(dxl->dxl_state_->goal_position_);
1412  goal_state.velocity.push_back(dxl->dxl_state_->goal_velocity_);
1413  goal_state.effort.push_back(dxl->dxl_state_->goal_torque_);
1414  }
1415 
1416  // -> publish present joint_states & goal joint states topic
1417  present_joint_state_pub_.publish(present_state);
1418  goal_joint_state_pub_.publish(goal_state);
1419 
1420  if (DEBUG_PRINT)
1421  {
1422  time_duration = ros::Time::now() - start_time;
1423  fprintf(stderr, "(%2.6f) Process() DONE \n", time_duration.nsec * 0.000001);
1424  }
1425 
1426  is_process_running = false;
1427 }
1428 
1430 {
1431  // check whether the module name already exists
1432  for (auto m_it = motion_modules_.begin(); m_it != motion_modules_.end(); m_it++)
1433  {
1434  if ((*m_it)->getModuleName() == module->getModuleName())
1435  {
1436  ROS_ERROR("Motion Module Name [%s] already exist !!", module->getModuleName().c_str());
1437  return;
1438  }
1439  }
1440 
1441  module->initialize(robot_->getControlCycle(), robot_);
1442  motion_modules_.push_back(module);
1443  motion_modules_.unique();
1444 }
1445 
1447 {
1448  motion_modules_.remove(module);
1449 }
1450 
1452 {
1453  // check whether the module name already exists
1454  for (auto m_it = sensor_modules_.begin(); m_it != sensor_modules_.end(); m_it++)
1455  {
1456  if ((*m_it)->getModuleName() == module->getModuleName())
1457  {
1458  ROS_ERROR("Sensor Module Name [%s] already exist !!", module->getModuleName().c_str());
1459  return;
1460  }
1461  }
1462 
1463  module->initialize(robot_->getControlCycle(), robot_);
1464  sensor_modules_.push_back(module);
1465  sensor_modules_.unique();
1466 }
1467 
1469 {
1470  sensor_modules_.remove(module);
1471 }
1472 
1473 void RobotisController::writeControlTableCallback(const robotis_controller_msgs::WriteControlTable::ConstPtr &msg)
1474 {
1475  Device *device = NULL;
1476 
1477  if (DEBUG_PRINT)
1478  fprintf(stderr, "[WriteControlTable] led control msg received\n");
1479 
1480  auto dev_it1 = robot_->dxls_.find(msg->joint_name);
1481  if(dev_it1 != robot_->dxls_.end())
1482  {
1483  device = dev_it1->second;
1484  }
1485  else
1486  {
1487  auto dev_it2 = robot_->sensors_.find(msg->joint_name);
1488  if(dev_it2 != robot_->sensors_.end())
1489  {
1490  device = dev_it2->second;
1491  }
1492  else
1493  {
1494  ROS_WARN("[WriteControlTable] Unknown device : %s", msg->joint_name.c_str());
1495  return;
1496  }
1497  }
1498 
1499  ControlTableItem *item = NULL;
1500  auto item_it = device->ctrl_table_.find(msg->start_item_name);
1501  if(item_it != device->ctrl_table_.end())
1502  {
1503  item = item_it->second;
1504  }
1505  else
1506  {
1507  ROS_WARN("[WriteControlTable] Unknown item : %s", msg->start_item_name.c_str());
1508  return;
1509  }
1510 
1511  dynamixel::PortHandler *port = robot_->ports_[device->port_name_];
1513 
1514  if (item->access_type_ == Read)
1515  return;
1516 
1517  queue_mutex_.lock();
1518 
1519  direct_sync_write_.push_back(new dynamixel::GroupSyncWrite(port, packet_handler, item->address_, msg->data_length));
1520  direct_sync_write_[direct_sync_write_.size() - 1]->addParam(device->id_, (uint8_t *)(msg->data.data()));
1521 
1522 // fprintf(stderr, "[WriteControlTable] %s -> %s : ", msg->joint_name.c_str(), msg->start_item_name.c_str());
1523 // for (auto &dt : msg->data)
1524 // fprintf(stderr, "%02X ", dt);
1525 // fprintf(stderr, "\n");
1526 
1527  queue_mutex_.unlock();
1528 
1529 }
1530 
1531 void RobotisController::syncWriteItemCallback(const robotis_controller_msgs::SyncWriteItem::ConstPtr &msg)
1532 {
1533  for (int i = 0; i < msg->joint_name.size(); i++)
1534  {
1535  Device *device;
1536 
1537  auto d_it1 = robot_->dxls_.find(msg->joint_name[i]);
1538  if (d_it1 != robot_->dxls_.end())
1539  {
1540  device = d_it1->second;
1541  }
1542  else
1543  {
1544  auto d_it2 = robot_->sensors_.find(msg->joint_name[i]);
1545  if (d_it2 != robot_->sensors_.end())
1546  {
1547  device = d_it2->second;
1548  }
1549  else
1550  {
1551  ROS_WARN("[SyncWriteItem] Unknown device : %s", msg->joint_name[i].c_str());
1552  continue;
1553  }
1554  }
1555 
1556 // ControlTableItem *item = device->ctrl_table_[msg->item_name];
1557  ControlTableItem *item = NULL;
1558  auto item_it = device->ctrl_table_.find(msg->item_name);
1559  if(item_it != device->ctrl_table_.end())
1560  {
1561  item = item_it->second;
1562  }
1563  else
1564  {
1565  ROS_WARN("SyncWriteItem] Unknown item : %s", msg->item_name.c_str());
1566  continue;
1567  }
1568 
1569  dynamixel::PortHandler *port = robot_->ports_[device->port_name_];
1571 
1572  if (item->access_type_ == Read)
1573  continue;
1574 
1575  queue_mutex_.lock();
1576 
1577  int idx = 0;
1578  if (direct_sync_write_.size() == 0)
1579  {
1580  direct_sync_write_.push_back(new dynamixel::GroupSyncWrite(port, packet_handler, item->address_, item->data_length_));
1581  idx = 0;
1582  }
1583  else
1584  {
1585  for (idx = 0; idx < direct_sync_write_.size(); idx++)
1586  {
1587  if (direct_sync_write_[idx]->getPortHandler() == port && direct_sync_write_[idx]->getPacketHandler() == packet_handler)
1588  break;
1589  }
1590 
1591  if (idx == direct_sync_write_.size())
1592  direct_sync_write_.push_back(new dynamixel::GroupSyncWrite(port, packet_handler, item->address_, item->data_length_));
1593  }
1594 
1595  uint8_t *data = new uint8_t[item->data_length_];
1596  if (item->data_length_ == 1)
1597  data[0] = (uint8_t) msg->value[i];
1598  else if (item->data_length_ == 2)
1599  {
1600  data[0] = DXL_LOBYTE((uint16_t )msg->value[i]);
1601  data[1] = DXL_HIBYTE((uint16_t )msg->value[i]);
1602  }
1603  else if (item->data_length_ == 4)
1604  {
1605  data[0] = DXL_LOBYTE(DXL_LOWORD((uint32_t)msg->value[i]));
1606  data[1] = DXL_HIBYTE(DXL_LOWORD((uint32_t)msg->value[i]));
1607  data[2] = DXL_LOBYTE(DXL_HIWORD((uint32_t)msg->value[i]));
1608  data[3] = DXL_HIBYTE(DXL_HIWORD((uint32_t)msg->value[i]));
1609  }
1610  direct_sync_write_[idx]->addParam(device->id_, data);
1611  delete[] data;
1612 
1613  queue_mutex_.unlock();
1614  }
1615 }
1616 
1617 void RobotisController::setControllerModeCallback(const std_msgs::String::ConstPtr &msg)
1618 {
1619  if (msg->data == "DirectControlMode")
1620  {
1621  for (auto& it : port_to_bulk_read_)
1622  {
1623  robot_->ports_[it.first]->setPacketTimeout(0.0);
1624  it.second->rxPacket();
1625  }
1627  }
1628  else if (msg->data == "MotionModuleMode")
1629  {
1630  for (auto& it : port_to_bulk_read_)
1631  {
1632  it.second->txPacket();
1633  }
1635  }
1636 }
1637 
1638 void RobotisController::setJointStatesCallback(const sensor_msgs::JointState::ConstPtr &msg)
1639 {
1641  return;
1642 
1643  queue_mutex_.lock();
1644 
1645  for (int i = 0; i < msg->name.size(); i++)
1646  {
1647  int32_t pos = 0;
1648 
1649  Dynamixel *dxl = robot_->dxls_[msg->name[i]];
1650  if (dxl == NULL)
1651  continue;
1652 
1653  dxl->dxl_state_->goal_position_ = msg->position[i];
1654  pos = dxl->convertRadian2Value((double) msg->position[i]);
1655 
1656  uint8_t sync_write_data[4];
1657  sync_write_data[0] = DXL_LOBYTE(DXL_LOWORD(pos));
1658  sync_write_data[1] = DXL_HIBYTE(DXL_LOWORD(pos));
1659  sync_write_data[2] = DXL_LOBYTE(DXL_HIWORD(pos));
1660  sync_write_data[3] = DXL_HIBYTE(DXL_HIWORD(pos));
1661 
1662  if (port_to_sync_write_position_[dxl->port_name_] != NULL)
1663  port_to_sync_write_position_[dxl->port_name_]->addParam(dxl->id_, sync_write_data);
1664  }
1665 
1666  queue_mutex_.unlock();
1667 }
1668 
1669 void RobotisController::setCtrlModuleCallback(const std_msgs::String::ConstPtr &msg)
1670 {
1671  if(set_module_thread_.joinable())
1672  set_module_thread_.join();
1673 
1674  std::string _module_name_to_set = msg->data;
1675 
1676  set_module_thread_ = boost::thread(boost::bind(&RobotisController::setCtrlModuleThread, this, _module_name_to_set));
1677 }
1678 
1679 void RobotisController::setCtrlModule(std::string module_name)
1680 {
1681  if(set_module_thread_.joinable())
1682  set_module_thread_.join();
1683 
1684  set_module_thread_ = boost::thread(boost::bind(&RobotisController::setCtrlModuleThread, this, module_name));
1685 }
1686 void RobotisController::setJointCtrlModuleCallback(const robotis_controller_msgs::JointCtrlModule::ConstPtr &msg)
1687 {
1688  if (msg->joint_name.size() != msg->module_name.size())
1689  return;
1690 
1691  if(set_module_thread_.joinable())
1692  set_module_thread_.join();
1693 
1694  set_module_thread_ = boost::thread(boost::bind(&RobotisController::setJointCtrlModuleThread, this, msg));
1695 }
1696 
1697 bool RobotisController::getJointCtrlModuleService(robotis_controller_msgs::GetJointModule::Request &req,
1698  robotis_controller_msgs::GetJointModule::Response &res)
1699 {
1700  for (unsigned int idx = 0; idx < req.joint_name.size(); idx++)
1701  {
1702  auto d_it = robot_->dxls_.find((std::string) (req.joint_name[idx]));
1703  if (d_it != robot_->dxls_.end())
1704  {
1705  res.joint_name.push_back(req.joint_name[idx]);
1706  res.module_name.push_back(d_it->second->ctrl_module_name_);
1707  }
1708  }
1709 
1710  if (res.joint_name.size() == 0)
1711  return false;
1712 
1713  return true;
1714 }
1715 
1716 bool RobotisController::setJointCtrlModuleService(robotis_controller_msgs::SetJointModule::Request &req, robotis_controller_msgs::SetJointModule::Response &res)
1717 {
1718  if(set_module_thread_.joinable())
1719  set_module_thread_.join();
1720 
1721  robotis_controller_msgs::JointCtrlModule modules;
1722  modules.joint_name = req.joint_name;
1723  modules.module_name = req.module_name;
1724 
1725  robotis_controller_msgs::JointCtrlModule::ConstPtr msg_ptr(new robotis_controller_msgs::JointCtrlModule(modules));
1726 
1727  if (modules.joint_name.size() != modules.module_name.size())
1728  return false;
1729 
1730  set_module_thread_ = boost::thread(boost::bind(&RobotisController::setJointCtrlModuleThread, this, msg_ptr));
1731 
1732  set_module_thread_.join();
1733 
1734  return true;
1735 }
1736 
1737 bool RobotisController::setCtrlModuleService(robotis_controller_msgs::SetModule::Request &req, robotis_controller_msgs::SetModule::Response &res)
1738 {
1739  if(set_module_thread_.joinable())
1740  set_module_thread_.join();
1741 
1742  std::string _module_name_to_set = req.module_name;
1743 
1744  set_module_thread_ = boost::thread(boost::bind(&RobotisController::setCtrlModuleThread, this, _module_name_to_set));
1745 
1746  set_module_thread_.join();
1747 
1748  return true;
1749 }
1750 
1751 void RobotisController::setJointCtrlModuleThread(const robotis_controller_msgs::JointCtrlModule::ConstPtr &msg)
1752 {
1753  // stop module list
1754  std::list<MotionModule *> _stop_modules;
1755  std::list<MotionModule *> _enable_modules;
1756 
1757  for(unsigned int idx = 0; idx < msg->joint_name.size(); idx++)
1758  {
1759  Dynamixel *_dxl = NULL;
1760  std::map<std::string, Dynamixel*>::iterator _dxl_it = robot_->dxls_.find((std::string)(msg->joint_name[idx]));
1761  if(_dxl_it != robot_->dxls_.end())
1762  _dxl = _dxl_it->second;
1763  else
1764  continue;
1765 
1766  // enqueue
1767  if(_dxl->ctrl_module_name_ != msg->module_name[idx])
1768  {
1769  for(std::list<MotionModule *>::iterator _stop_m_it = motion_modules_.begin(); _stop_m_it != motion_modules_.end(); _stop_m_it++)
1770  {
1771  if((*_stop_m_it)->getModuleName() == _dxl->ctrl_module_name_ && (*_stop_m_it)->getModuleEnable() == true)
1772  _stop_modules.push_back(*_stop_m_it);
1773  }
1774  }
1775  }
1776 
1777  // stop the module
1778  _stop_modules.unique();
1779  for(std::list<MotionModule *>::iterator _stop_m_it = _stop_modules.begin(); _stop_m_it != _stop_modules.end(); _stop_m_it++)
1780  {
1781  (*_stop_m_it)->stop();
1782  }
1783 
1784  // wait to stop
1785  for(std::list<MotionModule *>::iterator _stop_m_it = _stop_modules.begin(); _stop_m_it != _stop_modules.end(); _stop_m_it++)
1786  {
1787  while((*_stop_m_it)->isRunning())
1788  usleep(robot_->getControlCycle() * 1000);
1789  }
1790 
1791  // disable module(s)
1792  for(std::list<MotionModule *>::iterator _stop_m_it = _stop_modules.begin(); _stop_m_it != _stop_modules.end(); _stop_m_it++)
1793  {
1794  (*_stop_m_it)->setModuleEnable(false);
1795  }
1796 
1797  // set ctrl module
1798  queue_mutex_.lock();
1799 
1800  for(unsigned int idx = 0; idx < msg->joint_name.size(); idx++)
1801  {
1802  std::string ctrl_module = msg->module_name[idx];
1803  std::string joint_name = msg->joint_name[idx];
1804 
1805  Dynamixel *_dxl = NULL;
1806  std::map<std::string, Dynamixel*>::iterator _dxl_it = robot_->dxls_.find(joint_name);
1807  if(_dxl_it != robot_->dxls_.end())
1808  _dxl = _dxl_it->second;
1809  else
1810  continue;
1811 
1812  // none
1813  if(ctrl_module == "" || ctrl_module == "none")
1814  {
1815  _dxl->ctrl_module_name_ = "none";
1816 
1817  if(gazebo_mode_ == true)
1818  continue;
1819 
1820  uint32_t _pos_data = _dxl->convertRadian2Value(_dxl->dxl_state_->goal_position_ + _dxl->dxl_state_->position_offset_);
1821  uint8_t _sync_write_data[4];
1822  _sync_write_data[0] = DXL_LOBYTE(DXL_LOWORD(_pos_data));
1823  _sync_write_data[1] = DXL_HIBYTE(DXL_LOWORD(_pos_data));
1824  _sync_write_data[2] = DXL_LOBYTE(DXL_HIWORD(_pos_data));
1825  _sync_write_data[3] = DXL_HIBYTE(DXL_HIWORD(_pos_data));
1826 
1827  if(port_to_sync_write_position_[_dxl->port_name_] != NULL)
1828  port_to_sync_write_position_[_dxl->port_name_]->addParam(_dxl->id_, _sync_write_data);
1829 
1830  if(port_to_sync_write_current_[_dxl->port_name_] != NULL)
1831  port_to_sync_write_current_[_dxl->port_name_]->removeParam(_dxl->id_);
1832  if(port_to_sync_write_velocity_[_dxl->port_name_] != NULL)
1833  port_to_sync_write_velocity_[_dxl->port_name_]->removeParam(_dxl->id_);
1834  }
1835  else
1836  {
1837  // check whether the module exist
1838  for(std::list<MotionModule *>::iterator _m_it = motion_modules_.begin(); _m_it != motion_modules_.end(); _m_it++)
1839  {
1840  // if it exist
1841  if((*_m_it)->getModuleName() == ctrl_module)
1842  {
1843  std::map<std::string, DynamixelState*>::iterator _result_it = (*_m_it)->result_.find(joint_name);
1844  if(_result_it == (*_m_it)->result_.end())
1845  break;
1846 
1847  _dxl->ctrl_module_name_ = ctrl_module;
1848 
1849  // enqueue enable module list
1850  _enable_modules.push_back(*_m_it);
1851  ControlMode _mode = (*_m_it)->getControlMode();
1852 
1853  if(gazebo_mode_ == true)
1854  break;
1855 
1856  if(_mode == PositionControl)
1857  {
1858  uint32_t _pos_data = _dxl->convertRadian2Value(_dxl->dxl_state_->goal_position_ + _dxl->dxl_state_->position_offset_);
1859  uint8_t _sync_write_data[4];
1860  _sync_write_data[0] = DXL_LOBYTE(DXL_LOWORD(_pos_data));
1861  _sync_write_data[1] = DXL_HIBYTE(DXL_LOWORD(_pos_data));
1862  _sync_write_data[2] = DXL_LOBYTE(DXL_HIWORD(_pos_data));
1863  _sync_write_data[3] = DXL_HIBYTE(DXL_HIWORD(_pos_data));
1864 
1865  if(port_to_sync_write_position_[_dxl->port_name_] != NULL)
1866  port_to_sync_write_position_[_dxl->port_name_]->addParam(_dxl->id_, _sync_write_data);
1867 
1868  if(port_to_sync_write_current_[_dxl->port_name_] != NULL)
1869  port_to_sync_write_current_[_dxl->port_name_]->removeParam(_dxl->id_);
1870  if(port_to_sync_write_velocity_[_dxl->port_name_] != NULL)
1871  port_to_sync_write_velocity_[_dxl->port_name_]->removeParam(_dxl->id_);
1872  }
1873  else if(_mode == VelocityControl)
1874  {
1875  uint32_t _vel_data = _dxl->convertVelocity2Value(_dxl->dxl_state_->goal_velocity_);
1876  uint8_t _sync_write_data[4];
1877  _sync_write_data[0] = DXL_LOBYTE(DXL_LOWORD(_vel_data));
1878  _sync_write_data[1] = DXL_HIBYTE(DXL_LOWORD(_vel_data));
1879  _sync_write_data[2] = DXL_LOBYTE(DXL_HIWORD(_vel_data));
1880  _sync_write_data[3] = DXL_HIBYTE(DXL_HIWORD(_vel_data));
1881 
1882  if(port_to_sync_write_velocity_[_dxl->port_name_] != NULL)
1883  port_to_sync_write_velocity_[_dxl->port_name_]->addParam(_dxl->id_, _sync_write_data);
1884 
1885  if(port_to_sync_write_current_[_dxl->port_name_] != NULL)
1886  port_to_sync_write_current_[_dxl->port_name_]->removeParam(_dxl->id_);
1887  if(port_to_sync_write_position_[_dxl->port_name_] != NULL)
1888  port_to_sync_write_position_[_dxl->port_name_]->removeParam(_dxl->id_);
1889  }
1890  else if(_mode == TorqueControl)
1891  {
1892  uint32_t _curr_data = _dxl->convertTorque2Value(_dxl->dxl_state_->goal_torque_);
1893  uint8_t _sync_write_data[4];
1894  _sync_write_data[0] = DXL_LOBYTE(DXL_LOWORD(_curr_data));
1895  _sync_write_data[1] = DXL_HIBYTE(DXL_LOWORD(_curr_data));
1896  _sync_write_data[2] = DXL_LOBYTE(DXL_HIWORD(_curr_data));
1897  _sync_write_data[3] = DXL_HIBYTE(DXL_HIWORD(_curr_data));
1898 
1899  if(port_to_sync_write_current_[_dxl->port_name_] != NULL)
1900  port_to_sync_write_current_[_dxl->port_name_]->addParam(_dxl->id_, _sync_write_data);
1901 
1902  if(port_to_sync_write_velocity_[_dxl->port_name_] != NULL)
1903  port_to_sync_write_velocity_[_dxl->port_name_]->removeParam(_dxl->id_);
1904  if(port_to_sync_write_position_[_dxl->port_name_] != NULL)
1905  port_to_sync_write_position_[_dxl->port_name_]->removeParam(_dxl->id_);
1906  }
1907  break;
1908  }
1909  }
1910  }
1911  }
1912 
1913  // enable module(s)
1914  _enable_modules.unique();
1915  for(std::list<MotionModule *>::iterator _m_it = _enable_modules.begin(); _m_it != _enable_modules.end(); _m_it++)
1916  {
1917  (*_m_it)->setModuleEnable(true);
1918  }
1919 
1920  // TODO: set indirect address
1921  // -> check module's control_mode
1922 
1923  queue_mutex_.unlock();
1924 
1925  // publish current module
1926  robotis_controller_msgs::JointCtrlModule _current_module_msg;
1927  for(std::map<std::string, Dynamixel *>::iterator _dxl_iter = robot_->dxls_.begin(); _dxl_iter != robot_->dxls_.end(); ++_dxl_iter)
1928  {
1929  _current_module_msg.joint_name.push_back(_dxl_iter->first);
1930  _current_module_msg.module_name.push_back(_dxl_iter->second->ctrl_module_name_);
1931  }
1932 
1933  if(_current_module_msg.joint_name.size() == _current_module_msg.module_name.size())
1934  current_module_pub_.publish(_current_module_msg);
1935 }
1936 
1937 void RobotisController::setCtrlModuleThread(std::string ctrl_module)
1938 {
1939  // stop module
1940  std::list<MotionModule *> stop_modules;
1941 
1942  if (ctrl_module == "" || ctrl_module == "none")
1943  {
1944  // enqueue all modules in order to stop
1945  for (auto m_it = motion_modules_.begin(); m_it != motion_modules_.end(); m_it++)
1946  {
1947  if ((*m_it)->getModuleEnable() == true)
1948  stop_modules.push_back(*m_it);
1949  }
1950  }
1951  else
1952  {
1953  for (auto m_it = motion_modules_.begin(); m_it != motion_modules_.end(); m_it++)
1954  {
1955  // if it exist
1956  if ((*m_it)->getModuleName() == ctrl_module)
1957  {
1958  // enqueue the module which lost control of joint in order to stop
1959  for (auto& result_it : (*m_it)->result_)
1960  {
1961  auto d_it = robot_->dxls_.find(result_it.first);
1962 
1963  if (d_it != robot_->dxls_.end())
1964  {
1965  // enqueue
1966  if (d_it->second->ctrl_module_name_ != ctrl_module)
1967  {
1968  for (auto stop_m_it = motion_modules_.begin(); stop_m_it != motion_modules_.end(); stop_m_it++)
1969  {
1970  if (((*stop_m_it)->getModuleName() == d_it->second->ctrl_module_name_) &&
1971  ((*stop_m_it)->getModuleEnable() == true))
1972  {
1973  stop_modules.push_back(*stop_m_it);
1974  }
1975  }
1976  }
1977  }
1978  }
1979 
1980  break;
1981  }
1982  }
1983  }
1984 
1985  // stop the module
1986  stop_modules.unique();
1987  for (auto stop_m_it = stop_modules.begin(); stop_m_it != stop_modules.end(); stop_m_it++)
1988  {
1989  (*stop_m_it)->stop();
1990  }
1991 
1992  // wait to stop
1993  for (auto stop_m_it = stop_modules.begin(); stop_m_it != stop_modules.end(); stop_m_it++)
1994  {
1995  while ((*stop_m_it)->isRunning())
1996  usleep(robot_->getControlCycle() * 1000);
1997  }
1998 
1999  // disable module(s)
2000  for(std::list<MotionModule *>::iterator _stop_m_it = stop_modules.begin(); _stop_m_it != stop_modules.end(); _stop_m_it++)
2001  {
2002  (*_stop_m_it)->setModuleEnable(false);
2003  }
2004 
2005 
2006  // set ctrl module
2007  queue_mutex_.lock();
2008 
2009  if (DEBUG_PRINT)
2010  ROS_INFO_STREAM("set module : " << ctrl_module);
2011 
2012  // none
2013  if ((ctrl_module == "") || (ctrl_module == "none"))
2014  {
2015  // set dxl's control module to "none"
2016  for (auto& d_it : robot_->dxls_)
2017  {
2018  Dynamixel *dxl = d_it.second;
2019  dxl->ctrl_module_name_ = "none";
2020 
2021  if (gazebo_mode_ == true)
2022  continue;
2023 
2024  uint32_t pos_data = dxl->convertRadian2Value(dxl->dxl_state_->goal_position_ + dxl->dxl_state_->position_offset_);
2025  uint8_t sync_write_data[4] = { 0 };
2026  sync_write_data[0] = DXL_LOBYTE(DXL_LOWORD(pos_data));
2027  sync_write_data[1] = DXL_HIBYTE(DXL_LOWORD(pos_data));
2028  sync_write_data[2] = DXL_LOBYTE(DXL_HIWORD(pos_data));
2029  sync_write_data[3] = DXL_HIBYTE(DXL_HIWORD(pos_data));
2030 
2031  if (port_to_sync_write_position_[dxl->port_name_] != NULL)
2032  port_to_sync_write_position_[dxl->port_name_]->addParam(dxl->id_, sync_write_data);
2033 
2034  if (port_to_sync_write_current_[dxl->port_name_] != NULL)
2035  port_to_sync_write_current_[dxl->port_name_]->removeParam(dxl->id_);
2036  if (port_to_sync_write_velocity_[dxl->port_name_] != NULL)
2037  port_to_sync_write_velocity_[dxl->port_name_]->removeParam(dxl->id_);
2038  }
2039  }
2040  else
2041  {
2042  // check whether the module exist
2043  for (auto m_it = motion_modules_.begin(); m_it != motion_modules_.end(); m_it++)
2044  {
2045  // if it exist
2046  if ((*m_it)->getModuleName() == ctrl_module)
2047  {
2048  ControlMode mode = (*m_it)->getControlMode();
2049  for (auto& result_it : (*m_it)->result_)
2050  {
2051  auto d_it = robot_->dxls_.find(result_it.first);
2052  if (d_it != robot_->dxls_.end())
2053  {
2054  Dynamixel *dxl = d_it->second;
2055  dxl->ctrl_module_name_ = ctrl_module;
2056 
2057  if (gazebo_mode_ == true)
2058  continue;
2059 
2060  if (mode == PositionControl)
2061  {
2062  uint32_t pos_data = dxl->convertRadian2Value(dxl->dxl_state_->goal_position_ + dxl->dxl_state_->position_offset_);
2063  uint8_t sync_write_data[4] = { 0 };
2064  sync_write_data[0] = DXL_LOBYTE(DXL_LOWORD(pos_data));
2065  sync_write_data[1] = DXL_HIBYTE(DXL_LOWORD(pos_data));
2066  sync_write_data[2] = DXL_LOBYTE(DXL_HIWORD(pos_data));
2067  sync_write_data[3] = DXL_HIBYTE(DXL_HIWORD(pos_data));
2068 
2069  if (port_to_sync_write_position_[dxl->port_name_] != NULL)
2070  port_to_sync_write_position_[dxl->port_name_]->addParam(dxl->id_, sync_write_data);
2071 
2072  if (port_to_sync_write_current_[dxl->port_name_] != NULL)
2073  port_to_sync_write_current_[dxl->port_name_]->removeParam(dxl->id_);
2074  if (port_to_sync_write_velocity_[dxl->port_name_] != NULL)
2075  port_to_sync_write_velocity_[dxl->port_name_]->removeParam(dxl->id_);
2076  }
2077  else if (mode == VelocityControl)
2078  {
2079  uint32_t vel_data = dxl->convertVelocity2Value(dxl->dxl_state_->goal_velocity_);
2080  uint8_t sync_write_data[4] = { 0 };
2081  sync_write_data[0] = DXL_LOBYTE(DXL_LOWORD(vel_data));
2082  sync_write_data[1] = DXL_HIBYTE(DXL_LOWORD(vel_data));
2083  sync_write_data[2] = DXL_LOBYTE(DXL_HIWORD(vel_data));
2084  sync_write_data[3] = DXL_HIBYTE(DXL_HIWORD(vel_data));
2085 
2086  if (port_to_sync_write_velocity_[dxl->port_name_] != NULL)
2087  port_to_sync_write_velocity_[dxl->port_name_]->addParam(dxl->id_, sync_write_data);
2088 
2089  if (port_to_sync_write_current_[dxl->port_name_] != NULL)
2090  port_to_sync_write_current_[dxl->port_name_]->removeParam(dxl->id_);
2091  if (port_to_sync_write_position_[dxl->port_name_] != NULL)
2092  port_to_sync_write_position_[dxl->port_name_]->removeParam(dxl->id_);
2093  }
2094  else if (mode == TorqueControl)
2095  {
2096  uint32_t curr_data = dxl->convertTorque2Value(dxl->dxl_state_->goal_torque_);
2097  uint8_t sync_write_data[4] = { 0 };
2098  sync_write_data[0] = DXL_LOBYTE(DXL_LOWORD(curr_data));
2099  sync_write_data[1] = DXL_HIBYTE(DXL_LOWORD(curr_data));
2100  sync_write_data[2] = DXL_LOBYTE(DXL_HIWORD(curr_data));
2101  sync_write_data[3] = DXL_HIBYTE(DXL_HIWORD(curr_data));
2102 
2103  if (port_to_sync_write_current_[dxl->port_name_] != NULL)
2104  port_to_sync_write_current_[dxl->port_name_]->addParam(dxl->id_, sync_write_data);
2105 
2106  if (port_to_sync_write_velocity_[dxl->port_name_] != NULL)
2107  port_to_sync_write_velocity_[dxl->port_name_]->removeParam(dxl->id_);
2108  if (port_to_sync_write_position_[dxl->port_name_] != NULL)
2109  port_to_sync_write_position_[dxl->port_name_]->removeParam(dxl->id_);
2110  }
2111  }
2112  }
2113 
2114  break;
2115  }
2116  }
2117  }
2118 
2119  for (auto m_it = motion_modules_.begin(); m_it != motion_modules_.end(); m_it++)
2120  {
2121  // set all used modules -> enable
2122  for (auto& d_it : robot_->dxls_)
2123  {
2124  if (d_it.second->ctrl_module_name_ == (*m_it)->getModuleName())
2125  {
2126  (*m_it)->setModuleEnable(true);
2127  break;
2128  }
2129  }
2130  }
2131 
2132  // TODO: set indirect address
2133  // -> check module's control_mode
2134 
2135  queue_mutex_.unlock();
2136 
2137  // publish current module
2138  robotis_controller_msgs::JointCtrlModule current_module_msg;
2139  for (auto& dxl_iter : robot_->dxls_)
2140  {
2141  current_module_msg.joint_name.push_back(dxl_iter.first);
2142  current_module_msg.module_name.push_back(dxl_iter.second->ctrl_module_name_);
2143  }
2144 
2145  if (current_module_msg.joint_name.size() == current_module_msg.module_name.size())
2146  current_module_pub_.publish(current_module_msg);
2147 }
2148 
2149 void RobotisController::gazeboJointStatesCallback(const sensor_msgs::JointState::ConstPtr &msg)
2150 {
2151  queue_mutex_.lock();
2152 
2153  for (unsigned int i = 0; i < msg->name.size(); i++)
2154  {
2155  auto d_it = robot_->dxls_.find((std::string) msg->name[i]);
2156  if (d_it != robot_->dxls_.end())
2157  {
2158  d_it->second->dxl_state_->present_position_ = msg->position[i];
2159  d_it->second->dxl_state_->present_velocity_ = msg->velocity[i];
2160  d_it->second->dxl_state_->present_torque_ = msg->effort[i];
2161  }
2162  }
2163 
2164  if (init_pose_loaded_ == false)
2165  {
2166  for (auto& it : robot_->dxls_)
2167  it.second->dxl_state_->goal_position_ = it.second->dxl_state_->present_position_;
2168  init_pose_loaded_ = true;
2169  }
2170 
2171  queue_mutex_.unlock();
2172 }
2173 
2175 {
2176  if (this->is_timer_running_)
2177  {
2178  if (DEBUG_PRINT == true)
2179  ROS_WARN("Process Timer is running.. STOP the timer first.");
2180  return false;
2181  }
2182  return true;
2183 }
2184 
2185 int RobotisController::ping(const std::string joint_name, uint8_t *error)
2186 {
2187  return ping(joint_name, 0, error);
2188 }
2189 int RobotisController::ping(const std::string joint_name, uint16_t* model_number, uint8_t *error)
2190 {
2191  if (isTimerStopped() == false)
2192  return COMM_PORT_BUSY;
2193 
2194  Dynamixel *dxl = robot_->dxls_[joint_name];
2195  if (dxl == NULL)
2196  return COMM_NOT_AVAILABLE;
2197 
2199  dynamixel::PortHandler *port_handler = robot_->ports_[dxl->port_name_];
2200 
2201  return pkt_handler->ping(port_handler, dxl->id_, model_number, error);
2202 }
2203 
2204 int RobotisController::action(const std::string joint_name)
2205 {
2206  if (isTimerStopped() == false)
2207  return COMM_PORT_BUSY;
2208 
2209  Dynamixel *dxl = robot_->dxls_[joint_name];
2210  if (dxl == NULL)
2211  return COMM_NOT_AVAILABLE;
2212 
2214  dynamixel::PortHandler *port_handler = robot_->ports_[dxl->port_name_];
2215 
2216  return pkt_handler->action(port_handler, dxl->id_);
2217 }
2218 int RobotisController::reboot(const std::string joint_name, uint8_t *error)
2219 {
2220  if (isTimerStopped() == false)
2221  return COMM_PORT_BUSY;
2222 
2223  Dynamixel *dxl = robot_->dxls_[joint_name];
2224  if (dxl == NULL)
2225  return COMM_NOT_AVAILABLE;
2226 
2228  dynamixel::PortHandler *port_handler = robot_->ports_[dxl->port_name_];
2229 
2230  return pkt_handler->reboot(port_handler, dxl->id_, error);
2231 }
2232 int RobotisController::factoryReset(const std::string joint_name, uint8_t option, uint8_t *error)
2233 {
2234  if (isTimerStopped() == false)
2235  return COMM_PORT_BUSY;
2236 
2237  Dynamixel *dxl = robot_->dxls_[joint_name];
2238  if (dxl == NULL)
2239  return COMM_NOT_AVAILABLE;
2240 
2242  dynamixel::PortHandler *port_handler = robot_->ports_[dxl->port_name_];
2243 
2244  return pkt_handler->factoryReset(port_handler, dxl->id_, option, error);
2245 }
2246 
2247 int RobotisController::read(const std::string joint_name, uint16_t address, uint16_t length, uint8_t *data, uint8_t *error)
2248 {
2249  if (isTimerStopped() == false)
2250  return COMM_PORT_BUSY;
2251 
2252  Dynamixel *dxl = robot_->dxls_[joint_name];
2253  if (dxl == NULL)
2254  return COMM_NOT_AVAILABLE;
2255 
2257  dynamixel::PortHandler *port_handler = robot_->ports_[dxl->port_name_];
2258 
2259  return pkt_handler->readTxRx(port_handler, dxl->id_, address, length, data, error);
2260 }
2261 
2262 int RobotisController::readCtrlItem(const std::string joint_name, const std::string item_name, uint32_t *data, uint8_t *error)
2263 {
2264  if (isTimerStopped() == false)
2265  return COMM_PORT_BUSY;
2266 
2267  Dynamixel *dxl = robot_->dxls_[joint_name];
2268  if (dxl == NULL)
2269  return COMM_NOT_AVAILABLE;
2270 
2271  ControlTableItem *item = dxl->ctrl_table_[item_name];
2272  if (item == NULL)
2273  return COMM_NOT_AVAILABLE;
2274 
2276  dynamixel::PortHandler *port_handler = robot_->ports_[dxl->port_name_];
2277 
2278  int result = COMM_NOT_AVAILABLE;
2279  switch (item->data_length_)
2280  {
2281  case 1:
2282  {
2283  uint8_t read_data = 0;
2284  result = pkt_handler->read1ByteTxRx(port_handler, dxl->id_, item->address_, &read_data, error);
2285  if (result == COMM_SUCCESS)
2286  *data = read_data;
2287  break;
2288  }
2289  case 2:
2290  {
2291  uint16_t read_data = 0;
2292  result = pkt_handler->read2ByteTxRx(port_handler, dxl->id_, item->address_, &read_data, error);
2293  if (result == COMM_SUCCESS)
2294  *data = read_data;
2295  break;
2296  }
2297  case 4:
2298  {
2299  uint32_t read_data = 0;
2300  result = pkt_handler->read4ByteTxRx(port_handler, dxl->id_, item->address_, &read_data, error);
2301  if (result == COMM_SUCCESS)
2302  *data = read_data;
2303  break;
2304  }
2305  default:
2306  break;
2307  }
2308  return result;
2309 }
2310 
2311 int RobotisController::read1Byte(const std::string joint_name, uint16_t address, uint8_t *data, uint8_t *error)
2312 {
2313  if (isTimerStopped() == false)
2314  return COMM_PORT_BUSY;
2315 
2316  Dynamixel *dxl = robot_->dxls_[joint_name];
2317  if (dxl == NULL)
2318  return COMM_NOT_AVAILABLE;
2319 
2321  dynamixel::PortHandler *port_handler = robot_->ports_[dxl->port_name_];
2322 
2323  return pkt_handler->read1ByteTxRx(port_handler, dxl->id_, address, data, error);
2324 }
2325 
2326 int RobotisController::read2Byte(const std::string joint_name, uint16_t address, uint16_t *data, uint8_t *error)
2327 {
2328  if (isTimerStopped() == false)
2329  return COMM_PORT_BUSY;
2330 
2331  Dynamixel *dxl = robot_->dxls_[joint_name];
2332  if (dxl == NULL)
2333  return COMM_NOT_AVAILABLE;
2334 
2336  dynamixel::PortHandler *port_handler = robot_->ports_[dxl->port_name_];
2337 
2338  return pkt_handler->read2ByteTxRx(port_handler, dxl->id_, address, data, error);
2339 }
2340 
2341 int RobotisController::read4Byte(const std::string joint_name, uint16_t address, uint32_t *data, uint8_t *error)
2342 {
2343  if (isTimerStopped() == false)
2344  return COMM_PORT_BUSY;
2345 
2346  Dynamixel *dxl = robot_->dxls_[joint_name];
2347  if (dxl == NULL)
2348  return COMM_NOT_AVAILABLE;
2349 
2351  dynamixel::PortHandler *port_handler = robot_->ports_[dxl->port_name_];
2352 
2353  return pkt_handler->read4ByteTxRx(port_handler, dxl->id_, address, data, error);
2354 }
2355 
2356 int RobotisController::write(const std::string joint_name, uint16_t address, uint16_t length, uint8_t *data, uint8_t *error)
2357 {
2358  if (isTimerStopped() == false)
2359  return COMM_PORT_BUSY;
2360 
2361  Dynamixel *dxl = robot_->dxls_[joint_name];
2362  if (dxl == NULL)
2363  return COMM_NOT_AVAILABLE;
2364 
2366  dynamixel::PortHandler *port_handler = robot_->ports_[dxl->port_name_];
2367 
2368  return pkt_handler->writeTxRx(port_handler, dxl->id_, address, length, data, error);
2369 }
2370 
2371 int RobotisController::writeCtrlItem(const std::string joint_name, const std::string item_name, uint32_t data, uint8_t *error)
2372 {
2373  if (isTimerStopped() == false)
2374  return COMM_PORT_BUSY;
2375 
2376  Dynamixel *dxl = robot_->dxls_[joint_name];
2377  if (dxl == NULL)
2378  return COMM_NOT_AVAILABLE;
2379 
2380  ControlTableItem *item = dxl->ctrl_table_[item_name];
2381  if (item == NULL)
2382  return COMM_NOT_AVAILABLE;
2383 
2385  dynamixel::PortHandler *port_handler = robot_->ports_[dxl->port_name_];
2386 
2387  int result = COMM_NOT_AVAILABLE;
2388  uint8_t *write_data = new uint8_t[item->data_length_];
2389  if (item->data_length_ == 1)
2390  {
2391  write_data[0] = (uint8_t) data;
2392  result = pkt_handler->write1ByteTxRx(port_handler, dxl->id_, item->address_, data, error);
2393  }
2394  else if (item->data_length_ == 2)
2395  {
2396  write_data[0] = DXL_LOBYTE((uint16_t )data);
2397  write_data[1] = DXL_HIBYTE((uint16_t )data);
2398  result = pkt_handler->write2ByteTxRx(port_handler, dxl->id_, item->address_, data, error);
2399  }
2400  else if (item->data_length_ == 4)
2401  {
2402  write_data[0] = DXL_LOBYTE(DXL_LOWORD((uint32_t)data));
2403  write_data[1] = DXL_HIBYTE(DXL_LOWORD((uint32_t)data));
2404  write_data[2] = DXL_LOBYTE(DXL_HIWORD((uint32_t)data));
2405  write_data[3] = DXL_HIBYTE(DXL_HIWORD((uint32_t)data));
2406  result = pkt_handler->write4ByteTxRx(port_handler, dxl->id_, item->address_, data, error);
2407  }
2408  delete[] write_data;
2409  return result;
2410 }
2411 
2412 int RobotisController::write1Byte(const std::string joint_name, uint16_t address, uint8_t data, uint8_t *error)
2413 {
2414  if (isTimerStopped() == false)
2415  return COMM_PORT_BUSY;
2416 
2417  Dynamixel *dxl = robot_->dxls_[joint_name];
2418  if (dxl == NULL)
2419  return COMM_NOT_AVAILABLE;
2420 
2422  dynamixel::PortHandler *port_handler = robot_->ports_[dxl->port_name_];
2423 
2424  return pkt_handler->write1ByteTxRx(port_handler, dxl->id_, address, data, error);
2425 }
2426 
2427 int RobotisController::write2Byte(const std::string joint_name, uint16_t address, uint16_t data, uint8_t *error)
2428 {
2429  if (isTimerStopped() == false)
2430  return COMM_PORT_BUSY;
2431 
2432  Dynamixel *dxl = robot_->dxls_[joint_name];
2433  if (dxl == NULL)
2434  return COMM_NOT_AVAILABLE;
2435 
2437  dynamixel::PortHandler *port_handler = robot_->ports_[dxl->port_name_];
2438 
2439  return pkt_handler->write2ByteTxRx(port_handler, dxl->id_, address, data, error);
2440 }
2441 
2442 int RobotisController::write4Byte(const std::string joint_name, uint16_t address, uint32_t data, uint8_t *error)
2443 {
2444  if (isTimerStopped() == false)
2445  return COMM_PORT_BUSY;
2446 
2447  Dynamixel *dxl = robot_->dxls_[joint_name];
2448  if (dxl == NULL)
2449  return COMM_NOT_AVAILABLE;
2450 
2452  dynamixel::PortHandler *port_handler = robot_->ports_[dxl->port_name_];
2453 
2454  return pkt_handler->write4ByteTxRx(port_handler, dxl->id_, address, data, error);
2455 }
2456 
2457 int RobotisController::regWrite(const std::string joint_name, uint16_t address, uint16_t length, uint8_t *data,
2458  uint8_t *error)
2459 {
2460  if (isTimerStopped() == false)
2461  return COMM_PORT_BUSY;
2462 
2463  Dynamixel *dxl = robot_->dxls_[joint_name];
2464  if (dxl == NULL)
2465  return COMM_NOT_AVAILABLE;
2466 
2468  dynamixel::PortHandler *port_handler = robot_->ports_[dxl->port_name_];
2469 
2470  return pkt_handler->regWriteTxRx(port_handler, dxl->id_, address, length, data, error);
2471 }
2472 
void setCtrlModuleThread(std::string ctrl_module)
virtual int read1ByteTxRx(PortHandler *port, uint8_t id, uint16_t address, uint8_t *data, uint8_t *error=0)=0
std::list< SensorModule * > sensor_modules_
void initializeDevice(const std::string init_file_path)
int read4Byte(const std::string joint_name, uint16_t address, uint32_t *data, uint8_t *error=0)
int read(const std::string joint_name, uint16_t address, uint16_t length, uint8_t *data, uint8_t *error=0)
int regWrite(const std::string joint_name, uint16_t address, uint16_t length, uint8_t *data, uint8_t *error=0)
int reboot(const std::string joint_name, uint8_t *error=0)
int write(const std::string joint_name, uint16_t address, uint16_t length, uint8_t *data, uint8_t *error=0)
void publish(const boost::shared_ptr< M > &message) const
virtual int regWriteTxRx(PortHandler *port, uint8_t id, uint16_t address, uint16_t length, uint8_t *data, uint8_t *error=0)=0
double convertValue2Torque(int16_t value)
int COMM_NOT_AVAILABLE
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
ControlTableItem * present_velocity_item_
virtual int writeTxRx(PortHandler *port, uint8_t id, uint16_t address, uint16_t length, uint8_t *data, uint8_t *error=0)=0
std::map< std::string, ros::Publisher > gazebo_joint_position_pub_
double convertValue2Radian(int32_t value)
std::map< std::string, dynamixel::GroupSyncWrite * > port_to_sync_write_position_i_gain_
void setCtrlModuleCallback(const std_msgs::String::ConstPtr &msg)
ControlTableItem * position_p_gain_item_
std::map< std::string, ros::Publisher > gazebo_joint_effort_pub_
ControlTableItem * velocity_p_gain_item_
virtual int read2ByteTxRx(PortHandler *port, uint8_t id, uint16_t address, uint16_t *data, uint8_t *error=0)=0
virtual int reboot(PortHandler *port, uint8_t id, uint8_t *error=0)=0
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
void removeMotionModule(MotionModule *module)
std::map< std::string, ros::Publisher > gazebo_joint_velocity_pub_
void addMotionModule(MotionModule *module)
double convertValue2Velocity(int32_t value)
#define ROS_WARN(...)
std::map< std::string, dynamixel::PortHandler * > ports_
std::vector< ControlTableItem * > bulk_read_items_
std::map< std::string, Dynamixel * > dxls_
void setJointCtrlModuleCallback(const robotis_controller_msgs::JointCtrlModule::ConstPtr &msg)
int write2Byte(const std::string joint_name, uint16_t address, uint16_t data, uint8_t *error=0)
int COMM_SUCCESS
std::map< std::string, dynamixel::GroupSyncWrite * > port_to_sync_write_velocity_d_gain_
ControlTableItem * present_position_item_
std::map< std::string, std::string > port_default_device_
ControlTableItem * goal_current_item_
int COMM_PORT_BUSY
int32_t convertRadian2Value(double radian)
std::map< std::string, double > sensor_result_
virtual int readTxRx(PortHandler *port, uint8_t id, uint16_t address, uint16_t length, uint8_t *data, uint8_t *error=0)=0
int write1Byte(const std::string joint_name, uint16_t address, uint8_t data, uint8_t *error=0)
bool setJointCtrlModuleService(robotis_controller_msgs::SetJointModule::Request &req, robotis_controller_msgs::SetJointModule::Response &res)
std::map< std::string, dynamixel::GroupSyncWrite * > port_to_sync_write_position_p_gain_
bool initialize(const std::string robot_file_path, const std::string init_file_path)
#define ROS_INFO(...)
bool setCtrlModuleService(robotis_controller_msgs::SetModule::Request &req, robotis_controller_msgs::SetModule::Response &res)
virtual void initialize(const int control_cycle_msec, Robot *robot)=0
void setCallbackQueue(CallbackQueueInterface *queue)
void loadOffset(const std::string path)
std::map< std::string, dynamixel::GroupSyncWrite * > port_to_sync_write_current_
std::map< std::string, dynamixel::GroupSyncWrite * > port_to_sync_write_position_d_gain_
virtual int write1ByteTxRx(PortHandler *port, uint8_t id, uint16_t address, uint8_t data, uint8_t *error=0)=0
ControlTableItem * goal_position_item_
ControlTableItem * torque_enable_item_
std::map< std::string, dynamixel::GroupSyncWrite * > port_to_sync_write_velocity_i_gain_
std::list< MotionModule * > motion_modules_
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
int32_t convertVelocity2Value(double velocity)
static PacketHandler * getPacketHandler(float protocol_version=2.0)
int action(const std::string joint_name)
def DXL_HIBYTE(w)
ControlTableItem * position_i_gain_item_
void setControllerModeCallback(const std_msgs::String::ConstPtr &msg)
ControlTableItem * velocity_i_gain_item_
int write4Byte(const std::string joint_name, uint16_t address, uint32_t data, uint8_t *error=0)
ControlTableItem * position_d_gain_item_
ROSLIB_DECL std::string getPath(const std::string &package_name)
def DXL_LOWORD(l)
virtual void initialize(const int control_cycle_msec, Robot *robot)=0
std::map< std::string, uint32_t > bulk_read_table_
std::map< std::string, dynamixel::GroupSyncWrite * > port_to_sync_write_velocity_
std::map< std::string, Sensor * > sensors_
SensorState * sensor_state_
virtual int write4ByteTxRx(PortHandler *port, uint8_t id, uint16_t address, uint32_t data, uint8_t *error=0)=0
void addSensorModule(SensorModule *module)
#define ROS_INFO_STREAM(args)
std::map< std::string, dynamixel::GroupBulkRead * > port_to_bulk_read_
DynamixelState * dxl_state_
def DXL_HIWORD(l)
void syncWriteItemCallback(const robotis_controller_msgs::SyncWriteItem::ConstPtr &msg)
virtual int write2ByteTxRx(PortHandler *port, uint8_t id, uint16_t address, uint16_t data, uint8_t *error=0)=0
virtual int action(PortHandler *port, uint8_t id)=0
int ping(const std::string joint_name, uint8_t *error=0)
static void * timerThread(void *param)
ControlTableItem * goal_velocity_item_
static Time now()
virtual int read4ByteTxRx(PortHandler *port, uint8_t id, uint16_t address, uint32_t *data, uint8_t *error=0)=0
int16_t convertTorque2Value(double torque)
void gazeboJointStatesCallback(const sensor_msgs::JointState::ConstPtr &msg)
virtual int getBaudRate()=0
int read1Byte(const std::string joint_name, uint16_t address, uint8_t *data, uint8_t *error=0)
ControlTableItem * velocity_d_gain_item_
bool ok() const
virtual int ping(PortHandler *port, uint8_t id, uint8_t *error=0)=0
void removeSensorModule(SensorModule *module)
std::vector< dynamixel::GroupSyncWrite * > direct_sync_write_
void setJointCtrlModuleThread(const robotis_controller_msgs::JointCtrlModule::ConstPtr &msg)
#define INDIRECT_ADDRESS_1
std::map< std::string, uint32_t > bulk_read_table_
void setJointStatesCallback(const sensor_msgs::JointState::ConstPtr &msg)
virtual int factoryReset(PortHandler *port, uint8_t id, uint8_t option=0, uint8_t *error=0)=0
ControlTableItem * present_current_item_
virtual bool setBaudRate(const int baudrate)=0
int writeCtrlItem(const std::string joint_name, const std::string item_name, uint32_t data, uint8_t *error=0)
bool getJointCtrlModuleService(robotis_controller_msgs::GetJointModule::Request &req, robotis_controller_msgs::GetJointModule::Response &res)
std::map< std::string, dynamixel::GroupSyncWrite * > port_to_sync_write_position_
#define ROS_ERROR(...)
std::map< std::string, dynamixel::GroupSyncWrite * > port_to_sync_write_velocity_p_gain_
std::map< std::string, ControlTableItem * > ctrl_table_
def DXL_LOBYTE(w)
int factoryReset(const std::string joint_name, uint8_t option=0, uint8_t *error=0)
void writeControlTableCallback(const robotis_controller_msgs::WriteControlTable::ConstPtr &msg)
int readCtrlItem(const std::string joint_name, const std::string item_name, uint32_t *data, uint8_t *error=0)
void setCtrlModule(std::string module_name)
int read2Byte(const std::string joint_name, uint16_t address, uint16_t *data, uint8_t *error=0)
#define ROS_DEBUG(...)


robotis_controller
Author(s): Zerom , Kayman , SCH
autogenerated on Mon Jun 10 2019 14:35:12