static void standard_output (void) { /* CSV */ if (conf.output_format && strcmp ("csv", conf.output_format) == 0) output_csv (logger, holder); /* JSON */ else if (conf.output_format && strcmp ("json", conf.output_format) == 0) output_json (logger, holder); /* HTML */ else output_html (logger, holder); }
int main( int ac, char** av ) { try { comma::command_line_options options( ac, av, usage ); comma::csv::options input_csv( options, field_names< snark::control::target_t >() ); const char delimiter = input_csv.delimiter; comma::csv::input_stream< snark::control::target_t > input_stream( std::cin, input_csv, snark::control::target_t( options.exists( "--heading-is-absolute" ) ) ); comma::csv::options output_csv( options ); output_csv.full_xpath = true; output_csv.fields = "wayline/heading,error/cross_track,error/heading"; if( input_csv.binary() ) { output_csv.format( format< snark::control::control_data_t >( output_csv.fields, true ) ); } comma::csv::output_stream< snark::control::control_data_t > output_stream( std::cout, output_csv ); if( options.exists( "--format" ) ) { std::cout << format< snark::control::target_t >() << std::endl; return 0; } if( options.exists( "--output-format" ) ) { std::cout << format< snark::control::control_data_t >( output_csv.fields, true ) << std::endl; return 0; } if( options.exists( "--output-fields" ) ) { std::cout << output_csv.fields << std::endl; return 0; } double proximity = options.value< double >( "--proximity", default_proximity ); if( proximity <= 0 ) { std::cerr << name << ": expected positive proximity, got " << proximity << std::endl; return 1; } control_mode_t mode = mode_from_string( options.value< std::string >( "--mode", default_mode ) ); bool use_past_endpoint = options.exists( "--past-endpoint" ); bool use_delay = options.exists( "--frequency,-f" ); boost::posix_time::microseconds delay( 0 ); boost::posix_time::ptime next_output_time( boost::posix_time::microsec_clock::universal_time() ); if( use_delay ) { double frequency = options.value< double >( "--frequency,-f" ); if( frequency <= 0 ) { std::cerr << name << ": expected positive frequency, got " << frequency << std::endl; return 1; } delay = boost::posix_time::microseconds( static_cast< long >( 1000000 / frequency ) ); } bool verbose = options.exists( "--verbose,-v" ); std::vector< std::string > unnamed = options.unnamed( "--help,-h,--verbose,-v,--format,--output-format,--output-fields,--past-endpoint,--heading-is-absolute", "-.*,--.*" ); if( unnamed.empty() ) { std::cerr << name << ": feedback stream is not given" << std::endl; return 1; } comma::csv::options feedback_csv = comma::name_value::parser( "filename", ';', '=', false ).get< comma::csv::options >( unnamed[0] ); if( input_csv.binary() && !feedback_csv.binary() ) { std::cerr << name << ": cannot join binary input stream with ascii feedback stream" << std::endl; return 1; } if( !input_csv.binary() && feedback_csv.binary() ) { std::cerr << name << ": cannot join ascii input stream with binary feedback stream" << std::endl; return 1; } if( feedback_csv.fields.empty() ) { feedback_csv.fields = field_names< snark::control::feedback_t >(); } comma::io::istream feedback_in( feedback_csv.filename, feedback_csv.binary() ? comma::io::mode::binary : comma::io::mode::ascii, comma::io::mode::non_blocking ); comma::csv::input_stream< snark::control::feedback_t > feedback_stream( *feedback_in, feedback_csv ); comma::io::select select; select.read().add( feedback_in ); boost::optional< snark::control::vector_t > from; boost::scoped_ptr< snark::control::wayline_t > wayline; comma::signal_flag is_shutdown; while( !is_shutdown && ( input_stream.ready() || ( std::cin.good() && !std::cin.eof() ) ) ) { reached_t reached; const snark::control::target_t* target = input_stream.read(); if( !target ) { break; } snark::control::vector_t to = target->position; if( verbose ) { std::cerr << name << ": received target waypoint " << snark::control::serialise( to ) << std::endl; } if( from && snark::control::distance( *from, to ) < proximity ) { continue; } if( from ) { wayline.reset( new snark::control::wayline_t( *from, to, verbose ) ); } while( !is_shutdown && std::cout.good() ) { if( input_stream.ready() ) { if( mode == fixed ) {} else if( mode == dynamic ) { from = boost::none; break; } else { std::cerr << name << ": control mode '" << mode_to_string( mode ) << "' is not implemented" << std::endl; return 1; } } select.wait( boost::posix_time::microseconds( 10000 ) ); if( !is_shutdown && ( feedback_stream.ready() || select.read().ready( feedback_in ) ) ) { const snark::control::feedback_t* feedback = feedback_stream.read(); if( !feedback ) { std::cerr << name << ": feedback stream error occurred prior to reaching waypoint " << snark::control::serialise( to ) << std::endl; return 1; } if( use_delay && boost::posix_time::microsec_clock::universal_time() < next_output_time ) { continue; } if( !from ) { from = feedback->position; wayline.reset( new snark::control::wayline_t( *from, to, verbose ) ); } if( snark::control::distance( feedback->position, to ) < proximity ) { reached = reached_t( "proximity" ); } if( use_past_endpoint && wayline->is_past_endpoint( feedback->position ) ) { reached = reached_t( "past endpoint" ); } if( reached ) { if( verbose ) { std::cerr << name << ": waypoint " << snark::control::serialise( to ) << " is reached (" << reached.reason << ")" << std::endl; } if( mode == fixed ) { from = to; } else if( mode == dynamic ) { from = boost::none; } else { std::cerr << name << ": control mode '" << mode_to_string( mode ) << "' is not implemented" << std::endl; return 1; } break; } snark::control::error_t error; error.cross_track = wayline->cross_track_error( feedback->position ); if( target->is_absolute ) { error.heading = snark::control::wrap_angle( target->heading_offset - feedback->yaw ); } else { error.heading = wayline->heading_error( feedback->yaw, target->heading_offset ); } if( input_csv.binary() ) { std::cout.write( input_stream.binary().last(), input_csv.format().size() ); } else { std::cout << comma::join( input_stream.ascii().last(), delimiter ) << delimiter; } if( feedback_csv.binary() ) { std::cout.write( feedback_stream.binary().last(), feedback_csv.format().size() ); } else { std::cout << comma::join( feedback_stream.ascii().last(), delimiter ) << delimiter; } output_stream.write( snark::control::control_data_t( *wayline, error ) ); if( use_delay ) { next_output_time = boost::posix_time::microsec_clock::universal_time() + delay; } } } } return 0; } catch( std::exception& ex ) { std::cerr << name << ": " << ex.what() << std::endl; } catch( ... ) { std::cerr << name << ": unknown exception" << std::endl; } return 1; }
int main (int argc, char **argv) { int quit = 0; #if defined(__GLIBC__) setup_signal_handlers (); #endif /* command line/config options */ verify_global_config (argc, argv); parse_conf_file (&argc, &argv); parse_cmd_line (argc, argv); /* initialize storage */ init_storage (); /* setup to use the current locale */ set_locale (); #ifdef HAVE_LIBGEOIP init_geoip (); #endif /* init logger */ logger = init_log (); /* init parsing spinner */ parsing_spinner = new_gspinner (); parsing_spinner->process = &logger->process; /* outputting to stdout */ if (conf.output_html) { ui_spinner_create (parsing_spinner); goto out; } /* init curses */ set_input_opts (); if (conf.no_color || has_colors () == FALSE) { conf.color_scheme = NO_COLOR; conf.no_color = 1; } else { start_color (); } init_colors (); init_windows (&header_win, &main_win); set_curses_spinner (parsing_spinner); /* configuration dialog */ if (isatty (STDIN_FILENO) && (conf.log_format == NULL || conf.load_conf_dlg)) { refresh (); quit = verify_format (logger, parsing_spinner); } /* straight parsing */ else { ui_spinner_create (parsing_spinner); } out: /* main processing event */ time (&start_proc); if (conf.load_from_disk) set_general_stats (); else if (!quit && parse_log (&logger, NULL, -1)) FATAL ("Error while processing file"); logger->offset = logger->process; /* no valid entries to process from the log */ if ((logger->process == 0) || (logger->process == logger->invalid)) FATAL ("Nothing valid to process."); /* init reverse lookup thread */ gdns_init (); parse_initial_sort (); allocate_holder (); end_spinner (); time (&end_proc); /* stdout */ if (conf.output_html) { /* CSV */ if (conf.output_format && strcmp ("csv", conf.output_format) == 0) output_csv (logger, holder); /* JSON */ else if (conf.output_format && strcmp ("json", conf.output_format) == 0) output_json (logger, holder); /* HTML */ else output_html (logger, holder); } /* curses */ else { allocate_data (); if (!conf.skip_term_resolver) gdns_thread_create (); render_screens (); get_keys (); attroff (COLOR_PAIR (COL_WHITE)); /* restore tty modes and reset * terminal into non-visual mode */ endwin (); } /* clean */ house_keeping (); return EXIT_SUCCESS; }