1 /* 2 Filter Interface 3 Copyright (C) 2011 Jasem Mutlaq (mutlaqja@ikarustech.com) 4 5 This library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 This library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with this library; if not, write to the Free Software 17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 19 */ 20 21 #pragma once 22 23 #include "indibase.h" 24 25 #include <stdint.h> 26 27 // Alias 28 using FI = INDI::FocuserInterface; 29 30 namespace INDI 31 { 32 33 /** 34 * \class FocuserInterface 35 \brief Provides interface to implement focuser functionality. 36 37 A focuser can be an independent device, or an embedded focuser within another device (e.g. Camera or mount). 38 39 When developing a driver for a fully indepdent focuser device, use INDI::Focuser directly. To add focus functionality to 40 an existing mount or camera driver, subclass INDI::FocuserInterface. In your driver, then call the necessary focuser interface functions. 41 42 <table> 43 <tr><th>Function</th><th>Where to call it from your driver</th></tr> 44 <tr><td>FI::SetCapability</td><td>Constructor</td></tr> 45 <tr><td>FI::initProperties</td><td>initProperties()</td></tr> 46 <tr><td>FI::updateProperties</td><td>updateProperties()</td></tr> 47 <tr><td>FI::processNumber</td><td>ISNewNumber(...) Check if the property name contains FOCUS_* and then call FI::processNumber(..) for such properties</td></tr> 48 <tr><td>FI::processSwitch</td><td>ISNewSwitch(...)</td></tr> 49 </table> 50 51 The interface supports three types of focusers: 52 + **Absolute Position**: Focusers that know their absolute position in steps on power up. You can issue GOTO to an absolute position. By definition, 53 position 0 (zero) is where the focuser is completely @a retracted (i.e. closest to the OTA) and it increases positively as it move @a outwards. When moving 54 @a inward, the position value decreases. @warning Negative values are not accepted for absolute focusers. 55 + **Relateive Position**: Focusers that can move in specific steps inwward or outward, but have no information on absolute position on power up. 56 + **DC Motor**: Focusers without any position feedback. The only way to reliably control them is by using timers and moving them for specific pulses in or 57 out. 58 59 Implement and overwrite the rest of the virtual functions as needed. INDI GPhoto driver is a good example to check for an actual implementation 60 of a focuser interface within a CCD driver. 61 \author Jasem Mutlaq 62 */ 63 class FocuserInterface 64 { 65 public: 66 enum FocusDirection 67 { 68 FOCUS_INWARD, 69 FOCUS_OUTWARD 70 }; 71 72 enum 73 { 74 FOCUSER_CAN_ABS_MOVE = 1 << 0, /*!< Can the focuser move by absolute position? */ 75 FOCUSER_CAN_REL_MOVE = 1 << 1, /*!< Can the focuser move by relative position? */ 76 FOCUSER_CAN_ABORT = 1 << 2, /*!< Is it possible to abort focuser motion? */ 77 FOCUSER_CAN_REVERSE = 1 << 3, /*!< Is it possible to reverse focuser motion? */ 78 FOCUSER_CAN_SYNC = 1 << 4, /*!< Can the focuser sync to a custom position */ 79 FOCUSER_HAS_VARIABLE_SPEED = 1 << 5, /*!< Can the focuser move in different configurable speeds? */ 80 FOCUSER_HAS_BACKLASH = 1 << 6 /*!< Can the focuser compensate for backlash? */ 81 } FocuserCapability; 82 83 /** 84 * @brief GetFocuserCapability returns the capability of the focuser 85 */ GetCapability()86 uint32_t GetCapability() const 87 { 88 return capability; 89 } 90 91 /** 92 * @brief FI::SetCapability sets the focuser capabilities. All capabilities must be initialized. 93 * @param cap pointer to focuser capability struct. 94 */ SetCapability(uint32_t cap)95 void SetCapability(uint32_t cap) 96 { 97 capability = cap; 98 } 99 100 /** 101 * @return True if the focuser has absolute position encoders. 102 */ CanAbsMove()103 bool CanAbsMove() 104 { 105 return capability & FOCUSER_CAN_ABS_MOVE; 106 } 107 108 /** 109 * @return True if the focuser has relative position encoders. 110 */ CanRelMove()111 bool CanRelMove() 112 { 113 return capability & FOCUSER_CAN_REL_MOVE; 114 } 115 116 /** 117 * @return True if the focuser motion can be aborted. 118 */ CanAbort()119 bool CanAbort() 120 { 121 return capability & FOCUSER_CAN_ABORT; 122 } 123 124 /** 125 * @return True if the focuser motion can be reversed. 126 */ CanReverse()127 bool CanReverse() 128 { 129 return capability & FOCUSER_CAN_REVERSE; 130 } 131 132 /** 133 * @return True if the focuser motion can be reversed. 134 */ CanSync()135 bool CanSync() 136 { 137 return capability & FOCUSER_CAN_SYNC; 138 } 139 140 /** 141 * @return True if the focuser has multiple speeds. 142 */ HasVariableSpeed()143 bool HasVariableSpeed() 144 { 145 return capability & FOCUSER_HAS_VARIABLE_SPEED; 146 } 147 148 /** 149 * @return True if the focuser supports backlash. 150 */ HasBacklash()151 bool HasBacklash() 152 { 153 return capability & FOCUSER_HAS_BACKLASH; 154 } 155 156 protected: 157 explicit FocuserInterface(DefaultDevice * defaultDevice); 158 virtual ~FocuserInterface() = default; 159 160 /** 161 * \brief Initilize focuser properties. It is recommended to call this function within 162 * initProperties() of your primary device 163 * \param groupName Group or tab name to be used to define focuser properties. 164 */ 165 void initProperties(const char * groupName); 166 167 /** 168 * @brief updateProperties Define or Delete Rotator properties based on the connection status of the base device 169 * @return True if successful, false otherwise. 170 */ 171 bool updateProperties(); 172 173 /** \brief Process focus number properties */ 174 bool processNumber(const char * dev, const char * name, double values[], char * names[], int n); 175 176 /** \brief Process focus switch properties */ 177 bool processSwitch(const char * dev, const char * name, ISState * states, char * names[], int n); 178 179 /** 180 * @brief SetFocuserSpeed Set Focuser speed 181 * @param speed focuser speed 182 * @return true if successful, false otherwise 183 */ 184 virtual bool SetFocuserSpeed(int speed); 185 186 /** 187 * \brief MoveFocuser the focuser in a particular direction with a specific speed for a 188 * finite duration. 189 * \param dir Direction of focuser, either FOCUS_INWARD or FOCUS_OUTWARD. 190 * \param speed Speed of focuser if supported by the focuser. 191 * \param duration The timeout in milliseconds before the focus motion halts. Pass 0 to move indefinitely. 192 * \return Return IPS_OK if motion is completed and focuser reached requested position. 193 * Return IPS_BUSY if focuser started motion to requested position and is in progress. 194 * Return IPS_ALERT if there is an error. 195 */ 196 virtual IPState MoveFocuser(FocusDirection dir, int speed, uint16_t duration); 197 198 /** 199 * \brief MoveFocuser the focuser to an absolute position. 200 * \param ticks The new position of the focuser. 201 * \return Return IPS_OK if motion is completed and focuser reached requested position. Return 202 * IPS_BUSY if focuser started motion to requested position and is in progress. 203 * Return IPS_ALERT if there is an error. 204 */ 205 virtual IPState MoveAbsFocuser(uint32_t targetTicks); 206 207 /** 208 * \brief MoveFocuser the focuser to an relative position. 209 * \param dir Direction of focuser, either FOCUS_INWARD or FOCUS_OUTWARD. 210 * \param ticks The relative ticks to move. 211 * \return Return IPS_OK if motion is completed and focuser reached requested position. Return 212 * IPS_BUSY if focuser started motion to requested position and is in progress. 213 * Return IPS_ALERT if there is an error. 214 */ 215 virtual IPState MoveRelFocuser(FocusDirection dir, uint32_t ticks); 216 217 /** 218 * @brief ReverseFocuser Reverse focuser motion direction 219 * @param enabled If true, normal default focuser motion is reversed. If false, the direction is set to the default focuser motion. 220 * @return True if successful, false otherwise. 221 */ 222 virtual bool ReverseFocuser(bool enabled); 223 224 /** 225 * @brief SyncFocuser Set current position to ticks without moving the focuser. 226 * @param ticks Desired new sync position. 227 * @return True if successful, false otherwise. 228 */ 229 virtual bool SyncFocuser(uint32_t ticks); 230 231 /** 232 * @brief SetFocuserMaxPosition Set Focuser Maximum position limit in the hardware. 233 * @param ticks maximum steps permitted 234 * @return True if successful, false otherwise. 235 * @note If setting maximum position limit in the hardware is not available or not supported, do not override this function as the default 236 * implementation will always return true. 237 */ 238 virtual bool SetFocuserMaxPosition(uint32_t ticks); 239 240 /** 241 * @brief SetFocuserBacklash Set the focuser backlash compensation value 242 * @param steps value in absolute steps to compensate 243 * @return True if successful, false otherwise. 244 */ 245 virtual bool SetFocuserBacklash(int32_t steps); 246 247 /** 248 * @brief SetFocuserBacklashEnabled Enables or disables the focuser backlash compensation 249 * @param enable flag to enable or disable backlash compensation 250 * @return True if successful, false otherwise. 251 */ 252 virtual bool SetFocuserBacklashEnabled(bool enabled); 253 254 /** 255 * @brief AbortFocuser all focus motion 256 * @return True if abort is successful, false otherwise. 257 */ 258 virtual bool AbortFocuser(); 259 260 /** 261 * @brief saveConfigItems save focuser properties defined in the interface in config file 262 * @param fp pointer to config file 263 * @return Always return true 264 */ 265 bool saveConfigItems(FILE * fp); 266 267 // Focuser Speed (if variable speeds are supported) 268 INumberVectorProperty FocusSpeedNP; 269 INumber FocusSpeedN[1]; 270 271 // Focuser Motion switch. 272 // For absolute focusers, this controls the directoin of FocusRelPos when updated. 273 // For DC speed based focusers, this moves the focuser continues in the CW/CCW directions until stopped. 274 ISwitchVectorProperty FocusMotionSP; 275 ISwitch FocusMotionS[2]; 276 277 // Timer for user with DC focusers to run focuser in specific direction for this duration 278 INumberVectorProperty FocusTimerNP; 279 INumber FocusTimerN[1]; 280 281 // Absolute Focuser Position in steps 282 INumberVectorProperty FocusAbsPosNP; 283 INumber FocusAbsPosN[1]; 284 285 // Relative Focuser position to be commanded 286 INumberVectorProperty FocusRelPosNP; 287 INumber FocusRelPosN[1]; 288 289 // Absolute Focuser position is 0 to this maximum limit. By Default, it is set to 200,000. 290 INumberVectorProperty FocusMaxPosNP; 291 INumber FocusMaxPosN[1]; 292 293 // Sync 294 INumberVectorProperty FocusSyncNP; 295 INumber FocusSyncN[1]; 296 297 // Abort Focuser 298 ISwitchVectorProperty FocusAbortSP; 299 ISwitch FocusAbortS[1]; 300 301 // Reverse Focuser 302 ISwitchVectorProperty FocusReverseSP; 303 ISwitch FocusReverseS[2]; 304 305 // Backlash toogle 306 ISwitchVectorProperty FocusBacklashSP; 307 ISwitch FocusBacklashS[2]; 308 309 // Backlash steps 310 INumberVectorProperty FocusBacklashNP; 311 INumber FocusBacklashN[1]; 312 313 uint32_t capability; 314 315 double lastTimerValue = { 0 }; 316 317 DefaultDevice * m_defaultDevice { nullptr }; 318 }; 319 } 320