File indexing completed on 2024-05-12 15:23:37
0001 /* 0002 SPDX-FileCopyrightText: 2016 Jasem Mutlaq <mutlaqja@ikarustech.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #pragma once 0008 0009 #include "../guideinterface.h" 0010 0011 #include <QAbstractSocket> 0012 #include <QJsonArray> 0013 #include <QJsonObject> 0014 #include <QPointer> 0015 #include <QTimer> 0016 0017 class FITSView; 0018 class QTcpSocket; 0019 0020 namespace Ekos 0021 { 0022 /** 0023 * @class PHD2 0024 * Uses external PHD2 for guiding. 0025 * 0026 * @author Jasem Mutlaq 0027 * @version 1.1 0028 */ 0029 class PHD2 : public GuideInterface 0030 { 0031 Q_OBJECT 0032 0033 public: 0034 enum PHD2Event 0035 { 0036 Version, 0037 LockPositionSet, 0038 Calibrating, 0039 CalibrationComplete, 0040 StarSelected, 0041 StartGuiding, 0042 Paused, 0043 StartCalibration, 0044 AppState, 0045 CalibrationFailed, 0046 CalibrationDataFlipped, 0047 LoopingExposures, 0048 LoopingExposuresStopped, 0049 SettleBegin, 0050 Settling, 0051 SettleDone, 0052 StarLost, 0053 GuidingStopped, 0054 Resumed, 0055 GuideStep, 0056 GuidingDithered, 0057 LockPositionLost, 0058 Alert, 0059 GuideParamChange, 0060 ConfigurationChange 0061 0062 }; 0063 enum PHD2State 0064 { 0065 // these are the states exposed by phd2 0066 STOPPED, 0067 SELECTED, 0068 CALIBRATING, 0069 GUIDING, 0070 LOSTLOCK, 0071 PAUSED, 0072 LOOPING, 0073 DITHERING, 0074 }; 0075 enum PHD2Connection 0076 { 0077 DISCONNECTED, 0078 CONNECTED, 0079 EQUIPMENT_DISCONNECTED, 0080 EQUIPMENT_CONNECTED, 0081 CONNECTING, 0082 DISCONNECTING, 0083 }; 0084 enum PHD2MessageType 0085 { 0086 PHD2_UNKNOWN, 0087 PHD2_RESULT, 0088 PHD2_EVENT, 0089 PHD2_ERROR, 0090 }; 0091 0092 // These are the PHD2 Results and the commands they are associated with 0093 enum PHD2ResultType 0094 { 0095 NO_RESULT, 0096 CAPTURE_SINGLE_FRAME, //capture_single_frame 0097 CLEAR_CALIBRATION_COMMAND_RECEIVED, //clear_calibration 0098 DITHER_COMMAND_RECEIVED, //dither 0099 //find_star 0100 //flip_calibration 0101 //get_algo_param_names 0102 //get_algo_param 0103 APP_STATE_RECEIVED, //get_app_state 0104 //get_calibrated 0105 //get_calibration_data 0106 IS_EQUIPMENT_CONNECTED, //get_connected 0107 //get_cooler_status 0108 GET_CURRENT_EQUIPMENT, //get_current_equipment 0109 DEC_GUIDE_MODE, //get_dec_guide_mode 0110 EXPOSURE_TIME, //get_exposure 0111 EXPOSURE_DURATIONS, //get_exposure_durations 0112 LOCK_POSITION, //get_lock_position 0113 //get_lock_shift_enabled 0114 //get_lock_shift_params 0115 //get_paused 0116 PIXEL_SCALE, //get_pixel_scale 0117 //get_profile 0118 //get_profiles 0119 //get_search_region 0120 //get_sensor_temperature 0121 STAR_IMAGE, //get_star_image 0122 //get_use_subframes 0123 GUIDE_COMMAND_RECEIVED, //guide 0124 //guide_pulse 0125 LOOP, //loop 0126 //save_image 0127 //set_algo_param 0128 CONNECTION_RESULT, //set_connected 0129 SET_DEC_GUIDE_MODE_COMMAND_RECEIVED, //set_dec_guide_mode 0130 SET_EXPOSURE_COMMAND_RECEIVED, //set_exposure 0131 SET_LOCK_POSITION, //set_lock_position 0132 //set_lock_shift_enabled 0133 //set_lock_shift_params 0134 SET_PAUSED_COMMAND_RECEIVED, //set_paused 0135 //set_profile 0136 //shutdown 0137 STOP_CAPTURE_COMMAND_RECEIVED //stop_capture 0138 }; 0139 0140 PHD2(); 0141 ~PHD2(); 0142 0143 //These are the connection methods to connect the external guide program PHD2 0144 bool Connect() override; 0145 bool Disconnect() override; 0146 bool isConnected() override 0147 { 0148 return (connection == CONNECTED || connection == EQUIPMENT_CONNECTED); 0149 } 0150 0151 //These are the PHD2 Methods. Only some are implemented in Ekos. 0152 0153 void captureSingleFrame(); //capture_single_frame 0154 bool clearCalibration() override; //clear_calibration 0155 bool dither(double pixels) override; //dither 0156 //find_star 0157 //flip_calibration 0158 //get_algo_param_names 0159 //get_algo_param 0160 void requestAppState(); //get_app_state 0161 //get_calibrated 0162 //get_calibration_data 0163 void checkIfEquipmentConnected(); //get_connected 0164 //get_cooler_status 0165 void requestCurrentEquipmentUpdate(); //get_current_equipment 0166 void checkDEGuideMode(); //get_dec_guide_mode 0167 void requestExposureTime(); //get_exposure 0168 void requestExposureDurations(); //get_exposure_durations 0169 void requestLockPosition(); //get_lock_position 0170 //get_lock_shift_enabled 0171 //get_lock_shift_params 0172 //get_paused 0173 void requestPixelScale(); //get_pixel_scale 0174 //get_profile 0175 //get_profiles 0176 //get_search_region 0177 //get_sensor_temperature 0178 void requestStarImage(int size); //get_star_image 0179 //get_use_subframes 0180 bool guide() override; //guide 0181 //guide_pulse 0182 void loop(); //loop 0183 //save_image 0184 //set_algo_param 0185 void connectEquipment(bool enable);//set_connected 0186 void requestSetDEGuideMode(bool deEnabled, bool nEnabled, bool sEnabled); //set_dec_guide_mode 0187 void requestSetExposureTime(int time); //set_exposure 0188 void setLockPosition(double x, double y); //set_lock_position 0189 //set_lock_shift_enabled 0190 //set_lock_shift_params 0191 bool suspend() override; //set_paused 0192 bool resume() override; //set_paused 0193 //set_profile 0194 //shutdown 0195 bool abort() override; //stop_capture 0196 0197 bool calibrate() override; //Note PHD2 does not have a separate calibrate command. This is unused. 0198 void setGuideView(const QSharedPointer<FITSView> &guideView); 0199 0200 QString getCurrentCamera() 0201 { 0202 return currentCamera; 0203 } 0204 QString getCurrentMount() 0205 { 0206 return currentMount; 0207 } 0208 QString getCurrentAuxMount() 0209 { 0210 return currentAuxMount; 0211 } 0212 0213 bool isCurrentCameraNotInEkos() 0214 { 0215 return currentCameraIsNotInEkos; 0216 } 0217 void setCurrentCameraIsNotInEkos(bool enable) 0218 { 0219 currentCameraIsNotInEkos = enable; 0220 } 0221 0222 private slots: 0223 0224 void readPHD2(); 0225 void displayError(QAbstractSocket::SocketError socketError); 0226 0227 private: 0228 QSharedPointer<FITSView> m_GuideFrame; 0229 0230 QVector<QPointF> errorLog; 0231 0232 void sendPHD2Request(const QString &method, const QJsonArray &args = QJsonArray()); 0233 void sendRpcCall(QJsonObject &call, PHD2ResultType resultType); 0234 void sendNextRpcCall(); 0235 0236 void processPHD2Event(const QJsonObject &jsonEvent, const QByteArray &rawResult); 0237 void processPHD2Result(const QJsonObject &jsonObj, const QByteArray &rawResult); 0238 void processStarImage(const QJsonObject &jsonStarFrame); 0239 void processPHD2State(const QString &phd2State); 0240 void handlePHD2AppState(PHD2State state); 0241 void processPHD2Error(const QJsonObject &jsonError, const QByteArray &rawResult); 0242 0243 PHD2ResultType takeRequestFromList(const QJsonObject &response); 0244 0245 QPointer<QTcpSocket> tcpSocket; 0246 int nextRpcId { 1 }; 0247 0248 QHash<QString, PHD2Event> events; // maps event name to event type 0249 QHash<QString, PHD2ResultType> methodResults; // maps method name to result type 0250 0251 int pendingRpcId; // ID of outstanding RPC call 0252 PHD2ResultType pendingRpcResultType { NO_RESULT }; // result type of outstanding RPC call 0253 bool starImageRequested { false }; // true when there is an outstanding star image request 0254 0255 struct RpcCall 0256 { 0257 QJsonObject call; 0258 PHD2ResultType resultType; 0259 RpcCall() = default; 0260 RpcCall(const QJsonObject &call_, PHD2ResultType resultType_) : call(call_), resultType(resultType_) { } 0261 }; 0262 QVector<RpcCall> rpcRequestQueue; 0263 0264 PHD2State state { STOPPED }; 0265 bool isDitherActive { false }; 0266 bool isSettling { false }; 0267 PHD2Connection connection { DISCONNECTED }; 0268 PHD2Event event { Alert }; 0269 uint8_t setConnectedRetries { 0 }; 0270 0271 void setEquipmentConnected(); 0272 void updateGuideParameters(); 0273 void ResetConnectionState(); 0274 0275 QTimer *abortTimer; 0276 QTimer *ditherTimer; 0277 QTimer *stateTimer; 0278 0279 double pixelScale = 0; 0280 0281 QString logValidExposureTimes; 0282 0283 QString currentCamera; 0284 QString currentMount; 0285 QString currentAuxMount; 0286 bool currentCameraIsNotInEkos; 0287 0288 uint8_t m_PHD2ReconnectCounter {0}; 0289 0290 // Wait this many milliseconds before trying to reconnect again to PHD2 0291 static const uint32_t PHD2_RECONNECT_TIMEOUT {3000}; 0292 // Try to connect this many times before giving up. 0293 static const uint8_t PHD2_RECONNECT_THRESHOLD {10}; 0294 0295 }; 0296 0297 }