diff options
Diffstat (limited to 'kstars/kstars/indi/lx200_16.cpp')
-rw-r--r-- | kstars/kstars/indi/lx200_16.cpp | 396 |
1 files changed, 396 insertions, 0 deletions
diff --git a/kstars/kstars/indi/lx200_16.cpp b/kstars/kstars/indi/lx200_16.cpp new file mode 100644 index 00000000..fe37df18 --- /dev/null +++ b/kstars/kstars/indi/lx200_16.cpp @@ -0,0 +1,396 @@ +/* + LX200 16" + Copyright (C) 2003 Jasem Mutlaq (mutlaqja@ikarustech.com) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <math.h> + +#include "lx200_16.h" +#include "lx200driver.h" + +#define LX16GROUP "GPS/16 inch Features" + +extern LX200Generic *telescope; +extern ITextVectorProperty Time; +extern int MaxReticleFlashRate; + + +//void turnFanOn(); + //void turnFanOff(); + + //void seekHomeAndSave(); + // void seekHomeAndSet(); + + /** Turns the field derotator On or Off. This command applies <b>only</b> to 16" LX200. + @param turnOn if turnOn is true, the derotator is turned on, otherwise, it is turned off. */ + // void fieldDeRotator(bool turnOn); + + + /** Sets object Altitude. \n + @returns true if object's altitude is successfully set. */ + //bool setObjAlt(int degrees, int minutes); + + /** Sets object Azimuth. \n + @returns true if object's azimuth is successfully set. */ +// bool setObjAz(int degrees, int minutes); + + +static ISwitch FanStatusS[] = { {"On", "", ISS_OFF, 0, 0}, {"Off", "", ISS_OFF, 0, 0}}; +static ISwitch HomeSearchS[] = { {"Save home", "", ISS_OFF, 0, 0} , {"Set home", "", ISS_OFF, 0, 0}}; +static ISwitch FieldDeRotatorS[] = { {"On", "", ISS_OFF, 0, 0}, {"Off", "", ISS_OFF,0 ,0}}; +//static ISwitch SlewAltAzS[] = { {"Slew To Alt/Az", ISS_ON}}; + +#define MAXINDINAME 32 +#define MAXINDILABEL 32 +#define MAXINDIDEVICE 32 +#define MAXINDIGROUP 32 +#define MAXINDIFORMAT 32 + +static ISwitchVectorProperty FanStatusSw = { mydev, "Fan", "", LX16GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, FanStatusS, NARRAY(FanStatusS), "", 0}; + +static ISwitchVectorProperty HomeSearchSw = { mydev, "Park", "", LX16GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, HomeSearchS, NARRAY(HomeSearchS), "", 0}; + +static ISwitchVectorProperty FieldDeRotatorSw = { mydev, "Field De-rotator", "", LX16GROUP, IP_RW, ISR_1OFMANY, 0, IPS_IDLE, FieldDeRotatorS, NARRAY(FieldDeRotatorS), "", 0}; + +//static ISwitches SlewAltAzSw = { mydev, "AltAzSet", "On Alt/Az Set", SlewAltAzS, NARRAY(SlewAltAzS), ILS_IDLE, 0, LX16Group}; + +/* horizontal position */ +static INumber hor[] = { + {"ALT", "Alt D:M:S", "%10.6m", -90., 90., 0., 0., 0, 0, 0}, + {"AZ", "Az D:M:S", "%10.6m", 0., 360., 0., 0., 0, 0, 0}}; + +static INumberVectorProperty horNum = { + mydev, "HORIZONTAL_COORD", "Horizontal Coords", LX16GROUP, IP_RW, 0, IPS_IDLE, + hor, NARRAY(hor), "", 0}; + +void changeLX200_16DeviceName(const char * newName) +{ + strcpy(horNum.device, newName); + strcpy(FanStatusSw.device, newName); + strcpy(HomeSearchSw.device, newName); + strcpy(FieldDeRotatorSw.device,newName); +} + +LX200_16::LX200_16() : LX200Autostar() +{ + +} + +void LX200_16::ISGetProperties (const char *dev) +{ + +if (dev && strcmp (thisDevice, dev)) + return; + + // process parent first + LX200Autostar::ISGetProperties(dev); + + IDDefNumber (&horNum, NULL); + + IDDefSwitch (&FanStatusSw, NULL); + IDDefSwitch (&HomeSearchSw, NULL); + IDDefSwitch (&FieldDeRotatorSw, NULL); + +} + +void LX200_16::ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n) +{ + + // ignore if not ours // + if (strcmp (dev, thisDevice)) + return; + + LX200Autostar::ISNewText (dev, name, texts, names, n); + +} + +void LX200_16::ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n) +{ + double newAlt=0, newAz=0; + char altStr[64], azStr[64]; + int err; + + // ignore if not ours // + if (strcmp (dev, thisDevice)) + return; + + if ( !strcmp (name, horNum.name) ) + { + int i=0, nset=0; + + if (checkPower(&horNum)) + return; + + for (nset = i = 0; i < n; i++) + { + INumber *horp = IUFindNumber (&horNum, names[i]); + if (horp == &hor[0]) + { + newAlt = values[i]; + nset += newAlt >= -90. && newAlt <= 90.0; + } else if (horp == &hor[1]) + { + newAz = values[i]; + nset += newAz >= 0. && newAz <= 360.0; + } + } + + if (nset == 2) + { + if ( (err = setObjAz(newAz)) < 0 || (err = setObjAlt(newAlt)) < 0) + { + handleError(&horNum, err, "Setting Alt/Az"); + return; + } + horNum.s = IPS_OK; + //horNum.n[0].value = values[0]; + //horNum.n[1].value = values[1]; + targetAz = newAz; + targetAlt = newAlt; + + fs_sexa(azStr, targetAz, 2, 3600); + fs_sexa(altStr, targetAlt, 2, 3600); + + IDSetNumber (&horNum, "Attempting to slew to Alt %s - Az %s", altStr, azStr); + handleAltAzSlew(); + } + else + { + horNum.s = IPS_IDLE; + IDSetNumber(&horNum, "Altitude or Azimuth missing or invalid"); + } + + return; + } + + LX200Autostar::ISNewNumber (dev, name, values, names, n); +} + + + + +void LX200_16::ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n) +{ + int index; + int err; + + if (strcmp (dev, thisDevice)) + return; + + if (!strcmp(name, FanStatusSw.name)) + { + if (checkPower(&FanStatusSw)) + return; + + IUResetSwitches(&FanStatusSw); + IUUpdateSwitches(&FanStatusSw, states, names, n); + index = getOnSwitch(&FanStatusSw); + + if (index == 0) + { + if ( (err = turnFanOn()) < 0) + { + handleError(&FanStatusSw, err, "Changing fan status"); + return; + } + } + else + { + if ( (err = turnFanOff()) < 0) + { + handleError(&FanStatusSw, err, "Changing fan status"); + return; + } + } + + FanStatusSw.s = IPS_OK; + IDSetSwitch (&FanStatusSw, index == 0 ? "Fan is ON" : "Fan is OFF"); + return; + } + + if (!strcmp(name, HomeSearchSw.name)) + { + if (checkPower(&HomeSearchSw)) + return; + + IUResetSwitches(&HomeSearchSw); + IUUpdateSwitches(&HomeSearchSw, states, names, n); + index = getOnSwitch(&HomeSearchSw); + + index == 0 ? seekHomeAndSave() : seekHomeAndSet(); + HomeSearchSw.s = IPS_BUSY; + IDSetSwitch (&HomeSearchSw, index == 0 ? "Seek Home and Save" : "Seek Home and Set"); + return; + } + + if (!strcmp(name, FieldDeRotatorSw.name)) + { + if (checkPower(&FieldDeRotatorSw)) + return; + + IUResetSwitches(&FieldDeRotatorSw); + IUUpdateSwitches(&FieldDeRotatorSw, states, names, n); + index = getOnSwitch(&FieldDeRotatorSw); + + index == 0 ? seekHomeAndSave() : seekHomeAndSet(); + FieldDeRotatorSw.s = IPS_OK; + IDSetSwitch (&FieldDeRotatorSw, index == 0 ? "Field deRotator is ON" : "Field deRotator is OFF"); + return; + } + + LX200Autostar::ISNewSwitch (dev, name, states, names, n); + +} + +void LX200_16::handleAltAzSlew() +{ + int i=0; + char altStr[64], azStr[64]; + + if (horNum.s == IPS_BUSY) + { + abortSlew(); + + // sleep for 100 mseconds + usleep(100000); + } + + if ((i = slewToAltAz())) + { + horNum.s = IPS_IDLE; + IDSetNumber(&horNum, "Slew not possible"); + return; + } + + horNum.s = IPS_BUSY; + fs_sexa(azStr, targetAz, 2, 3600); + fs_sexa(altStr, targetAlt, 2, 3600); + + IDSetNumber(&horNum, "Slewing to Alt %s - Az %s", altStr, azStr); + return; +} + + void LX200_16::ISPoll () + { + int searchResult=0; + double dx, dy; + int err; + + LX200Autostar::ISPoll(); + + switch (HomeSearchSw.s) + { + case IPS_IDLE: + break; + + case IPS_BUSY: + + if ( (err = getHomeSearchStatus(&searchResult)) < 0) + { + handleError(&HomeSearchSw, err, "Home search"); + return; + } + + if (searchResult == 0) + { + HomeSearchSw.s = IPS_IDLE; + IDSetSwitch(&HomeSearchSw, "Home search failed."); + } + else if (searchResult == 1) + { + HomeSearchSw.s = IPS_OK; + IDSetSwitch(&HomeSearchSw, "Home search successful."); + } + else if (searchResult == 2) + IDSetSwitch(&HomeSearchSw, "Home search in progress..."); + else + { + HomeSearchSw.s = IPS_IDLE; + IDSetSwitch(&HomeSearchSw, "Home search error."); + } + break; + + case IPS_OK: + break; + case IPS_ALERT: + break; + } + + switch (horNum.s) + { + case IPS_IDLE: + break; + + case IPS_BUSY: + + if ( (err = getLX200Az(¤tAz)) < 0 || (err = getLX200Alt(¤tAlt)) < 0) + { + IDSetNumber(&horNum, NULL); + handleError(&horNum, err, "Get Alt/Az"); + return; + } + + dx = targetAz - currentAz; + dy = targetAlt - currentAlt; + + horNum.np[0].value = currentAlt; + horNum.np[1].value = currentAz; + + IDLog("targetAz is %g, currentAz is %g\n", targetAz, currentAz); + IDLog("targetAlt is %g, currentAlt is %g\n**********************\n", targetAlt, currentAlt); + + + // accuracy threshhold (3'), can be changed as desired. + if ( fabs(dx) <= 0.05 && fabs(dy) <= 0.05) + { + + horNum.s = IPS_OK; + currentAz = targetAz; + currentAlt = targetAlt; + IDSetNumber (&horNum, "Slew is complete"); + } else + IDSetNumber (&horNum, NULL); + break; + + case IPS_OK: + break; + + case IPS_ALERT: + break; + } + + } + + void LX200_16::getBasicData() + { + + getLX200Az(&targetAz); + getLX200Alt(&targetAlt); + + horNum.np[0].value = targetAlt; + horNum.np[1].value = targetAz; + + IDSetNumber (&horNum, NULL); + + LX200Autostar::getBasicData(); + + } |