/** * \brief Main function for the snowfocus program */ int main(int argc, char *argv[]) { snowstar::CommunicatorSingleton cs(argc, argv); std::string instrumentname; int steps = 10; double exposuretime = 1.0; double temperature = std::numeric_limits<double>::quiet_NaN(); std::string binning; std::string frame; std::string filtername; astro::focusing::Focusing::method_type method = astro::focusing::Focusing::FWHM; int c; int longindex; while (EOF != (c = getopt_long(argc, argv, "b:c:de:f:hi:m:r:t:", longopts, &longindex))) switch (c) { case 'b': binning = optarg; break; case 'c': astro::config::Configuration::set_default(optarg); break; case 'd': debuglevel = LOG_DEBUG; break; case 'e': exposuretime = std::stod(optarg); break; case 'f': filtername = optarg; break; case 'h': usage(argv[0]); return EXIT_SUCCESS; case 'i': instrumentname = optarg; break; case 'm': method = astro::focusing::Focusing::string2method(optarg); break; case 'r': frame = optarg; break; case 's': steps = std::stoi(optarg); break; case 't': temperature = std::stod(optarg); break; } // the next argument is the command if (argc <= optind) { throw std::runtime_error("not enough arguments"); } std::string command = argv[optind++]; debug(LOG_DEBUG, DEBUG_LOG, 0, "command: %s", command.c_str()); if (command == "help") { usage(argv[0]); return EXIT_SUCCESS; } // get the configuration ConfigurationPtr config = Configuration::get(); // check whether we have an instrument if (0 == instrumentname.size()) { throw std::runtime_error("instrument name not set"); } RemoteInstrument instrument(config->database(), instrumentname); // get the device names CcdPrx ccdprx = instrument.ccd_proxy(); std::string ccdname = ccdprx->getName(); FocuserPrx focuserprx = instrument.focuser_proxy(); std::string focusername = focuserprx->getName(); debug(LOG_DEBUG, DEBUG_LOG, 0, "ccd: %s focuser: %s", ccdname.c_str(), focusername.c_str()); // first get a connection to the server Ice::CommunicatorPtr ic = CommunicatorSingleton::get(); astro::ServerName servername = instrument.servername(astro::DeviceName::Ccd); Ice::ObjectPrx base = ic->stringToProxy( servername.connect("FocusingFactory")); FocusingFactoryPrx focusingfactory = FocusingFactoryPrx::checkedCast(base); // get the focusing interface FocusingPrx focusing = focusingfactory->get(ccdname, focusername); debug(LOG_DEBUG, DEBUG_LOG, 0, "got a focusing proxy"); // creating a callback Ice::ObjectPtr callback = new FocusCallbackI(); CallbackAdapter adapter(ic); Ice::Identity ident = adapter.add(callback); focusing->ice_getConnection()->setAdapter(adapter.adapter()); // handle the simple commands if (command == "status") { std::cout << "status: "; std::cout << focusingstate2string(focusing->status()); std::cout << std::endl; return EXIT_SUCCESS; } if (command == "history") { show_history(focusing->history()); return EXIT_SUCCESS; } if (command == "monitor") { std::cout << "current status: "; std::cout << focusingstate2string(focusing->status()); std::cout << std::endl; focusing->registerCallback(ident); signal(SIGINT, handler); while (!signal_received) { sleep(1); } focusing->unregisterCallback(ident); return EXIT_SUCCESS; } if (command == "cancel") { focusing->cancel(); std::cout << "cancel command sent" << std::endl; return EXIT_SUCCESS; } // throw exception for unknown commands if (command != "start") { throw std::runtime_error("unknown command"); } // make sure temperature is set CoolerPrx cooler; if (instrument.has(DeviceName::Cooler)) { cooler = instrument.cooler_proxy(); } CoolerTask coolertask(cooler, temperature); coolertask.wait(); // next two arguments are the interval boundaries if ((argc - optind) < 2) { throw std::runtime_error("missing intervale arguments"); } int min = std::stoi(argv[optind++]); int max = std::stoi(argv[optind++]); debug(LOG_DEBUG, DEBUG_LOG, 0, "interval [%d,%d]", min, max); if (min >= max) { throw std::runtime_error("not an interval"); } // ensure that focuser is ready FocusState state = focusing->status(); debug(LOG_DEBUG, DEBUG_LOG, 0, "current state = %d", state); if ((state == FocusMOVING) && (state == FocusMEASURING)) { throw std::runtime_error("already focusing"); } // set up the exposure CcdTask ccdtask(ccdprx); ccdtask.frame(frame); ccdtask.binning(binning); ccdtask.exposuretime(exposuretime); // set up the focusing focusing->setSteps(steps); focusing->setMethod(convert(method)); // start the focusing process debug(LOG_DEBUG, DEBUG_LOG, 0, "starting between %d and %d", min, max); focusing->start(min, max); debug(LOG_DEBUG, DEBUG_LOG, 0, "focusing started, status: %d", focusing->status()); // wait for the process to complete bool completed = false; signal(SIGINT, handler); do { sleep(1); switch (focusing->status()) { case FocusIDLE: case FocusMOVING: case FocusMEASURING: break; case FocusFOCUSED: case FocusFAILED: completed = true; break; } } while ((!completed) && (!signal_received)); if (completed) { std::cout << "final focus position: " << focuserprx->current(); std::cout << std::endl; // display the history show_history(focusing->history()); } else { std::cout << "focusing incomplete" << std::endl; return EXIT_FAILURE; } return EXIT_SUCCESS; }
/** * \brief Main function for the snowfocus program */ int main(int argc, char *argv[]) { debug_set_ident("snowfocus"); snowstar::CommunicatorSingleton cs(argc, argv); Ice::CommunicatorPtr ic = cs.get(); bool remote = false; int steps = 10; double exposuretime = 1.0; double temperature = std::numeric_limits<double>::quiet_NaN(); std::string binning; std::string frame; std::string filtername; astro::focusing::Focusing::method_type method = astro::focusing::Focusing::BRENNER; int c; int longindex; while (EOF != (c = getopt_long(argc, argv, "b:c:de:f:hi:m:r:Rt:", longopts, &longindex))) switch (c) { case 'b': binning = optarg; break; case 'c': astro::config::Configuration::set_default(optarg); break; case 'd': debuglevel = LOG_DEBUG; break; case 'e': exposuretime = std::stod(optarg); break; case 'f': filtername = optarg; break; case 'h': usage(argv[0]); return EXIT_SUCCESS; case 'm': method = astro::focusing::Focusing::string2method(optarg); break; case 'r': frame = optarg; break; case 'R': remote = true; break; case 's': steps = std::stoi(optarg); break; case 't': temperature = std::stod(optarg); break; default: throw std::runtime_error("unknown option"); } // the next argument is the command if (argc <= optind) { short_usage(argv[0]); throw std::runtime_error("missing service argument"); } std::string argument(argv[optind++]); if ("help" == argument) { usage(argv[0]); return EXIT_SUCCESS; } astro::ServerName servername(argument); if (argc <= optind) { short_usage(argv[0]); throw std::runtime_error("missing instrument name argument"); } // make sure the server offers instruments and guiding if (!remote) { astro::discover::ServiceDiscoveryPtr sd = astro::discover::ServiceDiscovery::get(); sd->start(); astro::discover::ServiceObject so = sd->find(sd->waitfor(argument)); if (!so.has(astro::discover::ServiceSubset::INSTRUMENTS)) { std::cerr << "service '" << argument; std::cerr << "' does not offer focusing service"; std::cerr << std::endl; return EXIT_FAILURE; } if (!so.has(astro::discover::ServiceSubset::FOCUSING)) { std::cerr << "service '" << argument; std::cerr << "' does not offer focusing service"; std::cerr << std::endl; return EXIT_FAILURE; } } std::string instrumentname(argv[optind++]); if (argc <= optind) { short_usage(argv[0]); throw std::runtime_error("missing command argument"); } std::string command = argv[optind++]; debug(LOG_DEBUG, DEBUG_LOG, 0, "command: %s", command.c_str()); // get a proxy for the instruments Ice::ObjectPrx base = ic->stringToProxy( servername.connect("Instruments")); InstrumentsPrx instruments = InstrumentsPrx::checkedCast(base); // get the configuration astro::config::ConfigurationPtr config = astro::config::Configuration::get(); // check whether we have an instrument if (0 == instrumentname.size()) { throw std::runtime_error("instrument name not set"); } RemoteInstrument instrument(instruments, instrumentname); // make sure the server names for focuser and ccd are identical astro::ServerName targetserver = instrument.servername(InstrumentCCD); if (targetserver != instrument.servername(InstrumentFocuser)) { throw std::runtime_error("ccd and focuser are on different " "servers"); } // get the device names CcdPrx ccdprx = instrument.ccd(); std::string ccdname = ccdprx->getName(); FocuserPrx focuserprx = instrument.focuser(); std::string focusername = focuserprx->getName(); debug(LOG_DEBUG, DEBUG_LOG, 0, "ccd: %s focuser: %s", ccdname.c_str(), focusername.c_str()); // first get a connection to the server Ice::ObjectPrx fbase = ic->stringToProxy( targetserver.connect("FocusingFactory")); FocusingFactoryPrx focusingfactory = FocusingFactoryPrx::checkedCast(fbase); // get the focusing interface FocusingPrx focusing = focusingfactory->get(ccdname, focusername); debug(LOG_DEBUG, DEBUG_LOG, 0, "got a focusing proxy"); // creating a callback Ice::ObjectPtr callback = new FocusCallbackI(); CallbackAdapter adapter(ic); Ice::Identity ident = adapter.add(callback); focusing->ice_getConnection()->setAdapter(adapter.adapter()); debug(LOG_DEBUG, DEBUG_LOG, 0, "callback installed"); // handle the simple commands if (command == "help") { short_usage(argv[0]); return EXIT_SUCCESS; } if (command == "status") { std::cout << "status: "; FocusState state = focusing->status(); std::cout << focusingstate2string(state); switch (state) { case FocusFOCUSED: std::cout << " "; std::cout << focusing->getFocuser()->current(); break; default: break; } std::cout << std::endl; return EXIT_SUCCESS; } if (command == "history") { show_history(focusing->history()); return EXIT_SUCCESS; } if (command == "monitor") { std::cout << "current status: "; std::cout << focusingstate2string(focusing->status()); std::cout << std::endl; focusing->registerCallback(ident); signal(SIGINT, handler); while (!signal_received) { sleep(1); } focusing->unregisterCallback(ident); return EXIT_SUCCESS; } if (command == "cancel") { focusing->cancel(); std::cout << "cancel command sent" << std::endl; return EXIT_SUCCESS; } if (command == "repository") { if (optind < argc) { std::string reponame(argv[optind]); focusing->setRepositoryName(reponame); } else { std::string reponame = focusing->getRepositoryName(); if (reponame.size() > 0) { std::cout << "repository: " << reponame; std::cout << std::endl; } else { std::cout << "repository not set" << std::endl; } } return EXIT_SUCCESS; } // throw exception for unknown commands if (command != "start") { short_usage(argv[0]); throw std::runtime_error("unknown command"); } debug(LOG_DEBUG, DEBUG_LOG, 0, "executing start command"); // make sure temperature is set CoolerTask coolertask(instrument, temperature); coolertask.stop_on_exit(true); coolertask.wait(); // next two arguments are the interval boundaries if ((argc - optind) < 2) { short_usage(argv[0]); throw std::runtime_error("missing interval arguments"); } int min = std::stoi(argv[optind++]); int max = std::stoi(argv[optind++]); debug(LOG_DEBUG, DEBUG_LOG, 0, "interval [%d,%d]", min, max); if (min >= max) { short_usage(argv[0]); throw std::runtime_error("not an interval"); } debug(LOG_DEBUG, DEBUG_LOG, 0, "focusing in interval [%d,%d]", min, max); // ensure that focuser is ready FocusState state = focusing->status(); debug(LOG_DEBUG, DEBUG_LOG, 0, "current state = %d", state); if ((state == FocusMOVING) && (state == FocusMEASURING)) { short_usage(argv[0]); throw std::runtime_error("already focusing"); } debug(LOG_DEBUG, DEBUG_LOG, 0, "focuser available"); // set up the exposure astro::camera::Exposure exposure; exposure.purpose(astro::camera::Exposure::focus); exposure.exposuretime(exposuretime); if (binning.size() > 0) { exposure.mode(astro::image::Binning(binning)); } exposure.shutter(astro::camera::Shutter::OPEN); if (frame.size() > 0) { exposure.frame(astro::image::ImageRectangle(frame)); } // set up the focusing focusing->setSteps(steps); focusing->setMethod(convert(method)); focusing->setExposure(convert(exposure)); debug(LOG_DEBUG, DEBUG_LOG, 0, "focusing set up %d steps, method %s", steps, astro::focusing::Focusing::method2string(method).c_str()); // start the focusing process debug(LOG_DEBUG, DEBUG_LOG, 0, "starting between %d and %d", min, max); focusing->start(min, max); debug(LOG_DEBUG, DEBUG_LOG, 0, "focusing started, status: %d", focusing->status()); // wait for the process to complete bool completed = false; signal(SIGINT, handler); do { sleep(1); switch (focusing->status()) { case FocusIDLE: case FocusMOVING: case FocusMEASURING: break; case FocusFOCUSED: case FocusFAILED: completed = true; break; } } while ((!completed) && (!signal_received)); if (completed) { std::cout << "final focus position: " << focuserprx->current(); std::cout << std::endl; // display the history show_history(focusing->history()); } else { std::cout << "focusing incomplete" << std::endl; return EXIT_FAILURE; } return EXIT_SUCCESS; }