63 stepsPerRevolution = ~0;
67 if (wordexp(
"~/.indi/ScopeDome_DomeInertia_Table.txt", &wexp, 0) == 0)
69 FILE *inertia = fopen(wexp.we_wordv[0],
"r");
73 fseek(inertia, 3, SEEK_SET);
77 while (fgets(line,
sizeof(line), inertia))
81 char* splitter = strchr(line,
';');
87 result = atoi(splitter);
90 inertiaTable.push_back(result);
96 LOGF_INFO(
"Read inertia file %s", wexp.we_wordv[0]);
100 LOG_WARN(
"Could not read inertia file, please generate one with Windows "
101 "driver setup and copy to "
102 "~/.indi/ScopeDome_DomeInertia_Table.txt");
192 stepsPerRevolution = interface->getStepsPerRevolution();
193 LOGF_INFO(
"Steps per revolution read as %d", stepsPerRevolution);
221 bool calibrationNeeded = interface->isCalibrationNeeded();
226 double fwMain, fwRotary;
227 interface->getFirmwareVersions(fwMain, fwRotary);
234 if(rotaryLinkEstablished ==
ISS_OFF)
236 LOG_WARN(
"Rotary link not established, shutter control not possible");
268 if (interface->detect())
272 LOG_ERROR(
"Can't identify the card, check card type and baud rate (115200 for USB Card 2.1, 9600 for Arduino Card)");
281 return (
const char *)
"ScopeDome Dome";
295 size_t numSensors = interface->getNumberOfSensors();
297 for(
size_t i = 0; i < numSensors; i++)
299 auto info = interface->getSensorInfo(i);
301 info.format.c_str(), info.minValue, info.maxValue, 1.0, 0.0);
308 size_t numRelays = interface->getNumberOfRelays();
310 for(
size_t i = 0; i < numRelays; i++)
312 auto info = interface->getRelayInfo(i);
321 size_t numInputs = interface->getNumberOfInputs();
323 for(
size_t i = 0; i < numInputs; i++)
325 auto info = interface->getInputInfo(i);
382 interface->findHome();
411 interface->calibrate();
419 for(
int i = 0; i < n; i++)
421 interface->setRelayState(i,
RelaysSP[i].getState());
454 LOG_DEBUG(
"Home sensor polarity set to ACTIVE_LOW");
459 LOG_DEBUG(
"Home sensor polarity set to ACTIVE_HIGH");
509 LOGF_ERROR(
"Error reading input state: %d", rc);
553 if (link != rotaryLinkEstablished)
555 rotaryLinkEstablished = link;
556 if(rotaryLinkEstablished ==
ISS_OFF)
558 LOG_WARN(
"Rotary link not established, shutter control not possible");
562 LOG_WARN(
"Rotary link established, shutter control now possible");
573 rotationCounter = interface->getRotationCounter();
577 double az = ((double)rotationCounter * -360.0 / stepsPerRevolution) +
DomeHomePositionNP[0].getValue();
578 az = fmod(az, 360.0);
584 LOGF_DEBUG(
"Dome position %f, step count %d", az, rotationCounter);
595 SensorsNP[i].setValue(interface->getSensorValue(i));
625 interface->updateState();
627 currentStatus = interface->getStatus();
658 interface->resetCounter();
676 currentRotation = interface->getRotationCounterExt();
677 LOGF_INFO(
"Current rotation is %d", currentRotation);
678 if (abs(currentRotation) < 100)
689 interface->move(currentRotation);
697 stepsPerRevolution = interface->getStepsPerRevolution();
698 LOGF_INFO(
"Calibration complete, steps per revolution read as %d", stepsPerRevolution);
730 LOG_INFO(
"Dome reached requested azimuth angle.");
767 static int tmpCounter = 0;
768 if (--tmpCounter <= 0)
800 return sendMove(azDiff);
809 return sendMove(azDiff);
815 IPState ScopeDome::sendMove(
double azDiff)
819 int steps =
static_cast<int>(-azDiff * stepsPerRevolution / 360.0);
825 steps = compensateInertia(steps);
831 interface->move(-steps);
835 int steps =
static_cast<int>(azDiff * stepsPerRevolution / 360.0);
841 steps = compensateInertia(steps);
847 interface->move(steps);
911 LOGF_INFO(
"Control shutter %d", (
int)operation);
984 void ScopeDome::reconnect()
987 LOG_INFO(
"Reconnecting serial port");
993 interface->setPortFD(
PortFD);
995 reconnecting =
false;
1008 static const float k0 = -5.8666426e3;
1009 static const float k1 = 2.232870244e1;
1010 static const float k2 = 1.39387003e-2;
1011 static const float k3 = -3.4262402e-5;
1012 static const float k4 = 2.7040955e-8;
1013 static const float k5 = 6.7063522e-1;
1015 static float pvsIce(
float T)
1017 float lnP = k0 / T + k1 + (k2 + (k3 + (k4 * T)) * T) * T + k5 * log(T);
1033 static const float n1 = 0.11670521452767e4;
1034 static const float n6 = 0.14915108613530e2;
1035 static const float n2 = -0.72421316703206e6;
1036 static const float n7 = -0.48232657361591e4;
1037 static const float n3 = -0.17073846940092e2;
1038 static const float n8 = 0.40511340542057e6;
1039 static const float n4 = 0.12020824702470e5;
1040 static const float n9 = -0.23855557567849;
1041 static const float n5 = -0.32325550322333e7;
1042 static const float n10 = 0.65017534844798e3;
1044 static float pvsWater(
float T)
1046 float th = T + n9 / (T - n10);
1047 float A = (
th + n1) *
th + n2;
1049 float B = (n3 *
th + n4) *
th + n5;
1050 float C = (n6 *
th + n7) *
th + n8;
1053 float p = 2.0f * C / (-B + sqrt(B * B - 4.0f * A * C));
1059 static const float C_OFFSET = 273.15f;
1060 static const float minT = 173;
1061 static const float maxT = 678;
1063 static float PVS(
float T)
1065 if (T < minT || T > maxT)
1067 else if (T < C_OFFSET)
1073 static float solve(
float (*f)(
float),
float y,
float x0)
1078 while (++count < maxCount)
1081 float dx = x / 1000;
1083 xNew = x + dx * (y - z) / (f(x + dx) - z);
1084 if (fabs((xNew - x) / xNew) < 0.0001f)
1091 float ScopeDome::getDewPoint(
float RH,
float T)
1094 return solve(PVS, RH / 100 * PVS(T), T) - C_OFFSET;
1097 int ScopeDome::compensateInertia(
int steps)
1099 if (inertiaTable.size() == 0)
1105 for (uint16_t out = 0; out < inertiaTable.size(); out++)
1107 if (inertiaTable[out] > steps)
1109 LOGF_DEBUG(
"inertia %d -> %d", steps, out - 1);
1115 int lastEntry = inertiaTable.size() - 1;
1116 int inertia = inertiaTable[lastEntry] - lastEntry;
1117 int movement = steps - inertia;
1118 LOGF_DEBUG(
"inertia %d -> %d", steps, movement);
void setDefaultBaudRate(BaudRate newRate)
setDefaultBaudRate Set default baud rate. The default baud rate is 9600 unless otherwise changed by t...
virtual bool Disconnect() override
Disconnect Disconnect from device.
virtual bool Connect() override
Connect Connect to device via the implemented communication medium. Do not perform any handshakes.
const char * getDeviceName() const
void setPollingPeriodRange(uint32_t minimum, uint32_t maximum)
setPollingPeriodRange Set the range permitted by the polling range in milliseconds
void setDefaultPollingPeriod(uint32_t msec)
setDefaultPollingPeriod Change the default polling period to call TimerHit() function in the driver.
void setVersion(uint16_t vMajor, uint16_t vMinor)
Set driver version information to be defined in DRIVER_INFO property as vMajor.vMinor.
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.
bool isSimulation() const
void addAuxControls()
Add Debug, Simulation, and Configuration options to the driver.
Connection::Interface * getActiveConnection()
int SetTimer(uint32_t ms)
Set a timer to call the function TimerHit after ms milliseconds.
void SetParked(bool isparked)
SetParked Change the mount parking status. The data park file (stored in ~/.indi/ParkData....
void SetDomeCapability(uint32_t cap)
SetDomeCapability set the dome capabilities. All capabilities must be initialized.
void setDomeConnection(const uint8_t &value)
setDomeConnection Set Dome connection mode. Child class should call this in the constructor before Do...
const char * GetShutterStatusString(ShutterState status)
getShutterStatusString
ShutterState m_ShutterState
void SetAxis1Park(double value)
SetRAPark Set current AZ parking position. The data park file (stored in ~/.indi/ParkData....
ISwitch ShutterParkPolicyS[2]
void SetAxis1ParkDefault(double steps)
SetAxis1Park Set default AZ parking position.
ShutterOperation
Shutter operation command.
virtual bool initProperties() override
Initilize properties initial state and value. The child class must implement this function.
INumberVectorProperty DomeAbsPosNP
ISwitchVectorProperty DomeShutterSP
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Saves the Device Port and Dome Presets in the configuration file
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n) override
Process the client newSwitch command.
void setShutterState(const ShutterState &value)
void setDomeState(const DomeState &value)
bool InitPark()
InitPark Loads parking data (stored in ~/.indi/ParkData.xml) that contains parking status and parking...
Connection::Serial * serialConnection
void SetParkDataType(DomeParkData type)
setParkDataType Sets the type of parking data stored in the park data file and presented to the user.
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
DomeState getDomeState() const
void setState(IPState state)
void apply(const char *format,...) const ATTRIBUTE_FORMAT_PRINTF(2
const char * getName() const
bool isNameMatch(const char *otherName) const
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)
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)
bool update(const char *const texts[], 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)
friend class ScopeDomeUSB21
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
INDI::PropertySwitch DerotateSP
virtual const char * getDefaultName() override
virtual bool SetDefaultPark() override
SetDefaultPark Set default coordinates/encoders value as the desired parking position.
virtual void TimerHit() override
Callback function to be called once SetTimer duration elapses.
INDI::PropertyText CredentialsTP
ShutterState simShutterStatus
friend class ScopeDomeArduino
INDI::PropertySwitch FindHomeSP
ShutterOperation targetShutter
virtual bool SetCurrentPark() override
SetCurrentPark Set current coordinates/encoders value as the desired parking position.
INDI::PropertyNumber DomeHomePositionNP
virtual bool initProperties() override
Initilize properties initial state and value. The child class must implement this function.
bool UpdateSensorStatus()
INDI::PropertyNumber FirmwareVersionsNP
virtual IPState MoveRel(double azDiff) override
Move the Dome to an relative position.
virtual IPState ControlShutter(ShutterOperation operation) override
Open or Close shutter.
virtual IPState UnPark() override
UnPark dome. The action of the Unpark command is dome specific, but it may include opening the shutte...
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
virtual bool Abort() override
Abort all dome motion.
INDI::PropertySwitch CardTypeSP
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
bool UpdateShutterStatus()
virtual bool Handshake() override
perform handshake with device to check communication
INDI::PropertySwitch StartCalibrationSP
INDI::PropertySwitch HomeSensorPolaritySP
INDI::PropertySwitch InputsSP
INDI::PropertySwitch RelaysSP
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Saves the Device Port and Dome Presets in the configuration file
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n) override
Process the client newSwitch command.
INDI::PropertyNumber SensorsNP
virtual IPState MoveAbs(double az) override
Move the Dome to an absolute azimuth.
INDI::PropertyNumber StepsPerRevolutionNP
INDI::PropertySwitch CalibrationNeededSP
virtual IPState Move(DomeDirection dir, DomeMotionCommand operation) override
Move the Dome in a particular direction.
virtual IPState Park() override
Goto Park Position. The park position is an absolute azimuth value.
const char * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
const char * INFO_TAB
INFO_TAB Where all the properties for general information are located.
const char * SITE_TAB
SITE_TAB Where all site information setting are located.
Implementations for common driver routines.
void IDSetNumber(const INumberVectorProperty *nvp, const char *fmt,...)
void IDSetSwitch(const ISwitchVectorProperty *svp, const char *fmt,...)
int IUGetConfigText(const char *dev, const char *property, const char *member, char *value, int len)
IUGetConfigText Opens configuration file and reads single text property.
int IUGetConfigSwitch(const char *dev, const char *property, const char *member, ISState *value)
IUGetConfigSwitch Opens configuration file and reads single switch property.
#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...
#define LOGF_ERROR(fmt,...)
const char * CONNECTION_TAB
std::unique_ptr< ScopeDome > scopeDome(new ScopeDome())