Exemple #1
0
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;
}