head_control_module.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  * HeadControlModule.cpp
19  *
20  * Created on: 2016. 1. 27.
21  * Author: Kayman
22  */
23 
24 #include <stdio.h>
26 
27 using namespace thormang3;
28 
30  : control_cycle_msec_(0),
31  stop_process_(false),
32  is_moving_(false),
33  is_direct_control_(false),
34  tra_count_(0),
35  tra_size_(0),
36  current_state_(None),
37  original_position_lidar_(0.0),
38  moving_time_(3.0),
39  scan_range_(0.0),
40  DEBUG(false)
41 {
42  enable_ = false;
43  module_name_ = "head_control_module";
45 
48 
49  using_joint_name_["head_y"] = 0;
50  using_joint_name_["head_p"] = 1;
51 
52  target_position_ = Eigen::MatrixXd::Zero(1, result_.size());
53  current_position_ = Eigen::MatrixXd::Zero(1, result_.size());
54  goal_position_ = Eigen::MatrixXd::Zero(1, result_.size());
55  goal_velocity_ = Eigen::MatrixXd::Zero(1, result_.size());
56  goal_acceleration_ = Eigen::MatrixXd::Zero(1, result_.size());
57 
58  tra_gene_thread_ = 0;
59 }
60 
62 {
63  queue_thread_.join();
64 }
65 
66 void HeadControlModule::initialize(const int control_cycle_msec, robotis_framework::Robot *robot)
67 {
68  queue_thread_ = boost::thread(boost::bind(&HeadControlModule::queueThread, this));
69 
70  control_cycle_msec_ = control_cycle_msec;
71 
72  ros::NodeHandle ros_node;
73 
74  /* publish topics */
75  moving_head_pub_ = ros_node.advertise<std_msgs::String>("/robotis/sensor/move_lidar", 0);
76  status_msg_pub_ = ros_node.advertise<robotis_controller_msgs::StatusMsg>("/robotis/status", 0);
77 
78  movement_done_pub_ = ros_node.advertise<std_msgs::String>("/robotis/movement_done", 1);
79 }
80 
82 {
83  ros::NodeHandle ros_node;
84  ros::CallbackQueue callback_queue;
85 
86  ros_node.setCallbackQueue(&callback_queue);
87 
88  /* subscribe topics */
89  ros::Subscriber get_3d_lidar_sub = ros_node.subscribe("/robotis/head_control/move_lidar", 1,
91  ros::Subscriber get_3d_lidar_range_sub = ros_node.subscribe("/robotis/head_control/move_lidar_with_range", 1,
93  ros::Subscriber set_head_joint_sub = ros_node.subscribe("/robotis/head_control/set_joint_states", 1,
95  ros::Subscriber set_head_joint_time_sub = ros_node.subscribe("/robotis/head_control/set_joint_states_time", 1,
97 
98  ros::WallDuration duration(control_cycle_msec_ / 1000.0);
99  while (ros_node.ok())
100  callback_queue.callAvailable(duration);
101 }
102 
103 void HeadControlModule::get3DLidarCallback(const std_msgs::String::ConstPtr &msg)
104 {
105  if (enable_ == false || is_moving_ == true)
106  {
107  publishStatusMsg(robotis_controller_msgs::StatusMsg::STATUS_ERROR, "Fail to move Lidar");
108  publishDoneMsg("scan_failed");
109  return;
110  }
111 
112  if (DEBUG)
113  fprintf(stderr, "TOPIC CALLBACK : get_3d_lidar\n");
114 
115  if (current_state_ == None)
116  {
117  // turn off direct control and move head joint in order to make pointcloud
118  is_direct_control_ = false;
119  scan_range_ = 0.0;
121 
122  publishStatusMsg(robotis_controller_msgs::StatusMsg::STATUS_INFO, "Start head joint in order to make pointcloud");
123  }
124  else
125  {
126  ROS_INFO("Head is used.");
127  publishStatusMsg(robotis_controller_msgs::StatusMsg::STATUS_ERROR, "Fail to move Lidar");
128  }
129 }
130 
131 void HeadControlModule::get3DLidarRangeCallback(const std_msgs::Float64::ConstPtr &msg)
132 {
133  if (enable_ == false || is_moving_ == true)
134  {
135  publishStatusMsg(robotis_controller_msgs::StatusMsg::STATUS_ERROR, "Fail to move Lidar");
136  publishDoneMsg("scan_failed");
137  return;
138  }
139 
140  if (DEBUG)
141  fprintf(stderr, "TOPIC CALLBACK : get_3d_lidar\n");
142 
143  if (current_state_ == None)
144  {
145  // turn off direct control and move head joint in order to make pointcloud
146  is_direct_control_ = false;
147  scan_range_ = msg->data;
148  double start_angle = current_position_.coeffRef(0, using_joint_name_["head_p"]) - scan_range_;
149  beforeMoveLidar(start_angle);
150 
151  publishStatusMsg(robotis_controller_msgs::StatusMsg::STATUS_INFO, "Start head joint in order to make pointcloud");
152  }
153  else
154  {
155  ROS_INFO("Head is used.");
156  publishStatusMsg(robotis_controller_msgs::StatusMsg::STATUS_ERROR, "Fail to move Lidar");
157  }
158 }
159 
160 void HeadControlModule::setHeadJointCallback(const sensor_msgs::JointState::ConstPtr &msg)
161 {
162  if (enable_ == false)
163  {
164  ROS_INFO("Head module is not enable.");
165  publishStatusMsg(robotis_controller_msgs::StatusMsg::STATUS_ERROR, "Not Enable");
166  publishDoneMsg("head_control_failed");
167  return;
168  }
169 
170  if (is_moving_ == true && is_direct_control_ == false)
171  {
172  ROS_INFO("Head is moving now.");
173  publishStatusMsg(robotis_controller_msgs::StatusMsg::STATUS_ERROR, "Head is busy.");
174  publishDoneMsg("head_control_failed");
175  return;
176  }
177 
178  // moving time
179  moving_time_ = 1.0; // default : 1 sec
180 
181  // set target joint angle
182  target_position_ = goal_position_; // default
183 
184  for (int ix = 0; ix < msg->name.size(); ix++)
185  {
186  std::string joint_name = msg->name[ix];
187  std::map<std::string, int>::iterator iter = using_joint_name_.find(joint_name);
188 
189  if (iter != using_joint_name_.end())
190  {
191  // set target position
192  target_position_.coeffRef(0, iter->second) = msg->position[ix];
193 
194  // set time
195  int calc_moving_time = fabs(goal_position_.coeff(0, iter->second) - target_position_.coeff(0, iter->second))
196  / 0.45;
197  if (calc_moving_time > moving_time_)
198  moving_time_ = calc_moving_time;
199 
200  if (DEBUG)
201  {
202  std::cout << "joint : " << joint_name << ", Index : " << iter->second << ", Angle : " << msg->position[ix]
203  << ", Time : " << moving_time_ << std::endl;
204  }
205  }
206  }
207 
208  // set init joint vel, accel
209  goal_velocity_ = Eigen::MatrixXd::Zero(1, result_.size());
210  goal_acceleration_ = Eigen::MatrixXd::Zero(1, result_.size());
211 
212  if (is_moving_ == true && is_direct_control_ == true)
213  {
214  goal_velocity_ = calc_joint_vel_tra_.block(tra_count_, 0, 1, result_.size());
215  goal_acceleration_ = calc_joint_accel_tra_.block(tra_count_, 0, 1, result_.size());
216  }
217 
218  // set mode
219  is_direct_control_ = true;
220 
221  // generate trajectory
222  tra_gene_thread_ = new boost::thread(boost::bind(&HeadControlModule::jointTraGeneThread, this));
223  delete tra_gene_thread_;
224 }
225 
226 void HeadControlModule::setHeadJointTimeCallback(const thormang3_head_control_module_msgs::HeadJointPose::ConstPtr &msg)
227 {
228  if (enable_ == false)
229  {
230  ROS_INFO("Head module is not enable.");
231  publishStatusMsg(robotis_controller_msgs::StatusMsg::STATUS_ERROR, "Not Enable");
232  publishDoneMsg("head_control_failed");
233  return;
234  }
235 
236  if (is_moving_ == true && is_direct_control_ == false)
237  {
238  ROS_INFO("Head is moving now.");
239  publishStatusMsg(robotis_controller_msgs::StatusMsg::STATUS_ERROR, "Head is busy.");
240  publishDoneMsg("head_control_failed");
241  return;
242  }
243 
244  // moving time
245  moving_time_ = msg->mov_time;
246 
247  // set target joint angle
248  target_position_ = goal_position_; // default
249 
250  for (int ix = 0; ix < msg->angle.name.size(); ix++)
251  {
252  std::string joint_name = msg->angle.name[ix];
253  std::map<std::string, int>::iterator iter = using_joint_name_.find(joint_name);
254 
255  if (iter != using_joint_name_.end())
256  {
257  // set target position
258  target_position_.coeffRef(0, iter->second) = msg->angle.position[ix];
259 
260  // set time
261  int calc_moving_time = fabs(goal_position_.coeff(0, iter->second) - target_position_.coeff(0, iter->second))
262  / 0.45;
263  if (moving_time_ == 0)
264  moving_time_ = calc_moving_time;
265 
266  if (DEBUG)
267  {
268  std::cout << "joint : " << joint_name << ", Index : " << iter->second << ", Angle : " << msg->angle.position[ix]
269  << ", Time : " << moving_time_ << std::endl;
270  }
271  }
272  }
273 
274  // set init joint vel, accel
275  goal_velocity_ = Eigen::MatrixXd::Zero(1, result_.size());
276  goal_acceleration_ = Eigen::MatrixXd::Zero(1, result_.size());
277 
278  if (is_moving_ == true && is_direct_control_ == true)
279  {
280  goal_velocity_ = calc_joint_vel_tra_.block(tra_count_, 0, 1, result_.size());
281  goal_acceleration_ = calc_joint_accel_tra_.block(tra_count_, 0, 1, result_.size());
282  }
283 
284  // set mode
285  is_direct_control_ = true;
286 
287  // generate trajectory
288  tra_gene_thread_ = new boost::thread(boost::bind(&HeadControlModule::jointTraGeneThread, this));
289  delete tra_gene_thread_;
290 }
291 
292 void HeadControlModule::process(std::map<std::string, robotis_framework::Dynamixel *> dxls,
293  std::map<std::string, double> sensors)
294 {
295  if (enable_ == false)
296  return;
297 
298  tra_lock_.lock();
299 
300  // get joint data
301  for (std::map<std::string, robotis_framework::DynamixelState *>::iterator state_iter = result_.begin();
302  state_iter != result_.end(); state_iter++)
303  {
304  std::string joint_name = state_iter->first;
305  int index = using_joint_name_[joint_name];
306 
307  robotis_framework::Dynamixel *dxl = NULL;
308  std::map<std::string, robotis_framework::Dynamixel*>::iterator dxl_it = dxls.find(joint_name);
309  if (dxl_it != dxls.end())
310  dxl = dxl_it->second;
311  else
312  continue;
313 
314  current_position_.coeffRef(0, index) = dxl->dxl_state_->present_position_;
315  goal_position_.coeffRef(0, index) = dxl->dxl_state_->goal_position_;
316  }
317 
318  // check to stop
319  if (stop_process_ == true)
320  {
321  stopMoving();
322  }
323  else
324  {
325  // process
326  if (tra_size_ != 0)
327  {
328  // start of steps
329  if (tra_count_ == 0)
330  {
331  startMoving();
332  }
333 
334  // end of steps
335  if (tra_count_ >= tra_size_)
336  {
337  finishMoving();
338  }
339  else
340  {
341  goal_position_ = calc_joint_tra_.block(tra_count_, 0, 1, result_.size());
342  tra_count_ += 1;
343  }
344  }
345  }
346  tra_lock_.unlock();
347 
348  // set joint data
349  for (std::map<std::string, robotis_framework::DynamixelState *>::iterator state_iter = result_.begin();
350  state_iter != result_.end(); state_iter++)
351  {
352  std::string joint_name = state_iter->first;
353  int index = using_joint_name_[joint_name];
354 
355  result_[joint_name]->goal_position_ = goal_position_.coeff(0, index);
356  }
357 }
358 
360 {
361  tra_lock_.lock();
362 
363  if (is_moving_ == true)
364  stop_process_ = true;
365 
366  tra_lock_.unlock();
367 
368  return;
369 }
370 
372 {
373  return is_moving_;
374 }
375 
377 {
378  is_moving_ = true;
379 
380  // set current lidar mode
381  if (is_direct_control_ == false)
382  {
384  ROS_INFO_STREAM("state is changed : " << current_state_);
385 
386  if (current_state_ == StartMove)
387  publishLidarMoveMsg("start");
388  }
389 }
390 
392 {
393  // init value
395  tra_size_ = 0;
396  tra_count_ = 0;
397 
398  // handle lidar state
399  switch (current_state_)
400  {
401  case BeforeStart:
402  {
403  // generate start trajectory
404  double target_angle =
405  (scan_range_ == 0) ?
406  SCAN_END_ANGLE : current_position_.coeffRef(0, using_joint_name_["head_p"]) + scan_range_ * 2;
407  startMoveLidar(target_angle);
408  break;
409  }
410  case StartMove:
411  publishLidarMoveMsg("end");
413 
414  // generate next trajectory
415  afterMoveLidar();
416  break;
417 
418  case AfterMove:
420  is_direct_control_ = true;
421  is_moving_ = false;
422  scan_range_ = 0.0;
423  publishStatusMsg(robotis_controller_msgs::StatusMsg::STATUS_INFO,
424  "Finish head joint in order to make pointcloud");
425  break;
426 
427  default:
428  publishStatusMsg(robotis_controller_msgs::StatusMsg::STATUS_INFO, "Head movement is finished.");
429  is_moving_ = false;
430  publishDoneMsg("head_control");
431 
432  break;
433  }
434 
435  // is_direct_control_ = false;
436  if (DEBUG)
437  std::cout << "Trajectory End" << std::endl;
438 }
439 
441 {
442  // init value
444  tra_size_ = 0;
445  tra_count_ = 0;
446  is_moving_ = false;
447 
448  // handle lidar state
449  switch (current_state_)
450  {
451  case StartMove:
452  publishLidarMoveMsg("end");
453 
454  default:
455  // stop moving
457  is_direct_control_ = true;
458  break;
459  }
460 
461  publishStatusMsg(robotis_controller_msgs::StatusMsg::STATUS_WARN, "Stop Module.");
462  stop_process_ = false;
463 }
464 
465 void HeadControlModule::beforeMoveLidar(double start_angle)
466 {
467  // angle and moving time
469  moving_time_ = fabs(current_position_.coeffRef(0, using_joint_name_["head_p"]) - start_angle) / (30 * DEGREE2RADIAN);
470  double min_moving_time = 1.0;
471 
472  moving_time_ = (moving_time_ < min_moving_time) ? min_moving_time : moving_time_;
473 
474  // moving_time_ = 1.0;
475 
476  // set target joint angle : pitch
478  target_position_.coeffRef(0, using_joint_name_["head_p"]) = start_angle;
479 
480  // set init joint vel, accel
481  goal_velocity_ = Eigen::MatrixXd::Zero(1, result_.size());
482  goal_acceleration_ = Eigen::MatrixXd::Zero(1, result_.size());
483 
484  // generate trajectory
485  tra_gene_thread_ = new boost::thread(boost::bind(&HeadControlModule::jointTraGeneThread, this));
486  delete tra_gene_thread_;
487 
488  ROS_INFO("Go to Lidar start position");
489 }
490 
491 void HeadControlModule::startMoveLidar(double target_angle)
492 {
493  // angle and moving time
494  moving_time_ = fabs(current_position_.coeffRef(0, using_joint_name_["head_p"]) - target_angle) / (10 * DEGREE2RADIAN);
495  double max_moving_time = 8.0;
496 
497  moving_time_ = (moving_time_ < max_moving_time) ? moving_time_ : max_moving_time;
498 
499  // moving_time_ = 8.0; // 8 secs
500 
501  // set target joint angle
503  target_position_.coeffRef(0, using_joint_name_["head_p"]) = target_angle;
504 
505  // set init joint vel, accel
506  goal_velocity_ = Eigen::MatrixXd::Zero(1, result_.size());
507  goal_acceleration_ = Eigen::MatrixXd::Zero(1, result_.size());
508 
509  // generate trajectory
510  //tra_gene_thread_ = new boost::thread(boost::bind(&HeadControlModule::jointTraGeneThread, this));
511  tra_gene_thread_ = new boost::thread(boost::bind(&HeadControlModule::lidarJointTraGeneThread, this));
512  delete tra_gene_thread_;
513 
514  ROS_INFO("Go to Lidar end position");
515 }
516 
518 {
519  // angle and moving time
520  moving_time_ = 2.0;
521 
522  // set target joint angle : pitch
525 
526  // set init joint vel, accel
527  goal_velocity_ = Eigen::MatrixXd::Zero(1, result_.size());
528  goal_acceleration_ = Eigen::MatrixXd::Zero(1, result_.size());
529 
530  // generate trajectory
531  tra_gene_thread_ = new boost::thread(boost::bind(&HeadControlModule::jointTraGeneThread, this));
532  delete tra_gene_thread_;
533 
534  ROS_INFO("Go to Lidar before position");
535 }
536 
537 void HeadControlModule::publishLidarMoveMsg(std::string msg_data)
538 {
539  std_msgs::String msg;
540  msg.data = msg_data;
541 
543 
544  if (msg_data == "end")
545  publishDoneMsg("scan");
546 }
547 
548 /*
549  simple minimum jerk trajectory
550 
551  pos_start : position at initial state
552  vel_start : velocity at initial state
553  accel_start : acceleration at initial state
554 
555  pos_end : position at final state
556  vel_end : velocity at final state
557  accel_end : acceleration at final state
558 
559  smp_time : sampling time
560 
561  mov_time : movement time
562  */
563 Eigen::MatrixXd HeadControlModule::calcMinimumJerkTraPVA(double pos_start, double vel_start, double accel_start,
564  double pos_end, double vel_end, double accel_end,
565  double smp_time, double mov_time)
566 {
567  Eigen::MatrixXd poly_matrix(3, 3);
568  Eigen::MatrixXd poly_vector(3, 1);
569 
570  poly_matrix << robotis_framework::powDI(mov_time, 3), robotis_framework::powDI(mov_time, 4), robotis_framework::powDI(
571  mov_time, 5), 3 * robotis_framework::powDI(mov_time, 2), 4 * robotis_framework::powDI(mov_time, 3), 5
572  * robotis_framework::powDI(mov_time, 4), 6 * mov_time, 12 * robotis_framework::powDI(mov_time, 2), 20
573  * robotis_framework::powDI(mov_time, 3);
574 
575  poly_vector << pos_end - pos_start - vel_start * mov_time - accel_start * pow(mov_time, 2) / 2, vel_end - vel_start
576  - accel_start * mov_time, accel_end - accel_start;
577 
578  Eigen::MatrixXd poly_coeff = poly_matrix.inverse() * poly_vector;
579 
580  int all_time_steps = round(mov_time / smp_time + 1);
581 
582  Eigen::MatrixXd time = Eigen::MatrixXd::Zero(all_time_steps, 1);
583  Eigen::MatrixXd minimum_jer_tra = Eigen::MatrixXd::Zero(all_time_steps, 3);
584 
585  for (int step = 0; step < all_time_steps; step++)
586  time.coeffRef(step, 0) = step * smp_time;
587 
588  for (int step = 0; step < all_time_steps; step++)
589  {
590  // position
591  minimum_jer_tra.coeffRef(step, 0) = pos_start + vel_start * time.coeff(step, 0)
592  + 0.5 * accel_start * robotis_framework::powDI(time.coeff(step, 0), 2)
593  + poly_coeff.coeff(0, 0) * robotis_framework::powDI(time.coeff(step, 0), 3)
594  + poly_coeff.coeff(1, 0) * robotis_framework::powDI(time.coeff(step, 0), 4)
595  + poly_coeff.coeff(2, 0) * robotis_framework::powDI(time.coeff(step, 0), 5);
596  // velocity
597  minimum_jer_tra.coeffRef(step, 1) = vel_start + accel_start * time.coeff(step, 0)
598  + 3 * poly_coeff.coeff(0, 0) * robotis_framework::powDI(time.coeff(step, 0), 2)
599  + 4 * poly_coeff.coeff(1, 0) * robotis_framework::powDI(time.coeff(step, 0), 3)
600  + 5 * poly_coeff.coeff(2, 0) * robotis_framework::powDI(time.coeff(step, 0), 4);
601  // accel
602  minimum_jer_tra.coeffRef(step, 2) = accel_start + 6 * poly_coeff.coeff(0, 0) * time.coeff(step, 0)
603  + 12 * poly_coeff.coeff(1, 0) * robotis_framework::powDI(time.coeff(step, 0), 2)
604  + 20 * poly_coeff.coeff(2, 0) * robotis_framework::powDI(time.coeff(step, 0), 3);
605  }
606 
607  return minimum_jer_tra;
608 }
609 
610 Eigen::MatrixXd HeadControlModule::calcLinearInterpolationTra(double pos_start, double pos_end, double smp_time,
611  double mov_time)
612 {
613  double time_steps = mov_time / smp_time;
614  int all_time_steps = round(time_steps + 1);
615  double next_step = (pos_end - pos_start) / all_time_steps;
616 
617  Eigen::MatrixXd minimum_jerk_tra = Eigen::MatrixXd::Zero(all_time_steps, 1);
618 
619  for (int step = 0; step < all_time_steps; step++)
620  minimum_jerk_tra.coeffRef(step, 0) = pos_start + next_step * (step + 1);
621 
622  return minimum_jerk_tra;
623 }
624 
626 {
627  tra_lock_.lock();
628 
629  double smp_time = control_cycle_msec_ * 0.001; // ms -> s
630  int all_time_steps = int(moving_time_ / smp_time) + 1;
631 
632  calc_joint_tra_.resize(all_time_steps, result_.size());
633  calc_joint_vel_tra_.resize(all_time_steps, result_.size());
634  calc_joint_accel_tra_.resize(all_time_steps, result_.size());
635 
636  for (std::map<std::string, robotis_framework::DynamixelState *>::iterator state_iter = result_.begin();
637  state_iter != result_.end(); state_iter++)
638  {
639  std::string joint_name = state_iter->first;
640  int index = using_joint_name_[joint_name];
641 
642  double ini_value = goal_position_.coeff(0, index);
643  double ini_vel = goal_velocity_.coeff(0, index);
644  double ini_accel = goal_acceleration_.coeff(0, index);
645 
646  double tar_value = target_position_.coeff(0, index);
647 
648  Eigen::MatrixXd tra = calcMinimumJerkTraPVA(ini_value, ini_vel, ini_accel, tar_value, 0.0, 0.0, smp_time,
649  moving_time_);
650 
651  calc_joint_tra_.block(0, index, all_time_steps, 1) = tra.block(0, 0, all_time_steps, 1);
652  calc_joint_vel_tra_.block(0, index, all_time_steps, 1) = tra.block(0, 1, all_time_steps, 1);
653  calc_joint_accel_tra_.block(0, index, all_time_steps, 1) = tra.block(0, 2, all_time_steps, 1);
654  }
655 
656  tra_size_ = calc_joint_tra_.rows();
657  tra_count_ = 0;
658 
659  if (DEBUG)
660  ROS_INFO("[ready] make trajectory : %d, %d", tra_size_, tra_count_);
661 
662  // init value
663  // moving_time_ = 0;
664 
665  tra_lock_.unlock();
666 }
667 
669 {
670  tra_lock_.lock();
671 
672  double smp_time = control_cycle_msec_ * 0.001; // ms -> s
673  int all_time_steps = int(moving_time_ / smp_time) + 1;
674 
675  calc_joint_tra_.resize(all_time_steps, result_.size());
676 
677  for (std::map<std::string, robotis_framework::DynamixelState *>::iterator state_iter = result_.begin();
678  state_iter != result_.end(); state_iter++)
679  {
680  std::string joint_name = state_iter->first;
681  int index = using_joint_name_[joint_name];
682 
683  double ini_value = goal_position_.coeff(0, index);
684  double tar_value = target_position_.coeff(0, index);
685 
686  Eigen::MatrixXd tra = calcLinearInterpolationTra(ini_value, tar_value, smp_time, moving_time_);
687 
688  calc_joint_tra_.block(0, index, all_time_steps, 1) = tra.block(0, 0, all_time_steps, 1);
689  }
690 
691  tra_size_ = calc_joint_tra_.rows();
692  tra_count_ = 0;
693 
694  if (DEBUG)
695  ROS_INFO("[ready] make trajectory : %d, %d", tra_size_, tra_count_);
696 
697  // init value
698  // moving_time_ = 0;
699 
700  tra_lock_.unlock();
701 }
702 
703 void HeadControlModule::publishStatusMsg(unsigned int type, std::string msg)
704 {
705  robotis_controller_msgs::StatusMsg status_msg;
706  status_msg.header.stamp = ros::Time::now();
707  status_msg.type = type;
708  status_msg.module_name = "Head Control";
709  status_msg.status_msg = msg;
710 
711  status_msg_pub_.publish(status_msg);
712 }
713 
714 void HeadControlModule::publishDoneMsg(const std::string done_msg)
715 {
716  std_msgs::String movement_msg;
717  movement_msg.data = done_msg;
718  movement_done_pub_.publish(movement_msg);
719 }
void setHeadJointTimeCallback(const thormang3_head_control_module_msgs::HeadJointPose::ConstPtr &msg)
std::map< std::string, DynamixelState * > result_
void publish(const boost::shared_ptr< M > &message) const
std::map< std::string, int > using_joint_name_
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
Eigen::MatrixXd calcLinearInterpolationTra(double pos_start, double pos_end, double smp_time, double mov_time)
void publishDoneMsg(const std::string done_msg)
void startMoveLidar(double target_angle)
void get3DLidarCallback(const std_msgs::String::ConstPtr &msg)
#define ROS_INFO(...)
void setCallbackQueue(CallbackQueueInterface *queue)
#define DEGREE2RADIAN
Eigen::MatrixXd calcMinimumJerkTraPVA(double pos_start, double vel_start, double accel_start, double pos_end, double vel_end, double accel_end, double smp_time, double mov_time)
void setHeadJointCallback(const sensor_msgs::JointState::ConstPtr &msg)
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
double powDI(double a, int b)
#define ROS_INFO_STREAM(args)
void publishStatusMsg(unsigned int type, std::string msg)
DynamixelState * dxl_state_
static Time now()
bool ok() const
void initialize(const int control_cycle_msec, robotis_framework::Robot *robot)
void process(std::map< std::string, robotis_framework::Dynamixel * > dxls, std::map< std::string, double > sensors)
void publishLidarMoveMsg(std::string msg_data)
void get3DLidarRangeCallback(const std_msgs::Float64::ConstPtr &msg)
void beforeMoveLidar(double start_angle)


thormang3_head_control_module
Author(s): Zerom , SCH , Kayman
autogenerated on Mon Jun 10 2019 15:37:48