1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.indi.examples;
19
20 import java.io.IOException;
21 import java.util.Date;
22
23 import org.indi.clientmessages.GetProperties;
24 import org.indi.objects.Number;
25 import org.indi.objects.NumberVector;
26 import org.indi.objects.Permission;
27 import org.indi.objects.State;
28 import org.indi.objects.Switch;
29 import org.indi.objects.SwitchRule;
30 import org.indi.objects.SwitchVector;
31 import org.indi.reactor.TimerCallback;
32 import org.indi.server.BasicDevice;
33 import org.indi.server.IndiServer;
34
35
36
37
38
39
40
41
42
43 public class SimpleTelescopeSimulator extends BasicDevice implements
44 TimerCallback {
45
46
47
48 private final SwitchVector powerswitch;
49
50
51
52
53 private final String powervectorname = "CONNECTION";
54
55
56
57 private final String name = "Simple Telescope Simulator";
58
59
60
61 private final String groupname = "Main Control";
62
63
64
65 private final String coordvectorname = "EQUATORIAL_EOD_COORD";
66
67
68
69 private final String decname = "DEC";
70
71
72
73 private final String raname = "RA";
74
75
76
77 private Switch connectswitch = null;
78
79
80
81 private NumberVector coordinates = null;
82
83
84
85 private final long timeout = 250;
86
87
88
89 private final double sidrate = 0.004178;
90
91
92
93
94 private final double slewrate = 1.0;
95
96
97
98 private Double lastTime = null;
99
100
101
102
103 private Number ra = null;
104
105
106
107
108 private Number dec = null;
109
110
111
112 private double targetRA;
113
114
115
116 private double targetDEC;
117
118
119
120
121
122
123
124 public SimpleTelescopeSimulator(IndiServer server) {
125 super(server);
126 this.powerswitch = new SwitchVector(this.name, this.powervectorname,
127 "Connection", this.groupname, State.Idle, Permission.ReadWrite,
128 SwitchRule.OneOfMany, 0);
129 this.connectswitch = new Switch("CONNECT", "Connect", Switch.State.Off);
130 this.powerswitch.add(this.connectswitch);
131 this.powerswitch.add(new Switch("DISCONNECT", "Disconnect",
132 Switch.State.On));
133 this.coordinates = new NumberVector(this.name, this.coordvectorname,
134 "Equatorial JNow", this.groupname, State.Idle,
135 Permission.ReadWrite, 0);
136 this.ra = new Number(this.raname,
137 "RA H:M:S",
138 "%f",
139 0.,
140 24.,
141 0.,
142 0.
143 this.coordinates.add(this.ra);
144 this.dec = new Number(this.decname, "Dec D:M:S", "%f", -90., 90., 0.,
145 0.);
146 this.coordinates.add(this.dec);
147 def(this.powerswitch);
148 def(this.coordinates);
149 timer(this.timeout);
150 }
151
152 @Override
153 public void onNew(SwitchVector vector) {
154 if (!((this.powervectorname.equals(vector.getName())) && (this.name
155 .equals(vector.getDevice())))) {
156 return;
157 }
158 this.powerswitch.update(vector);
159 switch (this.connectswitch.getState()) {
160 case On:
161 this.powerswitch.setState(State.Ok);
162 set(this.powerswitch, "Connection to Simple Telescope Simulator"
163 + " is successful.");
164 break;
165 case Off:
166 this.powerswitch.setState(State.Idle);
167 set(this.powerswitch,
168 "Simple Telescope Simulator has been disconneced.");
169 this.coordinates.setState(State.Idle);
170 set(this.coordinates);
171 break;
172 }
173 }
174
175 @Override
176 public void onNew(NumberVector vector) {
177 if (!((this.coordvectorname.equals(vector.getName())) && (this.name
178 .equals(vector.getDevice())))) {
179 return;
180 }
181 if (this.connectswitch.getState() == Switch.State.Off) {
182 msg("Position discaded because Telescope is disconnected");
183 return;
184 }
185 if (this.powerswitch.getState() == State.Idle) {
186 this.coordinates.setState(State.Idle);
187 set(this.coordinates, "Telescope is offline");
188 }
189 double newra = 0, newdec = 0;
190 int nset = 0;
191 for (Number n : vector.getChlidren()) {
192 String name = n.getName();
193 if (name.equals(this.raname)) {
194 newra = n.getDouble();
195 nset += ((newra >= 0.) && (newra <= 24.)) ? 1 : 0;
196 }
197 if (name.equals(this.decname)) {
198 newdec = n.getDouble();
199 nset += ((newdec >= -90.) && (newdec <= 90.)) ? 1 : 0;
200 }
201 if (nset == 2) {
202 this.targetRA = newra;
203 this.targetDEC = newdec;
204 this.coordinates.setState(State.Busy);
205 set(this.coordinates, "Moving to RA Dec"
206 + Double.toString(newra) + " "
207 + Double.toString(newdec));
208 } else {
209 this.coordinates.setState(State.Idle);
210 set(this.coordinates, "RA or Dec absent or bogus");
211 }
212 }
213 }
214
215 @Override
216 public void onGetProperties(GetProperties o) {
217 def(this.powerswitch);
218 def(this.coordinates);
219 }
220
221
222
223
224
225
226
227
228
229 public static void main(String[] args) throws IOException {
230 IndiServer s = new IndiServer();
231 new SimpleTelescopeSimulator(s);
232 while (true) {
233 s.reactor.handleEvents(10);
234 }
235 }
236
237 @Override
238 public void onTimer() {
239 double time = new Date().getTime();
240 if (this.lastTime == null) {
241 this.lastTime = time;
242 }
243 double dt = (time - this.lastTime) / 1000.0;
244 this.lastTime = time;
245 switch (this.coordinates.getState()) {
246 case Idle:
247 this.ra.addDouble((this.sidrate * dt / 15.));
248 set(this.coordinates);
249 break;
250 case Busy:
251 double da = this.slewrate * dt;
252 int nlocked = 0;
253 double dx = this.targetRA - this.ra.getDouble();
254 if (Math.abs(dx) <= da / 15.) {
255 this.ra.setDouble(this.targetRA);
256 nlocked++;
257 } else if (dx > 0) {
258 this.ra.addDouble(da / 15.);
259 } else {
260 this.ra.subtractDouble(da / 15.);
261 }
262
263 dx = this.targetDEC - this.dec.getDouble();
264 if (Math.abs(dx) <= da) {
265 this.dec.setDouble(this.targetDEC);
266 nlocked++;
267 } else if (dx > 0) {
268 this.dec.addDouble(da);
269 } else {
270 this.dec.subtractDouble(da);
271 }
272 if (nlocked == 2) {
273 this.coordinates.setState(State.Ok);
274 msg("Now tracking");
275 }
276 set(this.coordinates);
277 break;
278 case Ok:
279 set(this.coordinates);
280 break;
281 case Alert:
282 set(this.coordinates);
283 break;
284 }
285 timer(this.timeout);
286 }
287 }