driver_helpers.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2015 Aldebaran
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 #include "driver_helpers.hpp"
19 #include <boost/property_tree/ptree.hpp>
20 #include <boost/property_tree/xml_parser.hpp>
21 
22 namespace naoqi
23 {
24 namespace helpers
25 {
26 namespace driver
27 {
28 namespace pt = boost::property_tree;
29 
30 static pt::ptree empty_ptree;
31 
34 static naoqi_bridge_msgs::RobotInfo& getRobotInfoLocal( const qi::SessionPtr& session)
35 {
36  static naoqi_bridge_msgs::RobotInfo info;
37  static qi::Url robot_url;
38 
39  if (robot_url == session->url())
40  {
41  return info;
42  }
43 
44  robot_url = session->url();
45 
46  // Get the robot type
47  std::cout << "Receiving information about robot model" << std::endl;
48  qi::AnyObject p_memory = session->service("ALMemory").value();
49  std::string robot = p_memory.call<std::string>("getData", "RobotConfig/Body/Type" );
50  std::string hardware_version = p_memory.call<std::string>("getData", "RobotConfig/Body/BaseVersion" );
51  robot::NaoqiVersion naoqi_version = getNaoqiVersion(session);
52  std::transform(robot.begin(), robot.end(), robot.begin(), ::tolower);
53 
54  std::cout << BOLDYELLOW << "Robot detected/NAOqi version: " << RESETCOLOR;
55 
56  if (std::string(robot) == "nao")
57  {
59  std::cout << BOLDCYAN << "NAO " << hardware_version << RESETCOLOR;
60  }
61  if (std::string(robot) == "pepper" || std::string(robot) == "juliette" )
62  {
64  std::cout << BOLDCYAN << "Pepper " << hardware_version << RESETCOLOR;
65  }
66  if (std::string(robot) == "romeo" )
67  {
69  std::cout << BOLDCYAN << "Romeo " << hardware_version << RESETCOLOR;
70  }
71 
72  std::cout << BOLDCYAN << " / " << naoqi_version.text << RESETCOLOR << std::endl;
73 
74  // Get the data from RobotConfig
75  qi::AnyObject p_motion = session->service("ALMotion").value();
76  try
77  {
78  std::vector<std::vector<qi::AnyValue>> config = p_motion.call<std::vector<std::vector<qi::AnyValue>>>("getRobotConfig");
79 
80  // TODO, fill with the proper string matches from http://doc.aldebaran.com/2-1/naoqi/motion/tools-general-api.html#ALMotionProxy::getRobotConfig
81 
82  for (size_t i = 0; i < config[0].size(); ++i)
83  {
84  if (config[0][i].as<std::string>() == "Model Type")
85  {
86  try
87  {
88  info.model = config[1][i].as<std::string>();
89  }
90  catch (const std::exception &e)
91  {
92  std::cout << "Error in robot config variable " << (config[0][i]).as<std::string>() << std::endl;
93  }
94  }
95 
96  if (config[0][i].as<std::string>() == "Head Version")
97  {
98  try
99  {
100  info.head_version = config[1][i].as<std::string>();
101  }
102  catch (const std::exception &e)
103  {
104  std::cout << "Error in robot config variable " << (config[0][i]).as<std::string>() << std::endl;
105  }
106  }
107 
108  if (config[0][i].as<std::string>() == "Body Version")
109  {
110  try
111  {
112  info.body_version = config[1][i].as<std::string>();
113  }
114  catch (const std::exception &e)
115  {
116  std::cout << "Error in robot config variable " << (config[0][i]).as<std::string>() << std::endl;
117  }
118  }
119 
120  if (config[0][i].as<std::string>() == "Arm Version")
121  {
122  try
123  {
124  info.arm_version = config[1][i].as<std::string>();
125  }
126  catch (const std::exception &e)
127  {
128  std::cout << "Error in robot config variable " << (config[0][i]).as<std::string>() << std::endl;
129  }
130  }
131 
132  if (config[0][i].as<std::string>() == "Laser")
133  {
134  try
135  {
136  info.has_laser = config[1][i].as<bool>();
137  }
138  catch (const std::exception &e)
139  {
140  std::cout << "Error in robot config variable " << (config[0][i]).as<std::string>() << std::endl;
141  }
142  }
143 
144  if (config[0][i].as<std::string>() == "Extended Arms")
145  {
146  try
147  {
148  info.has_extended_arms = config[1][i].as<bool>();
149  }
150  catch (const std::exception &e)
151  {
152  std::cout << "Error in robot config variable " << (config[0][i]).as<std::string>() << std::endl;
153  }
154  }
155 
156  if (config[0][i].as<std::string>() == "Number of Legs")
157  {
158  try
159  {
160  info.number_of_legs = config[1][i].as<int>();
161  }
162  catch (const std::exception &e)
163  {
164  std::cout << "Error in robot config variable " << (config[0][i]).as<std::string>() << std::endl;
165  }
166  }
167 
168  if (config[0][i].as<std::string>() == "Number of Arms")
169  {
170  try
171  {
172  info.number_of_arms = config[1][i].as<int>();
173  }
174  catch (const std::exception &e)
175  {
176  std::cout << "Error in robot config variable " << (config[0][i]).as<std::string>() << std::endl;
177  }
178  }
179 
180  if (config[0][i].as<std::string>() == "Number of Hands")
181  {
182  try
183  {
184  info.number_of_hands = config[1][i].as<int>();
185  }
186  catch (const std::exception &e)
187  {
188  std::cout << "Error in robot config variable " << (config[0][i]).as<std::string>() << std::endl;
189  }
190  }
191  }
192  }
193  catch (...)
194  {
195  // NAOqi 2.9
196  std::cout << "ALMotion.getRobotConfig failed (" /*<< e.what()*/ << "), trying with newer service ALRobotModel" << std::endl;
197  auto p_robot_model = session->service("ALRobotModel").value();
198 
199  try
200  {
201  info.model = p_robot_model.call<std::string>("getRobotType");
202  }
203  catch (const std::exception &e)
204  {
205  std::cout << "Error getting robot type (with ALRobotModel.getRobotType): " << e.what() << std::endl;
206  }
207 
208  try
209  {
210  info.number_of_legs = p_robot_model.call<bool>("hasLegs") ? 1 : 0;
211  }
212  catch (const std::exception &e)
213  {
214  std::cout << "Error getting robot type (with ALRobotModel.getRobotType): " << e.what() << std::endl;
215  }
216 
217  try
218  {
219  std::istringstream config_data(p_robot_model.call<std::string>("getConfig"));
220  pt::ptree tree;
221  pt::read_xml(config_data, tree);
222 
223  auto preferences = tree.get_child("ModulePreference");
224  for (const auto& pref: preferences) {
225  if (pref.first != "Preference")
226  continue;
227  const pt::ptree& attributes = pref.second.get_child("<xmlattr>", empty_ptree);
228 
229  const auto& memory_key = attributes.get<std::string>("memoryName");
230  if (memory_key == "RobotConfig/Head/Version") {
231  info.head_version = attributes.get<std::string>("value");
232  } else if (memory_key == "RobotConfig/Body/Version") {
233  info.body_version = attributes.get<std::string>("value");
234  } else if (memory_key == "RobotConfig/Body/Device/LeftArm/Version") {
235  info.arm_version = attributes.get<std::string>("value");
236  }
237  }
238  }
239  catch (const std::exception &e)
240  {
241  std::cout << "Error getting head version (with ALRobotModel.getConfig): " << e.what() << std::endl;
242  }
243 
244  // Some data is missing, but anyways only Pepper 1.8 is supported by NAOqi 2.9.
245  info.has_laser = false;
246  info.has_extended_arms = false;
247  info.number_of_arms = 2;
248  info.number_of_hands = 2;
249  }
250 
251  return info;
252 }
253 
254 const robot::Robot& getRobot( const qi::SessionPtr& session )
255 {
256  static robot::Robot robot = robot::UNIDENTIFIED;
257 
258  if ( getRobotInfo(session).type == naoqi_bridge_msgs::RobotInfo::NAO )
259  {
260  robot = robot::NAO;
261  }
262  if ( getRobotInfo(session).type == naoqi_bridge_msgs::RobotInfo::PEPPER )
263  {
264  robot = robot::PEPPER;
265  }
266  if ( getRobotInfo(session).type == naoqi_bridge_msgs::RobotInfo::ROMEO )
267  {
268  robot = robot::ROMEO;
269  }
270 
271  return robot;
272 }
273 
280 const robot::NaoqiVersion& getNaoqiVersion( const qi::SessionPtr& session )
281 {
282  static robot::NaoqiVersion naoqi_version;
283 
284  try {
285  qi::AnyObject p_system = session->service("ALSystem").value();
286  naoqi_version.text = p_system.call<std::string>("systemVersion");
287 
288  } catch (const std::exception& e) {
289  std::cerr << "Could not retrieve the version of NAOqi: "
290  << e.what()
291  << std::endl;
292 
293  naoqi_version.text = "unknown";
294  return naoqi_version;
295  }
296 
297  std::string buff("");
298  std::vector<int> version_numbers;
299 
300  for (std::string::size_type i = 0; i < naoqi_version.text.size(); ++i)
301  {
302  if (naoqi_version.text[i] != '.')
303  {
304  buff += naoqi_version.text[i];
305  }
306  else if (naoqi_version.text[i] == '.' && buff != "")
307  {
308  version_numbers.push_back(std::atoi(buff.c_str()));
309  buff = "";
310  }
311  }
312 
313  if (buff != "")
314  {
315  version_numbers.push_back(std::atoi(buff.c_str()));
316  }
317 
318  if (version_numbers.size() != 4)
319  {
320  std::cerr << "Unconsistent version number for NAOqi, should contain 4 "
321  << "elements: "
322  << naoqi_version.text
323  << std::endl;
324 
325  return naoqi_version;
326  }
327 
328  naoqi_version.major = version_numbers[0];
329  naoqi_version.minor = version_numbers[1];
330  naoqi_version.patch = version_numbers[2];
331  naoqi_version.build = version_numbers[3];
332  return naoqi_version;
333 }
334 
335 const naoqi_bridge_msgs::RobotInfo& getRobotInfo( const qi::SessionPtr& session )
336 {
337  static naoqi_bridge_msgs::RobotInfo robot_info = getRobotInfoLocal(session);
338  return robot_info;
339 }
340 
343 bool& setLanguage( const qi::SessionPtr& session, naoqi_bridge_msgs::SetStringRequest req)
344 {
345  static bool success;
346  std::cout << "Receiving service call of setting speech language" << std::endl;
347  try{
348  qi::AnyObject p_text_to_speech = session->service("ALTextToSpeech").value();
349  p_text_to_speech.call<void>("setLanguage", req.data);
350  success = true;
351  return success;
352  }
353  catch(const std::exception& e){
354  success = false;
355  return success;
356  }
357 }
358 
361 std::string& getLanguage( const qi::SessionPtr& session )
362 {
363  static std::string language;
364  std::cout << "Receiving service call of getting speech language" << std::endl;
365  qi::AnyObject p_text_to_speech = session->service("ALTextToSpeech").value();
366  language = p_text_to_speech.call<std::string>("getLanguage");
367  return language;
368 }
369 
373 bool isDepthStereo(const qi::SessionPtr &session) {
374  std::vector<std::string> sensor_names;
375 
376  try {
377  qi::AnyObject p_motion = session->service("ALMotion").value();
378  sensor_names = p_motion.call<std::vector<std::string> >("getSensorNames");
379 
380  if (std::find(sensor_names.begin(),
381  sensor_names.end(),
382  "CameraStereo") != sensor_names.end()) {
383  return true;
384  }
385 
386  else {
387  return false;
388  }
389 
390  } catch (const std::exception &e) {
391  std::cerr << e.what() << std::endl;
392  return false;
393  }
394 }
395 
409  const robot::NaoqiVersion& naoqi_version,
410  const int& major,
411  const int& minor,
412  const int& patch,
413  const int& build)
414 {
415  if (naoqi_version.major < major)
416  {
417  return true;
418  }
419  else if (naoqi_version.minor < minor)
420  {
421  return true;
422  }
423  else if (naoqi_version.patch < patch)
424  {
425  return true;
426  }
427  else if (naoqi_version.build < build)
428  {
429  return true;
430  }
431  else
432  {
433  return false;
434  }
435 }
436 
437 } // driver
438 } // helpers
439 } // naoqi
const naoqi_bridge_msgs::RobotInfo & getRobotInfo(const qi::SessionPtr &session)
#define RESETCOLOR
Definition: tools.hpp:22
const robot::NaoqiVersion & getNaoqiVersion(const qi::SessionPtr &session)
Function that retrieves the NAOqi version of the robot.
#define BOLDCYAN
Definition: tools.hpp:28
static naoqi_bridge_msgs::RobotInfo & getRobotInfoLocal(const qi::SessionPtr &session)
static pt::ptree empty_ptree
bool isDepthStereo(const qi::SessionPtr &session)
std::string & getLanguage(const qi::SessionPtr &session)
#define BOLDYELLOW
Definition: tools.hpp:27
bool & setLanguage(const qi::SessionPtr &session, naoqi_bridge_msgs::SetStringRequest req)
const robot::Robot & getRobot(const qi::SessionPtr &session)
bool isNaoqiVersionLesser(const robot::NaoqiVersion &naoqi_version, const int &major, const int &minor, const int &patch, const int &build)
Function that returns true if the provided naoqi_version is (strictly) lesser than the specified one ...


naoqi_driver
Author(s): Karsten Knese
autogenerated on Sat Jul 1 2023 02:53:24