25 #include <libnova/julian_day.h>
31 static pthread_cond_t cv = PTHREAD_COND_INITIALIZER;
32 static pthread_mutex_t condMutex = PTHREAD_MUTEX_INITIALIZER;
35 static std::unique_ptr<GuideSim> ccd(
new GuideSim());
43 terminateThread =
false;
48 bool GuideSim::SetupParms()
51 SetCCDParams(SimulatorSettingsN[0].value, SimulatorSettingsN[1].value, 16, SimulatorSettingsN[2].value,
52 SimulatorSettingsN[3].value);
61 maxnoise = SimulatorSettingsN[8].value;
62 skyglow = SimulatorSettingsN[9].value;
63 maxval = SimulatorSettingsN[4].value;
64 bias = SimulatorSettingsN[5].value;
65 limitingmag = SimulatorSettingsN[7].value;
66 saturationmag = SimulatorSettingsN[6].value;
67 OAGoffset = SimulatorSettingsN[10].value;
68 polarError = SimulatorSettingsN[11].value;
69 polarDrift = SimulatorSettingsN[12].value;
70 rotationCW = SimulatorSettingsN[13].value;
72 king_gamma = SimulatorSettingsN[14].value * 0.0174532925;
73 king_theta = SimulatorSettingsN[15].value * 0.0174532925;
74 TimeFactor = SimulatorSettingsN[16].value;
89 terminateThread =
false;
97 pthread_mutex_lock(&condMutex);
99 terminateThread =
true;
100 pthread_cond_signal(&cv);
101 pthread_mutex_unlock(&condMutex);
108 return "Guide Simulator";
120 IUFillNumber(&SimulatorSettingsN[0],
"SIM_XRES",
"CCD X resolution",
"%4.0f", 0, 8192, 0, 1280);
121 IUFillNumber(&SimulatorSettingsN[1],
"SIM_YRES",
"CCD Y resolution",
"%4.0f", 0, 8192, 0, 1024);
122 IUFillNumber(&SimulatorSettingsN[2],
"SIM_XSIZE",
"CCD X Pixel Size",
"%4.2f", 0, 60, 0, 2.4);
123 IUFillNumber(&SimulatorSettingsN[3],
"SIM_YSIZE",
"CCD Y Pixel Size",
"%4.2f", 0, 60, 0, 2.4);
124 IUFillNumber(&SimulatorSettingsN[4],
"SIM_MAXVAL",
"CCD Maximum ADU",
"%4.0f", 0, 65000, 0, 65000);
125 IUFillNumber(&SimulatorSettingsN[5],
"SIM_BIAS",
"CCD Bias",
"%4.0f", 0, 6000, 0, 10);
126 IUFillNumber(&SimulatorSettingsN[6],
"SIM_SATURATION",
"Saturation Mag",
"%4.1f", 0, 20, 0, 1.0);
127 IUFillNumber(&SimulatorSettingsN[7],
"SIM_LIMITINGMAG",
"Limiting Mag",
"%4.1f", 0, 20, 0, 17.0);
128 IUFillNumber(&SimulatorSettingsN[8],
"SIM_NOISE",
"CCD Noise",
"%4.0f", 0, 6000, 0, 10);
129 IUFillNumber(&SimulatorSettingsN[9],
"SIM_SKYGLOW",
"Sky Glow (magnitudes)",
"%4.1f", 0, 6000, 0, 19.5);
130 IUFillNumber(&SimulatorSettingsN[10],
"SIM_OAGOFFSET",
"Oag Offset (arcminutes)",
"%4.1f", 0, 6000, 0, 0);
131 IUFillNumber(&SimulatorSettingsN[11],
"SIM_POLAR",
"PAE (arcminutes)",
"%4.1f", -600, 600, 0,
133 IUFillNumber(&SimulatorSettingsN[12],
"SIM_POLARDRIFT",
"PAE Drift (minutes)",
"%4.1f", 0, 6000, 0, 0);
134 IUFillNumber(&SimulatorSettingsN[13],
"SIM_ROTATION",
"Rotation CW (degrees)",
"%4.1f", -360, 360, 0, 0);
135 IUFillNumber(&SimulatorSettingsN[14],
"SIM_KING_GAMMA",
"(CP,TCP), deg",
"%4.1f", 0, 10, 0, 0);
136 IUFillNumber(&SimulatorSettingsN[15],
"SIM_KING_THETA",
"hour hangle, deg",
"%4.1f", 0, 360, 0, 0);
137 IUFillNumber(&SimulatorSettingsN[16],
"SIM_TIME_FACTOR",
"Time Factor (x)",
"%.2f", 0.01, 100, 0, 1);
154 IUFillNumber(&GainN[0],
"GAIN",
"Gain",
"%.f", 0, 100, 10, 50);
157 IUFillNumber(&EqPEN[0],
"RA_PE",
"RA (hh:mm:ss)",
"%010.6m", 0, 24, 0, 0);
158 IUFillNumber(&EqPEN[1],
"DEC_PE",
"DEC (dd:mm:ss)",
"%010.6m", -90, 90, 0, 0);
167 #ifdef USE_EQUATORIAL_PE
182 #ifdef HAVE_WEBSOCKET
199 void GuideSim::setRGB(
bool onOff)
256 TemperatureRequest = temperature;
275 AbortPrimaryFrame =
false;
276 ExposureRequest = duration;
279 gettimeofday(&ExpStart,
nullptr);
283 ExposureRequest = duration * TimeFactor;
294 AbortPrimaryFrame =
true;
299 float GuideSim::CalcTimeLeft(timeval start,
float req)
307 gettimeofday(&now,
nullptr);
310 (double)(now.tv_sec * 1000.0 + now.tv_usec / 1000) - (double)(start.tv_sec * 1000.0 + start.tv_usec / 1000);
311 timesince = timesince / 1000;
312 timeleft = req - timesince;
326 if (AbortPrimaryFrame)
329 AbortPrimaryFrame =
false;
334 timeleft = CalcTimeLeft(ExpStart, ExposureRequest);
344 if (timeleft <= 0.001)
353 nextTimer = timeleft * 1000;
386 double exposure_time;
388 uint16_t * ptr =
reinterpret_cast<uint16_t *
>(targetChip->
getFrameBuffer());
391 exposure_time = (ExposureRequest < 1) ? (ExposureRequest * 100) : ExposureRequest * 2;
393 exposure_time = ExposureRequest;
395 exposure_time *= (1 + sqrt(GainN[0].value));
407 int nwidth = 0, nheight = 0;
414 timesince = difftime(now, RunStart);
416 PESpot = timesince / PEPeriod;
418 PESpot = PESpot * 2.0 * 3.14159;
420 PEOffset = PEMax * std::sin(PESpot);
421 PEOffset = PEOffset / 3600;
432 double pa, pb, pc, pd, pe, pf;
439 double ccdW = targetChip->
getXRes();
442 pprx = targetFocalLength / targetChip->
getPixelSizeX() * 1000;
443 ppry = targetFocalLength / targetChip->
getPixelSizeY() * 1000;
449 Scalex = (targetChip->
getPixelSizeX() / targetFocalLength) * 206.3;
450 Scaley = (targetChip->
getPixelSizeY() / targetFocalLength) * 206.3;
455 "pprx: %g pixels per radian ppry: %g pixels per radian ScaleX: %g arcsecs/pixel ScaleY: %g arcsecs/pixel",
456 pprx, ppry, Scalex, Scaley);
459 double theta = rotationCW + 270;
464 else if (theta < -360)
468 pa = pprx * cos(theta * M_PI / 180.0);
469 pb = ppry * sin(theta * M_PI / 180.0);
471 pd = pprx * -sin(theta * M_PI / 180.0);
472 pe = ppry * cos(theta * M_PI / 180.0);
474 nwidth = targetChip->
getXRes();
477 nheight = targetChip->
getYRes();
480 ImageScalex = Scalex;
481 ImageScaley = Scaley;
483 #ifdef USE_EQUATORIAL_PE
490 if (std::isnan(currentRA))
499 currentRA = J2000Pos.rightascension;
500 currentDE = J2000Pos.declination;
501 currentDE += guideNSOffset;
502 currentRA += guideWEOffset;
503 #ifdef USE_EQUATORIAL_PE
508 rad = currentRA * 15.0 + PEOffset;
509 rar = rad * 0.0174532925;
512 cameradec = currentDE + OAGoffset / 60;
513 decr = cameradec * 0.0174532925;
515 decDrift = (polarDrift * polarError * cos(decr)) / 3.81;
518 decr += decDrift / 3600.0 * 0.0174532925;
523 radius = sqrt((Scalex * Scalex * targetChip->
getXRes() / 2.0 * targetChip->
getXRes() / 2.0) +
524 (Scaley * Scaley * targetChip->
getYRes() / 2.0 * targetChip->
getYRes() / 2.0));
526 radius = radius / 60;
535 k = (saturationmag - limitingmag) / ((-2.5 * log(maxval)) - (-2.5 * log(1.0 / 2.0)));
536 z = saturationmag - k * (-2.5 * log(maxval));
545 float lookuplimit = limitingmag;
562 char JnRAStr[64] = {0};
564 char JnDecStr[64] = {0};
575 double J2dec = J2000Pos.declination;
578 double J2decr = J2dec * 0.0174532925;
584 char sidStr[64] = {0};
586 char JnHAStr[64] = {0};
587 fs_sexa(JnHAStr, JnHAr / 15. / 0.0174532925, 2, 360000);
598 double J2_mnt_d_rar = king_gamma * sin(J2decr) * sin(JnHAr - king_theta) / cos(J2decr);
599 double J2_mnt_rar = rar - J2_mnt_d_rar
606 double J2_mnt_d_decr = king_gamma * cos(JnHAr - king_theta);
607 double J2_mnt_decr = decr + J2_mnt_d_decr
610 if (J2_mnt_decr > M_PI / 2.)
612 J2_mnt_decr = M_PI / 2. - (J2_mnt_decr - M_PI / 2.);
615 J2_mnt_rar = fmod(J2_mnt_rar, 2. * M_PI) ;
620 char J2RAStr[64] = {0};
621 fs_sexa(J2RAStr, J2_mnt_rar / 15. / 0.0174532925, 2, 360000);
622 char J2DecStr[64] = {0};
623 fs_sexa(J2DecStr, J2_mnt_decr / 0.0174532925, 2, 360000);
629 rad = rar / 0.0174532925;
631 cameradec = decr / 0.0174532925;
649 sprintf(gsccmd,
"gsc -c %8.6f %+8.6f -r %4.1f -m 0 %4.2f -n 3000",
655 if (!
Streamer->isStreaming() || (king_gamma > 0.))
658 pp = popen(gsccmd,
"r");
665 while (fgets(line, 256, pp) !=
nullptr)
681 int rc = sscanf(line,
"%10s %f %f %f %f %f %d %d %4s %2s %f %d",
id, &
ra, &
dec, &pose, &mag, &mage,
682 &band, &c, plate, ob, &dist, &dir);
697 srar =
ra * 0.0174532925;
698 sdecr =
dec * 0.0174532925;
704 sx = cos(sdecr) * sin(srar - rar) /
705 (cos(decr) * cos(sdecr) * cos(srar - rar) + sin(decr) * sin(sdecr));
706 sy = (sin(decr) * cos(sdecr) * cos(srar - rar) - cos(decr) * sin(sdecr)) /
707 (cos(decr) * cos(sdecr) * cos(srar - rar) + sin(decr) * sin(sdecr));
710 ccdx = pa * sx + pb * sy + pc;
711 ccdy = pd * sx + pe * sy + pf;
716 rc =
DrawImageStar(targetChip, mag, ccdx, ccdy, exposure_time);
729 LOG_ERROR(
"Error looking up stars, is gsc installed with appropriate environment variables set ??");
733 LOG_ERROR(
"Got no stars, is gsc installed with appropriate environment variables set ??");
746 float glow = skyglow;
758 skyflux = pow(10, ((glow - z) * k / -2.5));
761 skyflux = skyflux * exposure_time;
764 uint16_t * pt =
reinterpret_cast<uint16_t *
>(targetChip->
getFrameBuffer());
766 nheight = targetChip->
getSubH();
767 nwidth = targetChip->
getSubW();
769 for (
int y = 0; y < nheight; y++)
771 for (
int x = 0; x < nwidth; x++)
779 sy = nheight / 2 - y;
782 vig = vig * ImageScalex;
784 dc = std::sqrt(sx * sx * ImageScalex * ImageScalex + sy * sy * ImageScaley * ImageScaley);
789 fa = exp(-2.0 * 0.7 * (dc * dc) / vig / vig);
815 int subX = targetChip->
getSubX();
816 int subY = targetChip->
getSubY();
817 int subW = targetChip->
getSubW() + subX;
818 int subH = targetChip->
getSubH() + subY;
822 for (
int x = subX; x < subW; x++)
824 for (
int y = subY; y < subH; y++)
829 noise = noise % maxnoise;
842 uint16_t val = testvalue;
846 for (
int x = 0; x < nbuf; x++)
865 int subX = targetChip->
getSubX();
866 int subY = targetChip->
getSubY();
867 int subW = targetChip->
getSubW() + subX;
868 int subH = targetChip->
getSubH() + subY;
870 if ((x < subX) || (x > subW || (y < subY) || (y > subH)))
877 flux = pow(10, ((mag - z) * k / -2.5));
881 flux = flux * exposure_time;
885 qx = seeing / ImageScalex;
889 qx = seeing / ImageScaley;
891 boxsizey =
static_cast<int>(qx);
896 for (sy = -boxsizey; sy <= boxsizey; sy++)
898 for (sx = -boxsizey; sx <= boxsizey; sx++)
905 dc = std::sqrt(sx * sx * ImageScalex * ImageScalex + sy * sy * ImageScaley * ImageScaley);
909 float fa = exp(-2.0 * 0.7 * (dc * dc) / seeing / seeing);
916 rc =
AddToPixel(targetChip, x + sx, y + sy, fp);
926 int nwidth = targetChip->
getSubW();
927 int nheight = targetChip->
getSubH();
967 guideNSOffset += v / 1000.0 * GuideRate / 3600;
973 guideNSOffset += v / -1000.0 * GuideRate / 3600;
979 float c = v / 1000.0 * GuideRate;
980 c = c / 3600.0 / 15.0;
981 c = c / (cos(currentDE * 0.0174532925));
990 float c = v / -1000.0 * GuideRate;
991 c = c / 3600.0 / 15.0;
992 c = c / (cos(currentDE * 0.0174532925));
1004 if (!strcmp(name, GainNP.
name))
1012 if (strcmp(name,
"SIMULATOR_SETTINGS") == 0)
1015 SimulatorSettingsNP.
s =
IPS_OK;
1021 maxnoise = SimulatorSettingsN[8].value;
1022 skyglow = SimulatorSettingsN[9].value;
1023 maxval = SimulatorSettingsN[4].value;
1024 bias = SimulatorSettingsN[5].value;
1025 limitingmag = SimulatorSettingsN[7].value;
1026 saturationmag = SimulatorSettingsN[6].value;
1027 OAGoffset = SimulatorSettingsN[10].value;
1028 polarError = SimulatorSettingsN[11].value;
1029 polarDrift = SimulatorSettingsN[12].value;
1030 rotationCW = SimulatorSettingsN[13].value;
1032 king_gamma = SimulatorSettingsN[14].value * 0.0174532925;
1033 king_theta = SimulatorSettingsN[15].value * 0.0174532925;
1034 TimeFactor = SimulatorSettingsN[16].value;
1041 if (!strcmp(name, EqPENP.
name))
1048 currentRA = J2000Pos.rightascension;
1049 currentDE = J2000Pos.declination;
1064 if (!strcmp(name, SimulateRgbSP.
name))
1071 LOG_INFO(
"Cannot determine whether RGB simulation should be switched on or off.");
1076 simulateRGB = index == 0;
1077 setRGB(simulateRGB);
1087 if (strcmp(name, CoolerSP.
name) == 0)
1091 if (CoolerS[0].s ==
ISS_ON)
1096 TemperatureRequest = 20;
1107 ToggleTimeoutSP.
update(states, names, n);
1109 ToggleTimeoutSP.
apply();
1120 #ifdef USE_EQUATORIAL_PE
1130 #ifdef USE_EQUATORIAL_PE
1132 if (!strcmp(propName, EqPENP.
name))
1135 int rc_ra = -1, rc_de = -1;
1136 double newra = 0, newdec = 0;
1142 if (!strcmp(elemName,
"RA_PE"))
1144 else if (!strcmp(elemName,
"DEC_PE"))
1148 if (rc_ra == 0 && rc_de == 0 && ((newra != raPE) || (newdec != decPE)))
1151 epochPos.ra = newra * 15.0;
1152 epochPos.dec = newdec;
1153 ln_get_equ_prec2(&epochPos, ln_get_julian_from_sys(), JD2000, &J2000Pos);
1154 raPE = J2000Pos.ra / 15.0;
1155 decPE = J2000Pos.dec;
1159 EqPEN[
AXIS_DE].value = newdec;
1162 LOGF_DEBUG(
"raPE %g decPE %g Snooped raPE %g decPE %g", raPE, decPE, newra, newdec);
1192 ExposureRequest = 1.0 /
Streamer->getTargetExposure();
1193 pthread_mutex_lock(&condMutex);
1194 streamPredicate = 1;
1195 pthread_mutex_unlock(&condMutex);
1196 pthread_cond_signal(&cv);
1203 pthread_mutex_lock(&condMutex);
1204 streamPredicate = 0;
1205 pthread_mutex_unlock(&condMutex);
1206 pthread_cond_signal(&cv);
1216 bin_width = bin_width - (bin_width % 2);
1217 bin_height = bin_height - (bin_height % 2);
1219 Streamer->setSize(bin_width, bin_height);
1226 if (hor == 3 || ver == 3)
1228 LOG_ERROR(
"3x3 binning is not supported.");
1235 bin_width = bin_width - (bin_width % 2);
1236 bin_height = bin_height - (bin_height % 2);
1238 Streamer->setSize(bin_width, bin_height);
1250 auto start = std::chrono::high_resolution_clock::now();
1251 auto finish = std::chrono::high_resolution_clock::now();
1255 pthread_mutex_lock(&condMutex);
1257 while (streamPredicate == 0)
1259 pthread_cond_wait(&cv, &condMutex);
1260 ExposureRequest =
Streamer->getTargetExposure();
1263 if (terminateThread)
1267 pthread_mutex_unlock(&condMutex);
1275 finish = std::chrono::high_resolution_clock::now();
1276 std::chrono::duration<double> elapsed = finish - start;
1278 if (elapsed.count() < ExposureRequest)
1279 usleep(fabs(ExposureRequest - elapsed.count()) * 1e6);
1284 start = std::chrono::high_resolution_clock::now();
1287 pthread_mutex_unlock(&condMutex);
1295 fitsKeywords.push_back({
"GAIN", GainN[0].value, 3,
"Gain"});
The GuideSim class provides an advanced simulator for a CCD that includes a dedicated on-board guide ...
virtual IPState GuideNorth(uint32_t) override
Guide northward for ms milliseconds.
virtual bool UpdateCCDFrame(int x, int y, int w, int h) override
CCD calls this function when CCD Frame dimension needs to be updated in the hardware....
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Save configuration items in XML file.
virtual IPState GuideEast(uint32_t) override
Guide easward for ms milliseconds.
void TimerHit() override
Callback function to be called once SetTimer duration elapses.
virtual bool UpdateCCDBin(int hor, int ver) override
CCD calls this function when CCD Binning needs to be updated in the hardware. Derived classes should ...
int DrawCcdFrame(INDI::CCDChip *targetChip)
virtual void addFITSKeywords(INDI::CCDChip *targetChip, std::vector< INDI::FITSRecord > &fitsKeywords) override
Generate FITS keywords that will be added to FIST/XISF file.
const char * getDefaultName() override
virtual bool ISSnoopDevice(XMLEle *root) override
Process a snoop event from INDI server. This function is called when a snooped property is updated in...
bool Disconnect() override
Disconnect from device.
int AddToPixel(INDI::CCDChip *targetChip, int, int, int)
void ISGetProperties(const char *dev) override
define the driver's properties to the client. Usually, only a minimum set of properties are defined t...
bool AbortExposure() override
Abort ongoing exposure.
virtual bool StartStreaming() override
StartStreaming Start live video streaming.
virtual bool StopStreaming() override
StopStreaming Stop live video streaming.
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
bool initProperties() override
Initilize properties initial state and value. The child class must implement this function.
bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
virtual IPState GuideSouth(uint32_t) override
Guide southward for ms milliseconds.
static void * streamVideoHelper(void *context)
bool StartExposure(float duration) override
Start exposing primary CCD chip.
virtual void activeDevicesUpdated() override
activeDevicesUpdated Inform children that ActiveDevices property was updated so they can snoop on the...
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
int DrawImageStar(INDI::CCDChip *targetChip, float, float, float, float ExposureTime)
bool Connect() override
Connect to the device. INDI::DefaultDevice implementation connects to appropriate connection interfac...
virtual IPState GuideWest(uint32_t) override
Guide westward for ms milliseconds.
virtual int SetTemperature(double temperature) override
Set CCD temperature.
const char * getDeviceName() const
The CCDChip class provides functionality of a CCD Chip within a CCD.
uint8_t * getFrameBuffer()
getFrameBuffer Get raw frame buffer of the CCD chip.
int getSubX() const
getSubX Get the starting left coordinates (X) of the frame.
int getSubY() const
getSubY Get the starting top coordinates (Y) of the frame.
float getPixelSizeY() const
getPixelSizeY Get vertical pixel size in microns.
void setExposureDuration(double duration)
setExposureDuration Set desired CCD frame exposure duration for next exposure. You must call this fun...
int getSubH() const
getSubH Get the height of the frame
int getBPP() const
getBPP Get CCD Chip depth (bits per pixel).
CCD_FRAME getFrameType() const
isInterlaced
int getBinY() const
getBinY Get vertical binning of the CCD chip.
float getPixelSizeX() const
getPixelSizeX Get horizontal pixel size in microns.
int getXRes() const
getXRes Get the horizontal resolution in pixels of the CCD Chip.
int getBinX() const
getBinX Get horizontal binning of the CCD chip.
void setExposureLeft(double duration)
setExposureLeft Update exposure time left. Inform the client of the new exposure time left value.
int getSubW() const
getSubW Get the width of the frame
void setFrameBufferSize(uint32_t nbuf, bool allocMem=true)
setFrameBufferSize Set desired frame buffer size. The function will allocate memory accordingly....
int getFrameBufferSize() const
getFrameBufferSize Get allocated frame buffer size to hold the CCD image frame.
int getYRes() const
Get the vertical resolution in pixels of the CCD Chip.
void binFrame()
binFrame Perform software binning on the CCD frame. Only use this function if hardware binning is not...
uint32_t GetCCDCapability() const
GetCCDCapability returns the CCD capabilities.
std::unique_ptr< StreamManager > Streamer
virtual bool UpdateCCDFrame(int x, int y, int w, int h)
CCD calls this function when CCD Frame dimension needs to be updated in the hardware....
virtual void addFITSKeywords(CCDChip *targetChip, std::vector< FITSRecord > &fitsKeywords)
Generate FITS keywords that will be added to FIST/XISF file.
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
virtual bool ExposureComplete(CCDChip *targetChip)
Uploads target Chip exposed buffer as FITS to the client. Dervied classes should class this function ...
virtual void ISGetProperties(const char *dev) override
define the driver's properties to the client. Usually, only a minimum set of properties are defined t...
INDI::PropertyNumber ScopeInfoNP
virtual bool UpdateCCDBin(int hor, int ver)
CCD calls this function when CCD Binning needs to be updated in the hardware. Derived classes should ...
virtual bool initProperties() override
Initilize properties initial state and value. The child class must implement this function.
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
virtual void addCaptureFormat(const CaptureFormat &format)
addCaptureFormat Add a supported camera native capture format (e.g. Mono, Bayer8.....
virtual void SetGuiderParams(int x, int y, int bpp, float xf, float yf)
Setup CCD paramters for guide head CCD. Child classes call this function to update CCD parameters.
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Save configuration items in XML file.
virtual bool ISSnoopDevice(XMLEle *root) override
Process a snoop event from INDI server. This function is called when a snooped property is updated in...
void SetCCDCapability(uint32_t cap)
SetCCDCapability Set the CCD capabilities. Al fields must be initialized.
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
INumberVectorProperty TemperatureNP
TemperatureNP Camera Temperature in Celcius.
virtual void SetCCDParams(int x, int y, int bpp, float xf, float yf)
Setup CCD paramters for primary CCD. Child classes call this function to update CCD parameters.
double snoopedFocalLength
virtual bool deleteProperty(const char *propertyName)
Delete a property and unregister it. It will also be deleted from all clients.
void defineProperty(INumberVectorProperty *property)
uint32_t getCurrentPollingPeriod() const
getCurrentPollingPeriod Return the current polling period.
void setDriverInterface(uint16_t value)
setInterface Set driver interface. By default the driver interface is set to GENERAL_DEVICE....
int SetTimer(uint32_t ms)
Set a timer to call the function TimerHit after ms milliseconds.
uint16_t getDriverInterface() const
void addDebugControl()
Add Debug control to the driver.
void setState(IPState state)
void apply(const char *format,...) const ATTRIBUTE_FORMAT_PRINTF(2
bool isNameMatch(const char *otherName) const
bool update(const ISState states[], const char *const names[], int n)
int findOnSwitchIndex() const
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, ISRule rule, double timeout, IPState state)
const char * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
int f_scansexa(const char *str0, double *dp)
convert sexagesimal string str AxBxC to double. x can be anything non-numeric. Any missing A,...
double range360(double r)
range360 Limits an angle to be between 0-360 degrees.
double rangeDec(double decdegrees)
rangeDec Limits declination value to be in -90 to 90 range.
int fs_sexa(char *out, double a, int w, int fracbase)
Converts a sexagesimal number to a string. sprint the variable a in sexagesimal format into out[].
double get_local_hour_angle(double sideral_time, double ra)
get_local_hour_angle Returns local hour angle of an object
Implementations for common driver routines.
double get_local_sidereal_time(double longitude)
get_local_sidereal_time Returns local sideral time given longitude and system clock.
void IUSaveConfigSwitch(FILE *fp, const ISwitchVectorProperty *svp)
Add a switch vector property value to the configuration file.
void IUFillNumberVector(INumberVectorProperty *nvp, INumber *np, int nnp, const char *dev, const char *name, const char *label, const char *group, IPerm p, double timeout, IPState s)
Assign attributes for a number vector property. The vector's auxiliary elements will be set to NULL.
int IUFindOnSwitchIndex(const ISwitchVectorProperty *svp)
Returns the index of first ON switch it finds in the vector switch property.
void IUSaveText(IText *tp, const char *newtext)
Function to reliably save new text in a IText.
void IUSaveConfigNumber(FILE *fp, const INumberVectorProperty *nvp)
Add a number vector property value to the configuration file.
void IUFillSwitch(ISwitch *sp, const char *name, const char *label, ISState s)
Assign attributes for a switch property. The switch's auxiliary elements will be set to NULL.
void IUFillNumber(INumber *np, const char *name, const char *label, const char *format, double min, double max, double step, double value)
Assign attributes for a number property. The number's auxiliary elements will be set to NULL.
void IUFillSwitchVector(ISwitchVectorProperty *svp, ISwitch *sp, int nsp, const char *dev, const char *name, const char *label, const char *group, IPerm p, ISRule r, double timeout, IPState s)
Assign attributes for a switch vector property. The vector's auxiliary elements will be set to NULL.
int IUUpdateSwitch(ISwitchVectorProperty *svp, ISState *states, char *names[], int n)
Update all switches in a switch vector property.
void IDSetNumber(const INumberVectorProperty *nvp, const char *fmt,...)
void IDSetSwitch(const ISwitchVectorProperty *svp, const char *fmt,...)
void IDSnoopDevice(const char *snooped_device, const char *snooped_property)
Function a Driver calls to snoop on another Device. Snooped messages will then arrive via ISSnoopDevi...
int IUUpdateNumber(INumberVectorProperty *nvp, double values[], char *names[], int n)
Update all numbers in a number vector property.
#define LOGF_DEBUG(fmt,...)
#define LOG_ERROR(txt)
Shorter logging macros. In order to use these macros, the function (or method) "getDeviceName()" must...
#define DEBUGF(priority, msg,...)
const char * findXMLAttValu(XMLEle *ep, const char *name)
Find an XML element's attribute value.
char * pcdataXMLEle(XMLEle *ep)
Return the pcdata of an XML element.
XMLEle * nextXMLEle(XMLEle *ep, int init)
Iterate an XML element for a list of nesetd XML elements.
void ObservedToJ2000(IEquatorialCoordinates *observed, double jd, IEquatorialCoordinates *J2000pos)
ObservedToJ2000 converts an observed position to a J2000 catalogue position removes aberration,...