Instrument Neutral Distributed Interface INDI  2.0.2
indirotatorinterface.cpp
Go to the documentation of this file.
1 /*
2  Rotator Interface
3  Copyright (C) 2017 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 #include "indirotatorinterface.h"
22 #include "defaultdevice.h"
23 
24 #include "indilogger.h"
25 
26 #include <cstring>
27 
28 namespace INDI
29 {
30 
31 RotatorInterface::RotatorInterface(DefaultDevice *defaultDevice) : m_defaultDevice(defaultDevice)
32 {
33 }
34 
35 void RotatorInterface::initProperties(const char *groupName)
36 {
37  // Rotator Angle
38  IUFillNumber(&GotoRotatorN[0], "ANGLE", "Angle", "%.2f", 0, 360., 10., 0.);
39  IUFillNumberVector(&GotoRotatorNP, GotoRotatorN, 1, m_defaultDevice->getDeviceName(), "ABS_ROTATOR_ANGLE", "Goto",
40  groupName, IP_RW, 0, IPS_IDLE );
41 
42  // Abort Rotator
43  IUFillSwitch(&AbortRotatorS[0], "ABORT", "Abort", ISS_OFF);
45  "Abort Motion", groupName, IP_RW, ISR_ATMOST1, 0, IPS_IDLE);
46 
47  // Rotator Sync
48  IUFillNumber(&SyncRotatorN[0], "ANGLE", "Angle", "%.2f", 0, 360., 10., 0.);
49  IUFillNumberVector(&SyncRotatorNP, SyncRotatorN, 1, m_defaultDevice->getDeviceName(), "SYNC_ROTATOR_ANGLE", "Sync",
50  groupName, IP_RW, 0, IPS_IDLE );
51 
52  // Home Rotator
53  IUFillSwitch(&HomeRotatorS[0], "HOME", "Start", ISS_OFF);
54  IUFillSwitchVector(&HomeRotatorSP, HomeRotatorS, 1, m_defaultDevice->getDeviceName(), "ROTATOR_HOME", "Homing", groupName,
56 
57  // Reverse Direction
58  IUFillSwitch(&ReverseRotatorS[DefaultDevice::INDI_ENABLED], "INDI_ENABLED", "Enabled", ISS_OFF);
59  IUFillSwitch(&ReverseRotatorS[DefaultDevice::INDI_DISABLED], "INDI_DISABLED", "Disabled", ISS_ON);
61  groupName, IP_RW, ISR_1OFMANY,
62  0, IPS_IDLE);
63 
64  // Backlash Compensation
66  IUFillSwitch(&RotatorBacklashS[DefaultDevice::INDI_DISABLED], "INDI_DISABLED", "Disabled", ISS_ON);
68  "Backlash", groupName, IP_RW,
69  ISR_1OFMANY, 60, IPS_IDLE);
70 
71 
72  // Backlash Compensation Value
73  IUFillNumber(&RotatorBacklashN[0], "ROTATOR_BACKLASH_VALUE", "Steps", "%.f", 0, 1e6, 100, 0);
75  "Backlash",
76  groupName, IP_RW, 60, IPS_OK);
77 }
78 
79 bool RotatorInterface::processNumber(const char *dev, const char *name, double values[], char *names[], int n)
80 {
81  INDI_UNUSED(names);
82  INDI_UNUSED(n);
83 
84  if (dev != nullptr && strcmp(dev, m_defaultDevice->getDeviceName()) == 0)
85  {
87  // Move Absolute Angle
89  if (strcmp(name, GotoRotatorNP.name) == 0)
90  {
91  if (values[0] == GotoRotatorN[0].value)
92  {
94  IDSetNumber(&GotoRotatorNP, nullptr);
95  return true;
96  }
97 
98  GotoRotatorNP.s = MoveRotator(values[0]);
99  IDSetNumber(&GotoRotatorNP, nullptr);
100  if (GotoRotatorNP.s == IPS_BUSY)
101  DEBUGFDEVICE(m_defaultDevice->getDeviceName(), Logger::DBG_SESSION, "Rotator moving to %.2f degrees...", values[0]);
102  return true;
103  }
105  // Sync
107  else if (strcmp(name, SyncRotatorNP.name) == 0)
108  {
109  if (values[0] == GotoRotatorN[0].value)
110  {
112  IDSetNumber(&SyncRotatorNP, nullptr);
113  return true;
114  }
115 
116  bool rc = SyncRotator(values[0]);
117  SyncRotatorNP.s = rc ? IPS_OK : IPS_ALERT;
118  if (rc)
119  SyncRotatorN[0].value = values[0];
120 
121  IDSetNumber(&SyncRotatorNP, nullptr);
122  return true;
123  }
125  // Backlash value
127  else if (!strcmp(name, RotatorBacklashNP.name))
128  {
130  {
132  DEBUGDEVICE(dev, Logger::DBG_WARNING, "Rotatorer backlash must be enabled first.");
133  }
134  else
135  {
136  uint32_t steps = static_cast<uint32_t>(values[0]);
137  if (SetRotatorBacklash(steps))
138  {
139  RotatorBacklashN[0].value = values[0];
141  }
142  else
144  }
145  IDSetNumber(&RotatorBacklashNP, nullptr);
146  return true;
147  }
148  }
149 
150  return false;
151 }
152 
153 bool RotatorInterface::processSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
154 {
155  INDI_UNUSED(states);
156  INDI_UNUSED(names);
157  INDI_UNUSED(n);
158 
159  if (dev != nullptr && strcmp(dev, m_defaultDevice->getDeviceName()) == 0)
160  {
162  // Abort
164  if (strcmp(name, AbortRotatorSP.name) == 0)
165  {
167  IDSetSwitch(&AbortRotatorSP, nullptr);
168  if (AbortRotatorSP.s == IPS_OK)
169  {
170  if (GotoRotatorNP.s != IPS_OK)
171  {
173  IDSetNumber(&GotoRotatorNP, nullptr);
174  }
175  }
176  return true;
177  }
179  // Home
181  else if (strcmp(name, HomeRotatorSP.name) == 0)
182  {
185  if (HomeRotatorSP.s == IPS_BUSY)
186  HomeRotatorS[0].s = ISS_ON;
187  IDSetSwitch(&HomeRotatorSP, nullptr);
188  return true;
189  }
191  // Reverse Rotator
193  else if (strcmp(name, ReverseRotatorSP.name) == 0)
194  {
195  int prevIndex = IUFindOnSwitchIndex(&ReverseRotatorSP);
196  IUUpdateSwitch(&ReverseRotatorSP, states, names, n);
198 
199  if (ReverseRotator(enabled))
200  {
201  IUUpdateSwitch(&ReverseRotatorSP, states, names, n);
203  DEBUGFDEVICE(m_defaultDevice->getDeviceName(), Logger::DBG_SESSION, "Rotator direction is %s.",
204  (enabled ? "reversed" : "normal"));
205  }
206  else
207  {
209  ReverseRotatorS[prevIndex].s = ISS_ON;
211  DEBUGDEVICE(m_defaultDevice->getDeviceName(), Logger::DBG_SESSION, "Rotator reverse direction failed.");
212  }
213 
214  IDSetSwitch(&ReverseRotatorSP, nullptr);
215  return true;
216  }
218  // Backlash enable/disable
220  else if (strcmp(name, RotatorBacklashSP.name) == 0)
221  {
222  int prevIndex = IUFindOnSwitchIndex(&RotatorBacklashSP);
223  IUUpdateSwitch(&RotatorBacklashSP, states, names, n);
225 
226  if (SetRotatorBacklashEnabled(enabled))
227  {
229  DEBUGFDEVICE(m_defaultDevice->getDeviceName(), Logger::DBG_SESSION, "Rotator backlash is %s.",
230  (enabled ? "enabled" : "disabled"));
231  }
232  else
233  {
235  RotatorBacklashS[prevIndex].s = ISS_ON;
237  DEBUGDEVICE(m_defaultDevice->getDeviceName(), Logger::DBG_ERROR, "Failed to set trigger rotator backlash.");
238  }
239 
240  IDSetSwitch(&RotatorBacklashSP, nullptr);
241  return true;
242  }
243  }
244 
245  return false;
246 }
247 
249 {
251  {
253 
254  if (CanAbort())
256  if (CanSync())
258  if (CanHome())
260  if (CanReverse())
262  if (HasBacklash())
263  {
266  }
267  }
268  else
269  {
271 
272  if (CanAbort())
274  if (CanSync())
276  if (CanHome())
278  if (CanReverse())
280  if (HasBacklash())
281  {
284  }
285  }
286 
287  return true;
288 }
289 
291 {
292  INDI_UNUSED(angle);
293  DEBUGDEVICE(m_defaultDevice->getDeviceName(), Logger::DBG_ERROR, "Rotator does not support syncing.");
294  return false;
295 }
296 
298 {
299  DEBUGDEVICE(m_defaultDevice->getDeviceName(), Logger::DBG_ERROR, "Rotator does not support homing.");
300  return IPS_ALERT;
301 }
302 
304 {
305  DEBUGDEVICE(m_defaultDevice->getDeviceName(), Logger::DBG_ERROR, "Rotator does not support abort.");
306  return false;
307 }
308 
310 {
311  INDI_UNUSED(enabled);
312  DEBUGDEVICE(m_defaultDevice->getDeviceName(), Logger::DBG_ERROR, "Rotator does not support reverse.");
313  return false;
314 }
315 
317 {
318  INDI_UNUSED(steps);
319  DEBUGDEVICE(m_defaultDevice->getDeviceName(), Logger::DBG_ERROR, "Rotator does not support backlash compensation.");
320  return false;
321 }
322 
324 {
325  // If disabled, set the Rotatorer backlash to zero.
326  if (enabled)
327  return SetRotatorBacklash(static_cast<int32_t>(RotatorBacklashN[0].value));
328  else
329  return SetRotatorBacklash(0);
330 }
331 
333 {
334  if (CanReverse())
335  {
337  }
338  if (HasBacklash())
339  {
342  }
343 
344  return true;
345 }
346 
347 }
bool isConnected() const
Definition: basedevice.cpp:520
const char * getDeviceName() const
Definition: basedevice.cpp:821
Class to provide extended functionality for devices in addition to the functionality provided by INDI...
virtual bool deleteProperty(const char *propertyName)
Delete a property and unregister it. It will also be deleted from all clients.
void defineProperty(INumberVectorProperty *property)
bool processSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
Process Rotator switch properties.
virtual IPState MoveRotator(double angle)=0
MoveRotator Go to specific angle.
bool saveConfigItems(FILE *fp)
saveConfigItems save focuser properties defined in the interface in config file
INumberVectorProperty RotatorBacklashNP
virtual bool AbortRotator()
AbortRotator Abort all motion.
RotatorInterface(DefaultDevice *defaultDevice)
INumberVectorProperty GotoRotatorNP
void initProperties(const char *groupName)
Initilize Rotator properties. It is recommended to call this function within initProperties() of your...
bool updateProperties()
updateProperties Define or Delete Rotator properties based on the connection status of the base devic...
INumberVectorProperty SyncRotatorNP
ISwitchVectorProperty HomeRotatorSP
virtual bool SyncRotator(double angle)
SyncRotator Set current angle as the supplied angle without moving the rotator.
virtual bool ReverseRotator(bool enabled)
ReverseRotator Reverse the direction of the rotator. CW is usually the normal direction,...
ISwitchVectorProperty ReverseRotatorSP
virtual bool SetRotatorBacklashEnabled(bool enabled)
SetRotatorBacklashEnabled Enables or disables the Rotator backlash compensation.
bool processNumber(const char *dev, const char *name, double values[], char *names[], int n)
Process Rotator number properties.
ISwitchVectorProperty RotatorBacklashSP
virtual IPState HomeRotator()
HomeRotator Go to home position.
ISwitchVectorProperty AbortRotatorSP
virtual bool SetRotatorBacklash(int32_t steps)
SetRotatorBacklash Set the Rotatorer backlash compensation value.
ISState
Switch state.
Definition: indiapi.h:150
@ ISS_OFF
Definition: indiapi.h:151
@ ISS_ON
Definition: indiapi.h:152
@ IP_RW
Definition: indiapi.h:186
IPState
Property state.
Definition: indiapi.h:160
@ IPS_BUSY
Definition: indiapi.h:163
@ IPS_ALERT
Definition: indiapi.h:164
@ IPS_IDLE
Definition: indiapi.h:161
@ IPS_OK
Definition: indiapi.h:162
@ ISR_1OFMANY
Definition: indiapi.h:173
@ ISR_ATMOST1
Definition: indiapi.h:174
void IUSaveConfigSwitch(FILE *fp, const ISwitchVectorProperty *svp)
Add a switch vector property value to the configuration file.
Definition: indidevapi.c:25
void IUFillNumberVector(INumberVectorProperty *nvp, INumber *np, int nnp, const char *dev, const char *name, const char *label, const char *group, IPerm p, double timeout, IPState s)
Assign attributes for a number vector property. The vector's auxiliary elements will be set to NULL.
Definition: indidevapi.c:272
int IUFindOnSwitchIndex(const ISwitchVectorProperty *svp)
Returns the index of first ON switch it finds in the vector switch property.
Definition: indidevapi.c:128
void IUResetSwitch(ISwitchVectorProperty *svp)
Reset all switches in a switch vector property to OFF.
Definition: indidevapi.c:148
void IUSaveConfigNumber(FILE *fp, const INumberVectorProperty *nvp)
Add a number vector property value to the configuration file.
Definition: indidevapi.c:15
void IUFillSwitch(ISwitch *sp, const char *name, const char *label, ISState s)
Assign attributes for a switch property. The switch's auxiliary elements will be set to NULL.
Definition: indidevapi.c:158
void IUFillNumber(INumber *np, const char *name, const char *label, const char *format, double min, double max, double step, double value)
Assign attributes for a number property. The number's auxiliary elements will be set to NULL.
Definition: indidevapi.c:180
void IUFillSwitchVector(ISwitchVectorProperty *svp, ISwitch *sp, int nsp, const char *dev, const char *name, const char *label, const char *group, IPerm p, ISRule r, double timeout, IPState s)
Assign attributes for a switch vector property. The vector's auxiliary elements will be set to NULL.
Definition: indidevapi.c:235
#define INDI_UNUSED(x)
Definition: indidevapi.h:131
int IUUpdateSwitch(ISwitchVectorProperty *svp, ISState *states, char *names[], int n)
Update all switches in a switch vector property.
Definition: indidriver.c:1308
void IDSetNumber(const INumberVectorProperty *nvp, const char *fmt,...)
Definition: indidriver.c:1211
void IDSetSwitch(const ISwitchVectorProperty *svp, const char *fmt,...)
Definition: indidriver.c:1231
#define DEBUGDEVICE(device, priority, msg)
Definition: indilogger.h:60
#define DEBUGFDEVICE(device, priority, msg,...)
Definition: indilogger.h:61
Namespace to encapsulate INDI client, drivers, and mediator classes.
char name[MAXINDINAME]
Definition: indiapi.h:323
char name[MAXINDINAME]
Definition: indiapi.h:371