1 /*******************************************************************************
2 Dome Simulator
3 Copyright(c) 2014 Jasem Mutlaq. All rights reserved.
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License version 2 as published by the Free Software Foundation.
8 .
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13 .
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
18 *******************************************************************************/
19 #include "dome_simulator.h"
20
21 #include "indicom.h"
22
23 #include <cmath>
24 #include <memory>
25 #include <unistd.h>
26
27 // We declare an auto pointer to domeSim.
28 static std::unique_ptr<DomeSim> domeSim(new DomeSim());
29
30 #define DOME_SPEED 10.0 /* 10 degrees per second, constant */
31 #define SHUTTER_TIMER 5.0 /* Shutter closes/open in 5 seconds */
32
DomeSim()33 DomeSim::DomeSim()
34 {
35 targetAz = 0;
36 shutterTimer = 0;
37 prev_az = 0;
38 prev_alt = 0;
39
40 SetDomeCapability(DOME_CAN_ABORT | DOME_CAN_ABS_MOVE | DOME_CAN_REL_MOVE | DOME_CAN_PARK | DOME_HAS_SHUTTER);
41 }
42
43 /************************************************************************************
44 *
45 * ***********************************************************************************/
initProperties()46 bool DomeSim::initProperties()
47 {
48 INDI::Dome::initProperties();
49
50 SetParkDataType(PARK_AZ);
51
52 addAuxControls();
53
54 return true;
55 }
56
SetupParms()57 bool DomeSim::SetupParms()
58 {
59 targetAz = 0;
60 shutterTimer = SHUTTER_TIMER;
61
62 DomeAbsPosN[0].value = 0;
63
64 DomeParamN[0].value = 5;
65
66 IDSetNumber(&DomeAbsPosNP, nullptr);
67 IDSetNumber(&DomeParamNP, nullptr);
68
69 if (InitPark())
70 {
71 // If loading parking data is successful, we just set the default parking values.
72 SetAxis1ParkDefault(90);
73 }
74 else
75 {
76 // Otherwise, we set all parking data to default in case no parking data is found.
77 SetAxis1Park(90);
78 SetAxis1ParkDefault(90);
79 }
80
81 return true;
82 }
83
getDefaultName()84 const char *DomeSim::getDefaultName()
85 {
86 return "Dome Simulator";
87 }
88
updateProperties()89 bool DomeSim::updateProperties()
90 {
91 INDI::Dome::updateProperties();
92
93 if (isConnected())
94 {
95 SetupParms();
96 }
97
98 return true;
99 }
100
Connect()101 bool DomeSim::Connect()
102 {
103 SetTimer(1000); // start the timer
104 return true;
105 }
106
Disconnect()107 bool DomeSim::Disconnect()
108 {
109 return true;
110 }
111
TimerHit()112 void DomeSim::TimerHit()
113 {
114 int nexttimer = 1000;
115
116 if (!isConnected())
117 return; // No need to reset timer if we are not connected anymore
118
119 if (DomeAbsPosNP.s == IPS_BUSY)
120 {
121 if (targetAz > DomeAbsPosN[0].value)
122 {
123 DomeAbsPosN[0].value += DOME_SPEED;
124 }
125 else if (targetAz < DomeAbsPosN[0].value)
126 {
127 DomeAbsPosN[0].value -= DOME_SPEED;
128 }
129
130 DomeAbsPosN[0].value = range360(DomeAbsPosN[0].value);
131
132 if (fabs(targetAz - DomeAbsPosN[0].value) <= DOME_SPEED)
133 {
134 DomeAbsPosN[0].value = targetAz;
135 LOG_INFO("Dome reached requested azimuth angle.");
136
137 if (getDomeState() == DOME_PARKING)
138 SetParked(true);
139 else if (getDomeState() == DOME_UNPARKING)
140 SetParked(false);
141 else
142 setDomeState(DOME_SYNCED);
143 }
144
145 IDSetNumber(&DomeAbsPosNP, nullptr);
146 }
147
148 if (DomeShutterSP.s == IPS_BUSY)
149 {
150 if (shutterTimer-- <= 0)
151 {
152 shutterTimer = 0;
153 DomeShutterSP.s = IPS_OK;
154 LOGF_INFO("Shutter is %s.", (DomeShutterS[0].s == ISS_ON ? "open" : "closed"));
155 IDSetSwitch(&DomeShutterSP, nullptr);
156
157 if (getDomeState() == DOME_UNPARKING)
158 SetParked(false);
159 }
160 }
161 SetTimer(nexttimer);
162 }
163
Move(DomeDirection dir,DomeMotionCommand operation)164 IPState DomeSim::Move(DomeDirection dir, DomeMotionCommand operation)
165 {
166 if (operation == MOTION_START)
167 {
168 targetAz = (dir == DOME_CW) ? 1e6 : -1e6;
169 DomeAbsPosNP.s = IPS_BUSY;
170 }
171 else
172 {
173 targetAz = 0;
174 DomeAbsPosNP.s = IPS_IDLE;
175 }
176
177 IDSetNumber(&DomeAbsPosNP, nullptr);
178 return ((operation == MOTION_START) ? IPS_BUSY : IPS_OK);
179 }
180
MoveAbs(double az)181 IPState DomeSim::MoveAbs(double az)
182 {
183 targetAz = az;
184
185 // Requested position is within one cycle, let's declare it done
186 if (fabs(az - DomeAbsPosN[0].value) < DOME_SPEED)
187 return IPS_OK;
188
189 // It will take a few cycles to reach final position
190 return IPS_BUSY;
191 }
192
MoveRel(double azDiff)193 IPState DomeSim::MoveRel(double azDiff)
194 {
195 targetAz = DomeAbsPosN[0].value + azDiff;
196 ;
197
198 if (targetAz < DomeAbsPosN[0].min)
199 targetAz += DomeAbsPosN[0].max;
200 if (targetAz > DomeAbsPosN[0].max)
201 targetAz -= DomeAbsPosN[0].max;
202
203 // Requested position is within one cycle, let's declare it done
204 if (fabs(targetAz - DomeAbsPosN[0].value) < DOME_SPEED)
205 return IPS_OK;
206
207 // It will take a few cycles to reach final position
208 return IPS_BUSY;
209 }
210
Park()211 IPState DomeSim::Park()
212 {
213 targetAz = DomeParamN[0].value;
214 Dome::ControlShutter(SHUTTER_CLOSE);
215 Dome::MoveAbs(GetAxis1Park());
216
217 return IPS_BUSY;
218 }
219
UnPark()220 IPState DomeSim::UnPark()
221 {
222 return Dome::ControlShutter(SHUTTER_OPEN);
223 }
224
ControlShutter(ShutterOperation operation)225 IPState DomeSim::ControlShutter(ShutterOperation operation)
226 {
227 INDI_UNUSED(operation);
228 shutterTimer = SHUTTER_TIMER;
229 return IPS_BUSY;
230 }
231
Abort()232 bool DomeSim::Abort()
233 {
234 // If we abort while in the middle of opening/closing shutter, alert.
235 if (DomeShutterSP.s == IPS_BUSY)
236 {
237 DomeShutterSP.s = IPS_ALERT;
238 IDSetSwitch(&DomeShutterSP, "Shutter operation aborted. Status: unknown.");
239 return false;
240 }
241
242 return true;
243 }
244
SetCurrentPark()245 bool DomeSim::SetCurrentPark()
246 {
247 SetAxis1Park(DomeAbsPosN[0].value);
248 return true;
249 }
250
SetDefaultPark()251 bool DomeSim::SetDefaultPark()
252 {
253 // By default set position to 90
254 SetAxis1Park(90);
255 return true;
256 }
257