rcdynamics_stream.cc
Go to the documentation of this file.
00001 /*
00002  * This file is part of the rc_dynamics_api package.
00003  *
00004  * Copyright (c) 2017 Roboception GmbH
00005  * All rights reserved
00006  *
00007  * Author: Christian Emmerich
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions are met:
00011  *
00012  * 1. Redistributions of source code must retain the above copyright notice,
00013  * this list of conditions and the following disclaimer.
00014  *
00015  * 2. Redistributions in binary form must reproduce the above copyright notice,
00016  * this list of conditions and the following disclaimer in the documentation
00017  * and/or other materials provided with the distribution.
00018  *
00019  * 3. Neither the name of the copyright holder nor the names of its contributors
00020  * may be used to endorse or promote products derived from this software without
00021  * specific prior written permission.
00022  *
00023  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00024  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00025  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00026  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00027  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00028  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00029  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00030  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00031  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00032  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00033  * POSSIBILITY OF SUCH DAMAGE.
00034  */
00035 
00036 #include <fstream>
00037 #include <signal.h>
00038 #include <chrono>
00039 #include <iomanip>
00040 
00041 #include "rc_dynamics_api/remote_interface.h"
00042 #include "csv_printing.h"
00043 
00044 #ifdef WIN32
00045 #include <winsock2.h>
00046 #undef max
00047 #undef min
00048 #endif
00049 
00050 using namespace std;
00051 using namespace rc::dynamics;
00052 
00056 static bool caught_signal = false;
00057 void signal_callback_handler(int signum)
00058 {
00059   printf("Caught signal %d, stopping program!\n", signum);
00060   caught_signal = true;
00061 }
00062 
00066 void printUsage(char* arg)
00067 {
00068   cout << "\nLists available rcdynamics data streams of the specified rc_visard IP, "
00069           "\nor requests a data stream and either prints received messages or records "
00070           "\nthem as csv-file, see -o option."
00071        << "\n\nUsage: \n"
00072        << arg << " -v <rcVisardIP> -l | -s <stream> [-a] [-i <networkInterface>]"
00073                  " [-n <maxNumData>][-t <maxRecTimeSecs>][-o <output_file>]"
00074        << endl;
00075 }
00076 
00077 int main(int argc, char* argv[])
00078 {
00079 #ifdef WIN32
00080   WSADATA wsaData;
00081   WSAStartup(MAKEWORD(2, 2), &wsaData);
00082 #endif
00083 
00084   // Register signals and signal handler
00085   signal(SIGINT, signal_callback_handler);
00086   signal(SIGTERM, signal_callback_handler);
00087 
00091   string out_file_name, visard_ip, network_iface = "", stream_name;
00092   unsigned int max_num_recording = 50, max_secs_recording = 5;
00093   bool user_autostart = false;
00094   bool user_set_out_file = false;
00095   bool user_set_max_num_msgs = false;
00096   bool user_set_max_recording_time = false;
00097   bool user_set_ip = false;
00098   bool user_set_stream_type = false;
00099   bool only_list_streams = false;
00100 
00101   int i = 1;
00102   while (i < argc)
00103   {
00104     std::string p = argv[i++];
00105 
00106     if (p == "-l")
00107     {
00108       only_list_streams = true;
00109     }
00110     else if (p == "-s" && i < argc)
00111     {
00112       stream_name = string(argv[i++]);
00113       user_set_stream_type = true;
00114     }
00115     else if (p == "-a")
00116     {
00117       user_autostart = true;
00118     }
00119     else if (p == "-i" && i < argc)
00120     {
00121       network_iface = string(argv[i++]);
00122     }
00123     else if (p == "-v" && i < argc)
00124     {
00125       visard_ip = string(argv[i++]);
00126       user_set_ip = true;
00127     }
00128     else if (p == "-n" && i < argc)
00129     {
00130       max_num_recording = (unsigned int)std::max(0, atoi(argv[i++]));
00131       user_set_max_num_msgs = true;
00132     }
00133     else if (p == "-t" && i < argc)
00134     {
00135       max_secs_recording = (unsigned int)std::max(0, atoi(argv[i++]));
00136       user_set_max_recording_time = true;
00137     }
00138     else if (p == "-o" && i < argc)
00139     {
00140       out_file_name = string(argv[i++]);
00141       user_set_out_file = true;
00142     }
00143     else if (p == "-h")
00144     {
00145       printUsage(argv[0]);
00146       return EXIT_SUCCESS;
00147     }
00148     else
00149     {
00150       printUsage(argv[0]);
00151       return EXIT_FAILURE;
00152     }
00153   }
00154 
00155   if (!user_set_ip)
00156   {
00157     cerr << "Please specify rc_visard IP." << endl;
00158     printUsage(argv[0]);
00159     return EXIT_FAILURE;
00160   }
00161 
00162   if (!user_set_stream_type && !only_list_streams)
00163   {
00164     cerr << "Please specify stream type." << endl;
00165     printUsage(argv[0]);
00166     return EXIT_FAILURE;
00167   }
00168 
00169   if (!user_set_max_num_msgs && !user_set_max_recording_time)
00170   {
00171     user_set_max_num_msgs = true;
00172   }
00173 
00177   ofstream output_file;
00178   if (user_set_out_file)
00179   {
00180     output_file.open(out_file_name);
00181     if (!output_file.is_open())
00182     {
00183       cerr << "Could not open file '" << out_file_name << "' for writing!" << endl;
00184       return EXIT_FAILURE;
00185     }
00186   }
00187 
00191   cout << "connecting to rc_visard " << visard_ip << "..." << endl;
00192   auto rc_dynamics = RemoteInterface::create(visard_ip);
00193   try {
00194     while (!caught_signal && !rc_dynamics->checkSystemReady())
00195     {
00196       cout << "... system not yet ready. Trying again." << endl;
00197       usleep(1000*500);
00198     }
00199     cout << "... connected!" << endl;
00200   } catch (exception &e) {
00201     cout << "ERROR! Could not connect to rc_dynamics module on rc_visard: " << e.what() << endl;
00202     return EXIT_FAILURE;
00203   }
00204 
00205   /* Only list available streams of device and exit */
00206   if (only_list_streams)
00207   {
00208     auto streams = rc_dynamics->getAvailableStreams();
00209     string first_column = "Available streams:";
00210     size_t first_column_width = first_column.length();
00211     for (auto&& s : streams)
00212       if (s.length() > first_column_width)
00213         first_column_width = s.length();
00214     first_column_width += 5;
00215     cout << left << setw(first_column_width) << first_column << "Protobuf message types:" << endl;
00216     for (auto&& s : streams)
00217       cout << left << setw(first_column_width) << s << rc_dynamics->getPbMsgTypeOfStream(s) << endl;
00218     cout << endl << "rc_dynamics is in state: " << rc_dynamics->getDynamicsState();
00219     cout << endl << "rc_slam is in state: " << rc_dynamics->getSlamState();
00220     cout << endl << "rc_stereo_ins is in state: " << rc_dynamics->getStereoInsState();
00221     cout << endl;
00222     return EXIT_SUCCESS;
00223   }
00224 
00225   /* For all streams except 'imu' the rc_dynamcis node has to be started */
00226   if (user_autostart && stream_name != "imu")
00227   {
00228     try
00229     {
00230       cout << "starting SLAM on rc_visard..." << endl;
00231       rc_dynamics->startSlam();
00232     }
00233     catch (exception&)
00234     {
00235       try
00236       {
00237         // start the rc::dynamics module on the rc_visard
00238         cout << "SLAM not available!" << endl;
00239         cout << "starting stereo INS on rc_visard..." << endl;
00240         rc_dynamics->start();
00241       }
00242       catch (exception& e)
00243       {
00244         cout << "ERROR! Could not start rc_dynamics module on rc_visard: " << e.what() << endl;
00245         return EXIT_FAILURE;
00246       }
00247     }
00248   }
00249 
00253   unsigned int cnt_msgs = 0;
00254   try
00255   {
00256     cout << "Initializing " << stream_name << " data stream..." << endl;
00257     auto receiver = rc_dynamics->createReceiverForStream(stream_name, network_iface);
00258 
00259     unsigned int timeout_millis = 100;
00260     receiver->setTimeout(timeout_millis);
00261     cout << "Listening for " << stream_name << " messages..." << endl;
00262 
00263     chrono::time_point<chrono::system_clock> start = chrono::system_clock::now();
00264     chrono::duration<double> elapsed_secs(0);
00265     while (!caught_signal && (!user_set_max_num_msgs || cnt_msgs < max_num_recording) &&
00266            (!user_set_max_recording_time || elapsed_secs.count() < max_secs_recording))
00267     {
00268       auto msg = receiver->receive(rc_dynamics->getPbMsgTypeOfStream(stream_name));
00269       if (msg)
00270       {
00271         if (output_file.is_open())
00272         {
00273           if (cnt_msgs == 0)
00274           {
00275             csv::Header h;
00276             output_file << (h << *msg) << endl;
00277           }
00278           csv::Line l;
00279           output_file << (l << *msg) << endl;
00280         }
00281         else
00282         {
00283           cout << "received " << stream_name << " msg:" << endl << msg->DebugString() << endl;
00284         }
00285         ++cnt_msgs;
00286       }
00287       else
00288       {
00289         cerr << "did not receive any data during last " << timeout_millis << " ms." << endl;
00290       }
00291       elapsed_secs = chrono::system_clock::now() - start;
00292     }
00293   }
00294   catch (exception& e)
00295   {
00296     cout << "Caught exception during streaming, stopping: " << e.what() << endl;
00297   }
00298 
00303   if (user_autostart && stream_name != "imu")
00304   {
00305     try
00306     {
00307       cout << "stopping rc_dynamics module on rc_visard..." << endl;
00308       rc_dynamics->stop();
00309     }
00310     catch (exception& e)
00311     {
00312       cout << "Caught exception: " << e.what() << endl;
00313     }
00314   }
00315 
00316   if (output_file.is_open())
00317   {
00318     output_file.close();
00319     cout << "Recorded " << cnt_msgs << " " << stream_name << " messages to '" << out_file_name << "'." << endl;
00320   }
00321   else
00322   {
00323     cout << "Received  " << cnt_msgs << " " << stream_name << " messages." << endl;
00324   }
00325 
00326 #ifdef WIN32
00327   ::WSACleanup();
00328 #endif
00329 
00330   return EXIT_SUCCESS;
00331 }


rc_dynamics_api
Author(s): Heiko Hirschmueller , Christian Emmerich , Felix Endres
autogenerated on Thu May 9 2019 02:13:50