int Drivers::yarpdev(int argc, char *argv[]) { std::signal(SIGINT, handler); std::signal(SIGTERM, handler); // get command line options ResourceFinder rf; rf.configure(argc, argv); // this will process --from FILE if present Property options; // yarpdev will by default try to pass its thread on to the device. // this is because some libraries need configuration and all // access methods done in the same thread (e.g. opencv_grabber // apparently). options.put("single_threaded", 1); // interpret command line options as a set of flags //options.fromCommand(argc,argv,true,false); options.fromString(rf.toString().c_str(), false); // check if we're being asked to read the options from file Value *val; if (options.check("file",val)) { // FIXME use argv[0] yError("*** yarpdev --file is deprecated, please use --from\n"); yError("*** yarpdev --file will be removed in a future version of YARP\n"); std::string fname = val->toString(); options.unput("file"); yDebug("yarpdev: working with config file %s\n", fname.c_str()); options.fromConfigFile(fname,false); // interpret command line options as a set of flags again // (just in case we need to override something) options.fromCommand(argc,argv,true,false); } // check if we want to use nested options (less ambiguous) if (options.check("nested",val)||options.check("lispy",val)) { std::string lispy = val->toString(); yDebug("yarpdev: working with config %s\n", lispy.c_str()); options.fromString(lispy); } if (!options.check("device")) { // no device mentioned - maybe user needs help if (options.check("list")) { yInfo("Here are devices listed for your system:"); for (auto& s : split(Drivers::factory().toString(), '\n')) { yInfo("%s", s.c_str()); } } else { yInfo("Welcome to yarpdev, a program to create YARP devices\n"); yInfo("To see the devices available, try:\n"); yInfo(" yarpdev --list\n"); yInfo("To create a device whose name you know, call yarpdev like this:\n"); yInfo(" yarpdev --device DEVICENAME --OPTION VALUE ...\n"); yInfo(" For example:\n"); yInfo(" yarpdev --device test_grabber --width 32 --height 16 --name /grabber\n"); yInfo("You can always move options to a configuration file:\n"); yInfo(" yarpdev [--device DEVICENAME] --from CONFIG_FILENAME\n"); yInfo("If you have problems, you can add the \"verbose\" flag to get more information\n"); yInfo(" yarpdev --verbose --device ffmpeg_grabber\n"); if (options.check ("from")) { yError("Unable to find --device option in file %s. Closing.", options.find("from").asString().c_str()); } else { yWarning("--device option not specified. Closing."); } } return 0; } // ask for a wrapped, remotable device rather than raw device options.put("wrapped","1"); //YarpDevMonitor monitor; bool verbose = false; if (options.check("verbose")) { verbose = true; //options.setMonitor(&monitor,"top-level"); } // we now need network bool ret=Network::checkNetwork(); if (!ret) { yError("YARP network not available, check if yarp server is reachable\n"); return -1; } // // yarpdev initializes the clock only before starting to do real thing. // This way yarpdev --lish/help will not be affected by network clock. // // Shall other devices be affected by network clock ?? // Hereafter the device may need to use the SystemClock or the NetworkClock // depending by the device, a real or a fake / simulated one. // Using the YARP_CLOCK_DEFAULT the behaviour will be determined by the // environment variable. // yarp::os::NetworkBase::yarpClockInit(yarp::os::YARP_CLOCK_DEFAULT); PolyDriver dd(options); if (verbose) { toDox(dd,stdout); } if (!dd.isValid()) { yError("yarpdev: ***ERROR*** device not available.\n"); if (argc==1) { yInfo("Here are the known devices:\n"); yInfo("%s", Drivers::factory().toString().c_str()); } else { yInfo("Suggestions:\n"); yInfo("+ Do \"yarpdev --list\" to see list of supported devices.\n"); if (!options.check("verbose")) { yInfo("+ Or append \"--verbose\" option to get more information.\n"); } } return 1; } Terminee *terminee = nullptr; if (dd.isValid()) { Value *v; std::string s("/yarpdev/quit"); if (options.check("device", v)) { if (v->isString()) { s = ""; s += "/"; s += v->toString(); s += "/quit"; } } if (options.check("name", v)) { s = ""; s += v->toString(); s += "/quit"; } if (s.find("=") == std::string::npos && s.find("@") == std::string::npos) { terminee = new Terminee(s.c_str()); terminatorKey = s.c_str(); if (terminee == nullptr) { yError("Can't allocate terminator port\n"); terminatorKey = ""; dd.close(); return 1; } if (!terminee->isOk()) { yError("Failed to create terminator port\n"); terminatorKey = ""; delete terminee; terminee = nullptr; dd.close(); return 1; } } } double dnow = 3; double startTime = Time::now()-dnow; IService *service = nullptr; dd.view(service); if (service!=nullptr) { bool backgrounded = service->startService(); if (backgrounded) { // we don't need to poll this, so forget about the // service interface yDebug("yarpdev: service backgrounded\n"); service = nullptr; } } while (dd.isValid() && !(terminated||(terminee&&terminee->mustQuit()))) { if (service!=nullptr) { double now = Time::now(); if (now-startTime>dnow) { yInfo("device active..."); startTime += dnow; } // we requested single threading, so need to // give the device its chance if(!service->updateService()) { if(!service->stopService()) { yWarning("Error while stopping device"); } terminated = true; } } else { // we don't need to do anything yInfo("device active in background..."); SystemClock::delaySystem(dnow); } } if (terminee) { delete terminee; terminee = nullptr; } dd.close(); yInfo("yarpdev is finished."); return 0; }
int Drivers::yarpdev(int argc, char *argv[]) { ACE_OS::signal(SIGINT, (ACE_SignalHandler) handler); ACE_OS::signal(SIGTERM, (ACE_SignalHandler) handler); // get command line options ResourceFinder rf; rf.configure(argc, argv); // this will process --from FILE if present Property options; // yarpdev will by default try to pass its thread on to the device. // this is because some libraries need configuration and all // access methods done in the same thread (e.g. opencv_grabber // apparently). options.put("single_threaded", 1); // interpret command line options as a set of flags //options.fromCommand(argc,argv,true,false); options.fromString(rf.toString().c_str(), false); // check if we're being asked to read the options from file Value *val; if (options.check("file",val)) { fprintf(stderr,"*** yarpdev --file is deprecated, please use --from\n"); fprintf(stderr,"*** yarpdev --file will be removed in a future version of YARP\n"); ConstString fname = val->toString(); options.unput("file"); printf("yarpdev: working with config file %s\n", fname.c_str()); options.fromConfigFile(fname,false); // interpret command line options as a set of flags again // (just in case we need to override something) options.fromCommand(argc,argv,true,false); } // check if we want to use nested options (less ambiguous) if (options.check("nested",val)||options.check("lispy",val)) { ConstString lispy = val->toString(); printf("yarpdev: working with config %s\n", lispy.c_str()); options.fromString(lispy); } if (!options.check("device")) { // no device mentioned - maybe user needs help if (options.check("list")) { printf("Here are devices listed for your system:\n"); printf("%s", Drivers::factory().toString().c_str()); } else { printf("Welcome to yarpdev, a program to create YARP devices\n"); printf("To see the devices available, try:\n"); printf(" yarpdev --list\n"); printf("To create a device whose name you know, call yarpdev like this:\n"); printf(" yarpdev --device DEVICENAME --OPTION VALUE ...\n"); printf("For example:\n"); printf(" yarpdev --device test_grabber --width 32 --height 16 --name /grabber\n"); printf("You can always move options to a configuration file:\n"); printf(" yarpdev [--device DEVICENAME] --from CONFIG_FILENAME\n"); printf("If you have problems, you can add the \"verbose\" flag to get more information\n"); printf(" yarpdev --verbose --device ffmpeg_grabber\n"); } return 0; } // ask for a wrapped, remotable device rather than raw device options.put("wrapped","1"); //YarpDevMonitor monitor; bool verbose = false; if (options.check("verbose")) { verbose = true; //options.setMonitor(&monitor,"top-level"); } // we now need network bool ret=Network::checkNetwork(); if (!ret) { fprintf(stderr, "YARP network not available, check if yarp server is reachable\n"); return -1; } PolyDriver dd(options); if (verbose) { toDox(dd,stdout); } if (!dd.isValid()) { printf("yarpdev: ***ERROR*** device not available.\n"); if (argc==1) { printf("Here are the known devices:\n"); printf("%s", Drivers::factory().toString().c_str()); } else { printf("Suggestions:\n"); printf("+ Do \"yarpdev --list\" to see list of supported devices.\n"); if (!options.check("verbose")) { printf("+ Or append \"--verbose\" option to get more information.\n"); } } return 1; } Terminee *terminee = 0; if (dd.isValid()) { Value *v; ConstString s("/yarpdev/quit"); if (options.check("device", v)) { if (v->isString()) { s = ""; s += "/"; s += v->toString(); s += "/quit"; } } if (options.check("name", v)) { s = ""; s += v->toString(); s += "/quit"; } if (s.find("=") == ConstString::npos && s.find("@") == ConstString::npos) { terminee = new Terminee(s.c_str()); terminatorKey = s.c_str(); if (terminee == 0) { printf("Can't allocate terminator port\n"); terminatorKey = ""; dd.close(); return 1; } if (!terminee->isOk()) { printf("Failed to create terminator port\n"); terminatorKey = ""; delete terminee; terminee = NULL; dd.close(); return 1; } } } double dnow = 3; double startTime = Time::now()-dnow; IService *service = NULL; dd.view(service); if (service!=NULL) { bool backgrounded = service->startService(); if (backgrounded) { // we don't need to poll this, so forget about the // service interface printf("yarpdev: service backgrounded\n"); service = NULL; } } while (dd.isValid() && !(terminated||(terminee&&terminee->mustQuit()))) { if (service!=NULL) { double now = Time::now(); if (now-startTime>dnow) { if (yarp_show_info()) { YARP_LOG_INFO("device active..."); } startTime += dnow; } // we requested single threading, so need to // give the device its chance service->updateService(); } else { // we don't need to do anything if (yarp_show_info()) { YARP_LOG_INFO("device active in background..."); } Time::delay(dnow); } } if (terminee) { delete terminee; terminee = NULL; } dd.close(); if (yarp_show_info()) { printf("yarpdev is finished.\n"); } return 0; }