int main( int ac, char** av ) { bool verbose = false; try { comma::command_line_options options( ac, av ); if( options.exists( "--help,-h" ) ) { usage(); } const auto& unnamed = options.unnamed( "--accumulate,-a,--no-inertial,--output-fields,--verbose,-v" ); if( unnamed.empty() ) { std::cerr << "control-from-console: please specify operation" << std::endl; return 1; } if( unnamed.size() > 1 ) { std::cerr << "control-from-console: expected one operation, got: " << comma::join( unnamed, ',' ) << std::endl; return 1; } std::string operation = unnamed[0]; if( options.exists( "--output-fields" ) ) { if( operation == "cartesian" ) { std::cout << "velocity/x,velocity/y" << std::endl; return 0; } if( operation == "drive" ) { std::cout << "velocity,turn_rate" << std::endl; return 0; } if( operation == "pantilt" ) { std::cout << "pan,tilt" << std::endl; return 0; } std::cerr << "control-from-console: expected operation, got: \"" << operation << "\"" << std::endl; return 1; } std::pair< double, double > steps = default_steps( operation ); const auto& s = comma::split( options.value< std::string >( "--step,-s", "" ), ',' ); switch( s.size() ) { case 1: if( !s[0].empty() ) { steps.first = boost::lexical_cast< double >( s[0] ); } break; case 2: if( !s[0].empty() ) { steps.first = boost::lexical_cast< double >( s[0] ); } if( !s[1].empty() ) { steps.second = boost::lexical_cast< double >( s[1] ); } break; default: std::cerr << "control-from-console: expected --step <first>[,<second>]; got: \"" << options.value< std::string >( "--step,-s", "" ) << "\"" << std::endl; return 1; } bool inertial = !options.exists( "--no-inertial" ); verbose = options.exists( "--verbose,-v" ); bool accumulate = options.exists( "--accumulate,-a" ); if( verbose ) { std::cerr << "control-from-console: step: " << steps.first << "," << steps.second << std::endl; } comma::io::select select; select.read().add( 0 ); inertial::pair horizontal( boost::posix_time::millisec( inertial ? 500 : 0 ), inertial ? 5 : 1 ); inertial::pair vertical( boost::posix_time::millisec( inertial ? 500 : 0 ), inertial ? 5 : 1 ); comma::signal_flag is_shutdown; char b = 0; boost::posix_time::time_duration threshold = boost::posix_time::millisec( 200 ); boost::posix_time::ptime last = boost::posix_time::microsec_clock::universal_time(); std::pair< double, double > accumulated( 0, 0 ); while( !is_shutdown && std::cout.good() && !std::cout.eof() && std::cin.good() && !std::cin.eof() ) { // todo: it does not exit, if std::cout closed; catch sigpipe? if( select.wait( boost::posix_time::seconds( 1 ) ) == 0 ) { continue; } char c; if( ::read( 0, &c, 1 ) != 1 ) { break; } if( verbose ) { std::cerr << "control-from-console: got " << c << std::endl; } switch( c ) { case 0x41: ++vertical; break; case 0x42: --vertical; break; case 0x43: ++horizontal; break; case 0x44: --horizontal; break; default: continue; } boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time(); if( b != c || ( now - last ) > threshold ) { if( accumulate ) { accumulated.first += steps.first * horizontal.pick(); accumulated.second += steps.second * vertical.pick(); std::cout << accumulated.first << "," << accumulated.second << std::endl; } else { std::cout << ( steps.first * horizontal.pick() ) << "," << ( steps.second * vertical.pick() ) << std::endl; } std::cout.flush(); last = now; } b = c; } if( verbose ) { std::cerr << "control-from-console: done" << std::endl; } return 0; } catch( comma::last_error::interrupted_system_call_exception& ) { if( verbose ) { std::cerr << "control-from-console: done" << std::endl; } return 0; } catch( std::exception& ex ) { std::cerr << "control-from-console: " << ex.what() << std::endl; } catch( ... ) { std::cerr << "control-from-console: unknown exception" << std::endl; } return 1; }
double Texture::fraction_of_minerals_smaller_than (double size /* [um] */) const { return accumulated (log (size)); }