diff --git a/.gitignore b/.gitignore index f7d109d..b62fca7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .hg* *.tgz +.dropbox.attr *~ diff --git a/CMakeLists.txt b/CMakeLists.txt index 42d0c49..3f45b05 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,13 +28,13 @@ endif() if(DEFINED TELLAT) add_definitions(-DTELLAT=${TELLAT}) endif() -set(LCPATH locale/ru) +set(LCPATH ${CMAKE_CURRENT_SOURCE_DIR}/locale/ru) set(CFLAGS -O3 -Wall -Werror -W -std=gnu99) set(PO_FILE ${LCPATH}/messages.po) set(MO_FILE ${LCPATH}/LC_MESSAGES/${PROJ}.mo) set(RU_FILE ${LCPATH}/ru.po) find_package(PkgConfig REQUIRED) -set(MODULES cfitsio>=3.0 apogeec>=1.71) +set(MODULES cfitsio>=3.0 apogeec>=1.71 libusb>=0.1.10) if(DEFINED USEPNG) set(MODULES ${MODULES} libpng>=1.2) add_definitions(-DUSEPNG) @@ -62,7 +62,7 @@ if(NOT GETTEXT_XGETTEXT_EXECUTABLE OR NOT GETTEXT_MSGFMT_EXECUTABLE) endif() add_custom_command( OUTPUT ${PO_FILE} - COMMAND ${GETTEXT_XGETTEXT_EXECUTABLE} --from-code=koi8-r ${SOURCES} -c -k_ -kN_ -o ${PO_FILE} + COMMAND ${GETTEXT_XGETTEXT_EXECUTABLE} -D ${CMAKE_CURRENT_SOURCE_DIR} --from-code=koi8-r ${SOURCES} -c -k_ -kN_ -o ${PO_FILE} COMMAND sed 's/charset=UTF-8/charset=koi8-r/' ${PO_FILE} | enconv > tmp && mv -f tmp ${PO_FILE} COMMAND ${GETTEXT_MSGMERGE_EXECUTABLE} -Uis ${RU_FILE} ${PO_FILE} DEPENDS ${SOURCES}) diff --git a/apogee_C_wrapper/README b/apogee_C_wrapper/README index eccbf3f..d7c277a 100644 --- a/apogee_C_wrapper/README +++ b/apogee_C_wrapper/README @@ -8,6 +8,10 @@ To compile and install wrapper make: [5] You can run test applications: ./test will make testing connection to your camera and ./test_wheel will make test connection to your wheel, increasing its current position. + +Define -DEBUG=1 to see debug info + + After installing cd to apogee_control working directory and compile&install apogee_control. @@ -19,4 +23,3 @@ APOGEE_ALTAF APOGEE_ASPEN APOGEE_QUAD -If you wanna see debugging information, add -DEBUG to cmake options diff --git a/apogee_C_wrapper/src/libapogee.cpp b/apogee_C_wrapper/src/libapogee.cpp index 13b4d1e..80ee1d8 100644 --- a/apogee_C_wrapper/src/libapogee.cpp +++ b/apogee_C_wrapper/src/libapogee.cpp @@ -129,6 +129,25 @@ CamParams *getCamParams(std::string & msg){ return ∥ } +/** + * return camera info + * Don't forget to call FREE!!! + * @param pid, vid - device PID and VID + */ +char *ApnGlueGetInfo(int *pid, int *vid){ + if(pid || vid){ + uint16_t v = 1, p = 2, d = 3; + alta->GetUsbVendorInfo(v, p, d); + if(pid) *pid = p; + if(vid) *vid = v; + } + std::string str = alta->GetInfo(); + char *writable = new char[str.size() + 1]; + std::copy(str.begin(), str.end(), writable); + writable[str.size()] = '\0'; + return writable; +} + /** * Open camera device and assign it to variable * IT DON'T WORK WITH MULTIPLE CAMERAS SIMULTANEOUSLY! @@ -588,6 +607,8 @@ int ApnGlueReadPixels(unsigned short *buf, int nbuf, char whynot[]){ return altaerr; } + + /* ******************************** FILTER WHEEL ******************************** */ diff --git a/apogee_C_wrapper/src/libapogee.h b/apogee_C_wrapper/src/libapogee.h index aac985f..f30887a 100644 --- a/apogee_C_wrapper/src/libapogee.h +++ b/apogee_C_wrapper/src/libapogee.h @@ -153,6 +153,7 @@ int ApnGlueExpDone(); void ApnGlueExpAbort(void); int ApnGlueStopExposure(); int ApnGlueReadPixels(unsigned short *buf, int nbuf, char whynot[]); +char *ApnGlueGetInfo(int *pid, int *vid); // Wheel int ApnGlueWheelOpen(unsigned int id, Apn_Filter type); diff --git a/bta_print.c b/bta_print.c index a0039ad..a932162 100644 --- a/bta_print.c +++ b/bta_print.c @@ -23,6 +23,8 @@ do{ if(test_headers){printf("HISTORY: %s\n", comment);}else{ \ if(status) fits_report_error(stderr, status);\ }}while(0) +int shm_ready = FALSE; // BTA shm_get + // calculate airmass extern void calc_airmass( // in @@ -70,14 +72,12 @@ char *angle_asc(double a){ } typedef struct{ - double Sid_time; // S_time-EE_time - double JD; // JDate - double Alpha; // val_Alp - double Delta; // val_Del + double JD; // JDate double Azimuth; // val_A double Zenith; // val_Z double P2; // val_P - double Wind; // val_Wnd + double Wind; // val_Wnd + //double Tmir; // } BTA_PARAMS; typedef struct _BTA_Que{ @@ -96,7 +96,10 @@ void write_bta_data(fitsfile *fp){ struct tm *tm_ut, *tm_loc; tm_ut = gmtime(&t_now); tm_loc = localtime(&t_now); - if(!get_shm_block(&sdat, ClientSide)) return; + if(!shm_ready){ + if(!get_shm_block(&sdat, ClientSide)) return; + else shm_ready = TRUE; + } if(!check_shm_block(&sdat)) return; /* * Observatory parameters @@ -219,12 +222,12 @@ void write_bta_data(fitsfile *fp){ // get parameters int get_params(BTA_PARAMS *P){ - if(!get_shm_block(&sdat, ClientSide)) return -1; + if(!shm_ready){ + if(!get_shm_block(&sdat, ClientSide)) return -1; + else shm_ready = TRUE; + } if(!check_shm_block(&sdat)) return -1; - P->Sid_time = S_time-EE_time; P->JD = JDate; - P->Alpha = val_Alp; - P->Delta = val_Del; P->Azimuth = val_A; P->Zenith = val_Z; P->P2 = val_P; @@ -233,18 +236,23 @@ int get_params(BTA_PARAMS *P){ } int push_param(){ + DBG("Try to push parameter"); + if(!shm_ready){ + if(!get_shm_block(&sdat, ClientSide)) return -4; + else shm_ready = TRUE; + } if(!check_shm_block(&sdat)) return -3; BTA_PARAMS *Par = calloc(1, sizeof(BTA_PARAMS)); BTA_Queue *qcur = calloc(1, sizeof(BTA_Queue)); if(!Par || !qcur){ free(Par); free(qcur); - return -1; // malloc error + return -2; // malloc error } if(get_params(Par)){ free(Par); free(qcur); - return -2; // error getting parameters + return -1; // error getting parameters } qcur->data = Par; qcur->next = NULL; @@ -267,10 +275,7 @@ void write_bta_queue(fitsfile *fp){ do{ P = cur->data; HISTRY("Data record # %d", i); - HISTRY("ST = %.3f / Sidereal time: %s", P->Sid_time, time_asc(P->Sid_time)); HISTRY("JD = %.8g / Julian date", P->JD); - HISTRY("T_RA = %.8g / Telescope R.A: %s", P->Alpha / 3600., time_asc(P->Alpha)); - HISTRY("T_DEC = %.8g / Telescope Decl.: %s", P->Delta / 3600., angle_asc(P->Delta)); HISTRY("T_AZ = %.8g / Telescope Az: %s", P->Azimuth / 3600., angle_asc(P->Azimuth)); HISTRY("T_ZD = %.8g / Telescope ZD: %s", P->Zenith / 3600., angle_asc(P->Zenith)); HISTRY("T_P2 = %.8g / Current P: %s", P->P2 / 3600., angle_asc(P->P2)); diff --git a/takepic.c b/takepic.c index d38c157..61c2314 100644 --- a/takepic.c +++ b/takepic.c @@ -3,6 +3,11 @@ #include #include #include + +#include +#include +#include + #include "usage.h" #include "camtools.h" #include "bta_print.h" @@ -55,20 +60,94 @@ int check_filename(char *buff, char *outfile, char *ext){ return 0; } +void reset_usb_port(int pid, int vid){ + int fd, rc; + char buf[256], *d = NULL, *f = NULL; + struct usb_bus *bus; + struct usb_device *dev; + int found = 0; + usb_init(); + usb_find_busses(); + usb_find_devices(); + for(bus = usb_busses; bus && !found; bus = bus->next) { + for(dev = bus->devices; dev && !found; dev = dev->next) { + if (dev->descriptor.idVendor == vid && dev->descriptor.idProduct == pid){ + found = 1; + d = bus->dirname; + f = dev->filename; + } + } + } + if(!found){ + // "Устройство не найдено" + ERR(_("Device not found")); + return; + } + DBG("found camera device, reseting"); + snprintf(buf, 255, "/dev/bus/usb/%s/%s", d,f); + fd = open(buf, O_WRONLY); + if (fd < 0) { + // "Не могу открыть файл устройства %s: %s" + ERR(_("Can't open device file %s: %s"), buf, strerror(errno)); + return; + } + info("Resetting USB device %s", buf); + rc = ioctl(fd, USBDEVFS_RESET, 0); + if (rc < 0) { + // "Не могу вызывать ioctl" + perror(_("Error in ioctl")); + return; + } + close(fd); +} + // quit by signal static void signals(int sig){ int u; // "Получен сигнал %d, отключаюсь.\n" printf(_("Get signal %d, quit.\n"), sig); ApnGlueWheelClose(); - ApnGlueExpAbort(); + DBG("wheel closed"); +// ApnGlueExpAbort(); // this function stubs all! +// DBG("exp aborted"); ApnGlueClose(); + DBG("device closed"); u = unlink(pidfilename); // "Не могу удалить PID-файл" if(u == -1) perror(_("Can't delete PIDfile")); exit(sig); } +int sigcounter = 3; +static void cnt_signals(int sig){ + --sigcounter; + if(sigcounter != 0){ + // "Нажмите Ctrl+C еще %d раз[а], чтобы прервать считывание\n" + printf(_("Press Ctrl+C %d time[s] more to interrupt reading\n"), sigcounter); + signal(SIGINT, cnt_signals); + }else{ + signals(sig); + } +} + +// Try to ignore all signals exept SIGINT, which is counted +void ignore_signals(){ + sigcounter = 3; + for(int _=0; _<256; _++) + signal(_, SIG_IGN); + signal(SIGINT, cnt_signals); +} +// We must take care about signals to avoid ctrl+C problems +void catch_signals(){ + for(int _=0; _<256; _++) + signal(_, SIG_IGN); + signal(SIGTERM, signals); // kill (-15) - quit + signal(SIGHUP, signals); // hup - quit + signal(SIGINT, signals); // ctrl+C - quit + signal(SIGQUIT, signals); // ctrl+\ - quit + //signal(SIGTSTP, SIG_IGN); // ignore ctrl+Z +} + // check for running process void check4running(){ // get process name from /proc @@ -129,21 +208,6 @@ void check4running(){ fclose(pidfile); } -// Try to ignore all signals -void ignore_signals(){ - for(int _=0; _<256; _++) - signal(_, SIG_IGN); -} -// We must take care about signals to avoid ctrl+C problems -void catch_signals(){ - ignore_signals(); // first -- ignore all signals - signal(SIGTERM, signals); // kill (-15) - quit - signal(SIGHUP, signals); // hup - quit - signal(SIGINT, signals); // ctrl+C - quit - signal(SIGQUIT, signals); // ctrl+\ - quit - //signal(SIGTSTP, SIG_IGN); // ignore ctrl+Z -} - // Work with turret void parse_turret_args(){ int maxPos, curPos; @@ -184,6 +248,7 @@ wheelret: int main(int argc, char **argv){ int i; //cycles + int pid = -1, vid = -1; // device pid/vid FILE *f_tlog = NULL; // temperature logging file FILE *f_statlog = NULL; // stat file int roih=0, roiw=0, osh=0, osw=0, binh=0, binw=0, shtr=0; // camera parameters @@ -218,18 +283,26 @@ int main(int argc, char **argv){ // First - open camera devise if(ApnGlueOpen(Ncam)){ // "Не могу открыть камеру, завершаю" - ERR("Can't open camera device, exit"); + ERR(_("Can't open camera device, exit")); return 1; } ApnGlueGetName(&sensor, &camera); camera = strdup(camera); sensor = strdup(sensor); // "Обнаружена камера '%s' с датчиком '%s'" info(_("Find camera '%s' with sensor '%s'"), camera, sensor); + + // "Адрес USB: " + char *msg = NULL; + msg = ApnGlueGetInfo(&pid, &vid); + printf("\n Camera info:\n%s\n", msg); + free(msg); + // Second - check whether we want do a simple power operations if(StopRes){ switch(StopRes){ case Reset: ApnGlueReset(); + reset_usb_port(pid, vid); break; case Sleep: if(ApnGluePowerDown()) @@ -279,6 +352,7 @@ int main(int argc, char **argv){ // "закрыт\n" printf(_("closed\n")); printCoolerStat(NULL); + if(set_T){ if(cooler_off){ ApnGlueSetTemp(0); @@ -324,14 +398,14 @@ int main(int argc, char **argv){ ApnGlueSetDatabits(Apn_Resolution_SixteenBit); if(ROspeed) ApnGlueSetSpeed(ROspeed); - + DBG("here"); if(pre_exp){// pre-expose // "Предварительная экспозиция" info(_("Pre-expose")); double E = 0.; if(!twelveBit) ApnGlueSetDatabits(Apn_Resolution_TwelveBit); - if(ApnGlueSetExpGeom(roiw, roih, 0, 0, binw, binh, + if(ApnGlueSetExpGeom(roiw, roih, 0, 0, 8, 8, 0, 0, &imW, &imH, whynot)){ // "Не могу установить параметры считывания: %s" ERR("Can't set readout parameters: %s", whynot); @@ -366,6 +440,7 @@ int main(int argc, char **argv){ ERR("Can't set readout parameters: %s", whynot); goto returning; } + DBG("geomery: %dx%d", imW, imH); int L = imW*imH; buf = (unsigned short*) calloc(L, sizeof(unsigned short)); if(!buf){ @@ -380,11 +455,13 @@ int main(int argc, char **argv){ if(exptime > -1){ // do expositions only if there is -x key E = (double) exptime / 1000.; I = (int) E; + ignore_signals(); if(ApnGlueStartExp(&E, shutter)){ // "Ошибка экспозиции!" ERR("Error exposing frame!"); continue; } + DBG("Exposing"); #ifdef USE_BTA push_param(); #endif @@ -415,6 +492,7 @@ int main(int argc, char **argv){ #endif }else while(!ApnGlueExpDone()) usleep(100000); // make 100ms error }while(!ApnGlueExpDone()); + DBG("exp done"); #ifdef USE_BTA push_param(); #endif @@ -474,10 +552,15 @@ int main(int argc, char **argv){ fflush(NULL); } returning: + // set fan speed to 0 or 3 according cooler status + if(!only_turret) AutoadjustFanSpeed(TRUE); + DBG("abort exp"); + ApnGlueExpAbort(); + DBG("close"); + ApnGlueClose(); + DBG("free buffers & close files"); free(buf); if(f_tlog) fclose(f_tlog); if(f_statlog) fclose(f_statlog); - // set fan speed to 0 or 3 according cooler status - if(!only_turret) AutoadjustFanSpeed(TRUE); return 0; }