thormang3_offset_tuner_server.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  * thormang3_offset_tuner_server.cpp
19  *
20  * Created on: 2016. 2. 15.
21  * Author: Jay Song
22  */
23 
25 
26 #define OFFSET_ROSPARAM_KEY "offset"
27 #define OFFSET_INIT_POS_ROSPARAM_KEY "init_pose_for_offset_tuner"
28 
29 using namespace thormang3;
30 
32  : controller_(0),
33  init_file_(""),
34  robot_file_(""),
35  offset_file_("")
36 {
37 }
38 
40 {
41 }
42 
43 void OffsetTunerServer::setCtrlModule(std::string module)
44 {
45  robotis_controller_msgs::JointCtrlModule control_msg;
46 
47  std::map<std::string, robotis_framework::DynamixelState *>::iterator joint_iter;
48  ros::NodeHandle nh;
49  ros::Publisher set_ctrl_module_pub = nh.advertise<robotis_controller_msgs::JointCtrlModule>("/robotis/set_ctrl_module", 1);
50 
51  BaseModule* base_module = BaseModule::getInstance();
52 
53  for (joint_iter = base_module->result_.begin(); joint_iter != base_module->result_.end(); ++joint_iter)
54  {
55  control_msg.joint_name.push_back(joint_iter->first);
56  control_msg.module_name.push_back(module);
57  }
58 
59  set_ctrl_module_pub.publish(control_msg);
60 }
61 
63 {
65 
66  ros::NodeHandle nh;
67 
68  //Get File Path
69  nh.param<std::string>("offset_file_path", offset_file_, "");
70  nh.param<std::string>("robot_file_path", robot_file_, "");
71  nh.param<std::string>("init_file_path", init_file_, "");
72 
73  if ((offset_file_ == "") || (robot_file_ == ""))
74  {
75  ROS_ERROR("Failed to get file path");
76  return -1;
77  }
78  //
79  //Controller Initialize with robot file info
80  if (controller_->initialize(robot_file_, init_file_) == false)
81  {
82  ROS_ERROR("ROBOTIS Controller Initialize Fail!");
83  return -1;
84  }
85  //controller_->LoadOffset(offset_file_);
86  controller_->addMotionModule((robotis_framework::MotionModule*)BaseModule::getInstance());
87 
88  //Initialize RobotOffsetData
89  for (std::map<std::string, robotis_framework::Dynamixel *>::iterator robot_it = controller_->robot_->dxls_.begin();
90  robot_it != controller_->robot_->dxls_.end(); robot_it++)
91  {
92  std::string joint_name = robot_it->first;
93  robot_offset_data_[joint_name] = new JointOffsetData(0, 0);
94  robot_torque_enable_data_[joint_name] = true;
95  }
96 
97  //Get and Initialize Offset Data
98  std::map<std::string, double> _offset_data;
99  //bool result = nh.getParam(OFFSET_ROSPARAM_KEY, _offset_data);
100 // if(result == true)
101 // {
102  //ROS_INFO("Succeed to get offset");
103 
104  //offset data initialize
105  //referring to robotis file info the data will be initialized
106 
107 //
108 //
109 //
110 // for(std::map<std::string, double>::iterator _it = _offset_data.begin(); _it != _offset_data.end(); _it++)
111 // {
112 // std::string _joint_name = _it->first;
113 // double _joint_offset = _it->second;
114 //
115 // RobotOffsetData[_joint_name] = new JointOffsetData(_joint_offset, 0);
116 // RobotTorqueEnableData[_joint_name] = true;
117 // }
118 // }
119 // else {
120 // ROS_ERROR("Failed to get offset data");
121 // return false;
122 // }
123 
124  //Load Offset.yaml
125  YAML::Node offset_yaml_node = YAML::LoadFile(offset_file_.c_str());
126 
127  //Get Offset Data and Init_Pose for Offset Tuning
128  YAML::Node offset_data_node = offset_yaml_node[OFFSET_ROSPARAM_KEY];
129  YAML::Node offset_init_pose_node = offset_yaml_node[OFFSET_INIT_POS_ROSPARAM_KEY];
130 
131  //Initialize Offset Data in RobotOffsetData
132  for (YAML::const_iterator node_it = offset_data_node.begin(); node_it != offset_data_node.end(); node_it++)
133  {
134  std::string joint_name = node_it->first.as<std::string>();
135  double offset = node_it->second.as<double>();
136 
137  std::map<std::string, JointOffsetData*>::iterator robot_offset_data_it = robot_offset_data_.find(joint_name);
138  if (robot_offset_data_it != robot_offset_data_.end())
139  robot_offset_data_[joint_name]->joint_offset_rad_ = offset;
140  }
141 
142  //Initialize Init Pose for Offset Tuning in RobotOffsetData
143  for (YAML::const_iterator ode_it = offset_init_pose_node.begin(); ode_it != offset_init_pose_node.end(); ode_it++)
144  {
145  std::string joint_name = ode_it->first.as<std::string>();
146  double offset_init_pose = ode_it->second.as<double>();
147 
148  std::map<std::string, JointOffsetData*>::iterator robot_offset_data_it = robot_offset_data_.find(joint_name);
149  if (robot_offset_data_it != robot_offset_data_.end())
150  robot_offset_data_[joint_name]->joint_init_pos_rad_ = offset_init_pose;
151  }
152 
153 // //Get Initial Pose for Offset Tunning
154 // std::map<std::string, double> _init;
155 // result = _nh.getParam(OFFSET_INIT_POS_ROSPARAM_KEY, _init);
156 // if(result == true)
157 // {
158 // std::map<std::string, JointOffsetData*>::iterator _robot_offset_data_it; // iterator for RobotOffsetData
159 // ROS_INFO("Succeed to get offset init pose");
160 // for(std::map<std::string, double>::iterator _it = _init.begin(); _it != _init.end(); _it++) {
161 // std::string _joint_name = _it->first;
162 // double _joint_init = _it->second;
163 //
164 // //check the joint name exist at the offset data
165 // _robot_offset_data_it = RobotOffsetData.find(_joint_name);
166 //
167 // if(_robot_offset_data_it != RobotOffsetData.end())
168 // RobotOffsetData[_joint_name]->joint_init_pos_rad = _joint_init;
169 // else
170 // continue;
171 // }
172 // }
173 // else {
174 // ROS_ERROR("Failed to get offset init pose");
175 // return false;
176 // }
177 
178  ROS_INFO(" ");
179  ROS_INFO(" ");
180  //For Data Check, Print All Available Data
181  int i = 0;
182  ROS_INFO_STREAM("num" << " | " << "joint_name" << " | " << "InitPose" << ", " << "OffsetAngleRad");
183  for (std::map<std::string, JointOffsetData*>::iterator it = robot_offset_data_.begin(); it != robot_offset_data_.end(); it++)
184  {
185  std::string joint_name = it->first;
186  JointOffsetData *joint_data = it->second;
187 
188  ROS_INFO_STREAM(i << " | " << joint_name << " : " << joint_data->joint_init_pos_rad_ << ", "
189  << joint_data->joint_offset_rad_);
190  i++;
191  }
192 
193  send_tra_sub_ = nh.subscribe("/robotis/base/send_tra", 10, &OffsetTunerServer::stringMsgsCallBack, this);
194  joint_offset_data_sub_ = nh.subscribe("/robotis/offset_tuner/joint_offset_data", 10,
196  joint_torque_enable_sub_ = nh.subscribe("/robotis/offset_tuner/torque_enable", 10,
198  command_sub_ = nh.subscribe("/robotis/offset_tuner/command", 5, &OffsetTunerServer::commandCallback, this);
199  offset_data_server_ = nh.advertiseService("robotis/offset_tuner/get_present_joint_offset_data",
201 
202  return true;
203 }
204 
206 {
207 
209  BaseModule *base_module = BaseModule::getInstance();
210 
211 // Eigen::MatrixXd _offset_init_pose = Eigen::MatrixXd::Zero( MAX_JOINT_ID + 1 , 1 );
212 
213 // for(std::map<std::string, JointOffsetData*>::iterator _it = RobotOffsetData.begin(); _it != RobotOffsetData.end(); _it++)
214 // {
215 // std::string _joint_name = _it->first;
216 // JointOffsetData* _joint_data = _it->second;
217 //
218 //
219 // if ( controller_->robot->dxls.find(_joint_name) == controller_->robot->dxls.end() ) {
220 // continue;
221 // }
222 // else {
223 // int id = (int)(controller_->robot->dxls[_joint_name]->id);
224 // //if(id > MAX_JOINT_ID) {
225 // if(id > MAX_JOINT_ID) {
226 // ROS_ERROR("Invalid JointID");
227 // return;
228 // }
229 // else {
230 // offset_init_pose.coeffRef(id, 0) = _joint_data->joint_init_pos_rad;
231 // }
232 // }
233 // }
234 
235  //make map, key : joint_name, value : joint_init_pos_rad;
236  std::map<std::string, double> offset_init_pose;
237  for (std::map<std::string, JointOffsetData*>::iterator it = robot_offset_data_.begin();
238  it != robot_offset_data_.end(); it++)
239  {
240  std::string joint_name = it->first;
241  JointOffsetData *joint_data = it->second;
242 
243  if (controller_->robot_->dxls_.find(joint_name) == controller_->robot_->dxls_.end())
244  continue;
245  else
246  offset_init_pose[joint_name] = joint_data->joint_init_pos_rad_ + joint_data->joint_offset_rad_;
247  }
248 
249  usleep(80 * 1000);
250  base_module->poseGenerateProc(offset_init_pose);
251  usleep(10 * 000);
252 
253  while (base_module->isRunning())
254  usleep(50 * 1000);
255 
257  while (controller_->isTimerRunning())
258  usleep(10 * 1000);
259 
261  {
262  ROS_INFO("Timer Running");
263  }
264 
265  setCtrlModule("none");
266 }
267 
268 void OffsetTunerServer::stringMsgsCallBack(const std_msgs::String::ConstPtr& msg)
269 {
270  ROS_INFO_STREAM(msg->data);
271 }
272 
273 void OffsetTunerServer::commandCallback(const std_msgs::String::ConstPtr& msg)
274 {
275  if (msg->data == "save")
276  {
277 // YAML::Node _baseNode = YAML::LoadFile(offset_file_); // gets the root node
278 // for(std::map<std::string, JointOffsetData*>::iterator _it = RobotOffsetData.begin(); _it != RobotOffsetData.end(); _it++)
279 // {
280 // std::string _joint_name = _it->first;
281 // JointOffsetData* _joint_data = _it->second;
282 //
283 // _baseNode["offset"][_joint_name] = _joint_data->joint_offset_rad; // edit one of the nodes
284 // _baseNode["init_pose_for_offset_tuner"][_joint_name] = _joint_data->joint_init_pos_rad; // edit one of the nodes
285 // }
286 // std::ofstream fout(offset_file_.c_str());
287 // fout << _baseNode; // dump it back into the file
288 
289  YAML::Emitter out;
290  std::map<std::string, double> offset;
291  std::map<std::string, double> init_pose;
292  for (std::map<std::string, JointOffsetData*>::iterator it = robot_offset_data_.begin();
293  it != robot_offset_data_.end(); it++)
294  {
295  std::string joint_name = it->first;
296  JointOffsetData *joint_data = it->second;
297 
298  offset[joint_name] = joint_data->joint_offset_rad_; // edit one of the nodes
299  init_pose[joint_name] = joint_data->joint_init_pos_rad_; // edit one of the nodes
300  }
301 
302  out << YAML::BeginMap;
303  out << YAML::Key << "offset" << YAML::Value << offset;
304  out << YAML::Key << "init_pose_for_offset_tuner" << YAML::Value << init_pose;
305  out << YAML::EndMap;
306  std::ofstream fout(offset_file_.c_str());
307  fout << out.c_str(); // dump it back into the file
308 
309  }
310  else if (msg->data == "ini_pose")
311  moveToInitPose();
312  else
313  ROS_INFO_STREAM("Invalid Command : " << msg->data);
314 }
315 
316 void OffsetTunerServer::jointOffsetDataCallback(const thormang3_offset_tuner_msgs::JointOffsetData::ConstPtr &msg)
317 {
319  {
320  ROS_ERROR("Timer is running now");
321  return;
322  }
323 
324  //goal position
325  ROS_INFO_STREAM(msg->joint_name << " " << msg->goal_value << " " << msg->offset_value
326  << " " << msg->p_gain << " " << msg->i_gain << " " << msg->d_gain);
327 
328  std::map<std::string, JointOffsetData*>::iterator it;
329  it = robot_offset_data_.find(msg->joint_name);
330  if (it == robot_offset_data_.end())
331  {
332  ROS_ERROR("Invalid Joint Name");
333  return;
334  }
335 
336  if (robot_torque_enable_data_[msg->joint_name] == false)
337  {
338  ROS_ERROR_STREAM(msg->joint_name << "is turned off the torque");
339  return;
340  }
341 
342  double goal_pose_rad = msg->offset_value + msg->goal_value;
343  int32_t goal_pose_value = controller_->robot_->dxls_[msg->joint_name]->convertRadian2Value(goal_pose_rad);
344  uint8_t dxl_error = 0;
345  int32_t comm_result = COMM_SUCCESS;
346 
347  comm_result = controller_->writeCtrlItem(msg->joint_name,
348  controller_->robot_->dxls_[msg->joint_name]->goal_position_item_->item_name_,
349  goal_pose_value, &dxl_error);
350  if (comm_result != COMM_SUCCESS)
351  {
352  ROS_ERROR("Failed to write goal position");
353  return;
354  }
355  else
356  {
357  robot_offset_data_[msg->joint_name]->joint_init_pos_rad_ = msg->goal_value;
358  robot_offset_data_[msg->joint_name]->joint_offset_rad_ = msg->offset_value;
359  }
360 
361  if (dxl_error != 0)
362  {
363  ROS_ERROR_STREAM("goal_pos_set : " << msg->joint_name << " has error " << (int) dxl_error);
364  }
365 
366  robot_offset_data_[msg->joint_name]->p_gain_ = msg->p_gain;
367  robot_offset_data_[msg->joint_name]->i_gain_ = msg->i_gain;
368  robot_offset_data_[msg->joint_name]->d_gain_ = msg->d_gain;
369 
370 }
371 
373  const thormang3_offset_tuner_msgs::JointTorqueOnOffArray::ConstPtr& msg)
374 {
375  for (unsigned int i = 0; i < msg->torque_enable_data.size(); i++)
376  {
377  std::string joint_name = msg->torque_enable_data[i].joint_name;
378  bool torque_enable = msg->torque_enable_data[i].torque_enable;
379  ROS_INFO_STREAM(i << " " << joint_name << torque_enable);
380 
381  std::map<std::string, JointOffsetData*>::iterator it = robot_offset_data_.find(joint_name);
382  if (it == robot_offset_data_.end())
383  {
384  ROS_ERROR("Invalid Joint Name");
385  continue;
386  }
387  else
388  {
389  int32_t comm_result = COMM_SUCCESS;
390  uint8_t dxl_error = 0;
391  uint8_t torque_enable_value = 0;
392 
393  if (torque_enable)
394  torque_enable_value = 1;
395  else
396  torque_enable_value = 0;
397 
398  comm_result = controller_->writeCtrlItem(joint_name,
399  controller_->robot_->dxls_[joint_name]->torque_enable_item_->item_name_,
400  torque_enable_value, &dxl_error);
401  if (comm_result != COMM_SUCCESS)
402  {
403  ROS_ERROR("Failed to write goal position");
404  }
405  else
406  {
407  robot_torque_enable_data_[joint_name] = torque_enable;
408  }
409 
410  if (dxl_error != 0)
411  {
412  ROS_ERROR_STREAM("goal_pos_set : " << joint_name << " has error " << (int) dxl_error);
413  }
414  }
415  }
416 }
417 
419  thormang3_offset_tuner_msgs::GetPresentJointOffsetData::Request &req,
420  thormang3_offset_tuner_msgs::GetPresentJointOffsetData::Response &res)
421 {
422 
423  ROS_INFO("GetPresentJointOffsetDataService Called");
424 
425  for (std::map<std::string, JointOffsetData*>::iterator it = robot_offset_data_.begin();
426  it != robot_offset_data_.end(); it++)
427  {
428  std::string joint_name = it->first;
429  JointOffsetData *joint_data = it->second;
430 
431  thormang3_offset_tuner_msgs::JointOffsetPositionData joint_offset_pos;
432 
433  int32_t present_pos_value = 0;
434  uint8_t dxl_error = 0;
435  int comm_result = COMM_SUCCESS;
436 
437  comm_result = controller_->readCtrlItem(joint_name,
438  controller_->robot_->dxls_[joint_name]->present_position_item_->item_name_,
439  (uint32_t*) &present_pos_value,
440  &dxl_error);
441  if (comm_result != COMM_SUCCESS)
442  {
443  ROS_ERROR("Failed to read present pos");
444  return false;
445  }
446  else
447  {
448  if (dxl_error != 0)
449  {
450  ROS_ERROR_STREAM(joint_name << " has error " << (int) dxl_error);
451  }
452 
453  joint_offset_pos.joint_name = joint_name;
454  joint_offset_pos.goal_value = joint_data->joint_init_pos_rad_;
455  joint_offset_pos.offset_value = joint_data->joint_offset_rad_;
456  joint_offset_pos.present_value = controller_->robot_->dxls_[joint_name]->convertValue2Radian(present_pos_value);
457  joint_offset_pos.p_gain = joint_data->p_gain_;
458  joint_offset_pos.i_gain = joint_data->i_gain_;
459  joint_offset_pos.d_gain = joint_data->d_gain_;
460 
461  res.present_data_array.push_back(joint_offset_pos);
462  }
463  }
464  return true;
465 }
466 
void poseGenerateProc(Eigen::MatrixXd joint_angle_pose)
void publish(const boost::shared_ptr< M > &message) const
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
void jointOffsetDataCallback(const thormang3_offset_tuner_msgs::JointOffsetData::ConstPtr &msg)
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
void addMotionModule(MotionModule *module)
std::map< std::string, Dynamixel * > dxls_
int COMM_SUCCESS
std::map< std::string, bool > robot_torque_enable_data_
bool initialize(const std::string robot_file_path, const std::string init_file_path)
void jointTorqueOnOffCallback(const thormang3_offset_tuner_msgs::JointTorqueOnOffArray::ConstPtr &msg)
bool getPresentJointOffsetDataServiceCallback(thormang3_offset_tuner_msgs::GetPresentJointOffsetData::Request &req, thormang3_offset_tuner_msgs::GetPresentJointOffsetData::Response &res)
#define OFFSET_ROSPARAM_KEY
#define ROS_INFO(...)
bool param(const std::string &param_name, T &param_val, const T &default_val) const
#define OFFSET_INIT_POS_ROSPARAM_KEY
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
void commandCallback(const std_msgs::String::ConstPtr &msg)
robotis_framework::RobotisController * controller_
#define ROS_INFO_STREAM(args)
void stringMsgsCallBack(const std_msgs::String::ConstPtr &msg)
#define ROS_ERROR_STREAM(args)
int writeCtrlItem(const std::string joint_name, const std::string item_name, uint32_t data, uint8_t *error=0)
#define ROS_ERROR(...)
std::map< std::string, JointOffsetData * > robot_offset_data_
int readCtrlItem(const std::string joint_name, const std::string item_name, uint32_t *data, uint8_t *error=0)


thormang3_offset_tuner_server
Author(s): Kayman , SCH , Jay Song
autogenerated on Mon Jun 10 2019 15:37:48