1 /*
2 * CelestronCoordinateConverter.java
3 *
4 * Copyright (c) 2003, Raben Systems, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 *
13 * Redistributions in binary form must reproduce the above copyright notice,
14 * this list of conditions and the following disclaimer in the documentation
15 * and/or other materials provided with the distribution.
16 *
17 * Neither the name of Raben Systems, Inc. nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 *
33 */
34
35 package com.raben.telescope.comm;
36 import java.awt.geom.Point2D;
37
38 /***
39 * Facade to encode and decode Celestron coordinate formats
40 * @author Vern Raben
41 */
42 public class CelestronCoordinateConverter {
43
44 /*** Constant for 2 raised to 16th power */
45 private static final double TWO_EXP_16 = 65536.0; // 2 ^ 16
46
47 /*** Constant for 2 raised to 24th power */
48 private static final double TWO_EXP_24 = 16777216.0; // 2 ^ 24;
49
50 /*** Constant for 2 raised to 32nd power */
51 private static final double TWO_EXP_32 = 4294967296.0; // 2 ^ 32
52
53 /*** 16 bit constant to convert degrees to step count required for goto */
54 private static final double DEGREES_TO_COUNT_16 = TWO_EXP_16 / 360.0;
55
56 /*** 24 bit constant to convert degrees to step count required for goto */
57 private static final double DEGREES_TO_COUNT_24 = TWO_EXP_24 / 360.0;
58
59 /*** 16 bit constant to convert count to degrees */
60 private static final double COUNT_TO_DEGREES_16 = 360.0 / TWO_EXP_16;
61
62 /*** 24 bit constant to convert count to degrees */
63 private static final double COUNT_TO_DEGREES_24 = 360.0 / TWO_EXP_24;
64
65 /*** String containing zeros, used for padding */
66 private static final String STR0 = "00000000";
67
68 /*** TelescopeModel selected */
69 private TelescopeModel telescopeModel =
70 TelescopeModel.CELESTRON_NEXSTAR_GPS;
71
72 /*** Precision of encode/decode */
73 private boolean highPrecision = true;
74
75 /*** Creates a new instance of CelestronCoordinateAdapater */
76 public CelestronCoordinateConverter() {
77 }
78
79 /***
80 * Encode angle as hexadecimal value
81 * @param val Angle to be encoded
82 * @return Hexadecimal string for encode precision
83 */
84 public String encodeHexadecimal(double val) {
85 String str = "";
86
87 if (isHighPrecision()) {
88 str = encodeHexadecimal24(val);
89 } else {
90 str = encodeHexadecimal16(val);
91 }
92
93 return str;
94 }
95
96
97 /*** Encode as 16 bit hexadecimal value
98 * @param val Value to be converted
99 * @return String containing coordinate encoded as a hexadecimal
100 */
101 public String encodeHexadecimal16(double val) {
102 String str = "";
103
104 if (!Double.isNaN(val)) {
105
106 long val1 = Math.round(normalizeAngle(val) * DEGREES_TO_COUNT_16);
107
108 // Convert val1 to hex
109 str = Long.toHexString(val1);
110
111 // Pad str with zeros
112 if (str.length() < 4) {
113 str = STR0.substring(0, 4 - str.length()) + str;
114 }
115
116 }
117
118 return str.toUpperCase();
119 }
120
121 /***
122 * Normalize angle to be in range 0 to 360
123 * @param val angle in degrees
124 * @return angle in range 0 to 360
125 */
126 private double normalizeAngle(double val) {
127
128 while (val >= 360.0) {
129 val -= 360.0;
130 }
131
132 while (val < 0) {
133 val += 360.0;
134 }
135
136 return val;
137 }
138
139 /*** Encode as 24 bit hexadecimal value
140 * @param val Value to be converted
141 * @return String containing coordinate encoded as a hexadecimal
142 */
143 public String encodeHexadecimal24(double val) {
144 String str = "";
145
146 if (!Double.isNaN(val)) {
147 long val1 = Math.round(normalizeAngle(val) * DEGREES_TO_COUNT_24);
148
149 // Convert val1 to hex
150 str = Long.toHexString(val1);
151
152 // Pad str1 with zeros
153 if (str.length() < 6) {
154 str = STR0.substring(0, 6 - str.length()) + str;
155 }
156
157 str = str + "00";
158
159 }
160
161 return str.toUpperCase();
162 }
163
164 /***
165 * Decode hexadecimal format which does not contain comma or null separator
166 * @param str String containing the coordinate
167 * @param coord Reference to the coordinate to be returned
168 */
169 private void decodeHexadecimalFormat1(String str, Point2D coord) {
170 String str1 = str.substring(0, 4);
171 String str2 = str.substring(4, 8);
172 long val1 = Long.parseLong(str1, 16);
173 long val2 = Long.parseLong(str2, 16);
174 coord.setLocation((double) val1 * COUNT_TO_DEGREES_16,
175 (double) val2 * COUNT_TO_DEGREES_16);
176 }
177
178 /***
179 * Decode hexadecimal format which contains comma or null separator
180 * @param str String containing the coordinate
181 * @param coord Reference to the coordinate to be returned
182 */
183 private void decodeHexadecimalFormat2(String str, Point2D coord) {
184
185 String str1 = "";
186 String str2 = "";
187 long val1 = 0L;
188 long val2 = 0L;
189
190 if (isHighPrecision()) {
191 str1 = str.substring(0, 6);
192 str2 = str.substring(9, 15);
193 val1 = Long.parseLong(str1, 16);
194 val2 = Long.parseLong(str2, 16);
195 coord.setLocation((double) val1 * COUNT_TO_DEGREES_24,
196 (double) val2 * COUNT_TO_DEGREES_24);
197 } else {
198
199 str1 = str.substring(0, 4);
200 str2 = str.substring(5, 9);
201 val1 = Long.parseLong(str1, 16);
202 val2 = Long.parseLong(str2, 16);
203 coord.setLocation((double) val1 * COUNT_TO_DEGREES_16,
204 (double) val2 * COUNT_TO_DEGREES_16);
205 }
206
207 }
208
209 /***
210 * Decode hexadecimal string
211 * @param str String containing coordinate from telescope
212 * @param coord Point2D coordinate to be set
213 */
214 public void decodeHexadecimal(String str, Point2D coord) {
215
216 if ((str != null) && (str.length() >= 8)) {
217
218 String str1 = null;
219 String str2 = null;
220 long val1 = 0L;
221 long val2 = 0L;
222
223 if ((telescopeModel.equals(TelescopeModel.CELESTRON_CGE))
224 || (telescopeModel.equals(TelescopeModel.CELESTRON_NEXSTAR_GPS))
225 || (telescopeModel.equals(TelescopeModel.CELESTRON_NEXSTAR_GT))
226 || (telescopeModel.equals(TelescopeModel.CELESTRON_CGE))
227 || (telescopeModel.equals(TelescopeModel.CELESTRON_ASC))
228 || (telescopeModel.equals(
229 TelescopeModel.CELESTRON_NEXSTAR_5I_8I))) {
230 decodeHexadecimalFormat2(str, coord);
231
232 } else if (telescopeModel.equals(
233 TelescopeModel.CELESTRON_NEXSTAR_5_8)) {
234 decodeHexadecimalFormat1(str, coord);
235 } else {
236 // ISSUE - should throw exception here
237 System.err.println("Error - decodeHexadecimal TelescopeModel "
238 + telescopeModel + " not handled");
239 }
240
241
242
243
244 }
245
246 }
247
248 /***
249 * Set whether encode/decode should be high precision (24 bit)
250 * @param precision True if high precision is to be used
251 */
252 public void setHighPrecision(boolean precision) {
253 this.highPrecision = precision;
254 }
255
256 /***
257 * Returns whether precision is high or not
258 * @return boolean true if high precision
259 */
260 public boolean isHighPrecision() {
261 return highPrecision;
262 }
263
264 /***
265 * Set the Telescope model
266 * @param telescopeModel to be used
267 */
268 public void setTelescopeModel(TelescopeModel telescopeModel) {
269 this.telescopeModel = telescopeModel;
270
271 if ((telescopeModel.equals(TelescopeModel.CELESTRON_NEXSTAR_5_8))
272 || (telescopeModel.equals(TelescopeModel.CELESTRON_NEXSTAR_OGT))
273 || (telescopeModel.equals(TelescopeModel.CELESTRON_NEXSTAR_GT))) {
274 setHighPrecision(false);
275 } else {
276 setHighPrecision(true);
277 }
278
279 }
280
281 /***
282 * Get the Telescope model
283 * @return Model of telescope
284 */
285 public TelescopeModel getTelescopeModel() {
286 return this.telescopeModel;
287 }
288
289 /***
290 * Return String representation of CelestronCoordinateAdapter
291 * @return String containing TelescopeModel and highPrecision flag
292 */
293 public String toString() {
294 StringBuffer buf = new StringBuffer(getClass().getName());
295 buf.append("[telescopeModel=");
296 buf.append(getTelescopeModel().toString());
297 buf.append(", highPrecision=");
298 buf.append(isHighPrecision());
299 buf.append("]");
300 return buf.toString();
301 }
302
303
304
305 }
This page was automatically generated by Maven