robot.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  * robot.cpp
19  *
20  * Created on: 2015. 12. 11.
21  * Author: zerom
22  */
23 
24 #include <fstream>
25 #include <iostream>
26 #include <algorithm>
27 
28 #include "robotis_device/robot.h"
29 
30 using namespace robotis_framework;
31 
32 static inline std::string &ltrim(std::string &s)
33 {
34  s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
35  return s;
36 }
37 static inline std::string &rtrim(std::string &s)
38 {
39  s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
40  return s;
41 }
42 static inline std::string &trim(std::string &s)
43 {
44  return ltrim(rtrim(s));
45 }
46 
47 static inline std::vector<std::string> split(const std::string &text, char sep)
48 {
49  std::vector<std::string> tokens;
50  std::size_t start = 0, end = 0;
51 
52  while ((end = text.find(sep, start)) != (std::string::npos))
53  {
54  tokens.push_back(text.substr(start, end - start));
55  trim(tokens.back());
56  start = end + 1;
57  }
58  tokens.push_back(text.substr(start));
59  trim(tokens.back());
60 
61  return tokens;
62 }
63 
64 Robot::Robot(std::string robot_file_path, std::string dev_desc_dir_path)
65  : control_cycle_msec_(DEFAULT_CONTROL_CYCLE)
66 {
67  if (dev_desc_dir_path.compare(dev_desc_dir_path.size() - 1, 1, "/") != 0)
68  dev_desc_dir_path += "/";
69 
70  std::ifstream file(robot_file_path.c_str());
71  if (file.is_open())
72  {
73  std::string session = "";
74  std::string input_str;
75  while (!file.eof())
76  {
77  std::getline(file, input_str);
78 
79  // remove comment ( # )
80  std::size_t pos = input_str.find("#");
81  if (pos != std::string::npos)
82  input_str = input_str.substr(0, pos);
83 
84  // trim
85  input_str = trim(input_str);
86 
87  // find session
88  if (!input_str.compare(0, 1, "[") && !input_str.compare(input_str.size() - 1, 1, "]"))
89  {
90  input_str = input_str.substr(1, input_str.size() - 2);
91  std::transform(input_str.begin(), input_str.end(), input_str.begin(), ::tolower);
92  session = trim(input_str);
93  continue;
94  }
95 
96  if (session == SESSION_CONTROL_INFO)
97  {
98  std::vector<std::string> tokens = split(input_str, '=');
99  if (tokens.size() != 2)
100  continue;
101 
102  if (tokens[0] == "control_cycle")
103  control_cycle_msec_ = std::atoi(tokens[1].c_str());
104  }
105  else if (session == SESSION_PORT_INFO)
106  {
107  std::vector<std::string> tokens = split(input_str, '|');
108  if (tokens.size() != 3)
109  continue;
110 
111  std::cout << tokens[0] << " added. (baudrate: " << tokens[1] << ")" << std::endl;
112 
113  ports_[tokens[0]] = dynamixel::PortHandler::getPortHandler(tokens[0].c_str());
114  ports_[tokens[0]]->setBaudRate(std::atoi(tokens[1].c_str()));
115  port_default_device_[tokens[0]] = tokens[2];
116  }
117  else if (session == SESSION_DEVICE_INFO)
118  {
119  std::vector<std::string> tokens = split(input_str, '|');
120  if (tokens.size() != 7)
121  continue;
122 
123  if (tokens[0] == DYNAMIXEL)
124  {
125  std::string file_path = dev_desc_dir_path + tokens[0] + "/" + tokens[3] + ".device";
126  int id = std::atoi(tokens[2].c_str());
127  std::string port = tokens[1];
128  float protocol = std::atof(tokens[4].c_str());
129  std::string dev_name = tokens[5];
130 
131  dxls_[dev_name] = getDynamixel(file_path, id, port, protocol);
132 
133  Dynamixel *dxl = dxls_[dev_name];
134  std::vector<std::string> sub_tokens = split(tokens[6], ',');
135  if (sub_tokens.size() > 0)
136  {
137  std::map<std::string, ControlTableItem *>::iterator indirect_it = dxl->ctrl_table_.find(INDIRECT_ADDRESS_1);
138  if (indirect_it != dxl->ctrl_table_.end()) // INDIRECT_ADDRESS_1 exist
139  {
140  uint16_t indirect_data_addr = dxl->ctrl_table_[INDIRECT_DATA_1]->address_;
141  for (int _i = 0; _i < sub_tokens.size(); _i++)
142  {
143  std::map<std::string, ControlTableItem *>::iterator bulkread_it = dxl->ctrl_table_.find(sub_tokens[_i]);
144  if(bulkread_it == dxl->ctrl_table_.end())
145  {
146  fprintf(stderr, "\n ##### BULK READ ITEM [ %s ] NOT FOUND!! #####\n\n", sub_tokens[_i].c_str());
147  continue;
148  }
149 
150  dxl->bulk_read_items_.push_back(new ControlTableItem());
151  ControlTableItem *dest_item = dxl->bulk_read_items_[_i];
152  ControlTableItem *src_item = dxl->ctrl_table_[sub_tokens[_i]];
153 
154  dest_item->item_name_ = src_item->item_name_;
155  dest_item->address_ = indirect_data_addr;
156  dest_item->access_type_ = src_item->access_type_;
157  dest_item->memory_type_ = src_item->memory_type_;
158  dest_item->data_length_ = src_item->data_length_;
159  dest_item->data_min_value_ = src_item->data_min_value_;
160  dest_item->data_max_value_ = src_item->data_max_value_;
161  dest_item->is_signed_ = src_item->is_signed_;
162 
163  indirect_data_addr += dest_item->data_length_;
164  }
165  }
166  else // INDIRECT_ADDRESS_1 not exist
167  {
168  for (int i = 0; i < sub_tokens.size(); i++)
169  {
170  if (dxl->ctrl_table_[sub_tokens[i]] != NULL)
171  dxl->bulk_read_items_.push_back(dxl->ctrl_table_[sub_tokens[i]]);
172  }
173  }
174  }
175  }
176  else if (tokens[0] == SENSOR)
177  {
178  std::string file_path = dev_desc_dir_path + tokens[0] + "/" + tokens[3] + ".device";
179  int id = std::atoi(tokens[2].c_str());
180  std::string port = tokens[1];
181  float protocol = std::atof(tokens[4].c_str());
182  std::string dev_name = tokens[5];
183 
184  sensors_[dev_name] = getSensor(file_path, id, port, protocol);
185 
186  Sensor *sensor = sensors_[dev_name];
187  std::vector<std::string> sub_tokens = split(tokens[6], ',');
188  if (sub_tokens.size() > 0)
189  {
190  std::map<std::string, ControlTableItem *>::iterator indirect_it = sensor->ctrl_table_.find(INDIRECT_ADDRESS_1);
191  if (indirect_it != sensor->ctrl_table_.end()) // INDIRECT_ADDRESS_1 exist
192  {
193  uint16_t indirect_data_addr = sensor->ctrl_table_[INDIRECT_DATA_1]->address_;
194  for (int i = 0; i < sub_tokens.size(); i++)
195  {
196  sensor->bulk_read_items_.push_back(new ControlTableItem());
197  ControlTableItem *dest_item = sensor->bulk_read_items_[i];
198  ControlTableItem *src_item = sensor->ctrl_table_[sub_tokens[i]];
199 
200  dest_item->item_name_ = src_item->item_name_;
201  dest_item->address_ = indirect_data_addr;
202  dest_item->access_type_ = src_item->access_type_;
203  dest_item->memory_type_ = src_item->memory_type_;
204  dest_item->data_length_ = src_item->data_length_;
205  dest_item->data_min_value_ = src_item->data_min_value_;
206  dest_item->data_max_value_ = src_item->data_max_value_;
207  dest_item->is_signed_ = src_item->is_signed_;
208 
209  indirect_data_addr += dest_item->data_length_;
210  }
211  }
212  else // INDIRECT_ADDRESS_1 exist
213  {
214  for (int i = 0; i < sub_tokens.size(); i++)
215  sensor->bulk_read_items_.push_back(sensor->ctrl_table_[sub_tokens[i]]);
216  }
217  }
218  }
219  }
220  }
221  file.close();
222  }
223  else
224  {
225  std::cout << "Unable to open file : " + robot_file_path << std::endl;
226  }
227 }
228 
229 Sensor *Robot::getSensor(std::string path, int id, std::string port, float protocol_version)
230 {
231  Sensor *sensor;
232 
233  // load file model_name.device
234  std::ifstream file(path.c_str());
235  if (file.is_open())
236  {
237  std::string session = "";
238  std::string input_str;
239 
240  while (!file.eof())
241  {
242  std::getline(file, input_str);
243 
244  // remove comment ( # )
245  std::size_t pos = input_str.find("#");
246  if (pos != std::string::npos)
247  input_str = input_str.substr(0, pos);
248 
249  // trim
250  input_str = trim(input_str);
251  if (input_str == "")
252  continue;
253 
254  // find _session
255  if (!input_str.compare(0, 1, "[") && !input_str.compare(input_str.size() - 1, 1, "]"))
256  {
257  input_str = input_str.substr(1, input_str.size() - 2);
258  std::transform(input_str.begin(), input_str.end(), input_str.begin(), ::tolower);
259  session = trim(input_str);
260  continue;
261  }
262 
263  if (session == SESSION_DEVICE_INFO)
264  {
265  std::vector<std::string> tokens = split(input_str, '=');
266  if (tokens.size() != 2)
267  continue;
268 
269  if (tokens[0] == "model_name")
270  sensor = new Sensor(id, tokens[1], protocol_version);
271  }
272  else if (session == SESSION_CONTROL_TABLE)
273  {
274  std::vector<std::string> tokens = split(input_str, '|');
275  if (tokens.size() != 8)
276  continue;
277 
278  ControlTableItem *item = new ControlTableItem();
279  item->item_name_ = tokens[1];
280  item->address_ = std::atoi(tokens[0].c_str());
281  item->data_length_ = std::atoi(tokens[2].c_str());
282 
283  if (tokens[3] == "R")
284  item->access_type_ = Read;
285  else if (tokens[3] == "RW")
286  item->access_type_ = ReadWrite;
287 
288  if (tokens[4] == "EEPROM")
289  item->memory_type_ = EEPROM;
290  else if (tokens[4] == "RAM")
291  item->memory_type_ = RAM;
292 
293  item->data_min_value_ = std::atol(tokens[5].c_str());
294  item->data_max_value_ = std::atol(tokens[6].c_str());
295 
296  if (tokens[7] == "Y")
297  item->is_signed_ = true;
298  else if (tokens[7] == "N")
299  item->is_signed_ = false;
300  sensor->ctrl_table_[tokens[1]] = item;
301  }
302  }
303  sensor->port_name_ = port;
304 
305  fprintf(stderr, "(%s) [ID:%3d] %14s added. \n", port.c_str(), sensor->id_, sensor->model_name_.c_str());
306  //std::cout << "[ID:" << (int)(_sensor->id) << "] " << _sensor->model_name << " added. (" << port << ")" << std::endl;
307  file.close();
308  }
309  else
310  std::cout << "Unable to open file : " + path << std::endl;
311 
312  return sensor;
313 }
314 
315 Dynamixel *Robot::getDynamixel(std::string path, int id, std::string port, float protocol_version)
316 {
317  Dynamixel *dxl;
318 
319  // load file model_name.device
320  std::ifstream file(path.c_str());
321  if (file.is_open())
322  {
323  std::string session = "";
324  std::string input_str;
325 
326  std::string torque_enable_item_name = "";
327  std::string present_position_item_name = "";
328  std::string present_velocity_item_name = "";
329  std::string present_current_item_name = "";
330  std::string goal_position_item_name = "";
331  std::string goal_velocity_item_name = "";
332  std::string goal_current_item_name = "";
333  std::string position_d_gain_item_name = "";
334  std::string position_i_gain_item_name = "";
335  std::string position_p_gain_item_name = "";
336  std::string velocity_d_gain_item_name = "";
337  std::string velocity_i_gain_item_name = "";
338  std::string velocity_p_gain_item_name = "";
339 
340  while (!file.eof())
341  {
342  std::getline(file, input_str);
343 
344  // remove comment ( # )
345  std::size_t pos = input_str.find("#");
346  if (pos != std::string::npos)
347  input_str = input_str.substr(0, pos);
348 
349  // trim
350  input_str = trim(input_str);
351  if (input_str == "")
352  continue;
353 
354  // find session
355  if (!input_str.compare(0, 1, "[") && !input_str.compare(input_str.size() - 1, 1, "]"))
356  {
357  input_str = input_str.substr(1, input_str.size() - 2);
358  std::transform(input_str.begin(), input_str.end(), input_str.begin(), ::tolower);
359  session = trim(input_str);
360  continue;
361  }
362 
363  if (session == SESSION_DEVICE_INFO)
364  {
365  std::vector<std::string> tokens = split(input_str, '=');
366  if (tokens.size() != 2)
367  continue;
368 
369  if (tokens[0] == "model_name")
370  dxl = new Dynamixel(id, tokens[1], protocol_version);
371  }
372  else if (session == SESSION_TYPE_INFO)
373  {
374  std::vector<std::string> tokens = split(input_str, '=');
375  if (tokens.size() != 2)
376  continue;
377 
378  if (tokens[0] == "torque_to_current_value_ratio")
379  dxl->torque_to_current_value_ratio_ = std::atof(tokens[1].c_str());
380  else if (tokens[0] == "velocity_to_value_ratio")
381  dxl->velocity_to_value_ratio_ = std::atof(tokens[1].c_str());
382 
383  else if (tokens[0] == "value_of_0_radian_position")
384  dxl->value_of_0_radian_position_ = std::atoi(tokens[1].c_str());
385  else if (tokens[0] == "value_of_min_radian_position")
386  dxl->value_of_min_radian_position_ = std::atoi(tokens[1].c_str());
387  else if (tokens[0] == "value_of_max_radian_position")
388  dxl->value_of_max_radian_position_ = std::atoi(tokens[1].c_str());
389  else if (tokens[0] == "min_radian")
390  dxl->min_radian_ = std::atof(tokens[1].c_str());
391  else if (tokens[0] == "max_radian")
392  dxl->max_radian_ = std::atof(tokens[1].c_str());
393 
394  else if (tokens[0] == "torque_enable_item_name")
395  torque_enable_item_name = tokens[1];
396  else if (tokens[0] == "present_position_item_name")
397  present_position_item_name = tokens[1];
398  else if (tokens[0] == "present_velocity_item_name")
399  present_velocity_item_name = tokens[1];
400  else if (tokens[0] == "present_current_item_name")
401  present_current_item_name = tokens[1];
402  else if (tokens[0] == "goal_position_item_name")
403  goal_position_item_name = tokens[1];
404  else if (tokens[0] == "goal_velocity_item_name")
405  goal_velocity_item_name = tokens[1];
406  else if (tokens[0] == "goal_current_item_name")
407  goal_current_item_name = tokens[1];
408  else if (tokens[0] == "position_d_gain_item_name")
409  position_d_gain_item_name = tokens[1];
410  else if (tokens[0] == "position_i_gain_item_name")
411  position_i_gain_item_name = tokens[1];
412  else if (tokens[0] == "position_p_gain_item_name")
413  position_p_gain_item_name = tokens[1];
414  else if (tokens[0] == "velocity_d_gain_item_name")
415  velocity_d_gain_item_name = tokens[1];
416  else if (tokens[0] == "velocity_i_gain_item_name")
417  velocity_i_gain_item_name = tokens[1];
418  else if (tokens[0] == "velocity_p_gain_item_name")
419  velocity_p_gain_item_name = tokens[1];
420  }
421  else if (session == SESSION_CONTROL_TABLE)
422  {
423  std::vector<std::string> tokens = split(input_str, '|');
424  if (tokens.size() != 8)
425  continue;
426 
427  ControlTableItem *item = new ControlTableItem();
428  item->item_name_ = tokens[1];
429  item->address_ = std::atoi(tokens[0].c_str());
430  item->data_length_ = std::atoi(tokens[2].c_str());
431 
432  if (tokens[3] == "R")
433  item->access_type_ = Read;
434  else if (tokens[3] == "RW")
435  item->access_type_ = ReadWrite;
436 
437  if (tokens[4] == "EEPROM")
438  item->memory_type_ = EEPROM;
439  else if (tokens[4] == "RAM")
440  item->memory_type_ = RAM;
441 
442  item->data_min_value_ = std::atol(tokens[5].c_str());
443  item->data_max_value_ = std::atol(tokens[6].c_str());
444 
445  if (tokens[7] == "Y")
446  item->is_signed_ = true;
447  else if (tokens[7] == "N")
448  item->is_signed_ = false;
449  dxl->ctrl_table_[tokens[1]] = item;
450  }
451  }
452  dxl->port_name_ = port;
453 
454  if (dxl->ctrl_table_[torque_enable_item_name] != NULL)
455  dxl->torque_enable_item_ = dxl->ctrl_table_[torque_enable_item_name];
456  if (dxl->ctrl_table_[present_position_item_name] != NULL)
457  dxl->present_position_item_ = dxl->ctrl_table_[present_position_item_name];
458  if (dxl->ctrl_table_[present_velocity_item_name] != NULL)
459  dxl->present_velocity_item_ = dxl->ctrl_table_[present_velocity_item_name];
460  if (dxl->ctrl_table_[present_current_item_name] != NULL)
461  dxl->present_current_item_ = dxl->ctrl_table_[present_current_item_name];
462  if (dxl->ctrl_table_[goal_position_item_name] != NULL)
463  dxl->goal_position_item_ = dxl->ctrl_table_[goal_position_item_name];
464  if (dxl->ctrl_table_[goal_velocity_item_name] != NULL)
465  dxl->goal_velocity_item_ = dxl->ctrl_table_[goal_velocity_item_name];
466  if (dxl->ctrl_table_[goal_current_item_name] != NULL)
467  dxl->goal_current_item_ = dxl->ctrl_table_[goal_current_item_name];
468  if (dxl->ctrl_table_[position_d_gain_item_name] != NULL)
469  dxl->position_d_gain_item_ = dxl->ctrl_table_[position_d_gain_item_name];
470  if (dxl->ctrl_table_[position_i_gain_item_name] != NULL)
471  dxl->position_i_gain_item_ = dxl->ctrl_table_[position_i_gain_item_name];
472  if (dxl->ctrl_table_[position_p_gain_item_name] != NULL)
473  dxl->position_p_gain_item_ = dxl->ctrl_table_[position_p_gain_item_name];
474  if (dxl->ctrl_table_[velocity_d_gain_item_name] != NULL)
475  dxl->velocity_d_gain_item_ = dxl->ctrl_table_[velocity_d_gain_item_name];
476  if (dxl->ctrl_table_[velocity_i_gain_item_name] != NULL)
477  dxl->velocity_i_gain_item_ = dxl->ctrl_table_[velocity_i_gain_item_name];
478  if (dxl->ctrl_table_[velocity_p_gain_item_name] != NULL)
479  dxl->velocity_p_gain_item_ = dxl->ctrl_table_[velocity_p_gain_item_name];
480 
481  fprintf(stderr, "(%s) [ID:%3d] %14s added. \n", port.c_str(), dxl->id_, dxl->model_name_.c_str());
482  //std::cout << "[ID:" << (int)(_dxl->id) << "] " << _dxl->model_name << " added. (" << port << ")" << std::endl;
483  file.close();
484  }
485  else
486  std::cout << "Unable to open file : " + path << std::endl;
487 
488  return dxl;
489 }
490 
492 {
493  return control_cycle_msec_;
494 }
std::string model_name_
Definition: device.h:42
#define SESSION_CONTROL_INFO
Definition: robot.h:37
static PortHandler * getPortHandler(const char *port_name)
Dynamixel * getDynamixel(std::string path, int id, std::string port, float protocol_version)
Definition: robot.cpp:315
ROSCPP_DECL void start()
int32_t value_of_max_radian_position_
Definition: dynamixel.h:50
#define DEFAULT_CONTROL_CYCLE
Definition: robot.h:44
ControlTableItem * present_velocity_item_
Definition: dynamixel.h:56
ControlTableItem * position_p_gain_item_
Definition: dynamixel.h:61
static std::string & rtrim(std::string &s)
Definition: robot.cpp:37
ControlTableItem * velocity_p_gain_item_
Definition: dynamixel.h:64
#define SESSION_PORT_INFO
Definition: robot.h:38
Robot(std::string robot_file_path, std::string dev_desc_dir_path)
Definition: robot.cpp:64
#define DYNAMIXEL
Definition: robot.h:34
std::map< std::string, dynamixel::PortHandler * > ports_
Definition: robot.h:55
std::vector< ControlTableItem * > bulk_read_items_
Definition: device.h:46
std::string port_name_
Definition: device.h:43
std::map< std::string, Dynamixel * > dxls_
Definition: robot.h:58
#define SENSOR
Definition: robot.h:35
ControlTableItem * present_position_item_
Definition: dynamixel.h:55
std::map< std::string, std::string > port_default_device_
Definition: robot.h:56
ControlTableItem * goal_current_item_
Definition: dynamixel.h:60
#define SESSION_CONTROL_TABLE
Definition: robot.h:42
#define SESSION_TYPE_INFO
Definition: robot.h:41
ControlTableItem * goal_position_item_
Definition: dynamixel.h:58
ControlTableItem * torque_enable_item_
Definition: dynamixel.h:54
ControlTableItem * position_i_gain_item_
Definition: dynamixel.h:62
ControlTableItem * velocity_i_gain_item_
Definition: dynamixel.h:65
ControlTableItem * position_d_gain_item_
Definition: dynamixel.h:63
std::map< std::string, Sensor * > sensors_
Definition: robot.h:59
int32_t value_of_min_radian_position_
Definition: dynamixel.h:49
ControlTableItem * goal_velocity_item_
Definition: dynamixel.h:59
#define INDIRECT_DATA_1
static std::vector< std::string > split(const std::string &text, char sep)
Definition: robot.cpp:47
static std::string & ltrim(std::string &s)
Definition: robot.cpp:32
#define SESSION_DEVICE_INFO
Definition: robot.h:39
ControlTableItem * velocity_d_gain_item_
Definition: dynamixel.h:66
Sensor * getSensor(std::string path, int id, std::string port, float protocol_version)
Definition: robot.cpp:229
#define INDIRECT_ADDRESS_1
ControlTableItem * present_current_item_
Definition: dynamixel.h:57
static std::string & trim(std::string &s)
Definition: robot.cpp:42
std::map< std::string, ControlTableItem * > ctrl_table_
Definition: device.h:45


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