1 /* 2 * Stellarium Telescope Control Plug-in 3 * 4 * Copyright (C) 2006 Johannes Gajdosik 5 * Copyright (C) 2009 Bogdan Marinov 6 * 7 * This module was originally written by Johannes Gajdosik in 2006 8 * as a core module of Stellarium. In 2009 it was significantly extended with 9 * GUI features and later split as an external plug-in module by Bogdan Marinov. 10 * 11 * This program is free software; you can redistribute it and/or 12 * modify it under the terms of the GNU General Public License 13 * as published by the Free Software Foundation; either version 2 14 * of the License, or (at your option) any later version. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with this program; if not, write to the Free Software 23 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. 24 */ 25 26 #ifndef TELESCOPECLIENT_HPP 27 #define TELESCOPECLIENT_HPP 28 29 #include <QHostAddress> 30 #include <QHostInfo> 31 #include <QList> 32 #include <QString> 33 #include <QTcpSocket> 34 #include <QObject> 35 36 #include "StelApp.hpp" 37 #include "StelObject.hpp" 38 #include "common/InterpolatedPosition.hpp" 39 40 class StelCore; 41 42 qint64 getNow(void); 43 44 enum Equinox { 45 EquinoxJ2000, 46 EquinoxJNow 47 }; 48 49 //! An abstract base class that should never be used directly, only inherited. 50 //! This class used to be called Telescope, but it has been renamed 51 //! to TelescopeClient in order to resolve a compiler/linker conflict 52 //! with the identically named Telescope class in Stellarium's main code. 53 class TelescopeClient : public QObject, public StelObject 54 { 55 Q_OBJECT 56 public: 57 static const QString TELESCOPECLIENT_TYPE; 58 static TelescopeClient *create(const QString &url); ~TelescopeClient(void)59 virtual ~TelescopeClient(void) Q_DECL_OVERRIDE {} 60 61 // Method inherited from StelObject getEnglishName(void) const62 QString getEnglishName(void) const Q_DECL_OVERRIDE {return name;} getNameI18n(void) const63 QString getNameI18n(void) const Q_DECL_OVERRIDE {return nameI18n;} getInfoColor(void) const64 Vec3f getInfoColor(void) const Q_DECL_OVERRIDE 65 { 66 return Vec3f(1.f, 1.f, 1.f); 67 } 68 //! TelescopeClient supports the following InfoStringGroup flags: 69 //! - Name 70 //! - RaDecJ2000 71 //! - RaDec 72 //! - PlainText 73 //! @param core the StelCore object 74 //! @param flags a set of InfoStringGroup items to include in the return value. 75 //! @return a QString containing an HMTL encoded description of the Telescope. 76 QString getInfoString(const StelCore* core, const InfoStringGroup& flags) const Q_DECL_OVERRIDE; getType(void) const77 QString getType(void) const Q_DECL_OVERRIDE {return TELESCOPECLIENT_TYPE;} getID() const78 QString getID() const Q_DECL_OVERRIDE {return name;} getAngularSize(const StelCore *) const79 virtual double getAngularSize(const StelCore*) const Q_DECL_OVERRIDE {Q_ASSERT(0); return 0;} // TODO 80 81 // Methods specific to telescope 82 virtual void telescopeGoto(const Vec3d &j2000Pos, StelObjectP selectObject) = 0; 83 virtual void telescopeSync(const Vec3d &j2000Pos, StelObjectP selectObject) = 0; telescopeAbortSlew()84 virtual void telescopeAbortSlew() {} 85 86 //! 87 //! \brief move 88 //! \param angle [0,360) 89 //! \param speed [0,1] 90 //! 91 virtual void move(double angle, double speed); 92 virtual bool isConnected(void) const = 0; 93 virtual bool hasKnownPosition(void) const = 0; addOcular(double fov)94 void addOcular(double fov) {if (fov>=0.0) oculars.push_back(fov);} getOculars(void) const95 const QList<double> &getOculars(void) const {return oculars;} 96 prepareCommunication()97 virtual bool prepareCommunication() {return false;} performCommunication()98 virtual void performCommunication() {} 99 createControlWidget(QSharedPointer<TelescopeClient> telescope,QWidget * parent=Q_NULLPTR) const100 virtual QWidget* createControlWidget(QSharedPointer<TelescopeClient> telescope, QWidget* parent = Q_NULLPTR) const { Q_UNUSED(telescope) Q_UNUSED(parent) return Q_NULLPTR; } 101 102 protected: 103 TelescopeClient(const QString &name); 104 QString nameI18n; 105 const QString name; 106 getTelescopeInfoString(const StelCore * core,const InfoStringGroup & flags) const107 virtual QString getTelescopeInfoString(const StelCore* core, const InfoStringGroup& flags) const 108 { 109 Q_UNUSED(core) 110 Q_UNUSED(flags) 111 return QString(); 112 } 113 private: isInitialized(void) const114 virtual bool isInitialized(void) const {return true;} getSelectPriority(const StelCore * core) const115 float getSelectPriority(const StelCore* core) const Q_DECL_OVERRIDE {Q_UNUSED(core); return -10.f;} 116 private: 117 QList<double> oculars; // fov of the oculars 118 }; 119 120 //! Example Telescope class. A physical telescope does not exist. 121 //! This can be used as a starting point for implementing a derived 122 //! Telescope class. 123 //! This class used to be called TelescopeDummy, but it had to be renamed 124 //! in order to resolve a compiler/linker conflict with the identically named 125 //! TelescopeDummy class in Stellarium's main code. 126 class TelescopeClientDummy : public TelescopeClient 127 { 128 public: TelescopeClientDummy(const QString & name,const QString &)129 TelescopeClientDummy(const QString &name, const QString &) : TelescopeClient(name) 130 { 131 desired_pos[0] = XYZ[0] = 1.0; 132 desired_pos[1] = XYZ[1] = 0.0; 133 desired_pos[2] = XYZ[2] = 0.0; 134 } ~TelescopeClientDummy(void)135 ~TelescopeClientDummy(void) Q_DECL_OVERRIDE {} isConnected(void) const136 bool isConnected(void) const Q_DECL_OVERRIDE 137 { 138 return true; 139 } prepareCommunication(void)140 bool prepareCommunication(void) Q_DECL_OVERRIDE 141 { 142 XYZ = XYZ * 31.0 + desired_pos; 143 const double lq = XYZ.lengthSquared(); 144 if (lq > 0.0) 145 XYZ *= (1.0/std::sqrt(lq)); 146 else 147 XYZ = desired_pos; 148 return true; 149 } telescopeGoto(const Vec3d & j2000Pos,StelObjectP selectObject)150 void telescopeGoto(const Vec3d &j2000Pos, StelObjectP selectObject) Q_DECL_OVERRIDE 151 { 152 Q_UNUSED(selectObject) 153 desired_pos = j2000Pos; 154 desired_pos.normalize(); 155 } telescopeSync(const Vec3d & j2000Pos,StelObjectP selectObject)156 void telescopeSync(const Vec3d &j2000Pos, StelObjectP selectObject) Q_DECL_OVERRIDE 157 { 158 Q_UNUSED(selectObject) 159 Q_UNUSED(j2000Pos) 160 } hasKnownPosition(void) const161 bool hasKnownPosition(void) const Q_DECL_OVERRIDE 162 { 163 return true; 164 } getJ2000EquatorialPos(const StelCore *) const165 Vec3d getJ2000EquatorialPos(const StelCore*) const Q_DECL_OVERRIDE 166 { 167 return XYZ; 168 } 169 170 private: 171 Vec3d XYZ; // j2000 position 172 Vec3d desired_pos; 173 }; 174 175 //! This TelescopeClient class can control a telescope by communicating 176 //! to a server process ("telescope server") via 177 //! the "Stellarium telescope control protocol" over TCP/IP. 178 //! The "Stellarium telescope control protocol" is specified in a separate 179 //! document along with the telescope server software. 180 class TelescopeTCP : public TelescopeClient 181 { 182 Q_OBJECT 183 public: 184 TelescopeTCP(const QString &name, const QString ¶ms, Equinox eq = EquinoxJ2000); ~TelescopeTCP(void)185 ~TelescopeTCP(void) Q_DECL_OVERRIDE 186 { 187 hangup(); 188 } isConnected(void) const189 bool isConnected(void) const Q_DECL_OVERRIDE 190 { 191 //return (tcpSocket->isValid() && !wait_for_connection_establishment); 192 return (tcpSocket->state() == QAbstractSocket::ConnectedState); 193 } 194 195 private: 196 Vec3d getJ2000EquatorialPos(const StelCore* core=Q_NULLPTR) const Q_DECL_OVERRIDE; 197 bool prepareCommunication() Q_DECL_OVERRIDE; 198 void performCommunication() Q_DECL_OVERRIDE; 199 void telescopeGoto(const Vec3d &j2000Pos, StelObjectP selectObject) Q_DECL_OVERRIDE; 200 void telescopeSync(const Vec3d &j2000Pos, StelObjectP selectObject) Q_DECL_OVERRIDE; isInitialized(void) const201 bool isInitialized(void) const Q_DECL_OVERRIDE 202 { 203 return (!address.isNull()); 204 } 205 void performReading(void); 206 void performWriting(void); 207 208 private: 209 void hangup(void); 210 QHostAddress address; 211 quint16 port; 212 QTcpSocket * tcpSocket; 213 bool wait_for_connection_establishment; 214 qint64 end_of_timeout; 215 char readBuffer[120]; 216 char *readBufferEnd; 217 char writeBuffer[120]; 218 char *writeBufferEnd; 219 int time_delay; 220 221 InterpolatedPosition interpolatedPosition; hasKnownPosition(void) const222 virtual bool hasKnownPosition(void) const Q_DECL_OVERRIDE 223 { 224 return interpolatedPosition.isKnown(); 225 } 226 227 Equinox equinox; 228 229 private slots: 230 void socketConnected(void); 231 void socketFailed(QAbstractSocket::SocketError socketError); 232 }; 233 234 #endif // TELESCOPECLIENT_HPP 235