21 namespace AlignmentSubsystem
24 LoadDatabaseCallback(nullptr), LoadDatabaseCallbackThisPointer(nullptr)
29 double Tolerance)
const
31 return std::any_of(MySyncPoints.begin(), MySyncPoints.end(), [CandidateEntry, Tolerance](
const auto & point)
33 return (((std::abs(point.RightAscension - CandidateEntry.RightAscension) < 24.0 * Tolerance / 100.0) &&
34 (std::abs(point.Declination - CandidateEntry.Declination) < 180.0 * Tolerance / 100.0)) ||
35 ((std::abs(point.TelescopeDirection.x - CandidateEntry.TelescopeDirection.x) < Tolerance / 100.0) &&
36 (std::abs(point.TelescopeDirection.y - CandidateEntry.TelescopeDirection.y) < Tolerance / 100.0) &&
37 (std::abs(point.TelescopeDirection.z - CandidateEntry.TelescopeDirection.z) < Tolerance / 100.0)));
44 MySyncPoints.erase(std::remove_if(MySyncPoints.begin(), MySyncPoints.end(),
45 [CandidateEntry, Tolerance](
const auto & point)
47 return (((std::abs(point.RightAscension - CandidateEntry.RightAscension) < 24.0 * Tolerance / 100.0) &&
48 (std::abs(point.Declination - CandidateEntry.Declination) < 180.0 * Tolerance / 100.0)) ||
49 ((std::abs(point.TelescopeDirection.x - CandidateEntry.TelescopeDirection.x) < Tolerance / 100.0) &&
50 (std::abs(point.TelescopeDirection.y - CandidateEntry.TelescopeDirection.y) < Tolerance / 100.0) &&
51 (std::abs(point.TelescopeDirection.z - CandidateEntry.TelescopeDirection.z) < Tolerance / 100.0)));
59 if (DatabaseReferencePositionIsValid)
61 Position = DatabaseReferencePosition;
72 XMLEle *FileRoot =
nullptr;
73 XMLEle *EntriesRoot =
nullptr;
74 XMLEle *EntryRoot =
nullptr;
76 XMLAtt *Attribute =
nullptr;
81 snprintf(DatabaseFileName,
MAXRBUF,
"%s/.indi/%s_alignment_database.xml", getenv(
"HOME"), DeviceName);
83 fp = fopen(DatabaseFileName,
"r");
86 snprintf(Errmsg,
MAXRBUF,
"Unable to read alignment database file. Error loading file %s: %s\n",
87 DatabaseFileName, strerror(
errno));
92 if (
nullptr == (FileRoot =
readXMLFile(fp, Parser, whynot)))
94 snprintf(Errmsg,
MAXRBUF,
"Unable to parse database XML: %s", whynot);
98 if (strcmp(
tagXMLEle(FileRoot),
"INDIAlignmentDatabase") != 0)
103 if (
nullptr == (EntriesRoot =
findXMLEle(FileRoot,
"DatabaseEntries")))
105 snprintf(Errmsg,
MAXRBUF,
"Cannot find DatabaseEntries element");
109 if (
nullptr != (Element =
findXMLEle(FileRoot,
"DatabaseReferenceLocation")))
111 if (
nullptr == (Attribute =
findXMLAtt(Element,
"latitude")))
113 snprintf(Errmsg,
MAXRBUF,
"Cannot find latitude attribute");
117 if (
nullptr == (Attribute =
findXMLAtt(Element,
"longitude")))
119 snprintf(Errmsg,
MAXRBUF,
"Cannot find longitude attribute");
123 DatabaseReferencePositionIsValid =
true;
126 MySyncPoints.clear();
128 for (EntryRoot =
nextXMLEle(EntriesRoot, 1); EntryRoot !=
nullptr; EntryRoot =
nextXMLEle(EntriesRoot, 0))
131 if (strcmp(
tagXMLEle(EntryRoot),
"DatabaseEntry") != 0)
135 for (Element =
nextXMLEle(EntryRoot, 1); Element !=
nullptr; Element =
nextXMLEle(EntryRoot, 0))
137 if (strcmp(
tagXMLEle(Element),
"ObservationJulianDate") == 0)
141 else if (strcmp(
tagXMLEle(Element),
"RightAscension") == 0)
145 else if (strcmp(
tagXMLEle(Element),
"Declination") == 0)
149 else if (strcmp(
tagXMLEle(Element),
"TelescopeDirectionVectorX") == 0)
153 else if (strcmp(
tagXMLEle(Element),
"TelescopeDirectionVectorY") == 0)
157 else if (strcmp(
tagXMLEle(Element),
"TelescopeDirectionVectorZ") == 0)
164 MySyncPoints.push_back(CurrentValues);
171 if (
nullptr != LoadDatabaseCallback)
172 (*LoadDatabaseCallback)(LoadDatabaseCallbackThisPointer);
180 char DatabaseFileName[
MAXRBUF];
185 snprintf(ConfigDir,
MAXRBUF,
"%s/.indi/", getenv(
"HOME"));
186 snprintf(DatabaseFileName,
MAXRBUF,
"%s%s_alignment_database.xml", ConfigDir, DeviceName);
188 if (stat(ConfigDir, &Status) != 0)
190 if (
mkdir(ConfigDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0)
192 snprintf(Errmsg,
MAXRBUF,
"Unable to create config directory. Error %s: %s\n", ConfigDir, strerror(
errno));
197 fp = fopen(DatabaseFileName,
"w");
200 snprintf(Errmsg,
MAXRBUF,
"Unable to open database file. Error opening file %s: %s\n", DatabaseFileName,
205 fprintf(fp,
"<INDIAlignmentDatabase>\n");
207 if (DatabaseReferencePositionIsValid)
208 fprintf(fp,
" <DatabaseReferenceLocation latitude='%lf' longitude='%lf'/>\n", DatabaseReferencePosition.
latitude,
211 fprintf(fp,
" <DatabaseEntries>\n");
212 for (AlignmentDatabaseType::const_iterator Itr = MySyncPoints.begin(); Itr != MySyncPoints.end(); Itr++)
215 fprintf(fp,
" <DatabaseEntry>\n");
217 fprintf(fp,
" <ObservationJulianDate>%lf</ObservationJulianDate>\n", (*Itr).ObservationJulianDate);
218 fs_sexa(SexaString, (*Itr).RightAscension, 2, 3600);
219 fprintf(fp,
" <RightAscension>%s</RightAscension>\n", SexaString);
220 fs_sexa(SexaString, (*Itr).Declination, 2, 3600);
221 fprintf(fp,
" <Declination>%s</Declination>\n", SexaString);
222 fprintf(fp,
" <TelescopeDirectionVectorX>%lf</TelescopeDirectionVectorX>\n",
223 (*Itr).TelescopeDirection.x);
224 fprintf(fp,
" <TelescopeDirectionVectorY>%lf</TelescopeDirectionVectorY>\n",
225 (*Itr).TelescopeDirection.y);
226 fprintf(fp,
" <TelescopeDirectionVectorZ>%lf</TelescopeDirectionVectorZ>\n",
227 (*Itr).TelescopeDirection.z);
229 fprintf(fp,
" </DatabaseEntry>\n");
231 fprintf(fp,
" </DatabaseEntries>\n");
233 fprintf(fp,
"</INDIAlignmentDatabase>\n");
242 DatabaseReferencePosition.
latitude = Latitude;
243 DatabaseReferencePosition.
longitude = Longitude;
244 DatabaseReferencePositionIsValid =
true;
249 LoadDatabaseCallback = CallbackPointer;
250 LoadDatabaseCallbackThisPointer = ThisPointer;
bool SaveDatabase(const char *DeviceName)
Save the database to persistent storage.
void SetDatabaseReferencePosition(double Latitude, double Longitude)
Set the database reference position.
void SetLoadDatabaseCallback(LoadDatabaseCallbackPointer_t CallbackPointer, void *ThisPointer)
Set the function to be called when the database is loaded or reloaded.
bool CheckForDuplicateSyncPoint(const AlignmentDatabaseEntry &CandidateEntry, double Tolerance=0.1) const
Check if a entry already exists in the database.
InMemoryDatabase()
Default constructor.
void RemoveSyncPoint(const AlignmentDatabaseEntry &CandidateEntry, double Tolerance=0.1)
Remove a sync point that falls within the tolerance of a candidate point.
bool GetDatabaseReferencePosition(IGeographicCoordinates &Position)
Get the database reference position.
bool LoadDatabase(const char *DeviceName)
Load the database from persistent storage.
int f_scansexa(const char *str0, double *dp)
convert sexagesimal string str AxBxC to double. x can be anything non-numeric. Any missing A,...
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[].
Implementations for common driver routines.
XMLAtt * findXMLAtt(XMLEle *ep, const char *name)
Find an XML attribute within an XML element.
LilXML * newLilXML()
Create a new lilxml parser.
char * pcdataXMLEle(XMLEle *ep)
Return the pcdata of an XML element.
char * tagXMLEle(XMLEle *ep)
Return the tag of an XML element.
XMLEle * readXMLFile(FILE *fp, LilXML *lp, char ynot[])
Handy wrapper to read one xml file.
XMLEle * nextXMLEle(XMLEle *ep, int init)
Iterate an XML element for a list of nesetd XML elements.
void delXMLEle(XMLEle *ep)
delXMLEle Delete XML element.
void delLilXML(LilXML *lp)
Delete a lilxml parser.
XMLEle * findXMLEle(XMLEle *ep, const char *tag)
Find an XML element within an XML element.
char * valuXMLAtt(XMLAtt *ap)
Return the value of an XML attribute.
Namespace to encapsulate INDI client, drivers, and mediator classes.
int mkdir(const char *path, mode_t mode)
Entry in the in memory alignment database.
double RightAscension
Right ascension in decimal hours. N.B. libnova works in decimal degrees so conversion is always neede...
double ObservationJulianDate
TelescopeDirectionVector TelescopeDirection
Normalised vector giving telescope pointing direction. This is referred to elsewhere as the "apparent...
double Declination
Declination in decimal degrees.