Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
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
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
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
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
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 }