51#include <libnova/julian_day.h>
57static pthread_cond_t cv = PTHREAD_COND_INITIALIZER;
58static pthread_mutex_t condMutex = PTHREAD_MUTEX_INITIALIZER;
63static std::unique_ptr<GuideSim> ccd(
new GuideSim());
70 m_StreamPredicate = 0;
71 m_TerminateThread =
false;
77 SetCCDParams(SimulatorSettingsNP[SIM_XRES].getValue(), SimulatorSettingsNP[SIM_YRES].getValue(), 16,
78 SimulatorSettingsNP[SIM_XSIZE].getValue(),
79 SimulatorSettingsNP[SIM_YSIZE].getValue());
82 m_MaxNoise = SimulatorSettingsNP[SIM_NOISE].getValue();
84 m_SkyGlow = SimulatorSettingsNP[SIM_SKYGLOW].getValue();
86 m_MaxVal = SimulatorSettingsNP[SIM_MAXVAL].getValue();
89 m_Bias = SimulatorSettingsNP[SIM_BIAS].getValue();
92 m_LimitingMag = SimulatorSettingsNP[SIM_LIMITINGMAG].getValue();
93 m_SaturationMag = SimulatorSettingsNP[SIM_SATURATION].getValue();
95 m_OAGoffset = SimulatorSettingsNP[SIM_OAGOFFSET].getValue();
100 m_PolarError = SimulatorSettingsNP[SIM_POLAR].getValue();
101 m_PolarDrift = SimulatorSettingsNP[SIM_POLARDRIFT].getValue();
108 m_TimeFactor = SimulatorSettingsNP[SIM_TIME_FACTOR].getValue();
116 m_RotationOffset = SimulatorSettingsNP[SIM_ROTATION].getValue();
117 m_Seeing = SimulatorSettingsNP[SIM_SEEING].getValue();
118 m_RaTimeDrift = SimulatorSettingsNP[SIM_RA_DRIFT].getValue();
119 m_DecTimeDrift = SimulatorSettingsNP[SIM_DEC_DRIFT].getValue();
120 m_RaRand = SimulatorSettingsNP[SIM_RA_RAND].getValue();
121 m_DecRand = SimulatorSettingsNP[SIM_DEC_RAND].getValue();
122 m_PEPeriod = SimulatorSettingsNP[SIM_PE_PERIOD].getValue();
123 m_PEMax = SimulatorSettingsNP[SIM_PE_MAX].getValue();
124 m_TemperatureRequest = SimulatorSettingsNP[SIM_TEMPERATURE].getValue();
139 m_StreamPredicate = 0;
140 m_TerminateThread =
false;
148 pthread_mutex_lock(&condMutex);
149 m_StreamPredicate = 1;
150 m_TerminateThread =
true;
151 pthread_cond_signal(&cv);
152 pthread_mutex_unlock(&condMutex);
159 return "Guide Simulator";
171 SimulatorSettingsNP[SIM_XRES].
fill(
"SIM_XRES",
"X resolution",
"%4.0f", 0, 8192, 0, 1280);
172 SimulatorSettingsNP[SIM_YRES].
fill(
"SIM_YRES",
"Y resolution",
"%4.0f", 0, 8192, 0, 1024);
173 SimulatorSettingsNP[SIM_XSIZE].
fill(
"SIM_XSIZE",
"X Pixel Size",
"%4.2f", 0, 60, 0, 2.4);
174 SimulatorSettingsNP[SIM_YSIZE].
fill(
"SIM_YSIZE",
"Y Pixel Size",
"%4.2f", 0, 60, 0, 2.4);
175 SimulatorSettingsNP[SIM_MAXVAL].
fill(
"SIM_MAXVAL",
"Maximum ADU",
"%4.0f", 0, 65000, 0, 65000);
176 SimulatorSettingsNP[SIM_BIAS].
fill(
"SIM_BIAS",
"Bias",
"%4.0f", 0, 6000, 0, 10);
177 SimulatorSettingsNP[SIM_SATURATION].
fill(
"SIM_SATURATION",
"Saturation Mag",
"%4.1f", 0, 20, 0, 1.0);
178 SimulatorSettingsNP[SIM_LIMITINGMAG].
fill(
"SIM_LIMITINGMAG",
"Limiting Mag",
"%4.1f", 0, 20, 0, 17.0);
179 SimulatorSettingsNP[SIM_NOISE].
fill(
"SIM_NOISE",
"Noise",
"%4.0f", 0, 6000, 0, 10);
180 SimulatorSettingsNP[SIM_SKYGLOW].
fill(
"SIM_SKYGLOW",
"Sky Glow (magnitudes)",
"%4.1f", 0, 6000, 0, 19.5);
181 SimulatorSettingsNP[SIM_OAGOFFSET].
fill(
"SIM_OAGOFFSET",
"Oag Offset (arcminutes)",
"%4.1f", 0, 6000, 0, 0);
182 SimulatorSettingsNP[SIM_POLAR].
fill(
"SIM_POLAR",
"PAE (arcminutes)",
"%4.3f", -600, 600, 0,
184 SimulatorSettingsNP[SIM_POLARDRIFT].
fill(
"SIM_POLARDRIFT",
"PAE Drift (minutes)",
"%4.3f", 0, 6000, 0, 0);
185 SimulatorSettingsNP[SIM_ROTATION].
fill(
"SIM_ROTATION",
"Rotation Offset",
"%4.1f", -180, 180, 0, 0);
186 SimulatorSettingsNP[SIM_KING_GAMMA].
fill(
"SIM_KING_GAMMA",
"(CP,TCP), deg",
"%4.1f", 0, 10, 0, 0);
187 SimulatorSettingsNP[SIM_KING_THETA].
fill(
"SIM_KING_THETA",
"hour hangle, deg",
"%4.1f", 0, 360, 0, 0);
188 SimulatorSettingsNP[SIM_TIME_FACTOR].
fill(
"SIM_TIME_FACTOR",
"Time Factor (x)",
"%.2f", 0.01, 100, 0, 1);
190 SimulatorSettingsNP[SIM_SEEING].
fill(
"SIM_SEEING",
"Seeing (a-s)",
"%4.1f", 0, 20, 0, 6);
191 SimulatorSettingsNP[SIM_RA_DRIFT].
fill(
"SIM_RA_DRIFT",
"RA drift (a-s/second)",
"%5.3f", -2, 2, 0, 0.05);
192 SimulatorSettingsNP[SIM_DEC_DRIFT].
fill(
"SIM_DEC_DRIFT",
"DEC drift (a-s/second)",
"%5.3f", -2, 2, 0, -0.05);
193 SimulatorSettingsNP[SIM_RA_RAND].
fill(
"SIM_RA_RAND",
"Max random RA add (a-s)",
"%5.3f", -2, 2, 0, 0.2);
194 SimulatorSettingsNP[SIM_DEC_RAND].
fill(
"SIM_DEC_RAND",
"Max random DEC add (a-s)",
"%5.3f", -2, 2, 0,
196 SimulatorSettingsNP[SIM_PE_PERIOD].
fill(
"SIM_PE_PERIOD",
"Periodic error period (secs)",
"%4.1f", 0, 1000, 0, 120);
197 SimulatorSettingsNP[SIM_PE_MAX].
fill(
"SIM_PE_MAX",
"Periodic error maxval (a-s)",
"%4.1f", 0, 100, 0, 3);
198 SimulatorSettingsNP[SIM_TEMPERATURE].
fill(
"SIM_TEMPERATURE",
"Temperature (°C)",
"%4.1f", -100, 100, 0, 25);
204 SimulatorSettingsNP.
load();
206 SimTestsSP[SIM_TESTS_RGB].
fill(
"RGB",
"RGB",
ISS_OFF);
207 SimTestsSP[SIM_TESTS_CRASH].
fill(
"CRASH",
"Crash",
ISS_OFF);
208 SimTestsSP[SIM_TESTS_TIMEOUT].
fill(
"TIMEOUT",
"Timeout",
ISS_OFF);
213 GainNP[0].
fill(
"GAIN",
"Gain",
"%.f", 0, 100, 10, 50);
216 EqPENP[RA_PE].
fill(
"RA_PE",
"RA (hh:mm:ss)",
"%010.6m", 0, 24, 0, 0);
217 EqPENP[DEC_PE].
fill(
"DEC_PE",
"DEC (dd:mm:ss)",
"%010.6m", -90, 90, 0, 0);
221#ifdef USE_EQUATORIAL_PE
243 setRGB(m_SimulateRGB);
252void GuideSim::setRGB(
bool onOff)
307 m_AbortPrimaryFrame =
false;
308 m_ExposureRequest = duration;
311 gettimeofday(&m_ExpStart,
nullptr);
315 m_ExposureRequest = duration * m_TimeFactor;
326 m_AbortPrimaryFrame =
true;
341 if (m_AbortPrimaryFrame)
344 m_AbortPrimaryFrame =
false;
349 timeleft = CalcTimeLeft(m_ExpStart, m_ExposureRequest);
359 if (timeleft <= 0.001)
368 nextTimer = timeleft * 1000;
379 double exposure_time;
381 uint16_t * ptr =
reinterpret_cast<uint16_t *
>(targetChip->
getFrameBuffer());
384 exposure_time = (m_ExposureRequest < 1) ? (m_ExposureRequest * 100) : m_ExposureRequest * 2;
386 exposure_time = m_ExposureRequest;
388 exposure_time *= (1 + sqrt(GainNP[0].getValue()));
402 if (!m_RunStartInitialized || difftime(now, m_LastSim) > 30)
404 m_RunStartInitialized =
true;
409 const double timesince = difftime(now, m_RunStart);
411 if (m_PEPeriod != 0 && m_PEMax != 0)
413 const double PESpot = 2.0 * 3.14159 * timesince / m_PEPeriod;
414 PEOffset = m_PEMax * std::sin(PESpot) / 3600.0;
418 m_RotationOffset = SimulatorSettingsNP[SIM_ROTATION].getValue();
419 double theta = m_RotationOffset;
427#ifdef USE_EQUATORIAL_PE
435 static bool s_warnedNoSnoop =
false;
436 if (!s_warnedNoSnoop)
438 LOG_WARN(
"EQUATORIAL_PE not yet snooped -- rendering at raw EQUATORIAL_EOD_COORD (mount errors not active)");
439 s_warnedNoSnoop =
true;
457#ifdef USE_EQUATORIAL_PE
462 const float raTDrift = timesince * m_RaTimeDrift / 3600.0f;
463 const float decTDrift = timesince * m_DecTimeDrift / 3600.0f;
466 double raRandomDrift = 0;
467 double decRandomDrift = 0;
468 constexpr int scale = 1000000;
471 const int raScale = scale * m_RaRand;
472 raRandomDrift = ((random() % (2 * raScale)) - raScale) / (3600.0 * scale);
476 const int decScale = scale * m_DecRand;
477 decRandomDrift = ((random() % (2 * decScale)) - decScale) / (3600.0 * scale);
480 rad =
m_CurrentRA * 15.0 + PEOffset + raTDrift + raRandomDrift;
486 const double decDrift = (m_PolarDrift * m_PolarError * cos(decr)) / 3.81;
490 if (m_KingGamma > 0.)
498 double J2_mnt_d_rar = m_KingGamma * sin(J2decr) * sin(JnHAr - m_KingTheta) / cos(J2decr);
499 double J2_mnt_rar = rar - J2_mnt_d_rar;
501 double J2_mnt_d_decr = m_KingGamma * cos(JnHAr - m_KingTheta);
502 double J2_mnt_decr = decr + J2_mnt_d_decr;
504 if (J2_mnt_decr >
M_PI / 2.)
506 J2_mnt_decr =
M_PI / 2. - (J2_mnt_decr -
M_PI / 2.);
509 J2_mnt_rar = fmod(J2_mnt_rar, 2. *
M_PI);
519 double const kingMinRadius = (m_KingGamma > 0.) ? 60.0 : 0.0;
531 cfg.
skyGlow = isLight ? m_SkyGlow : m_SkyGlow / 10.0f;
536 if (isLight || isFlat)
538 int drawn = m_Renderer.
renderFrame(targetChip, rad, cameradec,
539 targetFocalLength, theta,
540 static_cast<float>(exposure_time), isLight,
542 if (isLight && drawn < 0)
543 LOG_ERROR(
"Error launching gsc, is it installed with appropriate environment variables set?");
544 else if (isLight && drawn == 0)
545 LOG_WARN(
"No stars found in field -- check gsc catalog coverage for this region.");
557 if (m_TestValue > 255)
559 uint16_t val = m_TestValue;
563 for (
int x = 0; x < nbuf; x++)
572float GuideSim::CalcTimeLeft(timeval start,
float req)
578 gettimeofday(&now,
nullptr);
579 double const timesince = (now.tv_sec * 1000.0 + now.tv_usec / 1000.0)
580 - (start.tv_sec * 1000.0 + start.tv_usec / 1000.0);
581 return static_cast<float>(req - timesince / 1000.0);
599 c = c / 3600.0 / 15.0;
610 c = c / 3600.0 / 15.0;
625 GainNP.
update(values, names, n);
631 if (strcmp(name,
"SIMULATOR_SETTINGS") == 0)
633 SimulatorSettingsNP.
update(values, names, n);
638 SimulatorSettingsNP.
apply();
640 m_MaxNoise = SimulatorSettingsNP[SIM_NOISE].getValue();
641 m_SkyGlow = SimulatorSettingsNP[SIM_SKYGLOW].getValue();
642 m_MaxVal = SimulatorSettingsNP[SIM_MAXVAL].getValue();
643 m_Bias = SimulatorSettingsNP[SIM_BIAS].getValue();
644 m_LimitingMag = SimulatorSettingsNP[SIM_LIMITINGMAG].getValue();
645 m_SaturationMag = SimulatorSettingsNP[SIM_SATURATION].getValue();
646 m_OAGoffset = SimulatorSettingsNP[SIM_OAGOFFSET].getValue();
647 m_PolarError = SimulatorSettingsNP[SIM_POLAR].getValue();
648 m_PolarDrift = SimulatorSettingsNP[SIM_POLARDRIFT].getValue();
649 m_RotationOffset = SimulatorSettingsNP[SIM_ROTATION].getValue();
653 m_TimeFactor = SimulatorSettingsNP[SIM_TIME_FACTOR].getValue();
655 m_Seeing = SimulatorSettingsNP[SIM_SEEING].getValue();
656 m_RaTimeDrift = SimulatorSettingsNP[SIM_RA_DRIFT].getValue();
657 m_DecTimeDrift = SimulatorSettingsNP[SIM_DEC_DRIFT].getValue();
658 m_RaRand = SimulatorSettingsNP[SIM_RA_RAND].getValue();
659 m_DecRand = SimulatorSettingsNP[SIM_DEC_RAND].getValue();
660 m_PEPeriod = SimulatorSettingsNP[SIM_PE_PERIOD].getValue();
661 m_PEMax = SimulatorSettingsNP[SIM_PE_MAX].getValue();
662 m_TemperatureRequest = SimulatorSettingsNP[SIM_TEMPERATURE].getValue();
673 EqPENP.
update(values, names, n);
696 SimTestsSP.
update(states, names, n);
699 if (SimTestsSP[SIM_TESTS_RGB].getState() ==
ISS_ON)
701 m_SimulateRGB =
true;
706 m_SimulateRGB =
false;
709 setRGB(m_SimulateRGB);
712 if (SimTestsSP[SIM_TESTS_CRASH].getState() ==
ISS_ON)
718 if (SimTestsSP[SIM_TESTS_TIMEOUT].getState() ==
ISS_ON)
720 m_SimulateTimeout =
true;
725 m_SimulateTimeout =
false;
741#ifdef USE_EQUATORIAL_PE
751#ifdef USE_EQUATORIAL_PE
753 if (!strcmp(propName,
"EQUATORIAL_PE"))
756 int rc_ra = -1, rc_de = -1;
757 double newra = 0, newdec = 0;
763 if (!strcmp(elemName,
"RA_PE"))
765 else if (!strcmp(elemName,
"DEC_PE"))
769 if (rc_ra == 0 && rc_de == 0)
773 raPE = J2000Pos.rightascension;
774 decPE = J2000Pos.declination;
779 if (!m_UsePE && strcmp(state,
"Ok") == 0)
781 LOGF_INFO(
"EQUATORIAL_PE snoop active: JNow RA %.4f Dec %.4f -> J2000 RA %.4f Dec %.4f", newra, newdec, raPE, decPE);
785 EqPENP[
AXIS_RA].setValue(newra);
786 EqPENP[
AXIS_DE].setValue(newdec);
789 LOGF_DEBUG(
"Snooped EQUATORIAL_PE JNow RA %g Dec %g -> J2000 RA %g Dec %g", newra, newdec, raPE, decPE);
806 SimulatorSettingsNP.
save(fp);
817 m_ExposureRequest = 1.0 /
Streamer->getTargetExposure();
818 pthread_mutex_lock(&condMutex);
819 m_StreamPredicate = 1;
820 pthread_mutex_unlock(&condMutex);
821 pthread_cond_signal(&cv);
828 pthread_mutex_lock(&condMutex);
829 m_StreamPredicate = 0;
830 pthread_mutex_unlock(&condMutex);
831 pthread_cond_signal(&cv);
841 bin_width = bin_width - (bin_width % 2);
842 bin_height = bin_height - (bin_height % 2);
844 Streamer->setSize(bin_width, bin_height);
851 if (hor == 3 || ver == 3)
853 LOG_ERROR(
"3x3 binning is not supported.");
860 bin_width = bin_width - (bin_width % 2);
861 bin_height = bin_height - (bin_height % 2);
863 Streamer->setSize(bin_width, bin_height);
875 auto start = std::chrono::high_resolution_clock::now();
876 auto finish = std::chrono::high_resolution_clock::now();
880 pthread_mutex_lock(&condMutex);
882 while (m_StreamPredicate == 0)
884 pthread_cond_wait(&cv, &condMutex);
885 m_ExposureRequest =
Streamer->getTargetExposure();
888 if (m_TerminateThread)
892 pthread_mutex_unlock(&condMutex);
900 finish = std::chrono::high_resolution_clock::now();
901 std::chrono::duration<double> elapsed = finish - start;
903 if (elapsed.count() < m_ExposureRequest)
904 usleep(fabs(m_ExposureRequest - elapsed.count()) * 1e6);
909 start = std::chrono::high_resolution_clock::now();
912 pthread_mutex_unlock(&condMutex);
920 fitsKeywords.push_back({
"GAIN", GainNP[0].getValue(), 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.
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
Initialize 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.
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.
INDI::PropertyText getText(const char *name) const
The CCDChip class provides functionality of a CCD Chip within a CCD.
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.
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.
uint8_t * getFrameBuffer()
getFrameBuffer Get raw frame buffer 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
INDI::PropertyText ActiveDeviceTP
ActiveDeviceTP defines 4 devices the camera driver can listen to (snoop) for properties of interest s...
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. Derived 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 TemperatureNP
TemperatureNP Camera Temperature in Celcius.
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
Initialize properties initial state and value. The child class must implement this function.
INDI::PropertyText BayerTP
BayerTP Bayer pattern offset and type.
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 parameters 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. All 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.
virtual void SetCCDParams(int x, int y, int bpp, float xf, float yf)
Setup CCD parameters for primary CCD. Child classes call this function to update CCD parameters.
double snoopedFocalLength
void setDriverInterface(uint32_t value)
setInterface Set driver interface. By default the driver interface is set to GENERAL_DEVICE....
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.
uint32_t getDriverInterface() const
int SetTimer(uint32_t ms)
Set a timer to call the function TimerHit after ms milliseconds.
void addDebugControl()
Add Debug control to the driver.
void setState(IPState state)
void apply(const char *format,...) const ATTRIBUTE_FORMAT_PRINTF(2
bool load()
load Attempt to load property values from configuration file.
void save(FILE *f) const
save Save property to configuration file.
bool isNameMatch(const char *otherName) const
void setPermission(IPerm permission)
bool update(const double values[], const char *const names[], int n)
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, double timeout, IPState state)
bool update(const ISState states[], const char *const names[], int n)
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, ISRule rule, double timeout, IPState state)
int renderFrame(INDI::CCDChip *chip, double ra_j2000_deg, double dec_j2000_deg, double focal_length_mm, double rotation_deg, float exposure_s, bool renderStars=true, double minSearchRadiusArcmin=0)
void applyReadoutNoise(INDI::CCDChip *chip, int bias, int maxNoise)
void setConfig(const RenderConfig &cfg)
const char * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
constexpr double DEGREES_TO_RADIANS
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 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 sidereal time given longitude and system clock.
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...
#define LOGF_INFO(fmt,...)
#define LOGF_DEBUG(fmt,...)
#define LOG_ERROR(txt)
Shorter logging macros. In order to use these macros, the function (or method) "getDeviceName()" must...
const char * findXMLAttValu(XMLEle *ep, const char *name)
Find an XML element's attribute value.
XMLEle * nextXMLEle(XMLEle *ep, int init)
Iterate an XML element for a list of nesetd XML elements.
char * pcdataXMLEle(XMLEle *ep)
Return the pcdata of an XML element.
void ObservedToJ2000(IEquatorialCoordinates *observed, double jd, IEquatorialCoordinates *J2000pos)
ObservedToJ2000 converts an observed position to a J2000 catalogue position removes aberration,...