Main MRPT website > C++ reference for MRPT 1.9.9
CRovio.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include "hwdrivers-precomp.h" // Precompiled headers
11 
12 #include <mrpt/hwdrivers/CRovio.h>
14 #include <mrpt/comms/net_utils.h>
17 
18 #include <thread>
19 
20 using namespace mrpt::utils;
21 using namespace mrpt::obs;
22 using namespace mrpt::hwdrivers;
23 using namespace mrpt::comms::net;
24 using namespace std;
25 
26 CRovio::TOptions::TOptions()
27  : IP("150.214.109.134"), user("admin"), password("investigacion")
28 // We could fill the camera matrices here instead of in initialization
29 {
30  double cam_params[] = {1650.740234375,
31  0,
32  805.33190917968750,
33  0,
34  1640.6497802734375,
35  675.1627197265625,
36  0,
37  0,
38  1};
41  0.12792350351810455, -0.4786585867404937, 0.011172077618539333,
42  -0.0037264013662934303);
43  // cameraParams.focalLengthMeters =
44 }
45 
46 /*-------------------------------------------------
47  INITIALIZE
48  -----------------------------------------------*/
49 void CRovio::initialize() // string &errormsg, string url_out, string user_out,
50 // string password_out)
51 {
52  string response, errormsg;
53  http_get(
54  format("http://%s/rev.cgi?Cmd=nav&action=1", options.IP.c_str()),
55  response, errormsg, 80, options.user, options.password);
56 
57  if (!response.empty())
58  cout << "[CRovio::Initialize] Response:\n" << response << endl;
59 
60  if (!errormsg.empty())
61  THROW_EXCEPTION_FMT("Error initializing Rovio: %s", errormsg.c_str());
62 }
63 
64 /*-------------------------------------------------
65  SEND MOVEMENT COMMAND (Manual Drive)
66  -----------------------------------------------*/
67 bool CRovio::send_cmd_action(int direction, int speed)
68 {
69  string response, errormsg;
70  string command = format(
71  "http://%s/rev.cgi?Cmd=nav&action=18&drive=%i&speed=%i",
72  options.IP.c_str(), direction, speed);
73  http_get(command, response, errormsg, 80, options.user, options.password);
74  return errormsg.empty();
75 }
76 
77 /*-------------------------------------------------
78  PATH MANAGEMENT
79  -----------------------------------------------*/
81 {
82  string response, errormsg;
83  string command;
84  command =
85  format("http://%s/rev.cgi?Cmd=nav&action=%i", options.IP.c_str(), act);
86  http_get(command, response, errormsg, 80, options.user, options.password);
87  return errormsg.empty();
88 }
89 
90 bool CRovio::path_management(int act, const string& path_name)
91 {
92  string response, errormsg;
93  string command;
94  command = format(
95  "http://%s/rev.cgi?Cmd=nav&action=%i&name=%s", options.IP.c_str(), act,
96  path_name.c_str());
97  http_get(command, response, errormsg, 80, options.user, options.password);
98  return errormsg.empty();
99 }
100 
101 /*-------------------------------------------------
102  GENERAL COMMAND
103  -----------------------------------------------*/
104 bool CRovio::general_command(int act, string& response, string& errormsg)
105 {
106  string command;
107  command =
108  format("http://%s/rev.cgi?Cmd=nav&action=%i", options.IP.c_str(), act);
109  http_get(command, response, errormsg, 80, options.user, options.password);
110  return errormsg.empty();
111 }
112 
113 /*-------------------------------------------------
114  MOVE ROBOT
115  -----------------------------------------------*/
116 bool CRovio::move(char direction, int speed)
117 {
118  switch (direction)
119  {
120  case 'f': // Forward
121  return send_cmd_action(1, speed);
122  case 'b': // Backward
123  return send_cmd_action(2, speed);
124  case 'l': // Left
125  return send_cmd_action(3, speed);
126  case 'r': // Right
127  return send_cmd_action(4, speed);
128  default:
129  cout << "Error in parameter of move()";
130  return false;
131  }
132 }
133 
134 bool CRovio::rotate(char direction, int speed)
135 {
136  switch (direction)
137  {
138  case 'l': // Left
139  return send_cmd_action(5, speed);
140  case 'r': // Right
141  return send_cmd_action(6, speed);
142  default:
143  cout << "Error in parameter of rotate()";
144  return false;
145  }
146 }
147 /*-------------------------------------------------
148  MOVE HEAD
149  -----------------------------------------------*/
150 bool CRovio::takeHeadUp() { return send_cmd_action(11, 5); }
151 bool CRovio::takeHeadMiddle() { return send_cmd_action(13, 5); }
152 bool CRovio::takeHeadDown() { return send_cmd_action(12, 5); }
153 /*-------------------------------------------------
154  PATH COMMAND
155  -----------------------------------------------*/
156 bool CRovio::pathRecord() { return path_management(2); }
158 bool CRovio::pathRecordSave(const string& path_name)
159 {
160  return path_management(4, path_name);
161 }
162 bool CRovio::pathDelete(const string& path_name)
163 {
164  return path_management(5, path_name);
165 }
166 bool CRovio::pathGetList(string& path_list)
167 {
168  string error;
169  general_command(6, path_list, error);
170  return error.empty();
171 }
175 bool CRovio::pathRunPause() { return path_management(10); }
176 bool CRovio::pathRename(const string& current_name, const string& new_name)
177 {
178  string response, errormsg;
179  string command = format(
180  "http://%s/rev.cgi?Cmd=nav&action=11&name=%s&newname=%s",
181  options.IP.c_str(), current_name.c_str(), new_name.c_str());
182  http_get(command, response, errormsg, 80, options.user, options.password);
183  return errormsg.empty();
184 }
185 
186 /*-------------------------------------------------
187  GO HOME
188  -----------------------------------------------*/
189 bool CRovio::goHome(bool dock, int speed)
190 {
191  if (dock)
192  return send_cmd_action(13, speed);
193  else
194  return send_cmd_action(12, speed);
195 }
196 
197 /*-------------------------------------------------
198  CAMERA FUNCTIONS
199  -----------------------------------------------*/
201  const mrpt::utils::CConfigFileBase& configSource,
202  const std::string& section)
203 {
204  options.cameraParams.loadFromConfigFile(section, configSource);
205 
206  // Any other params??
207 }
208 /*-------------------------------------------------
209  VIDEO STREAMING
210  -----------------------------------------------*/
211 void CRovio::thread_video() // This function takes a frame and waits until
212 // getLastImage() ask for it, and so on.
213 {
214  try
215  {
216  // obj -> this
217  CFFMPEG_InputStream in_video;
218  string video_url = format("rtsp://%s/webcam", options.IP.c_str());
219 
220  const bool open_ok = in_video.openURL(
221  video_url, false /*grayscale*/, false /* verbose */);
222 
225 
227  {
228  std::cerr << "[CRovio] Error opening video stream: " << video_url
229  << std::endl;
230  return; // Error!
231  }
232 
233  while (!m_videothread_must_exit)
234  {
236  mrpt::make_aligned_shared<CObservationImage>();
237 
238  if (in_video.retrieveFrame(obs->image))
239  {
240  obs->cameraParams = options.cameraParams;
241 
242  // Critical section
243  {
244  std::lock_guard<std::mutex> cs(this->buffer_img_cs);
245  this->buffer_img = obs;
246  // cout<<"[CRovio::threadVideo] Image grabbed\n";
247  }
248  }
249  else
250  {
251  // obs.clear(); //If no image was copied, destroy the thisect.
252  cout << "[CRovio::thread_video] Warning: the program doesn't "
253  "receive any image\n";
254  }
255  std::this_thread::sleep_for(10ms);
256  } // end while
257 
258  in_video.close();
259 
260  m_videothread_finished = true;
261  }
262  catch (std::exception& e) // que hace eactamente esto?
263  {
264  m_videothread_initialized_done = true; // Just in case...
265  m_videothread_finished = true;
266  cout << "Error in thread_video thread";
267  cerr << e.what() << endl;
268  }
269  catch (...)
270  {
271  m_videothread_initialized_done = true; // Just in case...
272  m_videothread_finished = true;
273  cout << "Error in thread_video thread";
274  }
275 }
276 
278 {
279  if (m_videoThread.get_id() == std::thread::id())
280  {
283  m_videothread_must_exit = false;
284  m_videothread_finished = false;
285 
286  m_videoThread =
287  std::thread(&mrpt::hwdrivers::CRovio::thread_video, this);
288 
290  {
291  std::this_thread::sleep_for(10ms);
292  }
293 
294  // Ok or error?
296  {
297  return false;
298  }
299  else
300  return true; // Grabbing video
301  }
302  else
303  return true;
304 }
305 
307 {
308  return (m_videoThread.joinable() && !m_videothread_finished);
309 }
310 
312 {
313  bool was_already_stop = true;
315  if (isVideoStreamming())
316  {
317  m_videoThread.join();
318  was_already_stop = false;
319  }
320 
321  return !was_already_stop;
322 }
323 
326  lastImage) // This function grabbes the images taken by thread_video
327 {
328  if (!isVideoStreamming()) return false;
329 
330  {
331  std::lock_guard<std::mutex> cs(buffer_img_cs);
332  if (!buffer_img) return false;
333 
334  lastImage = buffer_img;
335  }
336 
337  return true;
338 }
339 
340 /*-------------------------------------------------
341  CAPTURE PICTURE
342  -----------------------------------------------*/
343 bool CRovio::captureImageAsync(CImage& picture, bool rectified)
344 {
345  try
346  {
347  vector_byte resp;
348  string errormsg;
349  string MF =
350  format("http://%s/Jpeg/CamImg[0000].jpg", options.IP.c_str());
351  http_get(MF, resp, errormsg, 80, options.user, options.password);
352 
353  CMemoryStream stream(&resp[0], resp.size());
354  picture.loadFromStreamAsJPEG(stream);
355  if (rectified) // Comprobar que las matrices existen y son
356  // correctas********************
358  // picture.saveToFile("0000.jpg");
359  // cout<<"Response:\n"<<response<<endl;
360  return true;
361  }
362  catch (std::exception& e)
363  {
364  cerr << e.what() << endl;
365  return false;
366  }
367 }
368 
369 /*-------------------------------------------------
370  STATE
371  -----------------------------------------------*/
373 {
375  size_t x_pos, /*y_pos, theta_pos,*/ lenght;
376  string x_value, response, errormsg;
377  mrpt::math::TPose2D pose;
378  general_command(1, response, errormsg); // Get report from Rovio to
379  // response
380 
381  // Getting x value
382  x_pos = response.find("x=");
383  x_value = response.substr((x_pos + 2), 8);
384  lenght = x_value.find('|');
385  x_value = x_value.substr(0, lenght);
386  char* x_char = new char[lenght];
387  strcpy(x_char, x_value.c_str());
388  pose.x = atof(x_char);
389 
390  string error;
391  string state;
392  general_command(1, state, error);
393 
394  return error.empty();
395 }
396 
397 /*-------------------------------------------------
398  GET ENCODERS
399  -----------------------------------------------*/
400 long convertToLong(char* sLong)
401 {
402  char* result = strpbrk(sLong, "-0123456789ABCDEF");
403  char* stop;
404  return strtol(result, &stop, 16);
405 }
406 
408 {
410  string resp, error, field;
411  // string field_name[12]={"Packet length","Not Used","Left Wheel:Dir
412  // Rotation","Left Wheel:Ticks","Right Wheel:Dir Rotation","Right
413  // Wheel:Ticks","Rear Wheel:Dir Rotation","Rear Wheel:Ticks","Not
414  // used","Head Position","Batery","Config Status"};
415  size_t length;
416  int* a_enc = new int[11]; // 12 encoder's fields
417  long l_value;
418 
419  general_command(20, resp, error); // get Encoders string to resp
420  if (error.empty())
421  {
422  size_t pos = (resp.find("responses =") + 12);
423  for (int i = 0; i <= 11; i++)
424  {
425  if ((i == 3) || (i == 5) || (i == 7))
426  length = 4;
427  else
428  length = 2;
429 
430  field = resp.substr(pos, length);
431  pos += length;
432 
433  /*---------- String to binary conv------------------*/
434  char* cstr = new char[field.size() + 1];
435  strcpy(cstr, field.c_str());
436  l_value = convertToLong(cstr);
437 
438  if ((i == 2) || (i == 4) ||
439  (i == 6)) // just interested in bit(2)-> "0000X0"
440  l_value = ((l_value >> 1) & 0x1); // This extracts the last but
441  // one bit of l_value which
442  // sustitutes l_value
443  a_enc[i] = l_value;
444  }
445  // Upload the encoders value
446  if (a_enc[2])
447  this->encoders.left += a_enc[3]; // Esta esto bien asi? o deberia
448  // usar encoders como parametro de
449  // entrada
450  else
451  this->encoders.left -= a_enc[3];
452  if (a_enc[4])
453  this->encoders.left += a_enc[5];
454  else
455  this->encoders.left -= a_enc[5];
456  if (a_enc[6])
457  this->encoders.left += a_enc[7];
458  else
459  this->encoders.left -= a_enc[7];
460 
461  return true;
462  }
463  else
464  {
465  cout << "\n---------------------------------------------------" << endl;
466  cout << "ERROR->" << error << endl;
467 
468  return false;
469  }
470 }
471 
472 /*-------------------------------------------------
473  GET POSITION WITH NORTHSTAR SYSTEM
474  -----------------------------------------------*/
476 {
477  size_t x_pos, y_pos, theta_pos, lenght;
478  string x_value, y_value, theta_value, response, errormsg;
479  general_command(1, response, errormsg); // Get report from Rovio to
480  // response
481 
482  // Getting x value
483  x_pos = response.find("x=");
484  x_value = response.substr((x_pos + 2), 8);
485  lenght = x_value.find('|');
486  x_value = x_value.substr(0, lenght);
487  char* x_char = new char[lenght];
488  strcpy(x_char, x_value.c_str());
489  pose.x = atof(x_char);
490 
491  // Getting y value
492  y_pos = response.find("y=");
493  y_value = response.substr((y_pos + 2), 8);
494  lenght = y_value.find('|');
495  y_value = y_value.substr(0, lenght);
496  char* y_char = new char[lenght];
497  strcpy(y_char, y_value.c_str());
498  pose.y = atof(y_char);
499 
500  // Getting theta value
501  theta_pos = response.find("theta=");
502  theta_value = response.substr((theta_pos + 6), 8);
503  lenght = theta_value.find('|');
504  theta_value = theta_value.substr(0, lenght);
505  char* theta_char = new char[lenght];
506  strcpy(theta_char, theta_value.c_str());
507  pose.phi = atof(theta_char);
508 
509  return errormsg.empty();
510 }
511 
514 {
515  if (isVideoStreamming()) stop_video();
516 }
std::thread m_videoThread
Definition: CRovio.h:31
bool getNextImageSync(mrpt::obs::CObservationImage::Ptr &lastImage)
Returns the next frame from Rovio&#39;s live video stream, after starting the live streaming with retriev...
Definition: CRovio.cpp:324
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
std::vector< uint8_t > vector_byte
Definition: types_simple.h:27
bool getEncoders(TEncoders &encoders)
Returns a TEncoders with information of Rovio encoders (since last read, it seems Rovio is continuous...
Definition: CRovio.cpp:407
double x
X,Y coordinates.
bool send_cmd_action(int act, int speed)
Definition: CRovio.cpp:67
bool path_management(int act)
Definition: CRovio.cpp:80
A class for storing images as grayscale or RGB bitmaps.
Definition: CImage.h:118
void rectifyImageInPlace(const mrpt::utils::TCamera &cameraParams)
Rectify (un-distort) the image according to a certain camera matrix and vector of distortion coeffici...
Definition: CImage.cpp:2062
bool rotate(char direction, int speed=5)
rotate send Rovio the command to rotate in the specified direcction &#39;r&#39;->right, &#39;l&#39;->left ...
Definition: CRovio.cpp:134
#define THROW_EXCEPTION_FMT(_FORMAT_STRING,...)
bool pathDelete(const std::string &path_name)
Definition: CRovio.cpp:162
bool m_videothread_initialized_error
Definition: CRovio.h:34
bool m_videothread_initialized_done
Definition: CRovio.h:33
ERRORCODE_HTTP http_get(const string &url, vector_byte &out_content, string &out_errormsg, int port=80, const string &auth_user=string(), const string &auth_pass=string(), int *out_http_responsecode=nullptr, mrpt::utils::TParameters< string > *extra_headers=nullptr, mrpt::utils::TParameters< string > *out_headers=nullptr, int timeout_ms=1000)
Perform an HTTP GET operation (version for retrieving the data as a vector_byte)
Definition: net_utils.cpp:383
Contains classes for various device interfaces.
bool retrieveFrame(mrpt::utils::CImage &out_img)
Get the next frame from the video stream.
A generic class which process a video file or other kind of input stream (http, rtsp) and allows the ...
bool getPosition(mrpt::math::TPose2D &out_pose)
Returns the Rovio&#39;s pose.
Definition: CRovio.cpp:475
bool pathGetList(std::string &path_list)
Get list of saved paths.
Definition: CRovio.cpp:166
STL namespace.
bool m_videothread_finished
Definition: CRovio.h:35
This class allows loading and storing values and vectors of different types from a configuration text...
bool captureImageAsync(mrpt::utils::CImage &out_img, bool recttified)
Returns a snapshot from Rovio, if rectified is set true, the returned image is rectified with the par...
Definition: CRovio.cpp:343
bool move(char direction, int speed=5)
move send Rovio the command to move in the specified direcction
Definition: CRovio.cpp:116
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
This CStream derived class allow using a memory buffer as a CStream.
Definition: CMemoryStream.h:27
mrpt::utils::TCamera cameraParams
Definition: CRovio.h:60
void initialize()
Establish Connection with Rovio and log in its system: Important, fill out "options" members BEFORE c...
Definition: CRovio.cpp:49
This namespace contains representation of robot actions and observations.
void thread_video()
This function takes a frame and waits until getLastImage ask for it, and so on.
Definition: CRovio.cpp:211
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
Definition: format.cpp:19
bool isVideoStreamming() const
Return true if video is streaming correctly.
Definition: CRovio.cpp:306
bool openURL(const std::string &url, bool grab_as_grayscale=false, bool verbose=false)
Open a video file or a video stream (rtsp://) This can be used to open local video files (eg...
bool retrieve_video()
This function launchs a thread with the function "thread_video()" which gets frames into a buffer...
Definition: CRovio.cpp:277
GLsizei const GLchar ** string
Definition: glext.h:4101
mrpt::math::CMatrixDouble33 intrinsicParams
Matrix of intrinsic parameters (containing the focal length and principal point coordinates) ...
Definition: TCamera.h:57
long convertToLong(char *sLong)
Definition: CRovio.cpp:400
struct mrpt::hwdrivers::CRovio::TEncoders encoders
bool stop_video()
This function stops and joins the thread launched by "retrieve_video()".
Definition: CRovio.cpp:311
bool getRovioState(TRovioState &state)
Returns a TRovioState with internal information of Rovio (State, Navigation Signal Strength...
Definition: CRovio.cpp:372
bool m_videothread_must_exit
Definition: CRovio.h:32
std::shared_ptr< CObservationImage > Ptr
GLuint id
Definition: glext.h:3909
GLuint GLsizei GLsizei * length
Definition: glext.h:4064
bool takeHeadUp()
Head positions.
Definition: CRovio.cpp:150
Lightweight 2D pose.
bool pathRecordSave(const std::string &path_name)
Definition: CRovio.cpp:158
A set of useful routines for networking.
Definition: net_utils.h:23
void setDistortionParamsFromValues(double k1, double k2, double p1, double p2, double k3=0)
Set the vector of distortion params of the camera from the individual values of the distortion coeffi...
Definition: TCamera.h:163
bool goHome(bool dock, int speed=5)
goHome(bool dock) drives Rovio in front of charging station if the paremeter dock is set to false...
Definition: CRovio.cpp:189
void close()
Close the video stream (this is called automatically at destruction).
struct mrpt::hwdrivers::CRovio::TOptions options
std::mutex buffer_img_cs
Definition: CRovio.h:38
char * strcpy(char *dest, size_t destSize, const char *source) noexcept
An OS-independent version of strcpy.
Definition: os.cpp:296
double phi
Orientation (rads)
bool general_command(int act, std::string &response, std::string &errormsg)
Definition: CRovio.cpp:104
void loadFromConfigFile(const std::string &section, const mrpt::utils::CConfigFileBase &cfg)
Load all the params from a config source, in the format used in saveToConfigFile(), that is:
Definition: TCamera.cpp:138
bool pathRename(const std::string &old_name, const std::string &new_name)
Definition: CRovio.cpp:176
mrpt::obs::CObservationImage::Ptr buffer_img
Definition: CRovio.h:37
void loadConfig(const mrpt::utils::CConfigFileBase &configSource, const std::string &section)
Loads the rovio camera calibration parameters (of leave the default ones if not found) (See CGenericS...
Definition: CRovio.cpp:200
void loadFromStreamAsJPEG(CStream &in)
Reads the image from a binary stream containing a binary jpeg file.



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ae4571287 Thu Nov 23 00:06:53 2017 +0100 at dom oct 27 23:51:55 CET 2019