base_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  * ThorManipulation.cpp
19  *
20  * Created on: 2016. 1. 18.
21  * Author: Zerom
22  */
23 
24 #include <stdio.h>
25 
27 
28 using namespace robotis_manipulator_h;
29 
31  : control_cycle_msec_(0)
32 {
33  enable_ = false;
34  module_name_ = "base_module";
36 
37  tra_gene_thread_ = NULL;
38 
45 
46  joint_name_to_id_["joint1"] = 1;
47  joint_name_to_id_["joint2"] = 2;
48  joint_name_to_id_["joint3"] = 3;
49  joint_name_to_id_["joint4"] = 4;
50  joint_name_to_id_["joint5"] = 5;
51  joint_name_to_id_["joint6"] = 6;
52 
53  robotis_ = new RobotisState();
56 }
57 
59 {
60  queue_thread_.join();
61 }
62 
63 void BaseModule::initialize(const int control_cycle_msec, robotis_framework::Robot *robot)
64 {
65  control_cycle_msec_ = control_cycle_msec;
66  queue_thread_ = boost::thread(boost::bind(&BaseModule::queueThread, this));
67 }
68 
69 void BaseModule::parseIniPoseData(const std::string &path)
70 {
71  YAML::Node doc;
72  try
73  {
74  // load yaml
75  doc = YAML::LoadFile(path.c_str());
76  } catch (const std::exception& e)
77  {
78  ROS_ERROR("Fail to load yaml file.");
79  return;
80  }
81 
82  // parse movement time
83  double _mov_time;
84  _mov_time = doc["mov_time"].as<double>();
85 
86  robotis_->mov_time_ = _mov_time;
87 
88  // parse target pose
89  YAML::Node _tar_pose_node = doc["tar_pose"];
90  for (YAML::iterator _it = _tar_pose_node.begin(); _it != _tar_pose_node.end(); ++_it)
91  {
92  int _id;
93  double _value;
94 
95  _id = _it->first.as<int>();
96  _value = _it->second.as<double>();
97 
98  robotis_->joint_ini_pose_.coeffRef(_id, 0) = _value * DEGREE2RADIAN;
99  }
100 
103 }
104 
106 {
107  ros::NodeHandle ros_node;
108  ros::CallbackQueue callback_queue;
109 
110  ros_node.setCallbackQueue(&callback_queue);
111 
112  /* publish topics */
113  status_msg_pub_ = ros_node.advertise<robotis_controller_msgs::StatusMsg>("/robotis/status", 1);
114  set_ctrl_module_pub_ = ros_node.advertise<std_msgs::String>("/robotis/enable_ctrl_module", 1);
115 
116  /* subscribe topics */
117  ros::Subscriber ini_pose_msg_sub = ros_node.subscribe("/robotis/base/ini_pose_msg", 5,
119  ros::Subscriber set_mode_msg_sub = ros_node.subscribe("/robotis/base/set_mode_msg", 5,
121 
122  ros::Subscriber joint_pose_msg_sub = ros_node.subscribe("/robotis/base/joint_pose_msg", 5,
124  ros::Subscriber kinematics_pose_msg_sub = ros_node.subscribe("/robotis/base/kinematics_pose_msg", 5,
126 
127  ros::ServiceServer get_joint_pose_server = ros_node.advertiseService("/robotis/base/get_joint_pose",
129  ros::ServiceServer get_kinematics_pose_server = ros_node.advertiseService("/robotis/base/get_kinematics_pose",
131 
132  while (ros_node.ok())
133  {
134  callback_queue.callAvailable();
135  usleep(1000);
136  }
137 }
138 
139 void BaseModule::initPoseMsgCallback(const std_msgs::String::ConstPtr& msg)
140 {
141  if (enable_ == false)
142  return;
143 
144  if (robotis_->is_moving_ == false)
145  {
146  if (msg->data == "ini_pose")
147  {
148  // parse initial pose
149  std::string ini_pose_path = ros::package::getPath("manipulator_h_base_module") + "/config/ini_pose.yaml";
150  parseIniPoseData(ini_pose_path);
151 
152  tra_gene_thread_ = new boost::thread(boost::bind(&BaseModule::generateInitPoseTrajProcess, this));
153  delete tra_gene_thread_;
154  }
155  }
156  else
157  {
158  ROS_INFO("previous task is alive");
159  }
160 
161  return;
162 }
163 
164 void BaseModule::setModeMsgCallback(const std_msgs::String::ConstPtr& msg)
165 {
166  std_msgs::String str_msg;
167  str_msg.data = "base_module";
168 
169  set_ctrl_module_pub_.publish(str_msg);
170 
171  return;
172 }
173 
174 bool BaseModule::getJointPoseCallback(manipulator_h_base_module_msgs::GetJointPose::Request &req,
175  manipulator_h_base_module_msgs::GetJointPose::Response &res)
176 {
177  if (enable_ == false)
178  return false;
179 
180  for (int id = 1; id <= MAX_JOINT_ID; id++)
181  {
182  for (int name_index = 0; name_index < req.joint_name.size(); name_index++)
183  {
184  if (manipulator_->manipulator_link_data_[id]->name_ == req.joint_name[name_index])
185  {
186  res.joint_name.push_back(manipulator_->manipulator_link_data_[id]->name_);
187  res.joint_value.push_back(joint_state_->goal_joint_state_[id].position_);
188 
189  break;
190  }
191  }
192  }
193 
194  return true;
195 }
196 
197 bool BaseModule::getKinematicsPoseCallback(manipulator_h_base_module_msgs::GetKinematicsPose::Request &req,
198  manipulator_h_base_module_msgs::GetKinematicsPose::Response &res)
199 {
200  if (enable_ == false)
201  return false;
202 
203  res.group_pose.position.x = manipulator_->manipulator_link_data_[END_LINK]->position_.coeff(0, 0);
204  res.group_pose.position.y = manipulator_->manipulator_link_data_[END_LINK]->position_.coeff(1, 0);
205  res.group_pose.position.z = manipulator_->manipulator_link_data_[END_LINK]->position_.coeff(2, 0);
206 
208 
209  res.group_pose.orientation.w = quaternion.w();
210  res.group_pose.orientation.x = quaternion.x();
211  res.group_pose.orientation.y = quaternion.y();
212  res.group_pose.orientation.z = quaternion.z();
213 
214  return true;
215 }
216 
217 void BaseModule::kinematicsPoseMsgCallback(const manipulator_h_base_module_msgs::KinematicsPose::ConstPtr& msg)
218 {
219  if (enable_ == false)
220  return;
221 
223 
224  robotis_->ik_id_start_ = 0;
226 
227  if (robotis_->is_moving_ == false)
228  {
229  tra_gene_thread_ = new boost::thread(boost::bind(&BaseModule::generateTaskTrajProcess, this));
230  delete tra_gene_thread_;
231  }
232  else
233  {
234  ROS_INFO("previous task is alive");
235  }
236 
237  return;
238 }
239 
240 void BaseModule::jointPoseMsgCallback(const manipulator_h_base_module_msgs::JointPose::ConstPtr& msg)
241 {
242  if (enable_ == false)
243  return;
244 
245  robotis_->joint_pose_msg_ = *msg;
246 
247  if (robotis_->is_moving_ == false)
248  {
249  tra_gene_thread_ = new boost::thread(boost::bind(&BaseModule::generateJointTrajProcess, this));
250  delete tra_gene_thread_;
251  }
252  else
253  {
254  ROS_INFO("previous task is alive");
255  }
256 
257  return;
258 }
259 
261 {
262  if (enable_ == false)
263  return;
264 
265  for (int id = 1; id <= MAX_JOINT_ID; id++)
266  {
267  double ini_value = joint_state_->goal_joint_state_[id].position_;
268  double tar_value = robotis_->joint_ini_pose_.coeff(id, 0);
269 
270  Eigen::MatrixXd tra = robotis_framework::calcMinimumJerkTra(ini_value, 0.0, 0.0, tar_value, 0.0, 0.0,
272 
273  robotis_->calc_joint_tra_.block(0, id, robotis_->all_time_steps_, 1) = tra;
274  }
275 
276  robotis_->cnt_ = 0;
277  robotis_->is_moving_ = true;
278 
279  ROS_INFO("[start] send trajectory");
280  publishStatusMsg(robotis_controller_msgs::StatusMsg::STATUS_INFO, "Start Trajectory");
281 }
282 
284 {
285  if (enable_ == false)
286  return;
287 
288  /* set movement time */
289  double tol = 35 * DEGREE2RADIAN; // rad per sec
290  double mov_time = 2.0;
291 
292  double max_diff, abs_diff;
293  max_diff = 0.0;
294 
295  for (int name_index = 0; name_index < robotis_->joint_pose_msg_.name.size(); name_index++)
296  {
297  double ini_value;
298  double tar_value;
299 
300  for (int id = 1; id <= MAX_JOINT_ID; id++)
301  {
302  if (manipulator_->manipulator_link_data_[id]->name_ == robotis_->joint_pose_msg_.name[name_index])
303  {
304  ini_value = joint_state_->goal_joint_state_[id].position_;
305  tar_value = robotis_->joint_pose_msg_.value[name_index];
306 
307  break;
308  }
309  }
310 
311  abs_diff = fabs(tar_value - ini_value);
312 
313  if (max_diff < abs_diff)
314  max_diff = abs_diff;
315  }
316 
317  robotis_->mov_time_ = max_diff / tol;
318  int all_time_steps = int(floor((robotis_->mov_time_ / robotis_->smp_time_) + 1.0));
319  robotis_->mov_time_ = double(all_time_steps - 1) * robotis_->smp_time_;
320 
321  if (robotis_->mov_time_ < mov_time)
322  robotis_->mov_time_ = mov_time;
323 
325 
327 
328  /* calculate joint trajectory */
329  for (int id = 1; id <= MAX_JOINT_ID; id++)
330  {
331  double ini_value = joint_state_->goal_joint_state_[id].position_;
332  double tar_value;
333 
334  for (int name_index = 0; name_index < robotis_->joint_pose_msg_.name.size(); name_index++)
335  {
336  if (manipulator_->manipulator_link_data_[id]->name_ == robotis_->joint_pose_msg_.name[name_index])
337  {
338  tar_value = robotis_->joint_pose_msg_.value[name_index];
339  break;
340  }
341  }
342 
343  Eigen::MatrixXd tra = robotis_framework::calcMinimumJerkTra(ini_value, 0.0, 0.0, tar_value, 0.0, 0.0,
345 
346  robotis_->calc_joint_tra_.block(0, id, robotis_->all_time_steps_, 1) = tra;
347  }
348 
349  robotis_->cnt_ = 0;
350  robotis_->is_moving_ = true;
351 
352  ROS_INFO("[start] send trajectory");
353  publishStatusMsg(robotis_controller_msgs::StatusMsg::STATUS_INFO, "Start Trajectory");
354 }
355 
357 {
358  /* set movement time */
359  double tol = 0.1; // m per sec
360  double mov_time = 2.0;
361 
362  double diff = sqrt(
364  - robotis_->kinematics_pose_msg_.pose.position.x, 2)
366  - robotis_->kinematics_pose_msg_.pose.position.y, 2)
368  - robotis_->kinematics_pose_msg_.pose.position.z, 2)
369  );
370 
371  robotis_->mov_time_ = diff / tol;
372  int all_time_steps = int(floor((robotis_->mov_time_ / robotis_->smp_time_) + 1.0));
373  robotis_->mov_time_ = double(all_time_steps - 1) * robotis_->smp_time_;
374 
375  if (robotis_->mov_time_ < mov_time)
376  robotis_->mov_time_ = mov_time;
377 
379 
381 
382  /* calculate trajectory */
383  for (int dim = 0; dim < 3; dim++)
384  {
385  double ini_value = manipulator_->manipulator_link_data_[robotis_->ik_id_end_]->position_.coeff(dim, 0);
386  double tar_value;
387 
388  if (dim == 0)
389  tar_value = robotis_->kinematics_pose_msg_.pose.position.x;
390  else if (dim == 1)
391  tar_value = robotis_->kinematics_pose_msg_.pose.position.y;
392  else if (dim == 2)
393  tar_value = robotis_->kinematics_pose_msg_.pose.position.z;
394 
395  Eigen::MatrixXd tra = robotis_framework::calcMinimumJerkTra(ini_value, 0.0, 0.0, tar_value, 0.0, 0.0,
397 
398  robotis_->calc_task_tra_.block(0, dim, robotis_->all_time_steps_, 1) = tra;
399  }
400 
401  robotis_->cnt_ = 0;
402  robotis_->is_moving_ = true;
403  robotis_->ik_solve_ = true;
404 
405  ROS_INFO("[start] send trajectory");
406  publishStatusMsg(robotis_controller_msgs::StatusMsg::STATUS_INFO, "Start Trajectory");
407 }
408 
409 void BaseModule::process(std::map<std::string, robotis_framework::Dynamixel *> dxls,
410  std::map<std::string, double> sensors)
411 {
412  if (enable_ == false)
413  return;
414 
415  /*----- write curr position -----*/
416 
417  for (std::map<std::string, robotis_framework::DynamixelState *>::iterator state_iter = result_.begin();
418  state_iter != result_.end(); state_iter++)
419  {
420  std::string joint_name = state_iter->first;
421 
422  robotis_framework::Dynamixel *dxl = NULL;
423  std::map<std::string, robotis_framework::Dynamixel*>::iterator dxl_it = dxls.find(joint_name);
424  if (dxl_it != dxls.end())
425  dxl = dxl_it->second;
426  else
427  continue;
428 
429  double joint_curr_position = dxl->dxl_state_->present_position_;
430  double joint_goal_position = dxl->dxl_state_->goal_position_;
431 
432  joint_state_->curr_joint_state_[joint_name_to_id_[joint_name]].position_ = joint_curr_position;
433  joint_state_->goal_joint_state_[joint_name_to_id_[joint_name]].position_ = joint_goal_position;
434  }
435 
436  /*----- forward kinematics -----*/
437 
438  for (int id = 1; id <= MAX_JOINT_ID; id++)
440 
442 
443  /* ----- send trajectory ----- */
444 
445 // ros::Time time = ros::Time::now();
446  if (robotis_->is_moving_ == true)
447  {
448  if (robotis_->cnt_ == 0)
450 
451  if (robotis_->ik_solve_ == true)
452  {
454 
455  int max_iter = 30;
456  double ik_tol = 1e-3;
459 
460  if (ik_success == true)
461  {
462  for (int id = 1; id <= MAX_JOINT_ID; id++)
464  }
465  else
466  {
467  ROS_INFO("[end] send trajectory (ik failed)");
468  publishStatusMsg(robotis_controller_msgs::StatusMsg::STATUS_INFO, "End Trajectory (IK Failed)");
469 
470  robotis_->is_moving_ = false;
471  robotis_->ik_solve_ = false;
472  robotis_->cnt_ = 0;
473  }
474  }
475  else
476  {
477  for (int id = 1; id <= MAX_JOINT_ID; id++)
479  }
480 
481  robotis_->cnt_++;
482  }
483 
484  /*----- set joint data -----*/
485 
486  for (std::map<std::string, robotis_framework::DynamixelState *>::iterator state_iter = result_.begin();
487  state_iter != result_.end(); state_iter++)
488  {
489  std::string joint_name = state_iter->first;
490  result_[joint_name]->goal_position_ = joint_state_->goal_joint_state_[joint_name_to_id_[joint_name]].position_;
491  }
492 
493  /*---------- initialize count number ----------*/
494 
496  {
497  ROS_INFO("[end] send trajectory");
498  publishStatusMsg(robotis_controller_msgs::StatusMsg::STATUS_INFO, "End Trajectory");
499 
500  robotis_->is_moving_ = false;
501  robotis_->ik_solve_ = false;
502  robotis_->cnt_ = 0;
503  }
504 }
505 
507 {
508  robotis_->is_moving_ = false;
509  robotis_->ik_solve_ = false;
510  robotis_->cnt_ = 0;
511 
512  return;
513 }
514 
516 {
517  return robotis_->is_moving_;
518 }
519 
520 void BaseModule::publishStatusMsg(unsigned int type, std::string msg)
521 {
522  robotis_controller_msgs::StatusMsg status;
523  status.header.stamp = ros::Time::now();
524  status.type = type;
525  status.module_name = "Base";
526  status.status_msg = msg;
527 
528  status_msg_pub_.publish(status);
529 }
void initialize(const int control_cycle_msec, robotis_framework::Robot *robot)
Definition: base_module.cpp:63
bool inverseKinematics(int to, Eigen::MatrixXd tar_position, Eigen::MatrixXd tar_orientation, int max_iter, double ik_err)
std::map< std::string, DynamixelState * > result_
Eigen::MatrixXd calcMinimumJerkTra(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 publish(const boost::shared_ptr< M > &message) const
BaseJointData curr_joint_state_[MAX_JOINT_ID+1]
Definition: base_module.h:73
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
Eigen::Quaterniond convertRotationToQuaternion(const Eigen::Matrix3d &rotation)
void kinematicsPoseMsgCallback(const manipulator_h_base_module_msgs::KinematicsPose::ConstPtr &msg)
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
void setInverseKinematics(int cnt, Eigen::MatrixXd start_rotation)
void parseIniPoseData(const std::string &path)
Definition: base_module.cpp:69
void setModeMsgCallback(const std_msgs::String::ConstPtr &msg)
void jointPoseMsgCallback(const manipulator_h_base_module_msgs::JointPose::ConstPtr &msg)
manipulator_h_base_module_msgs::JointPose joint_pose_msg_
Definition: robotis_state.h:54
#define MAX_JOINT_ID
bool getJointPoseCallback(manipulator_h_base_module_msgs::GetJointPose::Request &req, manipulator_h_base_module_msgs::GetJointPose::Response &res)
#define ROS_INFO(...)
void setCallbackQueue(CallbackQueueInterface *queue)
#define DEGREE2RADIAN
manipulator_h_base_module_msgs::KinematicsPose kinematics_pose_msg_
Definition: robotis_state.h:55
void publishStatusMsg(unsigned int type, std::string msg)
std::map< std::string, int > joint_name_to_id_
Definition: base_module.h:90
ManipulatorKinematicsDynamics * manipulator_
Definition: base_module.h:128
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
ROSLIB_DECL std::string getPath(const std::string &package_name)
void initPoseMsgCallback(const std_msgs::String::ConstPtr &msg)
DynamixelState * dxl_state_
static Time now()
bool ok() const
bool getKinematicsPoseCallback(manipulator_h_base_module_msgs::GetKinematicsPose::Request &req, manipulator_h_base_module_msgs::GetKinematicsPose::Response &res)
#define ROS_ERROR(...)
void process(std::map< std::string, robotis_framework::Dynamixel * > dxls, std::map< std::string, double > sensors)
#define END_LINK
BaseJointData goal_joint_state_[MAX_JOINT_ID+1]
Definition: base_module.h:74


manipulator_h_base_module
Author(s): SCH
autogenerated on Mon Jun 10 2019 14:02:58