From b73587a5e47602c4ef09228b37bfacdfe5798b90 Mon Sep 17 00:00:00 2001 From: eddyem Date: Sun, 25 Mar 2018 10:50:23 +0300 Subject: [PATCH] Add short list to HSFV_manage --- HSFW_management/Readme.md | 29 +- HSFW_management/cmdlnopts.c | 135 ++++---- HSFW_management/cmdlnopts.h | 22 +- HSFW_management/hsfw.c | 50 +-- astrosib/CMakeLists.txt | 6 + astrosib/Readme.md | 6 + astrosib/astrosib.cpp | 481 ++++++++++++++++++++++++++ astrosib/astrosib.h | 103 ++++++ cmakelists_/CMakeLists_regular_01.txt | 5 +- cmakelists_/CMakeLists_regular_02.txt | 140 ++++++++ cmakelists_/get_proc_count | 1 + get_avail_mem.c | 14 + image_view_module/README | 2 + usefull_macros.c | 4 +- usefull_macros.h | 3 + 15 files changed, 889 insertions(+), 112 deletions(-) create mode 100644 astrosib/CMakeLists.txt create mode 100644 astrosib/Readme.md create mode 100644 astrosib/astrosib.cpp create mode 100644 astrosib/astrosib.h create mode 100644 cmakelists_/CMakeLists_regular_02.txt create mode 100644 cmakelists_/get_proc_count create mode 100644 get_avail_mem.c create mode 100644 image_view_module/README diff --git a/HSFW_management/Readme.md b/HSFW_management/Readme.md index d84857d..6c2f276 100644 --- a/HSFW_management/Readme.md +++ b/HSFW_management/Readme.md @@ -23,18 +23,16 @@ given turret. ## Usage examples -#### List all devices connected - Свойства подключенного колеса - Wheel ID 'A', name 'UBVRI', serial '00000563', 5 filters: - 1: 'U' - 2: 'B' - 3: 'V' - 4: 'R' - 5: 'I' - current position: 1 +#### Short list of connected devices (wheel ID, turret serial and current position): + HSFW_manage + 'B' '00000563' 1 + 'A' '00000532' 1 - Свойства подключенного колеса - Wheel ID 'B', name 'Sloan', serial '00000532', 5 filters: +#### List all devices connected + HSFW_manage --list + + Connected wheel properties + Wheel ID 'B' , name 'Sloan', serial '00000563' , 5 filters: 1: '1' 2: '2' 3: '3' @@ -42,6 +40,15 @@ given turret. 5: '5' current position: 1 + Connected wheel properties + Wheel ID 'A' , name 'UBVRI', serial '00000532' , 5 filters: + 1: 'U' + 2: 'B' + 3: 'V' + 4: 'R' + 5: 'I' + current position: 1 + #### Move wheel by turret's serial and position number HSFW_manage -s 00000563 -p 3 diff --git a/HSFW_management/cmdlnopts.c b/HSFW_management/cmdlnopts.c index 01ea52e..583aec3 100644 --- a/HSFW_management/cmdlnopts.c +++ b/HSFW_management/cmdlnopts.c @@ -36,54 +36,54 @@ int help; glob_pars G; -int listNms = 0 // list names - ,gohome = 0 // first go home - ,reName = 0 // rename wheels/positions - ,showpos = 0 // show current position (if none args) - ,setdef = 0 // reset all names to default values +int listNms = LIST_NONE // list names + ,gohome = 0 // first go home + ,reName = 0 // rename wheels/positions + ,showpos = 0 // show current position (if none args) + ,setdef = 0 // reset all names to default values ; // DEFAULTS // default global parameters glob_pars const Gdefault = { - NULL // wheelID - ,NULL // wheelName - ,NULL // serial - ,0 // filterPos ( 0 - get current position) - ,NULL // filterName - ,NULL // filterId + NULL // wheelID + ,NULL // wheelName + ,NULL // serial + ,0 // filterPos ( 0 - get current position) + ,NULL // filterName + ,NULL // filterId }; /* * Define command line options by filling structure: - * name has_arg flag val type argptr help + * name has_arg flag val type argptr help */ myoption cmdlnopts[] = { - /// " " - {"help", NO_ARGS, NULL, 'h', arg_int, APTR(&help), N_("show this help")}, - /// " " - {"wheel-id",NEED_ARG, NULL, 'W', arg_string, APTR(&G.wheelID), N_("letter wheel identificator")}, - /// " " - {"wheel-name",NEED_ARG, NULL, 'N', arg_string, APTR(&G.wheelName), N_("wheel name")}, - /// " ( )" - {"serial", NEED_ARG, NULL, 's', arg_string, APTR(&G.serial), N_("turret serial (with leading zeros)")}, - /// " " - {"f-position",NEED_ARG, NULL, 'p', arg_int, APTR(&G.filterPos), N_("filter position number")}, - /// " " - {"filter-name",NEED_ARG,NULL, 'n', arg_string, APTR(&G.filterName),N_("filter name")}, - /// " , , \"A3\"" - {"filter-id",NEED_ARG, NULL, 'i', arg_string, APTR(&G.filterId), N_("filter identificator like \"A3\"")}, - /// " " - {"list-all",NO_ARGS, &listNms,LIST_ALL,arg_none, NULL, N_("list all stored names")}, - /// " " - {"list", NO_ARGS, &listNms,LIST_PRES,arg_none,NULL, N_("list only present devices' names")}, - /// " " - {"home", NO_ARGS, NULL, 'H', arg_none, &gohome, N_("move to home position")}, - /// " /" - {"rename", NO_ARGS, &reName,1, arg_none, NULL, N_("rename stored wheels/filters names")}, - {"resetnames",NO_ARGS, &setdef,1, arg_none, NULL, N_("reset all names to default values")}, - end_option + /// " " + {"help", NO_ARGS, NULL, 'h', arg_int, APTR(&help), N_("show this help")}, + /// " " + {"wheel-id",NEED_ARG, NULL, 'W', arg_string, APTR(&G.wheelID), N_("letter wheel identificator")}, + /// " " + {"wheel-name",NEED_ARG, NULL, 'N', arg_string, APTR(&G.wheelName), N_("wheel name")}, + /// " ( )" + {"serial", NEED_ARG, NULL, 's', arg_string, APTR(&G.serial), N_("turret serial (with leading zeros)")}, + /// " " + {"f-position",NEED_ARG, NULL, 'p', arg_int, APTR(&G.filterPos), N_("filter position number")}, + /// " " + {"filter-name",NEED_ARG,NULL, 'n', arg_string, APTR(&G.filterName),N_("filter name")}, + /// " , , \"A3\"" + {"filter-id",NEED_ARG, NULL, 'i', arg_string, APTR(&G.filterId), N_("filter identificator like \"A3\"")}, + /// " " + {"list-all",NO_ARGS, &listNms,LIST_ALL,arg_none, NULL, N_("list all stored names")}, + /// " " + {"list", NO_ARGS, &listNms,LIST_PRES,arg_none,NULL, N_("list only present devices' names")}, + /// " " + {"home", NO_ARGS, NULL, 'H', arg_none, &gohome, N_("move to home position")}, + /// " /" + {"rename", NO_ARGS, &reName,1, arg_none, NULL, N_("rename stored wheels/filters names")}, + {"resetnames",NO_ARGS, &setdef,1, arg_none, NULL, N_("reset all names to default values")}, + end_option }; /** @@ -94,45 +94,46 @@ myoption cmdlnopts[] = { * @return TRUE if success */ bool myatod(double *num, const char *str){ - double res; - char *endptr; - assert(str); - res = strtod(str, &endptr); - if(endptr == str || *str == '\0' || *endptr != '\0'){ - /// " double!" - WARNX(_("Wrong double number format!")); - return FALSE; - } - *num = res; - return TRUE; + double res; + char *endptr; + assert(str); + res = strtod(str, &endptr); + if(endptr == str || *str == '\0' || *endptr != '\0'){ + /// " double!" + WARNX(_("Wrong double number format!")); + return FALSE; + } + *num = res; + return TRUE; } /** * Parse command line options and return dynamically allocated structure - * to global parameters + * to global parameters * @param argc - copy of argc from main * @param argv - copy of argv from main * @return allocated structure with global parameters */ glob_pars *parse_args(int argc, char **argv){ - int i, oldargc = argc - 1; - void *ptr; - ptr = memcpy(&G, &Gdefault, sizeof(G)); assert(ptr); - /// ": %s [] [ ]\n\n\t []:\n" - //change_helpstring(_("Usage: %s [args] [outfile prefix] [file list for group operations]\n\n\tWhere args are:\n")); - // parse arguments - parseargs(&argc, &argv, cmdlnopts); - if(help) showhelp(-1, cmdlnopts); - if(argc > 0){ - /// " : " - WARNX(_("Ignore parameters:")); - for (i = 0; i < argc; i++){ - printf("%s\n", argv[i]); - } - } - if(argc == oldargc){ // no parameters given or given only wrong parameters - showpos = 1; - } - return &G; + int i, oldargc = argc - 1; + void *ptr; + ptr = memcpy(&G, &Gdefault, sizeof(G)); assert(ptr); + /// ": %s [] [ ]\n\n\t []:\n" + //change_helpstring(_("Usage: %s [args] [outfile prefix] [file list for group operations]\n\n\tWhere args are:\n")); + // parse arguments + parseargs(&argc, &argv, cmdlnopts); + if(help) showhelp(-1, cmdlnopts); + if(argc > 0){ + /// " : " + WARNX(_("Ignore parameters:")); + for (i = 0; i < argc; i++){ + printf("%s\n", argv[i]); + } + } + if(argc == oldargc){ // no parameters given or given only wrong parameters + //showpos = 1; + listNms = LIST_SHORT; // short list of turrets present + } + return &G; } diff --git a/HSFW_management/cmdlnopts.h b/HSFW_management/cmdlnopts.h index c5182f4..239cd60 100644 --- a/HSFW_management/cmdlnopts.h +++ b/HSFW_management/cmdlnopts.h @@ -29,17 +29,21 @@ * here are some typedef's for global data */ typedef struct{ - char *wheelID; // ID of wheel to work with - char *wheelName; // and/or its name - char *serial; // turret's serial (string description) - int filterPos; // position of filter - char *filterName; // and/or its name - char *filterId; // or full ID like "A2" + char *wheelID; // ID of wheel to work with + char *wheelName; // and/or its name + char *serial; // turret's serial (string description) + int filterPos; // position of filter + char *filterName; // and/or its name + char *filterId; // or full ID like "A2" } glob_pars; -// ids for "list all" & "list present" -#define LIST_ALL (1) -#define LIST_PRES (2) +// ids for "list all", "list present", "list short" +typedef enum{ + LIST_NONE = 0, + LIST_ALL, + LIST_PRES, + LIST_SHORT +} listopts; // default & global parameters extern glob_pars const Gdefault; diff --git a/HSFW_management/hsfw.c b/HSFW_management/hsfw.c index 31f37cd..4046665 100644 --- a/HSFW_management/hsfw.c +++ b/HSFW_management/hsfw.c @@ -66,9 +66,10 @@ void set_cur_wheel(int idx){ * Check command line arguments, find filters/wheels by name, find max positions & so on */ void check_args(){ + FNAME(); // here we fill value of wheel_id if no given and present only one turret list_hw(listNms); // also exit if no HW found - if(listNms) return; + if(listNms != LIST_NONE) return; int i; // add wheel ID to global parameters if there was nothing if(G.serial){ // HW given by its serial @@ -170,6 +171,7 @@ void check_args(){ /// " !" ERRX(_("Given wheel not found!")); } + DBG("listNms = %d", listNms); if(reName && !G.wheelID){ G.wheelID = calloc(2, 1); *G.wheelID = wheel_id; @@ -286,7 +288,7 @@ int poll_regstatus(int fd, int msg){ ERRX(_("Error ocured, repeat again")); } usleep(50000); - if(msg) printf("."); fflush(stdout); + if(msg){printf("."); fflush(stdout);} } if(msg) printf("\n"); return buf[4]; @@ -339,6 +341,7 @@ void list_props(int verblevl, wheel_descr *wheel){ wheel->ID = buf[5]; wheel->maxpos = buf[4]; DBG("Wheel with id '%c' and maxpos %d", wheel->ID, wheel->maxpos); + DBG("Verblevl = %d", verblevl); char *getwname(int id){ memset(buf, 0, sizeof(buf)); buf[0] = REG_NAME; @@ -353,33 +356,40 @@ void list_props(int verblevl, wheel_descr *wheel){ } else return NULL; } - if(verblevl == LIST_PRES || !verblevl){ // list only presented devices or not list + if(verblevl == LIST_PRES || verblevl == LIST_SHORT || verblevl == LIST_NONE){ // list only presented devices or not list char *nm; /// "\n \n" - if(verblevl) green(_("\nConnected wheel properties\n")); - if(verblevl) printf("Wheel ID '%c'", wheel->ID); + if(verblevl != LIST_NONE){ + if(verblevl == LIST_PRES){ + green(_("\nConnected wheel properties\n")); + printf("Wheel ID "); + } + printf("'%c' ", wheel->ID); + } nm = getwname(wheel->ID); if(nm){ strncpy(wheel->name, nm, 9); - if(verblevl) printf(", name '%s'", wheel->name); + if(verblevl == LIST_PRES) printf(", name '%s'", wheel->name); DBG("Wheel name: %s", wheel->name); } - if(wheel->serial && verblevl){ - printf(", serial '%s'", wheel->serial); + if(wheel->serial && verblevl != LIST_NONE){ + if(verblevl == LIST_PRES) printf(", serial "); + printf("'%s' ", wheel->serial); } - if(verblevl) printf(", %d filters:\n", wheel->maxpos); - else return; - int i, m = wheel->maxpos + 1; - // now get filter names - for(i = 1; i < m; ++i){ - nm = get_filter_name(wheel, i); - printf("\t%d", i); - if(nm) printf(": '%s'", nm); - printf("\n"); - } - if(verblevl){ - printf("current position: %d\n", poll_regstatus(wheel->fd, 0)); + if(verblevl == LIST_NONE) return; + if(verblevl == LIST_PRES){ + printf(", %d filters:\n", wheel->maxpos); + int i, m = wheel->maxpos + 1; + // now get filter names + for(i = 1; i < m; ++i){ + nm = get_filter_name(wheel, i); + printf("\t%d", i); + if(nm) printf(": '%s'", nm); + printf("\n"); + } + printf("current position: "); } + printf("%d\n", poll_regstatus(wheel->fd, 0)); } if(verblevl != LIST_ALL) return; // now list all things stored in memory of turret driver diff --git a/astrosib/CMakeLists.txt b/astrosib/CMakeLists.txt new file mode 100644 index 0000000..5be16cc --- /dev/null +++ b/astrosib/CMakeLists.txt @@ -0,0 +1,6 @@ +########## Tutorial two ############## +add_executable(astrosib astrosib.cpp) + +target_link_libraries(astrosib indidriver) + + diff --git a/astrosib/Readme.md b/astrosib/Readme.md new file mode 100644 index 0000000..f7fddde --- /dev/null +++ b/astrosib/Readme.md @@ -0,0 +1,6 @@ +INDI driver for ASTROSIB telescopes + + + +*Write at level upper to CMakeLists.txt:* +add_subdirectory(astrosib) diff --git a/astrosib/astrosib.cpp b/astrosib/astrosib.cpp new file mode 100644 index 0000000..855afba --- /dev/null +++ b/astrosib/astrosib.cpp @@ -0,0 +1,481 @@ +/* + * geany_encoding=koi8-r + * astrosib.cpp + * + * Copyright 2017 Edward V. Emelianov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + */ +/* + INDI Developers Manual + Tutorial #2 + + "Simple Telescope Driver" + + We develop a simple telescope simulator. + + Refer to README, which contains instruction on how to build this driver, and use it + with an INDI-compatible client. + +*/ + +/** \file simplescope.cpp + \brief Construct a basic INDI telescope device that simulates GOTO commands. + \author Jasem Mutlaq + + \example simplescope.cpp + A simple GOTO telescope that simulator slewing operation. +*/ + +#include "astrosib.h" + +#include "indicom.h" + +#include +#include +#include + +// timer polling time +#define POLLMS 1000 + +static const char *FOCUSER_TAB = "Focuser management"; +static const char *COOLER_TAB = "Cooler management"; +static const char *HEATER_TAB = "Heater management"; + +std::unique_ptr aSib(new AstroSib()); + +/************************************************************************************** +** Return properties of device. +***************************************************************************************/ +void ISGetProperties(const char *dev){ + aSib->ISGetProperties(dev); +} + +/************************************************************************************** +** Process new switch from client +***************************************************************************************/ +void ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n){ + aSib->ISNewSwitch(dev, name, states, names, n); +} + +/************************************************************************************** +** Process new text from client +***************************************************************************************/ +void ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n){ + aSib->ISNewText(dev, name, texts, names, n); +} + +/************************************************************************************** +** Process new number from client +***************************************************************************************/ +void ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n){ + aSib->ISNewNumber(dev, name, values, names, n); +} + +/************************************************************************************** +** Process new blob from client +***************************************************************************************/ +void ISNewBLOB(const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[], + char *names[], int n){ + aSib->ISNewBLOB(dev, name, sizes, blobsizes, blobs, formats, names, n); +} + +/************************************************************************************** +** Process snooped property from another driver +***************************************************************************************/ +void ISSnoopDevice(XMLEle *root){ + INDI_UNUSED(root); +} + +AstroSib::AstroSib(){ + /* code should be here */ + //DBG_LEVEL = INDI::Logger::getInstance().addDebugLevel("Astrosib Verbose", "SCOPE"); +} + +AstroSib::~AstroSib(){ + /* code should be here */ + if (isConnected()) AstroSib::Disconnect(); +} + +/************************************************************************************** +** We init our properties here. The only thing we want to init are the Debug controls +***************************************************************************************/ +bool AstroSib::initProperties(){ + // ALWAYS call initProperties() of parent first + INDI::DefaultDevice::initProperties(); + + // Shutter leaves + IUFillSwitch(&ShtrsS[SHTR_OPENED], "SHTR_OPENED", "Open Scope", ISS_OFF); + IUFillSwitch(&ShtrsS[SHTR_CLOSED], "SHTR_CLOSED", "Close Scope", ISS_ON); + IUFillSwitchVector(&ShtrsSP, ShtrsS, 2, getDeviceName(), "SHTR_CONTROL", "Shutter Control", + MAIN_CONTROL_TAB, IP_RW, ISR_1OFMANY, 1, IPS_OK); + + // Mirror and ambient temperature + IUFillNumber(&TempN[0], "MIRROR_TEMP", "Mirror temperature", "%.1f", -100., 100., 0.1, 0.); + IUFillNumber(&TempN[1], "AMBIENT_TEMP", "Ambient temperature", "%.1f", -100., 100., 0.1, 0.); + IUFillNumber(&TempN[2], "FOCUSER_TEMP", "Focuser temperature", "%.1f", -100., 100., 0.1, 0.); + IUFillNumberVector(&TempNP, TempN, 3, getDeviceName(), "TEMPERATURE", "Temperature", + MAIN_CONTROL_TAB, IP_RO, 1, IPS_IDLE); + + // Focuser: current, relative and absolute position + IUFillNumber(&FocuserN[0], "FOC_CUR", "Current focuser position", "%.0f", 0, 65536, 1, 0); + IUFillNumber(&FocuserN[1], "FOC_REL", "Relative focuser position", "%.0f", -65536, 65536, 1, 0); + IUFillNumber(&FocuserN[2], "FOC_ABS", "Absolute focuser position", "%.0f", 0, 65536, 1, 0); + IUFillNumberVector(&FocuserNPcur, FocuserN, 1, getDeviceName(), "FOCUS_CUR", "Focuser current", + FOCUSER_TAB, IP_RO, 1, IPS_IDLE); + FocuserNPcur.s = IPS_OK; + IUFillNumberVector(&FocuserNP, &FocuserN[1], 2, getDeviceName(), "FOCUS_SET", "Focuser set", + FOCUSER_TAB, IP_RW, 1, IPS_IDLE); + DEBUGF(INDI::Logger::DBG_SESSION, "FOCINIT, cur: %g, rel: %g, abs: %g", FocuserN[0].value, FocuserN[1].value, FocuserN[2].value); + // Mirror cooler ON/OFF + IUFillSwitch(&CoolerS[_ON], "COOLER_ON", "Cooler ON", ISS_OFF); + IUFillSwitch(&CoolerS[_OFF], "COOLER_OFF", "Cooler OFF", ISS_ON); + IUFillSwitchVector(&CoolerSP, CoolerS, 2, getDeviceName(), "COOLER_CONTROL", "Cooler Control", + COOLER_TAB, IP_RW, ISR_1OFMANY, 1, IPS_IDLE); + IUFillSwitch(&ACoolerS[_ON], "ACOOLER_ON", "Cooler auto ON", ISS_OFF); + IUFillSwitch(&ACoolerS[_OFF], "ACOOLER_OFF", "Cooler auto OFF", ISS_ON); + IUFillSwitchVector(&ACoolerSP, ACoolerS, 2, getDeviceName(), "ACOOLER_CONTROL", "Auto Cooler Control", + COOLER_TAB, IP_RW, ISR_1OFMANY, 1, IPS_IDLE); + // Secondary mirror / Primary focus corrector Heater + IUFillSwitch(&AHeaterS[_ON], "HTR_ON", "Auto Heater ON", ISS_OFF); + IUFillSwitch(&AHeaterS[_OFF], "HTR_OFF", "Auto Heater OFF", ISS_ON); + IUFillSwitchVector(&AHeaterSP, AHeaterS, 2, getDeviceName(), "HEATER_CONTROL", "Heater Control", + HEATER_TAB, IP_RW, ISR_1OFMANY, 1, IPS_IDLE); + IUFillNumber(&PHeaterN, "PHTR", "Set heater power", "%.0f", 0, 100, 1, 0); + IUFillNumberVector(&PHeaterNP, &PHeaterN, 1, getDeviceName(), "PHTR_CTRL", "Heater power", + HEATER_TAB, IP_RW, 1, IPS_IDLE); + return true; +} + +bool AstroSib::updateProperties(){ + // We must ALWAYS call the parent class updateProperties() first + DefaultDevice::updateProperties(); + + // If we are connected, we define the property to the client. + if (isConnected()){ + defineSwitch(&ShtrsSP); + defineNumber(&TempNP); + defineNumber(&FocuserNPcur); + defineNumber(&FocuserNP); + defineSwitch(&CoolerSP); + defineSwitch(&ACoolerSP); + defineSwitch(&AHeaterSP); + defineNumber(&PHeaterNP); + SetTimer(POLLMS); + // Otherwise, we delete the property from the client + }else{ + deleteProperty(ShtrsSP.name); + deleteProperty(TempNP.name); + deleteProperty(FocuserNPcur.name); + deleteProperty(FocuserNP.name); + deleteProperty(CoolerSP.name); + deleteProperty(ACoolerSP.name); + deleteProperty(AHeaterSP.name); + deleteProperty(PHeaterNP.name); + } + + return true; +} + +/************************************************************************************** +** Process new switch from client +***************************************************************************************/ +bool AstroSib::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n){ + // Mak sure the call is for our device + if(!strcmp(dev,getDeviceName())){ + // Check if the call for shutters + if (!strcmp(name, ShtrsSP.name)){ + // Find out which state is requested by the client + const char *actionName = IUFindOnSwitchName(states, names, n); + // If door is the same state as actionName, then we do nothing. i.e. if actionName is SHTR_OPENED and our shutter is already open, we return + int currentIndex = IUFindOnSwitchIndex(&ShtrsSP); + if (!strcmp(actionName, ShtrsS[currentIndex].name)){ + DEBUGF(INDI::Logger::DBG_SESSION, "Shutter is already %s", ShtrsS[currentIndex].label); + ShtrsSP.s = IPS_OK; + IDSetSwitch(&ShtrsSP, NULL); + return true; + } + // Otherwise, let us update the switch state + IUUpdateSwitch(&ShtrsSP, states, names, n); + DEBUGF(INDI::Logger::DBG_SESSION, "Shutter is going to %s", ShtrsS[currentIndex].label); + ShtrsSP.s = IPS_BUSY; + IDSetSwitch(&ShtrsSP, NULL); + return ShutterSetState(currentIndex); + }else if (!strcmp(name, CoolerSP.name)){ + // Find out which state is requested by the client + const char *actionName = IUFindOnSwitchName(states, names, n); + int currentIndex = IUFindOnSwitchIndex(&CoolerSP); + CoolerSP.s = IPS_OK; + if (!strcmp(actionName, CoolerS[currentIndex].name)){ + DEBUGF(INDI::Logger::DBG_SESSION, "Cooler is already %s", CoolerS[currentIndex].label); + IDSetSwitch(&CoolerSP, NULL); + return true; + } + IUUpdateSwitch(&CoolerSP, states, names, n); + currentIndex = IUFindOnSwitchIndex(&CoolerSP); + DEBUGF(INDI::Logger::DBG_SESSION, "Cooler is now %s", CoolerS[currentIndex].label); + IDSetSwitch(&CoolerSP, NULL); + return CoolerSetState(currentIndex); + }else if (!strcmp(name, ACoolerSP.name)){ + // Find out which state is requested by the client + const char *actionName = IUFindOnSwitchName(states, names, n); + int currentIndex = IUFindOnSwitchIndex(&ACoolerSP); + ACoolerSP.s = IPS_OK; + if (!strcmp(actionName, ACoolerS[currentIndex].name)){ + DEBUGF(INDI::Logger::DBG_SESSION, "Auto Cooler is already %s", ACoolerS[currentIndex].label); + IDSetSwitch(&ACoolerSP, NULL); + return true; + } + IUUpdateSwitch(&ACoolerSP, states, names, n); + currentIndex = IUFindOnSwitchIndex(&ACoolerSP); + DEBUGF(INDI::Logger::DBG_SESSION, "Auto Cooler is now %s", ACoolerS[currentIndex].label); + IDSetSwitch(&ACoolerSP, NULL); + return ACoolerSetState(currentIndex); + }else if (!strcmp(name, AHeaterSP.name)){ + // Find out which state is requested by the client + const char *actionName = IUFindOnSwitchName(states, names, n); + int currentIndex = IUFindOnSwitchIndex(&AHeaterSP); + AHeaterSP.s = IPS_OK; + if (!strcmp(actionName, AHeaterS[currentIndex].name)){ + DEBUGF(INDI::Logger::DBG_SESSION, "Auto Heater is already %s", AHeaterS[currentIndex].label); + IDSetSwitch(&AHeaterSP, NULL); + return true; + } + IUUpdateSwitch(&AHeaterSP, states, names, n); + currentIndex = IUFindOnSwitchIndex(&AHeaterSP); + DEBUGF(INDI::Logger::DBG_SESSION, "Auto Heater is now %s", AHeaterS[currentIndex].label); + IDSetSwitch(&AHeaterSP, NULL); + return AHeaterSetState(currentIndex); + } + } + // If we did not process the switch, let us pass it to the parent class to process it + return INDI::DefaultDevice::ISNewSwitch(dev, name, states, names, n); +} + +bool AstroSib::ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) +{ + DEBUGF(INDI::Logger::DBG_SESSION, "NEW NUM, name: %s, value=%g, names = %s, n: %d", name, values[0], names[0], n); + if (dev != nullptr && strcmp(dev, getDeviceName()) == 0){ + if(strcmp(name, FocuserNP.name) == 0){ + if(FocInProgress){ // Already moving + DEBUG(INDI::Logger::DBG_ERROR, "Wait still focus moving ends"); + return false; + } + if(IUUpdateNumber(&FocuserNP, values, names, n)){ + DEBUG(INDI::Logger::DBG_ERROR, "Can't set focuser value"); + FocuserN[1].value = 0; + FocuserN[2].value = focabs; + FocuserNP.s = IPS_ALERT; + IDSetNumber(&FocuserNP, nullptr); + return false; + } + DEBUGF(INDI::Logger::DBG_SESSION, "NEW NUMBER, rel: %g, abs: %g", FocuserN[1].value, FocuserN[2].value); + if(FocuserN[1].value){ // relative + focabs = foccur + FocuserN[1].value; + }else if(FocuserN[2].value){ // absolute + focabs = FocuserN[2].value; + } + if(focabs < 0){ + DEBUG(INDI::Logger::DBG_ERROR, "Can't move focuser to negative values"); + focabs = foccur; + FocuserNP.s = IPS_ALERT; + IDSetNumber(&FocuserNP, nullptr); + return false; + } + FocInProgress = true; + FocuserNP.s = IPS_BUSY; + FocuserN[1].value = focabs - foccur; + FocuserN[2].value = focabs; + IDSetNumber(&FocuserNP, nullptr); + return FocuserSetVal(focabs); + }else if(strcmp(name, PHeaterNP.name) == 0){ + float oldval = PHeaterN.value; + if(IUUpdateNumber(&PHeaterNP, values, names, n)){ + DEBUG(INDI::Logger::DBG_ERROR, "Can't set heater power value"); + return false; + } + bool stat = HeaterSetPower(*values); + if(!stat) PHeaterN.value = oldval; + PHeaterNP.s = (stat) ? IPS_OK : IPS_ALERT; + IDSetNumber(&PHeaterNP, nullptr); + return stat; + } + } + return INDI::DefaultDevice::ISNewNumber(dev, name, values, names, n); +} + + +/************************************************************************************** +** INDI is asking us for our default device name +***************************************************************************************/ +const char *AstroSib::getDefaultName(){ + return "AstroSib telescope"; +} + + +// Timer events +void AstroSib::TimerHit(){ + static int tensecond = 0; + ++tensecond; + if (isConnected()){ + // once per 10 seconds check cooler & heater status + if(tensecond == 10){ + CoolerChk(); + HeaterChk(); + tensecond = 0; + } + // check shutter if(ShtrInProgress) + if(ShtrInProgress){ + ShutterChk(); + } + // once per second check temperatures + TemperatureChk(); + // check focuser if(FocInProgress) + if(FocInProgress){ + FocuserChk(); + } + SetTimer(POLLMS); + } +} + +/** + * Private functions working with RS-232 + */ +void AstroSib::FocuserChk(){ + if(!FocInProgress){ + int cur = foccur, abs = focabs, del = cur - abs; + if(del){ + if(cur > abs){ + cur -= 10; + if(cur < abs) cur = abs; + }else{ + cur += 10; + if(cur > abs) cur = abs; + } + foccur = cur; + focabs = abs; + //DEBUGF(INDI::Logger::DBG_SESSION, "move, cur: %d, abs: %d", foccur, focabs); + } + if(foccur == focabs){ + FocInProgress = false; + FocuserNP.s = IPS_IDLE; + IDSetNumber(&FocuserNPcur, "Position reached"); + }else FocuserNP.s = IPS_BUSY; + }else{ + FocuserNP.s = IPS_IDLE; + } + FocuserNPcur.s = IPS_OK; + FocuserN[0].value = foccur; + FocuserN[1].value = focabs - foccur; + FocuserN[2].value = focabs; + IDSetNumber(&FocuserNPcur, nullptr); + IDSetNumber(&FocuserNP, nullptr); +} + +void AstroSib::TemperatureChk(){ +mirrtemp += 0.01; if(mirrtemp > 20.) mirrtemp = -20.; +ambtemp += 0.05; if(ambtemp > 20.) ambtemp = -20; + TempN[0].value = mirrtemp; + TempN[1].value = ambtemp; + TempN[2].value = focusert; + TempNP.s = IPS_OK; + IDSetNumber(&TempNP, nullptr); +} + +void AstroSib::ShutterChk(){ + if(ShtrInProgress){ + static bool closed = false; + if(closed){ + ShtrsS[SHTR_OPENED].s = ISS_OFF; + ShtrsS[SHTR_CLOSED].s = ISS_ON; + }else{ + ShtrsS[SHTR_OPENED].s = ISS_ON; + ShtrsS[SHTR_CLOSED].s = ISS_OFF; + } + closed = !closed; + } + ShtrInProgress = false; + ShtrsSP.s = IPS_OK; + IDSetSwitch(&ShtrsSP, NULL); +} + +void AstroSib::CoolerChk(){ +} + +void AstroSib::HeaterChk(){ +} + +bool AstroSib::ShutterSetState(int newstate){ + (void) newstate; + ShtrInProgress = true; + return true; +} + +bool AstroSib::CoolerSetState(int newstate){ + (void) newstate; + return true; +} + +bool AstroSib::ACoolerSetState(int newstate){ + (void) newstate; + return true; +} + +bool AstroSib::AHeaterSetState(int newstate){ + (void) newstate; + return true; +} + +bool AstroSib::AstroSib::FocuserSetVal(int focval){ + (void) focval; + return true; +} + +bool AstroSib::HeaterSetPower(int pwr){ + (void) pwr; + return true; +} + +/************************************************************************************** +** Client is asking us to establish connection to the device +***************************************************************************************/ +bool AstroSib::Connect(){ + /* code should be here */ + IDMessage(getDeviceName(), "Astrosib telescope connected successfully!"); + SetTimer(POLLMS); + return true; +} + +/************************************************************************************** +** Client is asking us to terminate connection to the device +***************************************************************************************/ +bool AstroSib::Disconnect(){ + /* code should be here */ + IDMessage(getDeviceName(), "Astrosib telescope disconnected successfully!"); + return true; +} + + +/************************************************************************************** +** INDI is asking us to check communication with the device via a handshake +***************************************************************************************/ +bool AstroSib::Handshake(){ + // When communicating with a real scope, we check here if commands are receieved + // and acknolowedged by the mount. + /* code should be here */ + return true; +} diff --git a/astrosib/astrosib.h b/astrosib/astrosib.h new file mode 100644 index 0000000..ddc2f51 --- /dev/null +++ b/astrosib/astrosib.h @@ -0,0 +1,103 @@ +/* + * geany_encoding=koi8-r + * astrosib.h + * + * Copyright 2017 Edward V. Emelianov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + */ + +/* + INDI Developers Manual + Tutorial #2 + + "Simple Telescope Driver" + + We develop a simple telescope simulator. + + Refer to README, which contains instruction on how to build this driver, and use it + with an INDI-compatible client. + +*/ + +/** \file simplescope.h + \brief Construct a basic INDI telescope device that simulates GOTO commands. + \author Jasem Mutlaq + + \example simplescope.h + A simple GOTO telescope that simulator slewing operation. +*/ +#pragma once + +#include "inditelescope.h" + +class AstroSib : public INDI::DefaultDevice{ + public: + AstroSib(); + ~AstroSib(); + bool ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n); + bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n); + void TimerHit(); + + protected: + bool Connect(); + bool Disconnect(); + + bool Handshake(); + const char *getDefaultName(); + bool initProperties(); + bool updateProperties(); + + private: + enum {_ON, _OFF}; + // last ambient & mirror temperature values + float ambtemp {0}, mirrtemp {0}, focusert{0}; + INumber TempN[3]; // mirror, ambient and focuser + INumberVectorProperty TempNP; + void TemperatureChk(); + // shutter leaves state + enum {SHTR_OPENED, SHTR_CLOSED}; + bool ShtrInProgress{false}; + ISwitch ShtrsS[2]; // roof shutters switch + ISwitchVectorProperty ShtrsSP; + bool ShutterSetState(int newstate); + void ShutterChk(); + // focuser current/relative/absolute position + bool FocInProgress{false}; + int foccur{0}, focabs{0}; + INumber FocuserN[3]; + INumberVectorProperty FocuserNP, FocuserNPcur; + bool FocuserSetVal(int focval); + void FocuserChk(); + // mirror cooler + ISwitch CoolerS[2]; + ISwitchVectorProperty CoolerSP; + // cooler auto + ISwitch ACoolerS[2]; + ISwitchVectorProperty ACoolerSP; + bool CoolerSetState(int newstate); + bool ACoolerSetState(int newstate); + void CoolerChk(); + // heater + ISwitch AHeaterS[2]; + ISwitchVectorProperty AHeaterSP; + INumber PHeaterN; + INumberVectorProperty PHeaterNP; + bool AHeaterSetState(int newstate); + bool HeaterSetPower(int pwr); + void HeaterChk(); +}; diff --git a/cmakelists_/CMakeLists_regular_01.txt b/cmakelists_/CMakeLists_regular_01.txt index 76c15ae..eb9d895 100644 --- a/cmakelists_/CMakeLists_regular_01.txt +++ b/cmakelists_/CMakeLists_regular_01.txt @@ -8,7 +8,7 @@ set(VERSION "${MAJOR_VERSION}.${MID_VERSION}.${MINOR_VERSION}") message("VER: ${VERSION}") # default flags -set(CFLAGS -O2 -Wextra -Wall -Werror -W -std=gnu99) +set(CFLAGS -O2 -std=gnu99) set(CMAKE_COLOR_MAKEFILE ON) @@ -24,6 +24,7 @@ aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} SOURCES) # cmake -DEBUG=1 -> debugging if(DEFINED EBUG) + set(CFLAGS ${CFLAGS} -Wextra -Wall -Werror -W) add_definitions(-DEBUG) endif() @@ -117,7 +118,7 @@ add_custom_command( COMMAND enconv ${PO_FILE} DEPENDS ${SOURCES} ) -# we need this to prewent ru.po from deleting by make clean +# we need this to prevent ru.po from deleting by make clean add_custom_target( RU_FILE COMMAND [ -f ${RU_FILE} ] && ${GETTEXT_MSGMERGE_EXECUTABLE} -Uis ${RU_FILE} ${PO_FILE} || cp ${PO_FILE} ${RU_FILE} diff --git a/cmakelists_/CMakeLists_regular_02.txt b/cmakelists_/CMakeLists_regular_02.txt new file mode 100644 index 0000000..46807c8 --- /dev/null +++ b/cmakelists_/CMakeLists_regular_02.txt @@ -0,0 +1,140 @@ +cmake_minimum_required(VERSION 2.8) +set(PROJ fitsread) +set(MINOR_VERSION "1") +set(MID_VERSION "0") +set(MAJOR_VERSION "0") +set(VERSION "${MAJOR_VERSION}.${MID_VERSION}.${MINOR_VERSION}") + +enable_language(C) + +message("VER: ${VERSION}") +# threads number definition +if(NOT DEFINED PROCESSOR_COUNT) + set(PROCESSOR_COUNT 2) # by default 2 cores + set(cpuinfo_file "/proc/cpuinfo") + if(EXISTS "${cpuinfo_file}") + file(STRINGS "${cpuinfo_file}" procs REGEX "^processor.: [0-9]+$") + list(LENGTH procs PROCESSOR_COUNT) + endif() +endif() +add_definitions(-DTHREAD_NUMBER=${PROCESSOR_COUNT}) +message("In multithreaded operations will use ${PROCESSOR_COUNT} threads") + +# default flags +set(CFLAGS -O2 -Wextra -Wall -Werror -W -Wno-trampolines -std=gnu99) + +set(CMAKE_COLOR_MAKEFILE ON) + +# here is one of two variants: all .c in directory or .c files in list +aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} SOURCES) + +# cmake -DDEBUG=1 -> debugging +if(DEFINED DEBUG) + add_definitions(-DEBUG) +endif() + +# directory should contain dir locale/ru for gettext translations +set(LCPATH ${CMAKE_SOURCE_DIR}/locale/ru) + +if(NOT DEFINED LOCALEDIR) + if(DEFINED DEBUG) + set(LOCALEDIR ${CMAKE_CURRENT_SOURCE_DIR}/locale) + else() + set(LOCALEDIR ${CMAKE_INSTALL_PREFIX}/share/locale) + endif() +endif() + +###### pkgconfig ###### +# pkg-config modules (for pkg-check-modules) +set(MODULES cfitsio fftw3) + +# find packages: +find_package(PkgConfig REQUIRED) + +pkg_check_modules(${PROJ} REQUIRED ${MODULES}) + +# external modules like OpenMP: +include(FindOpenMP) +if(OPENMP_FOUND) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}") + add_definitions(-DOMP_FOUND) +endif() + +###### additional flags ###### +list(APPEND ${PROJ}_LIBRARIES "-lfftw3_threads") + +project(${PROJ}) +# change wrong behaviour with install prefix +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT AND CMAKE_INSTALL_PREFIX MATCHES "/usr/local") + message("Change default install path to /usr") + set(CMAKE_INSTALL_PREFIX "/usr") +endif() +message("Install dir prefix: ${CMAKE_INSTALL_PREFIX}") + +# gettext files +set(PO_FILE ${LCPATH}/messages.po) +set(MO_FILE ${LCPATH}/LC_MESSAGES/${PROJ}.mo) +set(RU_FILE ${LCPATH}/ru.po) +set(CTAGS_FILE ${CMAKE_SOURCE_DIR}/${PROJ}.c.tags) + +# exe file +add_executable(${PROJ} ${SOURCES}) +# -I +include_directories(${${PROJ}_INCLUDE_DIRS}) +# -L +link_directories(${${PROJ}_LIBRARY_DIRS}) +# -D +add_definitions(${CFLAGS} -DLOCALEDIR=\"${LOCALEDIR}\" + -DPACKAGE_VERSION=\"${VERSION}\" -DGETTEXT_PACKAGE=\"${PROJ}\" + -DMINOR_VERSION=\"${MINOR_VERSION}\" -DMID_VERSION=\"${MID_VERSION}\" + -DMAJOR_VERSION=\"${MAJOR_VESION}\") + +# -l +target_link_libraries(${PROJ} ${${PROJ}_LIBRARIES} -lm) + +# Installation of the program +INSTALL(FILES ${MO_FILE} DESTINATION "share/locale/ru/LC_MESSAGES") + #PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ) +INSTALL(TARGETS ${PROJ} DESTINATION "bin") + +###### gettext & ctags ###### +if(DEFINED EBUG) + message("Generate locale & tags files") + find_package(Gettext REQUIRED) + find_program(GETTEXT_XGETTEXT_EXECUTABLE xgettext) + if(NOT GETTEXT_XGETTEXT_EXECUTABLE OR NOT GETTEXT_MSGFMT_EXECUTABLE) + message(FATAL_ERROR "xgettext not found") + endif() + file(MAKE_DIRECTORY ${LCPATH}) + file(MAKE_DIRECTORY ${LCPATH}/LC_MESSAGES) + + add_custom_command( + OUTPUT ${PO_FILE} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + COMMAND ${GETTEXT_XGETTEXT_EXECUTABLE} --from-code=utf-8 ${SOURCES} -c -k_ -kN_ -o ${PO_FILE} + COMMAND sed -i 's/charset=.*\\\\n/charset=koi8-r\\\\n/' ${PO_FILE} + COMMAND enconv ${PO_FILE} + DEPENDS ${SOURCES} + ) + # we need this to prevent ru.po & .mo from deleting by make clean + add_custom_target( + RU_FILE + COMMAND [ -f ${RU_FILE} ] && ${GETTEXT_MSGMERGE_EXECUTABLE} -Uis ${RU_FILE} ${PO_FILE} || cp ${PO_FILE} ${RU_FILE} + DEPENDS ${PO_FILE} ${SOURCES} + ) + add_custom_target( + MO_FILE + COMMAND make RU_FILE && ${GETTEXT_MSGFMT_EXECUTABLE} ${RU_FILE} -o ${MO_FILE} + DEPENDS ${SOURCES} + ) + add_dependencies(${PROJ} MO_FILE) + + set(CFLAGS_A CFLAGS=${CFLAGS}) + add_custom_target(ctags + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + COMMAND CFLAGS=-DEBUG geany -g ${CTAGS_FILE} ${SOURCES} + DEPENDS ${SOURCES} + ) + add_dependencies(${PROJ} ctags) +endif() diff --git a/cmakelists_/get_proc_count b/cmakelists_/get_proc_count new file mode 100644 index 0000000..1384b42 --- /dev/null +++ b/cmakelists_/get_proc_count @@ -0,0 +1 @@ +getconf _NPROCESSORS_ONLN diff --git a/get_avail_mem.c b/get_avail_mem.c new file mode 100644 index 0000000..606df59 --- /dev/null +++ b/get_avail_mem.c @@ -0,0 +1,14 @@ +#include +#include + +static unsigned long long get_available_mem(){ + return sysconf(_SC_AVPHYS_PAGES) * (unsigned long long) sysconf(_SC_PAGE_SIZE); +} + +int main(){ + unsigned long long m = get_available_mem(); + printf("MEM: %llu == %lluGB\n", m, m/1024/1024/1024); + return 0; +} + +// Never allocate memory by big pieces with malloc! Only mmap with MAP_POPULATE!!!!!!!!!11111111111 diff --git a/image_view_module/README b/image_view_module/README new file mode 100644 index 0000000..0196142 --- /dev/null +++ b/image_view_module/README @@ -0,0 +1,2 @@ +GLUT -> GLFW +For GUI: look for analog of GLUI diff --git a/usefull_macros.c b/usefull_macros.c index 3f2f663..9dad087 100644 --- a/usefull_macros.c +++ b/usefull_macros.c @@ -202,7 +202,7 @@ mmapbuf *My_mmap(char *filename){ void My_munmap(mmapbuf *b){ if(munmap(b->data, b->len)){ /// " munmap" - ERR(_("Can't munmap")); + WARN(_("Can't munmap")); } FREE(b); } @@ -291,8 +291,6 @@ void tty_init(char *comdev){ DBG("\nOpen port...\n"); if ((comfd = open(comdev,O_RDWR|O_NOCTTY|O_NONBLOCK)) < 0){ WARN("Can't use port %s\n",comdev); - ioctl(comfd, TCSANOW, &oldtty); // return TTY to previous state - close(comfd); signals(0); // quit? } DBG(" OK\nGet current settings... "); diff --git a/usefull_macros.h b/usefull_macros.h index 5f80b9f..bf8edac 100644 --- a/usefull_macros.h +++ b/usefull_macros.h @@ -56,6 +56,9 @@ // unused arguments with -Wall -Werror #define _U_ __attribute__((__unused__)) +#define ASTRING(MACRO) #MACRO +#define STRING(MACRO) ASTRING(MACRO) + /* * Coloured messages output */