Add INDI rotator backend

This backend lets Hamlib control an astronomical (telescope) rotator through an
INDI (https://indilib.org/) server.
pull/442/head
Nonoo 2020-11-15 12:46:35 +01:00
rodzic 801e16ac97
commit 8ba011eaf7
16 zmienionych plików z 941 dodań i 1 usunięć

Wyświetl plik

@ -265,6 +265,10 @@ C: Chris Bryant, G3WIE
M: Øystein Hårberg, LA7LKA
[indi]
M: Norbert Varga, HA2NON
[Frontend]
M: Stephane Fillod, F8CFE
@ -362,3 +366,4 @@ Alexander Sack <pisymbol (at) gmail.com>
Nirgal Vourgère <contact_hamlib (at) nirgal.com>
Andrew Errington <a.errington (at) lancaster.ac.uk>
Kārlis Millers YL3ALK <yl3alk (at) lrg.lv>
Norbert Varga HA2NON <nonoo (at) nonoo.hu>

Wyświetl plik

@ -287,6 +287,7 @@ are:
--with-tcl-binding build Tcl binding and demo [default=no]
--with-tcl=PATH directory containing tcl configuration (tclConfig.sh)
--with-lua-binding build lua binding and demo [default=no]
--without-indi disable INDI rotator support [default=no]
Optional features that may require specialized hardware are:

Wyświetl plik

@ -363,6 +363,46 @@ AS_IF([test x"$ax_cv_lib_readline" = "xno"], [
cf_with_readline_support=no
])
dnl Check if INDI support in rigctl/rotctl is wanted
AC_MSG_CHECKING([whether to use INDI in rigctl/rotctl])
AC_ARG_WITH([indi],
[AS_HELP_STRING([--without-indi],
[disable INDI in rigctl/rotctl @<:@default=yes@:>@])],
[cf_with_indi_support=no],
[cf_with_indi_support=yes]
)
AS_IF([test x"$cf_with_indi_support" != "xno"], [
# INDI support needs a C++ compiler, tested for presence above.
AS_IF([test x"${cf_with_cxx}" != "xyes"], [
AC_MSG_WARN([INDI support needs a C++ compiler.])
cf_with_indi_support=no
])
])
AS_IF([test x"$cf_with_indi_support" != "xno"], [
# macros/ax_lib_nova.m4
AX_LIB_NOVA
AS_IF([test x"$ax_cv_lib_nova" = "xno"], [
AC_MSG_WARN([libnova support not found, required by INDI.])
cf_with_indi_support=no
])
AS_IF([test x"$ax_cv_lib_nova" != "xno"], [
# macros/ax_lib_indi.m4
AX_LIB_INDI
AS_IF([test x"$ax_cv_lib_indi" = "xno"], [
AC_MSG_WARN([INDI support not found.])
cf_with_indi_support=no
])
AS_IF([test x"$cf_with_indi_support" != "xno"], [
ROT_BACKEND_LIST="$ROT_BACKEND_LIST rotators/indi"
])
])
])
dnl Check if libgd-dev is installed, so we can enable rigmatrix
AC_MSG_CHECKING([whether to build HTML rig feature matrix])
@ -801,6 +841,7 @@ rotators/rotorez/Makefile
rotators/sartek/Makefile
rotators/spid/Makefile
rotators/ts7400/Makefile
rotators/indi/Makefile
rigs/adat/Makefile
rigs/alinco/Makefile
rigs/aor/Makefile
@ -857,6 +898,7 @@ echo \
With Lua binding ${cf_with_lua_binding}
With rigmem XML support ${cf_with_xml_support}
With Readline support ${cf_with_readline_support}
With INDI support ${cf_with_indi_support}
Enable HTML rig feature matrix ${cf_enable_html_matrix}
Enable WinRadio ${cf_with_winradio}

Wyświetl plik

@ -455,6 +455,20 @@
#define ROT_MODEL_IOPTRON ROT_MAKE_MODEL(ROT_IOPTRON, 1)
/**
+ * \def ROT_MODEL_INDI
+ * \brief A macro that returns the model number of the INDI backend.
+ *
+ * The INDI backend can be used with rotators that support, among other, the
+ * INDI interface.
+ */
//! @cond Doxygen_Suppress
#define ROT_INDI 20
#define ROT_BACKEND_INDI "indi"
//! @endcond
#define ROT_MODEL_INDI ROT_MAKE_MODEL(ROT_INDI, 1)
/**

Wyświetl plik

@ -6,6 +6,8 @@ MACROS = \
ax_pkg_swig.m4 \
ax_pthread.m4 \
ax_python_devel.m4 \
ax_lib_indi.m4 \
ax_lib_nova.m4 \
gr_doxygen.m4 \
gr_pwin32.m4 \
hl_getaddrinfo.m4 \

Wyświetl plik

@ -0,0 +1,23 @@
AU_ALIAS([VL_LIB_INDI], [AX_LIB_INDI])
AC_DEFUN([AX_LIB_INDI], [
AC_CACHE_CHECK([for INDI library],
ax_cv_lib_indi, [
AC_LANG_PUSH(C++)
AC_CHECK_HEADER(libindi/baseclient.h, ax_cv_lib_indi="-lindiclient -lstdc++ -lz")
AC_LANG_POP()
if test -z "$ax_cv_lib_indi"; then
ax_cv_lib_indi="no"
fi
])
if test "$ax_cv_lib_indi" != "no"; then
ORIG_LIBS="$LIBS"
LIBS="$LIBS $ax_cv_lib_indi"
AC_DEFINE(HAVE_LIBINDI, 1,
[Define if you have an INDI compatible library])
LIBS="$ORIG_LIBS"
INDI_LIBS="$ax_cv_lib_indi"
AC_SUBST([INDI_LIBS])
fi
])

Wyświetl plik

@ -0,0 +1,23 @@
AU_ALIAS([VL_LIB_NOVA], [AX_LIB_NOVA])
AC_DEFUN([AX_LIB_NOVA], [
AC_CACHE_CHECK([for nova library],
ax_cv_lib_nova, [
AC_LANG_PUSH(C++)
AC_CHECK_HEADER(libnova/libnova.h, ax_cv_lib_nova="-lnova -lstdc++ -lz")
AC_LANG_POP()
if test -z "$ax_cv_lib_nova"; then
ax_cv_lib_nova="no"
fi
])
if test "$ax_cv_lib_nova" != "no"; then
ORIG_LIBS="$LIBS"
LIBS="$LIBS $ax_cv_lib_nova"
AC_DEFINE(HAVE_LIBNOVA, 1,
[Define if you have a nova compatible library])
LIBS="$ORIG_LIBS"
NOVA_LIBS="$ax_cv_lib_nova"
AC_SUBST([NOVA_LIBS])
fi
])

Wyświetl plik

@ -0,0 +1,12 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := indi.c indi_wrapper.cpp
LOCAL_MODULE := indi
LOCAL_CFLAGS := -DHAVE_CONFIG_H
LOCAL_C_INCLUDES := android include src
LOCAL_LDLIBS := -lhamlib -Lobj/local/armeabi
include $(BUILD_STATIC_LIBRARY)

Wyświetl plik

@ -0,0 +1,6 @@
noinst_LTLIBRARIES = libhamlib-indi.la
libhamlib_indi_la_SOURCES = indi.c indi_wrapper.cpp indi_wrapper.hpp indi_wrapper.h
libhamlib_indi_la_LDFLAGS = $(INDI_LIBS)
EXTRA_DIST = Android.mk

Wyświetl plik

@ -0,0 +1,8 @@
INDI rotator backend
====================
This backend lets Hamlib control an astronomical (telescope) rotator through an
[INDI](https://indilib.org/) server.
The easiest way to set up an INDI server is to use [EKOS](https://www.indilib.org/about/ekos.html),
which is available in [KStars](https://edu.kde.org/kstars/).

Wyświetl plik

@ -0,0 +1,70 @@
/*
* Hamlib Rotator backend - INDI integration
* Copyright (c) 2020 by Norbert Varga HA2NON <nonoo@nonoo.hu>
*
*
* 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
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "indi_wrapper.h"
#include <hamlib/rotator.h>
#include <register.h>
const struct rot_caps indi_rot_caps =
{
ROT_MODEL(ROT_MODEL_INDI),
.model_name = "INDI",
.mfg_name = "INDI",
.version = "0.1",
.copyright = "LGPL",
.status = RIG_STATUS_ALPHA,
.rot_type = ROT_TYPE_OTHER,
.port_type = RIG_PORT_NONE,
.write_delay = 0,
.post_write_delay = 0,
.timeout = 200,
.retry = 3,
.min_az = 0,
.max_az = 360,
.min_el = -90,
.max_el = 90,
.set_position = indi_wrapper_set_position,
.get_position = indi_wrapper_get_position,
.stop = indi_wrapper_stop,
.park = indi_wrapper_park,
.move = indi_wrapper_move,
.get_info = indi_wrapper_get_info,
.rot_open = indi_wrapper_open,
.rot_close = indi_wrapper_close,
};
/* ************************************************************************* */
DECLARE_INITROT_BACKEND(indi)
{
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
rot_register(&indi_rot_caps);
return RIG_OK;
}

Wyświetl plik

@ -0,0 +1,621 @@
/*
* Hamlib Rotator backend - INDI integration
* Copyright (c) 2020 by Norbert Varga HA2NON <nonoo@nonoo.hu>
*
*
* 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 "indi_wrapper.hpp"
#include <math.h>
#include <limits.h>
#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
static std::unique_ptr<RotINDIClient> indi_wrapper_client(new RotINDIClient());
int RotINDIClient::setSpeed(int speedPercent)
{
if (!mTelescope || !mTelescope->isConnected())
{
rig_debug(RIG_DEBUG_ERR, "indi: telescope not connected\n");
return -RIG_EIO;
}
ISwitchVectorProperty *switchVector =
mTelescope->getSwitch("TELESCOPE_SLEW_RATE");
if (!switchVector)
{
rig_debug(RIG_DEBUG_ERR,
"indi: unable to find telescope or TELESCOPE_SLEW_RATE switch\n");
return -RIG_EPROTO;
}
if (speedPercent < 0)
{
speedPercent = 0;
}
if (speedPercent > 100)
{
speedPercent = 100;
}
int speed = DIV_ROUND_UP(speedPercent, 10);
for (int i = 1; i <= 10; i++)
{
char switchName[4];
snprintf(switchName, sizeof(switchName), "%ux", i);
ISwitch *slewrate = IUFindSwitch(switchVector, switchName);
if (slewrate)
{
if (speed == i)
{
rig_debug(RIG_DEBUG_VERBOSE, "indi: setting speed %s\n", switchName);
slewrate->s = ISS_ON;
}
else
{
slewrate->s = ISS_OFF;
}
}
else
{
rig_debug(RIG_DEBUG_ERR, "indi: unable to find switch member %s\n", switchName);
return -RIG_EPROTO;
}
}
sendNewSwitch(switchVector);
return RIG_OK;
}
int RotINDIClient::move(int direction, int speedPercent)
{
if (!mTelescope || !mTelescope->isConnected())
{
rig_debug(RIG_DEBUG_ERR, "indi: telescope not connected\n");
return -RIG_EIO;
}
int err = setSpeed(speedPercent);
if (err != RIG_OK)
{
return err;
}
ISwitchVectorProperty *switchVector =
mTelescope->getSwitch("TELESCOPE_MOTION_NS");
if (!switchVector)
{
rig_debug(RIG_DEBUG_ERR,
"indi: unable to find telescope or TELESCOPE_MOTION_NS switch\n");
return -RIG_EPROTO;
}
ISwitch *motion_north = IUFindSwitch(switchVector, "MOTION_NORTH");
if (!motion_north)
{
rig_debug(RIG_DEBUG_ERR, "indi: unable to find switch member MOTION_NORTH\n");
return -RIG_EPROTO;
}
if (direction & ROT_MOVE_UP)
{
rig_debug(RIG_DEBUG_VERBOSE, "indi: moving up\n");
motion_north->s = ISS_ON;
}
else
{
motion_north->s = ISS_OFF;
}
ISwitch *motion_south = IUFindSwitch(switchVector, "MOTION_SOUTH");
if (!motion_south)
{
rig_debug(RIG_DEBUG_ERR, "indi: unable to find switch member MOTION_SOUTH\n");
return -RIG_EPROTO;
}
if (direction & ROT_MOVE_DOWN)
{
rig_debug(RIG_DEBUG_VERBOSE, "indi: moving down\n");
motion_south->s = ISS_ON;
}
else
{
motion_south->s = ISS_OFF;
}
sendNewSwitch(switchVector);
switchVector = mTelescope->getSwitch("TELESCOPE_MOTION_WE");
if (!switchVector)
{
rig_debug(RIG_DEBUG_ERR,
"indi: unable to find telescope or TELESCOPE_MOTION_WE switch\n");
return -RIG_EPROTO;
}
ISwitch *motion_west = IUFindSwitch(switchVector, "MOTION_WEST");
if (!motion_west)
{
rig_debug(RIG_DEBUG_ERR, "indi: unable to find switch member MOTION_WEST\n");
return -RIG_EPROTO;
}
if (direction & ROT_MOVE_LEFT)
{
rig_debug(RIG_DEBUG_VERBOSE, "indi: moving left\n");
motion_west->s = ISS_ON;
}
else
{
motion_west->s = ISS_OFF;
}
ISwitch *motion_east = IUFindSwitch(switchVector, "MOTION_EAST");
if (!motion_east)
{
rig_debug(RIG_DEBUG_ERR, "indi: unable to find switch member MOTION_RIGHT\n");
return -RIG_EPROTO;
}
if (direction & ROT_MOVE_RIGHT)
{
rig_debug(RIG_DEBUG_VERBOSE, "indi: moving right\n");
motion_east->s = ISS_ON;
}
else
{
motion_east->s = ISS_OFF;
}
sendNewSwitch(switchVector);
return RIG_OK;
}
int RotINDIClient::stop()
{
if (!mTelescope || !mTelescope->isConnected())
{
rig_debug(RIG_DEBUG_ERR, "indi: telescope not connected\n");
return -RIG_EIO;
}
ISwitchVectorProperty *switchVector =
mTelescope->getSwitch("TELESCOPE_ABORT_MOTION");
if (!switchVector)
{
rig_debug(RIG_DEBUG_ERR,
"indi: unable to find telescope or TELESCOPE_ABORT_MOTION switch\n");
return -RIG_EPROTO;
}
ISwitch *sw = IUFindSwitch(switchVector, "ABORT");
if (!sw)
{
rig_debug(RIG_DEBUG_ERR, "indi: unable to find switch member ABORT_MOTION\n");
return -RIG_EPROTO;
}
sw->s = ISS_ON;
sendNewSwitch(switchVector);
return RIG_OK;
}
int RotINDIClient::park()
{
if (!mTelescope)
{
return -RIG_EIO;
}
if (!mTelescope->isConnected())
{
rig_debug(RIG_DEBUG_ERR, "indi: telescope not connected\n");
return -RIG_EIO;
}
ISwitchVectorProperty *switchVector = mTelescope->getSwitch("TELESCOPE_PARK");
if (!switchVector)
{
rig_debug(RIG_DEBUG_ERR,
"indi: unable to find telescope or TELESCOPE_PARK switch\n");
return -RIG_EPROTO;
}
ISwitch *unpark = IUFindSwitch(switchVector, "UNPARK");
if (!unpark)
{
rig_debug(RIG_DEBUG_ERR, "indi: unable to find switch member UNPARK\n");
return -RIG_EPROTO;
}
unpark->s = ISS_OFF;
ISwitch *park = IUFindSwitch(switchVector, "PARK");
if (!park)
{
rig_debug(RIG_DEBUG_ERR, "indi: unable to find switch member PARK\n");
return -RIG_EPROTO;
}
park->s = ISS_ON;
sendNewSwitch(switchVector);
return RIG_OK;
}
int RotINDIClient::unPark()
{
if (!mTelescope || !mTelescope->isConnected())
{
rig_debug(RIG_DEBUG_ERR, "indi: telescope not connected\n");
return -RIG_EIO;
}
ISwitchVectorProperty *switchVector = mTelescope->getSwitch("TELESCOPE_PARK");
if (!switchVector)
{
rig_debug(RIG_DEBUG_ERR,
"indi: unable to find telescope or TELESCOPE_PARK switch\n");
return -RIG_EPROTO;
}
ISwitch *park = IUFindSwitch(switchVector, "PARK");
if (!park)
{
rig_debug(RIG_DEBUG_ERR, "indi: unable to find switch member PARK\n");
return -RIG_EPROTO;
}
park->s = ISS_OFF;
ISwitch *unpark = IUFindSwitch(switchVector, "UNPARK");
if (!unpark)
{
rig_debug(RIG_DEBUG_ERR, "indi: unable to find switch member UNPARK\n");
return -RIG_EPROTO;
}
unpark->s = ISS_ON;
sendNewSwitch(switchVector);
return RIG_OK;
}
void RotINDIClient::position(azimuth_t *az, elevation_t *el)
{
*az = mAz;
*el = mEl;
}
double RotINDIClient::getPositionDiffBetween(double deg1, double deg2)
{
return fabs(deg1 - deg2);
}
double RotINDIClient::getPositionDiffOutside(double deg1, double deg2,
double minDeg, double maxDeg)
{
if (deg1 < deg2)
{
return getPositionDiffBetween(minDeg, deg1) + getPositionDiffBetween(deg2,
maxDeg);
}
return getPositionDiffBetween(minDeg, deg2) + getPositionDiffBetween(deg1,
maxDeg);
}
double RotINDIClient::getPositionDiff(double deg1, double deg2, double minDeg,
double maxDeg)
{
double between = getPositionDiffBetween(deg1, deg2);
double outside = getPositionDiffOutside(deg1, deg2, minDeg, maxDeg);
if (between < outside)
{
return between;
}
return outside;
}
int RotINDIClient::setPosition(azimuth_t az, elevation_t el)
{
if (!mTelescope || !mTelescope->isConnected())
{
rig_debug(RIG_DEBUG_ERR, "indi: telescope not connected\n");
return -RIG_EIO;
}
if (fabs(mDstAz - az) < 0.001 && fabs(mDstEl - el) < 0.001)
{
rig_debug(RIG_DEBUG_VERBOSE,
"indi: ignoring new position, already approaching\n");
return RIG_OK;
}
// Each coordinate set command stops and restarts the rotator, so we have to avoid unnecessary
// set calls by defining a range of distance from the new az/el coords which we ignore until
// we are closer to the new az/el coords than this value.
const int quickJumpRangeDegrees = 10;
double currDstNewDstAzDiff = getPositionDiff(mDstAz, az, 0, 360);
double currDstNewDstElDiff = getPositionDiff(mDstEl, el, -90, 90);
double currDstNewDstDistance = sqrt(pow(currDstNewDstAzDiff,
2) + pow(currDstNewDstElDiff, 2));
double currPosNewDstAzDiff = getPositionDiff(mAz, az, 0, 360);
double currPosNewDstElDiff = getPositionDiff(mEl, el, -90, 90);
double currPosNewDstDistance = sqrt(pow(currPosNewDstAzDiff,
2) + pow(currPosNewDstElDiff, 2));
if (currDstNewDstDistance < quickJumpRangeDegrees
&& currPosNewDstDistance > quickJumpRangeDegrees)
{
rig_debug(RIG_DEBUG_VERBOSE,
"indi: ignoring new position, approaching quickly, newDst/currDst distance: %f newDst/currPos distance: %f\n",
currDstNewDstDistance, currPosNewDstDistance);
return RIG_OK;
}
rig_debug(RIG_DEBUG_VERBOSE, "indi: setting position to az: %f el: %f\n", az,
el);
mDstAz = az;
mDstEl = el;
ISwitchVectorProperty *switchVector = mTelescope->getSwitch("ON_COORD_SET");
if (!switchVector)
{
rig_debug(RIG_DEBUG_ERR,
"indi: unable to find telescope or ON_COORD_SET switch\n");
return -RIG_EPROTO;
}
ISwitch *slew = IUFindSwitch(switchVector, "SLEW");
if (!slew)
{
rig_debug(RIG_DEBUG_ERR, "indi: unable to find switch member SLEW\n");
return -RIG_EPROTO;
}
slew->s = ISS_OFF;
ISwitch *track = IUFindSwitch(switchVector, "TRACK");
if (!track)
{
rig_debug(RIG_DEBUG_ERR, "indi: unable to find switch member TRACK\n");
return -RIG_EPROTO;
}
track->s = ISS_ON;
ISwitch *sync = IUFindSwitch(switchVector, "SYNC");
if (!sync)
{
rig_debug(RIG_DEBUG_ERR, "indi: unable to find switch member SYNC\n");
return -RIG_EPROTO;
}
sync->s = ISS_OFF;
sendNewSwitch(switchVector);
INumberVectorProperty *property = mTelescope->getNumber("HORIZONTAL_COORD");
if (!property)
{
rig_debug(RIG_DEBUG_ERR,
"indi: unable to find telescope or HORIZONTAL_COORD property\n");
return -RIG_EPROTO;
}
property->np[0].value = az;
property->np[1].value = el;
sendNewNumber(property);
return RIG_OK;
}
void RotINDIClient::removeDevice(INDI::BaseDevice *dp) {}
void RotINDIClient::newProperty(INDI::Property *property)
{
std::string name(property->getName());
if (!mTelescope && name == "TELESCOPE_INFO")
{
mTelescope = property->getBaseDevice();
rig_debug(RIG_DEBUG_VERBOSE, "indi: using device %s\n",
mTelescope->getDeviceName());
watchDevice(mTelescope->getDeviceName());
if (!mTelescope->isConnected())
{
connectDevice(mTelescope->getDeviceName());
}
mDstAz = INT_MAX;
mDstEl = INT_MAX;
}
if (name == "HORIZONTAL_COORD")
{
mAz = property->getNumber()->np[0].value;
mEl = property->getNumber()->np[1].value;
}
}
void RotINDIClient::removeProperty(INDI::Property *property) {}
void RotINDIClient::newBLOB(IBLOB *bp) {}
void RotINDIClient::newSwitch(ISwitchVectorProperty *svp) {}
void RotINDIClient::newNumber(INumberVectorProperty *nvp)
{
std::string name(nvp->name);
if (name == "HORIZONTAL_COORD")
{
mAz = nvp->np[0].value;
mEl = nvp->np[1].value;
}
}
void RotINDIClient::newMessage(INDI::BaseDevice *dp, int messageID) {}
void RotINDIClient::newText(ITextVectorProperty *tvp) {}
void RotINDIClient::newLight(ILightVectorProperty *lvp) {}
void RotINDIClient::newDevice(INDI::BaseDevice *dp) {}
void RotINDIClient::serverConnected()
{
rig_debug(RIG_DEBUG_VERBOSE, "indi: server connected\n");
}
void RotINDIClient::serverDisconnected(int exit_code)
{
rig_debug(RIG_DEBUG_VERBOSE, "indi: server disconnected\n");
}
const char *RotINDIClient::getInfo(void)
{
static char info[128];
if (mTelescope && mTelescope->isConnected())
{
snprintf(info, sizeof(info), "using INDI device %s",
mTelescope->getDeviceName());
return info;
}
return "no INDI device connected";
}
void RotINDIClient::close(void)
{
if (mTelescope && mTelescope->isConnected())
{
disconnectDevice(mTelescope->getDeviceName());
}
disconnectServer();
}
extern "C" int indi_wrapper_set_position(ROT *rot, azimuth_t az,
elevation_t el)
{
int res;
rig_debug(RIG_DEBUG_TRACE, "%s called: az=%f el=%f\n", __func__, az, el);
res = indi_wrapper_client->unPark();
if (res != RIG_OK)
{
return res;
}
return indi_wrapper_client->setPosition(az, el);
}
extern "C" int indi_wrapper_get_position(ROT *rot, azimuth_t *az,
elevation_t *el)
{
rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__);
indi_wrapper_client->position(az, el);
return RIG_OK;
}
extern "C" int indi_wrapper_stop(ROT *rot)
{
rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__);
return indi_wrapper_client->stop();
}
extern "C" int indi_wrapper_park(ROT *rot)
{
rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__);
return indi_wrapper_client->park();
}
extern "C" int indi_wrapper_move(ROT *rot, int direction, int speed)
{
rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__);
return indi_wrapper_client->move(direction, speed);
}
extern "C" const char *indi_wrapper_get_info(ROT *rot)
{
rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__);
return indi_wrapper_client->getInfo();
}
extern "C" int indi_wrapper_open(ROT *rot)
{
rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__);
indi_wrapper_client->setServer("localhost", 7624);
if (!indi_wrapper_client->connectServer())
{
rig_debug(RIG_DEBUG_ERR, "indi: server refused connection\n");
return -RIG_EPROTO;
}
return RIG_OK;
}
extern "C" int indi_wrapper_close(ROT *rot)
{
rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__);
indi_wrapper_client->close();
return RIG_OK;
}

Wyświetl plik

@ -0,0 +1,36 @@
/*
* Hamlib Rotator backend - INDI integration
* Copyright (c) 2020 by Norbert Varga HA2NON <nonoo@nonoo.hu>
*
*
* 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
*
*/
#ifndef _INDI_WRAPPER_H
#define _INDI_WRAPPER_H 1
#include <hamlib/rotator.h>
int indi_wrapper_set_position(ROT *rot, azimuth_t az, elevation_t el);
int indi_wrapper_get_position(ROT *rot, azimuth_t *az, elevation_t *el);
int indi_wrapper_stop(ROT *rot);
int indi_wrapper_park(ROT *rot);
int indi_wrapper_move(ROT *rot, int direction, int speed);
const char *indi_wrapper_get_info(ROT *rot);
int indi_wrapper_open(ROT *rot);
int indi_wrapper_close(ROT *rot);
#endif // _INDI_WRAPPER_H

Wyświetl plik

@ -0,0 +1,71 @@
/*
* Hamlib Rotator backend - INDI integration
* Copyright (c) 2020 by Norbert Varga HA2NON <nonoo@nonoo.hu>
*
*
* 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
*
*/
#ifndef _INDI_WRAPPER_HPP
#define _INDI_WRAPPER_HPP 1
#include <libindi/basedevice.h>
#include <libindi/baseclient.h>
#include <hamlib/rotator.h>
class RotINDIClient : public INDI::BaseClient
{
public:
int setSpeed(int speedPercent);
int move(int direction, int speedPercent);
int stop();
int park();
int unPark();
void position(azimuth_t *az, elevation_t *el);
int setPosition(azimuth_t az, elevation_t el);
const char *getInfo();
void close(void);
protected:
virtual void newDevice(INDI::BaseDevice *dp);
virtual void removeDevice(INDI::BaseDevice *dp);
virtual void newProperty(INDI::Property *property);
virtual void removeProperty(INDI::Property *property);
virtual void newBLOB(IBLOB *bp);
virtual void newSwitch(ISwitchVectorProperty *svp);
virtual void newNumber(INumberVectorProperty *nvp);
virtual void newMessage(INDI::BaseDevice *dp, int messageID);
virtual void newText(ITextVectorProperty *tvp);
virtual void newLight(ILightVectorProperty *lvp);
virtual void serverConnected();
virtual void serverDisconnected(int exit_code);
private:
double getPositionDiffBetween(double deg1, double deg2);
double getPositionDiffOutside(double deg1, double deg2, double minDeg, double maxDeg);
double getPositionDiff(double deg1, double deg2, double minDeg, double maxDeg);
INDI::BaseDevice *mTelescope;
azimuth_t mDstAz;
elevation_t mDstEl;
azimuth_t mAz;
elevation_t mEl;
};
#endif // _INDI_WRAPPER_HPP

Wyświetl plik

@ -12,7 +12,7 @@ libhamlib_la_SOURCES = $(RIGSRC)
libhamlib_la_LDFLAGS = $(WINLDFLAGS) $(OSXLDFLAGS) -no-undefined -version-info $(ABI_VERSION):$(ABI_REVISION):$(ABI_AGE)
libhamlib_la_LIBADD = $(top_builddir)/lib/libmisc.la \
$(BACKENDEPS) $(RIG_BACKENDEPS) $(ROT_BACKENDEPS) $(AMP_BACKENDEPS) $(NET_LIBS) $(MATH_LIBS) $(LIBUSB_LIBS)
$(BACKENDEPS) $(RIG_BACKENDEPS) $(ROT_BACKENDEPS) $(AMP_BACKENDEPS) $(NET_LIBS) $(MATH_LIBS) $(LIBUSB_LIBS) $(INDI_LIBS)
libhamlib_la_DEPENDENCIES = $(top_builddir)/lib/libmisc.la $(BACKENDEPS) $(RIG_BACKENDEPS) $(ROT_BACKENDEPS) $(AMP_BACKENDEPS)

Wyświetl plik

@ -84,6 +84,9 @@ DEFINE_INITROT_BACKEND(cnctrk);
DEFINE_INITROT_BACKEND(prosistel);
DEFINE_INITROT_BACKEND(meade);
DEFINE_INITROT_BACKEND(ioptron);
#if HAVE_LIBINDI
DEFINE_INITROT_BACKEND(indi);
#endif
//! @endcond
/**
@ -123,6 +126,9 @@ static struct
{ ROT_PROSISTEL, ROT_BACKEND_PROSISTEL, ROT_FUNCNAMA(prosistel) },
{ ROT_MEADE, ROT_BACKEND_MEADE, ROT_FUNCNAMA(meade) },
{ ROT_IOPTRON, ROT_BACKEND_IOPTRON, ROT_FUNCNAMA(ioptron) },
#if HAVE_LIBINDI
{ ROT_INDI, ROT_BACKEND_INDI, ROT_FUNCNAMA(indi) },
#endif
{ 0, NULL }, /* end */
};