sr_hand_autodetect.cpp
Go to the documentation of this file.
1 /*
2 * Copyright 2020 Shadow Robot Company Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the Free
6 * Software Foundation version 2 of the License.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16 
17 #include <iostream>
18 #include <ros/package.h>
19 #include <string>
20 #include <utility>
21 #include <map>
22 #include <vector>
23 
25 #include "yaml-cpp/yaml.h"
26 #include "yaml-cpp/exceptions.h"
27 
28 namespace sr_hand_detector
29 {
30 SrHandAutodetect::SrHandAutodetect(std::string detected_hands_file,
31  std::string hand_config_path,
32  ForcedHandSide forced_hand_side) :
33  detected_hands_file_(detected_hands_file),
34  forced_hand_side_(forced_hand_side)
35 {
36  if (hand_config_path.empty())
37  {
39  }
40  else
41  {
42  sr_hand_config_path_ = hand_config_path;
43  }
44 }
45 
47 {
48 }
49 
51 {
52  sr_hand_config_path_ = ros::package::getPath("sr_hand_config");
53  if (sr_hand_config_path_.empty())
54  {
55  throw std::runtime_error("sr_hand_autodetect: Did not find sr_hand_config package.");
56  }
57 }
58 
60 {
61  detect_hands();
64 }
65 
67 {
68  return command_suffix_;
69 }
70 
72 {
73  std::string path_to_info_file = sr_hand_config_path_ + "/" + std::to_string(serial) + "/general_info.yaml";
74  try
75  {
76  return YAML::LoadFile(path_to_info_file);
77  }
78  catch(YAML::BadFile)
79  {
80  std::cerr << "sr_hand_autodetect: General info for detected hand does not exist!";
81  throw;
82  }
83 }
84 
86 {
87  YAML::Node config = YAML::LoadFile(detected_hands_file_);
88  for (YAML::const_iterator it = config.begin(); it != config.end(); ++it)
89  {
90  hand_serial_and_port_map_.insert(std::pair<int, std::string>(it->first.as<int>(), it->second.as<std::string>()));
91  }
93 }
94 
96 {
98 
99  std::string side_to_remove_string;
100  switch (forced_hand_side_)
101  {
103  side_to_remove_string = "left";
104  break;
105 
107  side_to_remove_string = "right";
108  break;
109 
110  default:
111  throw std::runtime_error("sr_hand_autodetect: Unknown side to be forced");
112  }
113 
114  for (auto it = hand_serial_and_port_map_.cbegin(); it != hand_serial_and_port_map_.cend(); /* no increment */)
115  {
116  auto detected_hand_side = get_hand_general_info(it->first)["side"].as<std::string>();
117  if (side_to_remove_string == detected_hand_side)
118  {
119  hand_serial_and_port_map_.erase(it++);
120  }
121  else
122  {
123  ++it;
124  }
125  }
126 
128 }
129 
131 {
133  {
134  case 0:
135  std::cout << "No hands detected. Not wrapping the roslaunch command!" << std::endl;
136  command_suffix_ = "";
137  break;
138 
139  case 1:
141  break;
142 
143  case 2:
145  break;
146 
147  default:
148  throw std::runtime_error("sr_hand_autodetect: Unsupported number of hands detected in the system");
149  }
150 }
151 
153 {
154  int hand_serial = hand_serial_and_port_map_.begin()->first;
155  std::string eth_port = hand_serial_and_port_map_.begin()->second;
156  YAML::Node hand_info = get_hand_general_info(hand_serial);
157 
158  command_suffix_ = " eth_port:=" + eth_port +
159  " hand_serial:=" + std::to_string(hand_serial) +
160  " side:=" + hand_info["side"].as<std::string>() +
161  " hand_type:=" + hand_info["type"].as<std::string>() +
162  " hand_version:=" + hand_info["version"].as<std::string>() +
163  " fingers:=" + vector_to_xacro_string(yaml_node_list_to_std_vector(hand_info["fingers"])) +
164  " tip_sensors:=" + map_to_xacro_string(yaml_node_map_to_std_map(hand_info["sensors"]["tip"])) +
165  " mid_sensors:=" + map_to_xacro_string(yaml_node_map_to_std_map(hand_info["sensors"]["mid"])) +
166  " prox_sensors:=" + map_to_xacro_string(yaml_node_map_to_std_map(hand_info["sensors"]["prox"])) +
167  " palm_sensor:=" + map_to_xacro_string(yaml_node_map_to_std_map(hand_info["sensors"]["palm"]));
168 
169  if (hand_info["mapping_path"])
170  {
171  std::string mapping_path = ros::package::getPath(hand_info["mapping_path"] \
172  ["package_name"].as<std::string>()) +
173  "/" + hand_info["mapping_path"] \
174  ["relative_path"].as<std::string>();
175  command_suffix_ += " mapping_path:=" + mapping_path;
176  }
177 }
178 
180 {
181  int rh_serial, lh_serial;
182  std::string rh_eth_port, lh_eth_port, rh_command_component, lh_command_component, mapping_path_suffix_component;
183  command_suffix_.clear();
184 
185  for (auto const& serial_to_port : hand_serial_and_port_map_)
186  {
187  YAML::Node hand_info = get_hand_general_info(serial_to_port.first);
188  std::string hand_side = hand_info["side"].as<std::string>();
189  if ("right" == hand_side)
190  {
191  rh_serial = serial_to_port.first;
192  rh_eth_port = serial_to_port.second;
193  rh_command_component = command_suffix_bimanual_per_hand(hand_info);
194  }
195  else if ("left" == hand_side)
196  {
197  lh_serial = serial_to_port.first;
198  lh_eth_port = serial_to_port.second;
199  lh_command_component = command_suffix_bimanual_per_hand(hand_info);
200  }
201  else
202  {
203  throw std::runtime_error("sr_hand_autodetect: Unsupported hand id");
204  }
205  }
206 
207  command_suffix_ += " eth_port:=" + rh_eth_port + "_" + lh_eth_port + " rh_serial:=" +
208  std::to_string(rh_serial) + " lh_serial:=" + std::to_string(lh_serial) +
209  rh_command_component + lh_command_component + mapping_path_suffix_component;
210 }
211 
212 
213 std::string SrHandAutodetect::command_suffix_bimanual_per_hand(const YAML::Node &hand_info)
214 {
215  std::string mapping_path_suffix_component;
216  std::string side = hand_info["side"].as<std::string>();
217 
218  if (hand_info["mapping_path"])
219  {
220  std::string mapping_path = ros::package::getPath(hand_info["mapping_path"] \
221  ["package_name"].as<std::string>()) +
222  "/" + hand_info["mapping_path"] \
223  ["relative_path"].as<std::string>();
224  mapping_path_suffix_component += " " + hand_side_to_prefix(side) + "_mapping_path:=" + mapping_path;
225  }
226 
227  return " " + side + "_hand_type:=" + hand_info["type"].as<std::string>() +
228  " " + side + "_hand_version:=" + hand_info["version"].as<std::string>() +
229  " " + side + "_fingers:=" + vector_to_xacro_string(yaml_node_list_to_std_vector(hand_info["fingers"])) +
230  " " + side + "_tip_sensors:=" + map_to_xacro_string(yaml_node_map_to_std_map(hand_info["sensors"]["tip"])) +
231  " " + side + "_mid_sensors:=" + map_to_xacro_string(yaml_node_map_to_std_map(hand_info["sensors"]["mid"])) +
232  " " + side + "_prox_sensors:=" + map_to_xacro_string(yaml_node_map_to_std_map(hand_info["sensors"]["prox"])) +
233  " " + side + "_palm_sensor:=" + map_to_xacro_string(yaml_node_map_to_std_map(hand_info["sensors"]["palm"])) +
234  mapping_path_suffix_component;
235 }
236 
237 std::string SrHandAutodetect::hand_side_to_prefix(const std::string &side)
238 {
239  if ("right" == side)
240  {
241  return "rh";
242  }
243  else if ("left" == side)
244  {
245  return "lh";
246  }
247 
248  throw std::runtime_error("Unknown hand type!");
249 }
250 
251 std::string SrHandAutodetect::vector_to_xacro_string(const std::vector<std::string> &vec)
252 {
253  if (vec.size() == 0) return "none";
254 
255  std::string result;
256 
257  for (auto it = vec.begin(); it != vec.end(); ++it)
258  {
259  result += (*it);
260  if (it != std::prev(vec.end())) result += ",";
261  }
262 
263  return result;
264 }
265 
266 std::string SrHandAutodetect::map_to_xacro_string(const std::map<std::string, std::string> &m)
267 {
268  if (m.size() == 0) return "none";
269 
270  std::string result;
271 
272  for (auto it = m.begin(); it != m.end(); it++)
273  {
274  result += (it->first + "=" + it->second);
275  if (it != std::prev(m.end())) result += ",";
276  }
277 
278  return result;
279 }
280 
281 std::vector<std::string> SrHandAutodetect::yaml_node_list_to_std_vector(const YAML::Node &node_list)
282 {
283  std::vector<std::string> result;
284 
285  for (std::size_t i = 0; i < node_list.size(); ++i)
286  {
287  result.push_back(node_list[i].as<std::string>());
288  }
289 
290  return result;
291 }
292 
293 std::map<std::string, std::string> SrHandAutodetect::yaml_node_map_to_std_map(const YAML::Node &node_map)
294 {
295  std::map<std::string, std::string> result;
296 
297  for (auto it=node_map.begin(); it != node_map.end(); ++it)
298  {
299  result.insert(std::pair<std::string, std::string>(it->first.as<std::string>(), it->second.as<std::string>()));
300  }
301 
302  return result;
303 }
304 
305 
306 } // namespace sr_hand_detector
sr_hand_detector::SrHandAutodetect::map_to_xacro_string
std::string map_to_xacro_string(const std::map< std::string, std::string > &map)
Definition: sr_hand_autodetect.cpp:266
sr_hand_detector::SrHandAutodetect::run
void run()
Definition: sr_hand_autodetect.cpp:59
sr_hand_detector::SrHandAutodetect::get_command_suffix
std::string get_command_suffix()
Definition: sr_hand_autodetect.cpp:66
ros::package::getPath
ROSLIB_DECL std::string getPath(const std::string &package_name)
sr_hand_detector::SrHandAutodetect::hand_serial_and_port_map_
std::map< int, std::string > hand_serial_and_port_map_
Definition: sr_hand_autodetect.h:62
sr_hand_detector::SrHandAutodetect::yaml_node_list_to_std_vector
std::vector< std::string > yaml_node_list_to_std_vector(const YAML::Node &node)
Definition: sr_hand_autodetect.cpp:281
sr_hand_detector::SrHandAutodetect::forced_hand_side_
ForcedHandSide forced_hand_side_
Definition: sr_hand_autodetect.h:57
sr_hand_detector::SrHandAutodetect::command_suffix_bimanual_per_hand
std::string command_suffix_bimanual_per_hand(const YAML::Node &hand_info)
Definition: sr_hand_autodetect.cpp:213
sr_hand_detector::SrHandAutodetect::detect_hands
void detect_hands()
Definition: sr_hand_autodetect.cpp:85
sr_hand_detector::SrHandAutodetect::hand_side_to_prefix
std::string hand_side_to_prefix(const std::string &side)
Definition: sr_hand_autodetect.cpp:237
sr_hand_detector
Definition: sr_hand_autodetect.h:27
sr_hand_detector::SrHandAutodetect::compose_command_suffix_unimanual
void compose_command_suffix_unimanual()
Definition: sr_hand_autodetect.cpp:152
sr_hand_detector::SrHandAutodetect::yaml_node_map_to_std_map
std::map< std::string, std::string > yaml_node_map_to_std_map(const YAML::Node &node_map)
Definition: sr_hand_autodetect.cpp:293
sr_hand_detector::SrHandAutodetect::command_suffix_
std::string command_suffix_
Definition: sr_hand_autodetect.h:61
sr_hand_detector::SrHandAutodetect::compose_command_suffix
void compose_command_suffix()
Definition: sr_hand_autodetect.cpp:130
sr_hand_detector::SrHandAutodetect::get_path_to_sr_hand_config
void get_path_to_sr_hand_config()
Definition: sr_hand_autodetect.cpp:50
sr_hand_detector::SrHandAutodetect::compose_command_suffix_bimanual
void compose_command_suffix_bimanual()
Definition: sr_hand_autodetect.cpp:179
package.h
sr_hand_detector::SrHandAutodetect::detected_hands_file_
std::string detected_hands_file_
Definition: sr_hand_autodetect.h:60
sr_hand_detector::ForcedHandSide::right
@ right
sr_hand_detector::SrHandAutodetect::SrHandAutodetect
SrHandAutodetect(std::string detected_hands_file="/tmp/sr_hand_detector.yaml", std::string hand_config_path="", ForcedHandSide forced_hand_side=ForcedHandSide::none)
Definition: sr_hand_autodetect.cpp:30
sr_hand_detector::SrHandAutodetect::vector_to_xacro_string
std::string vector_to_xacro_string(const std::vector< std::string > &vec)
Definition: sr_hand_autodetect.cpp:251
sr_hand_detector::ForcedHandSide::left
@ left
sr_hand_detector::SrHandAutodetect::number_of_detected_hands_
int number_of_detected_hands_
Definition: sr_hand_autodetect.h:58
sr_hand_detector::ForcedHandSide::none
@ none
sr_hand_detector::SrHandAutodetect::sr_hand_config_path_
std::string sr_hand_config_path_
Definition: sr_hand_autodetect.h:59
sr_hand_detector::SrHandAutodetect::~SrHandAutodetect
~SrHandAutodetect()
Definition: sr_hand_autodetect.cpp:46
sr_hand_autodetect.h
sr_hand_detector::ForcedHandSide
ForcedHandSide
Definition: sr_hand_autodetect.h:30
sr_hand_detector::SrHandAutodetect::filter_hands_if_side_forced
void filter_hands_if_side_forced()
Definition: sr_hand_autodetect.cpp:95
sr_hand_detector::SrHandAutodetect::get_hand_general_info
YAML::Node get_hand_general_info(int serial)
Definition: sr_hand_autodetect.cpp:71


sr_hand_detector
Author(s):
autogenerated on Sat Sep 24 2022 02:26:10