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>
26 
27 #define EXT_PORT_DATA_1 "external_port_data_1"
28 #define EXT_PORT_DATA_2 "external_port_data_2"
29 #define EXT_PORT_DATA_3 "external_port_data_3"
30 #define EXT_PORT_DATA_4 "external_port_data_4"
31 
32 using namespace thormang3;
33 
35  : control_cycle_msec_(0),
36  has_goal_joints_(false),
37  ini_pose_only_(false)
38 {
39  enable_ = false;
40  module_name_ = "base_module";
42 
43  /* arm */
44  result_["r_arm_sh_p1"] = new robotis_framework::DynamixelState();
45  result_["l_arm_sh_p1"] = new robotis_framework::DynamixelState();
46  result_["r_arm_sh_r"] = new robotis_framework::DynamixelState();
47  result_["l_arm_sh_r"] = new robotis_framework::DynamixelState();
48  result_["r_arm_sh_p2"] = new robotis_framework::DynamixelState();
49  result_["l_arm_sh_p2"] = new robotis_framework::DynamixelState();
50  result_["r_arm_el_y"] = new robotis_framework::DynamixelState();
51  result_["l_arm_el_y"] = new robotis_framework::DynamixelState();
52  result_["r_arm_wr_r"] = new robotis_framework::DynamixelState();
53  result_["l_arm_wr_r"] = new robotis_framework::DynamixelState();
54  result_["r_arm_wr_y"] = new robotis_framework::DynamixelState();
55  result_["l_arm_wr_y"] = new robotis_framework::DynamixelState();
56  result_["r_arm_wr_p"] = new robotis_framework::DynamixelState();
57  result_["l_arm_wr_p"] = new robotis_framework::DynamixelState();
58 
59  /* gripper */
60  result_["r_arm_grip"] = new robotis_framework::DynamixelState();
61  result_["l_arm_grip"] = new robotis_framework::DynamixelState();
62 
63  /* body */
64  result_["torso_y"] = new robotis_framework::DynamixelState();
65 
66  /* leg */
67  result_["r_leg_hip_y"] = new robotis_framework::DynamixelState();
68  result_["r_leg_hip_r"] = new robotis_framework::DynamixelState();
69  result_["r_leg_hip_p"] = new robotis_framework::DynamixelState();
70  result_["r_leg_kn_p"] = new robotis_framework::DynamixelState();
71  result_["r_leg_an_p"] = new robotis_framework::DynamixelState();
72  result_["r_leg_an_r"] = new robotis_framework::DynamixelState();
73 
74  result_["l_leg_hip_y"] = new robotis_framework::DynamixelState();
75  result_["l_leg_hip_r"] = new robotis_framework::DynamixelState();
76  result_["l_leg_hip_p"] = new robotis_framework::DynamixelState();
77  result_["l_leg_kn_p"] = new robotis_framework::DynamixelState();
78  result_["l_leg_an_p"] = new robotis_framework::DynamixelState();
79  result_["l_leg_an_r"] = new robotis_framework::DynamixelState();
80 
81  /* head */
84 
85  /* arm */
86  joint_name_to_id_["r_arm_sh_p1"] = 1;
87  joint_name_to_id_["l_arm_sh_p1"] = 2;
88  joint_name_to_id_["r_arm_sh_r"] = 3;
89  joint_name_to_id_["l_arm_sh_r"] = 4;
90  joint_name_to_id_["r_arm_sh_p2"] = 5;
91  joint_name_to_id_["l_arm_sh_p2"] = 6;
92  joint_name_to_id_["r_arm_el_y"] = 7;
93  joint_name_to_id_["l_arm_el_y"] = 8;
94  joint_name_to_id_["r_arm_wr_r"] = 9;
95  joint_name_to_id_["l_arm_wr_r"] = 10;
96  joint_name_to_id_["r_arm_wr_y"] = 11;
97  joint_name_to_id_["l_arm_wr_y"] = 12;
98  joint_name_to_id_["r_arm_wr_p"] = 13;
99  joint_name_to_id_["l_arm_wr_p"] = 14;
100 
101  /* leg */
102  joint_name_to_id_["r_leg_hip_y"] = 15;
103  joint_name_to_id_["l_leg_hip_y"] = 16;
104  joint_name_to_id_["r_leg_hip_r"] = 17;
105  joint_name_to_id_["l_leg_hip_r"] = 18;
106  joint_name_to_id_["r_leg_hip_p"] = 19;
107  joint_name_to_id_["l_leg_hip_p"] = 20;
108  joint_name_to_id_["r_leg_kn_p"] = 21;
109  joint_name_to_id_["l_leg_kn_p"] = 22;
110  joint_name_to_id_["r_leg_an_p"] = 23;
111  joint_name_to_id_["l_leg_an_p"] = 24;
112  joint_name_to_id_["r_leg_an_r"] = 25;
113  joint_name_to_id_["l_leg_an_r"] = 26;
114 
115  /* body */
116  joint_name_to_id_["torso_y"] = 27;
117 
118  /* head */
119  joint_name_to_id_["head_y"] = 28;
120  joint_name_to_id_["head_p"] = 29;
121 
122  /* gripper */
123  joint_name_to_id_["r_arm_grip"] = 31;
124  joint_name_to_id_["l_arm_grip"] = 30;
125 
128 }
129 
131 {
132  queue_thread_.join();
133 }
134 
135 void BaseModule::initialize(const int control_cycle_msec, robotis_framework::Robot *robot)
136 {
137  control_cycle_msec_ = control_cycle_msec;
138  queue_thread_ = boost::thread(boost::bind(&BaseModule::queueThread, this));
139 
140  ros::NodeHandle ros_node;
141 
142  /* publish topics */
143  status_msg_pub_ = ros_node.advertise<robotis_controller_msgs::StatusMsg>("/robotis/status", 1);
144  set_ctrl_module_pub_ = ros_node.advertise<std_msgs::String>("/robotis/enable_ctrl_module", 1);
145 
146  movement_done_pub_ = ros_node.advertise<std_msgs::String>("/robotis/movement_done", 1);
147 }
148 
149 void BaseModule::parseIniPoseData(const std::string &path)
150 {
151  YAML::Node doc;
152  try
153  {
154  // load yaml
155  doc = YAML::LoadFile(path.c_str());
156  } catch (const std::exception& e)
157  {
158  ROS_ERROR("Fail to load yaml file.");
159  return;
160  }
161 
162  // parse movement time
163  double mov_time;
164  mov_time = doc["mov_time"].as<double>();
165 
166  base_module_state_->mov_time_ = mov_time;
167 
168  // parse via-point number
169  int via_num;
170  via_num = doc["via_num"].as<int>();
171 
172  base_module_state_->via_num_ = via_num;
173 
174  // parse via-point time
175  std::vector<double> via_time;
176  via_time = doc["via_time"].as<std::vector<double> >();
177 
178  base_module_state_->via_time_.resize(via_num, 1);
179  for (int num = 0; num < via_num; num++)
180  base_module_state_->via_time_.coeffRef(num, 0) = via_time[num];
181 
182  // parse via-point pose
183  base_module_state_->joint_via_pose_.resize(via_num, MAX_JOINT_ID + 1);
184  base_module_state_->joint_via_dpose_.resize(via_num, MAX_JOINT_ID + 1);
185  base_module_state_->joint_via_ddpose_.resize(via_num, MAX_JOINT_ID + 1);
186 
190 
191  YAML::Node via_pose_node = doc["via_pose"];
192  for (YAML::iterator it = via_pose_node.begin(); it != via_pose_node.end(); ++it)
193  {
194  int id;
195  std::vector<double> value;
196 
197  id = it->first.as<int>();
198  value = it->second.as<std::vector<double> >();
199 
200  for (int num = 0; num < via_num; num++)
201  base_module_state_->joint_via_pose_.coeffRef(num, id) = value[num] * DEGREE2RADIAN;
202  }
203 
204  // parse target pose
205  YAML::Node tar_pose_node = doc["tar_pose"];
206  for (YAML::iterator it = tar_pose_node.begin(); it != tar_pose_node.end(); ++it)
207  {
208  int id;
209  double value;
210 
211  id = it->first.as<int>();
212  value = it->second.as<double>();
213 
214  base_module_state_->joint_ini_pose_.coeffRef(id, 0) = value * DEGREE2RADIAN;
215  }
216 
219 }
220 
222 {
223  ros::NodeHandle ros_node;
224  ros::CallbackQueue callback_queue;
225 
226  ros_node.setCallbackQueue(&callback_queue);
227 
228  /* subscribe topics */
229 
230  // for gui
231  ros::Subscriber ini_pose_msg_sub = ros_node.subscribe("/robotis/base/ini_pose", 5, &BaseModule::initPoseMsgCallback, this);
232 
233  ros::WallDuration duration(control_cycle_msec_ / 1000.0);
234  while(ros_node.ok())
235  callback_queue.callAvailable(duration);
236 }
237 
238 void BaseModule::initPoseMsgCallback(const std_msgs::String::ConstPtr& msg)
239 {
240  if (base_module_state_->is_moving_ == false)
241  {
242  if (msg->data == "ini_pose")
243  {
244  // set module of all joints -> this module
246 
247  // wait to change module and to get goal position for init
248  while (enable_ == false || has_goal_joints_ == false)
249  usleep(8 * 1000);
250 
251  // parse initial pose
252  std::string init_pose_path = ros::package::getPath("thormang3_base_module") + "/data/ini_pose.yaml";
253  parseIniPoseData(init_pose_path);
254 
255  // generate trajectory
256  tra_gene_tread_ = boost::thread(boost::bind(&BaseModule::initPoseTrajGenerateProc, this));
257  }
258  }
259  else
260  ROS_INFO("previous task is alive");
261 
262  return;
263 }
264 
266 {
267  for (int id = 1; id <= MAX_JOINT_ID; id++)
268  {
269  double ini_value = joint_state_->goal_joint_state_[id].position_;
270  double tar_value = base_module_state_->joint_ini_pose_.coeff(id, 0);
271 
272  Eigen::MatrixXd tra;
273 
274  if (base_module_state_->via_num_ == 0)
275  {
276  tra = robotis_framework::calcMinimumJerkTra(ini_value, 0.0, 0.0, tar_value, 0.0, 0.0,
278  }
279  else
280  {
281  Eigen::MatrixXd via_value = base_module_state_->joint_via_pose_.col(id);
282  Eigen::MatrixXd d_via_value = base_module_state_->joint_via_dpose_.col(id);
283  Eigen::MatrixXd dd_via_value = base_module_state_->joint_via_ddpose_.col(id);
284 
286  via_value, d_via_value, dd_via_value, tar_value,
287  0.0, 0.0, base_module_state_->smp_time_,
289  }
290 
292  }
293 
296  ROS_INFO("[start] send trajectory");
297 }
298 
299 void BaseModule::poseGenerateProc(Eigen::MatrixXd joint_angle_pose)
300 {
302  while (enable_ == false || has_goal_joints_ == false)
303  usleep(8 * 1000);
304 
307 
309 
310  base_module_state_->joint_pose_ = joint_angle_pose;
311 
312  for (int id = 1; id <= MAX_JOINT_ID; id++)
313  {
314  double ini_value = joint_state_->goal_joint_state_[id].position_;
315  double tar_value = base_module_state_->joint_pose_.coeff(id, 0);
316 
317  ROS_INFO_STREAM("[ID : " << id << "] ini_value : " << ini_value << " tar_value : " << tar_value);
318 
319  Eigen::MatrixXd tra = robotis_framework::calcMinimumJerkTra(ini_value, 0.0, 0.0, tar_value, 0.0, 0.0,
321 
323  }
324 
327  ini_pose_only_ = true;
328  ROS_INFO("[start] send trajectory");
329 }
330 
331 void BaseModule::poseGenerateProc(std::map<std::string, double>& joint_angle_pose)
332 {
334  while (enable_ == false || has_goal_joints_ == false)
335  usleep(8 * 1000);
336 
337  Eigen::MatrixXd target_pose = Eigen::MatrixXd::Zero( MAX_JOINT_ID + 1, 1);
338 
339  for (std::map<std::string, double>::iterator it = joint_angle_pose.begin(); it != joint_angle_pose.end(); it++)
340  {
341  std::string joint_name = it->first;
342  double joint_angle_rad = it->second;
343 
344  std::map<std::string, int>::iterator joint_name_to_id_it = joint_name_to_id_.find(joint_name);
345  if (joint_name_to_id_it != joint_name_to_id_.end())
346  {
347  target_pose.coeffRef(joint_name_to_id_it->second, 0) = joint_angle_rad;
348  }
349  }
350 
351  base_module_state_->joint_pose_ = target_pose;
352 
355 
357 
358  for (int id = 1; id <= MAX_JOINT_ID; id++)
359  {
360  double ini_value = joint_state_->goal_joint_state_[id].position_;
361  double tar_value = base_module_state_->joint_pose_.coeff(id, 0);
362 
363  ROS_INFO_STREAM("[ID : " << id << "] ini_value : " << ini_value << " tar_value : " << tar_value);
364 
365  Eigen::MatrixXd tra = robotis_framework::calcMinimumJerkTra(ini_value, 0.0, 0.0, tar_value, 0.0, 0.0,
367 
369  }
370 
373  ini_pose_only_ = true;
374  ROS_INFO("[start] send trajectory");
375 }
376 
378 {
380 }
381 
382 void BaseModule::process(std::map<std::string, robotis_framework::Dynamixel *> dxls,
383  std::map<std::string, double> sensors)
384 {
385  if (enable_ == false)
386  return;
387 
388  /*----- write curr position -----*/
389  for (std::map<std::string, robotis_framework::DynamixelState *>::iterator state_iter = result_.begin();
390  state_iter != result_.end(); state_iter++)
391  {
392  std::string joint_name = state_iter->first;
393 
394  robotis_framework::Dynamixel *dxl = NULL;
395  std::map<std::string, robotis_framework::Dynamixel*>::iterator dxl_it = dxls.find(joint_name);
396  if (dxl_it != dxls.end())
397  dxl = dxl_it->second;
398  else
399  continue;
400 
401  double joint_curr_position = dxl->dxl_state_->present_position_;
402  double joint_goal_position = dxl->dxl_state_->goal_position_;
403 
404  joint_state_->curr_joint_state_[joint_name_to_id_[joint_name]].position_ = joint_curr_position;
405  joint_state_->goal_joint_state_[joint_name_to_id_[joint_name]].position_ = joint_goal_position;
406  }
407 
408  has_goal_joints_ = true;
409 
410  /* ----- send trajectory ----- */
411 
412  if (base_module_state_->is_moving_ == true)
413  {
414  if (base_module_state_->cnt_ == 1)
415  publishStatusMsg(robotis_controller_msgs::StatusMsg::STATUS_INFO, "Start Init Pose");
416 
417  for (int id = 1; id <= MAX_JOINT_ID; id++)
419 
421  }
422 
423  /*----- set joint data -----*/
424 
425  for (std::map<std::string, robotis_framework::DynamixelState *>::iterator state_iter = result_.begin();
426  state_iter != result_.end(); state_iter++)
427  {
428  std::string joint_name = state_iter->first;
429 
430  result_[joint_name]->goal_position_ = joint_state_->goal_joint_state_[joint_name_to_id_[joint_name]].position_;
431  }
432 
433  /*---------- initialize count number ----------*/
434 
436  {
437  ROS_INFO("[end] send trajectory");
438 
439  publishStatusMsg(robotis_controller_msgs::StatusMsg::STATUS_INFO, "Finish Init Pose");
440  publishDoneMsg("base_init");
441 
444 
445  // set all joints -> none
446  if (ini_pose_only_ == true)
447  {
448  setCtrlModule("none");
449  ini_pose_only_ = false;
450  }
451  }
452 }
453 
455 {
456  return;
457 }
458 
459 void BaseModule::setCtrlModule(std::string module)
460 {
461  std_msgs::String control_msg;
462  control_msg.data = module_name_;
463 
464  set_ctrl_module_pub_.publish(control_msg);
465 }
466 
467 void BaseModule::publishStatusMsg(unsigned int type, std::string msg)
468 {
469  robotis_controller_msgs::StatusMsg status;
470  status.header.stamp = ros::Time::now();
471  status.type = type;
472  status.module_name = "Base";
473  status.status_msg = msg;
474 
475  status_msg_pub_.publish(status);
476 }
477 
478 void BaseModule::publishDoneMsg(const std::string done_msg)
479 {
480  std_msgs::String movement_msg;
481  movement_msg.data = done_msg;
482  movement_done_pub_.publish(movement_msg);
483 }
void poseGenerateProc(Eigen::MatrixXd joint_angle_pose)
ros::Publisher movement_done_pub_
Definition: base_module.h:113
std::map< std::string, DynamixelState * > result_
void process(std::map< std::string, robotis_framework::Dynamixel * > dxls, std::map< std::string, double > sensors)
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:66
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
void parseIniPoseData(const std::string &path)
boost::thread tra_gene_tread_
Definition: base_module.h:108
void publishStatusMsg(unsigned int type, std::string msg)
void publishDoneMsg(const std::string done_msg)
#define ROS_INFO(...)
Eigen::MatrixXd calcMinimumJerkTraWithViaPoints(int via_num, double pos_start, double vel_start, double accel_start, Eigen::MatrixXd pos_via, Eigen::MatrixXd vel_via, Eigen::MatrixXd accel_via, double pos_end, double vel_end, double accel_end, double smp_time, Eigen::MatrixXd via_time, double mov_time)
void setCallbackQueue(CallbackQueueInterface *queue)
#define DEGREE2RADIAN
BaseJointState * joint_state_
Definition: base_module.h:95
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
Eigen::MatrixXd joint_via_dpose_
ros::Publisher set_ctrl_module_pub_
Definition: base_module.h:112
ROSLIB_DECL std::string getPath(const std::string &package_name)
boost::thread queue_thread_
Definition: base_module.h:107
#define ROS_INFO_STREAM(args)
void initialize(const int control_cycle_msec, robotis_framework::Robot *robot)
DynamixelState * dxl_state_
BaseJointData goal_joint_state_[MAX_JOINT_ID+1]
Definition: base_module.h:67
ros::Publisher status_msg_pub_
Definition: base_module.h:111
static Time now()
#define MAX_JOINT_ID
bool ok() const
Eigen::MatrixXd joint_via_ddpose_
#define ROS_ERROR(...)
BaseModuleState * base_module_state_
Definition: base_module.h:94
std::map< std::string, int > joint_name_to_id_
Definition: base_module.h:115
void setCtrlModule(std::string module)
void initPoseMsgCallback(const std_msgs::String::ConstPtr &msg)


thormang3_base_module
Author(s): SCH
autogenerated on Mon Jun 10 2019 15:37:51