Statistics
| Revision:

svn-gvsig-desktop / trunk / extensions / extGPS / src / org / gvsig / gps / GPSDriver.java @ 4749

History | View | Annotate | Download (9.13 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2005 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program 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
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 *
19
 * For more information, contact:
20
 *
21
 *  Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib??ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *      +34 963862235
28
 *   gvsig@gva.es
29
 *      www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   IVER T.I. S.A
34
 *   Salamanca 50
35
 *   46005 Valencia
36
 *   Spain
37
 *
38
 *   +34 963163400
39
 *   dac@iver.es
40
 */
41

    
42
/* CVS MESSAGES:
43
*
44
* $Id: GPSDriver.java 4749 2006-04-05 17:08:18Z jaume $
45
* $Log$
46
* Revision 1.1  2006-04-05 17:08:18  jaume
47
* *** empty log message ***
48
*
49
* Revision 1.2  2006/04/03 21:07:35  jaume
50
* *** empty log message ***
51
*
52
* Revision 1.1  2006/04/03 16:10:27  jaume
53
* *** empty log message ***
54
*
55
* Revision 1.1  2006/03/31 09:55:34  jaume
56
* *** empty log message ***
57
*
58
*
59
*/
60
package org.gvsig.gps;
61

    
62
import gnu.io.CommPortIdentifier;
63
import gnu.io.PortInUseException;
64
import gnu.io.SerialPort;
65
import gnu.io.UnsupportedCommOperationException;
66

    
67
import java.io.IOException;
68
import java.io.InputStream;
69
import java.io.OutputStream;
70
import java.util.ArrayList;
71
import java.util.Enumeration;
72
import java.util.Hashtable;
73
import java.util.Iterator;
74

    
75
import org.gvsig.gps.listeners.GPSEventListener;
76
import org.gvsig.gps.parser.NMEA.GGASentence;
77
import org.gvsig.gps.parser.NMEA.IllegalSentenceException;
78
import org.gvsig.gps.parser.NMEA.NMEASentence;
79
import org.gvsig.gps.parser.NMEA.NMEASentenceFactory;
80
import org.gvsig.gps.parser.NMEA.RMCSentence;
81
import org.gvsig.gps.parser.NMEA.VTGSentence;
82

    
83
public class GPSDriver extends Thread {
84
        
85
        private ArrayList eventListeners = new ArrayList();
86
        
87
        // The timeOut field specifies how long a value received from the device
88
        // is valid. After this time, no more events of the corresponding class
89
        // will be fired.
90
        private static final long timeOut = 60 * 1000; // 60 seconds.
91
        
92
        private SerialPort serialPort = null;
93
        private InputStream inputStream;
94
        private OutputStream outputStream;
95

    
96
        private Hashtable register        = new Hashtable();
97
        private int rate = 1000;
98
        private long lastSampleTime;
99
        private boolean eventsEnabled;
100
        private static GPSDriver instance = null;
101
        
102
        private GPSDriver() {};
103
        
104
        public static GPSDriver getInstance() {
105
                if (instance == null) 
106
                        instance = new GPSDriver();
107
                return instance;
108
        }
109
        
110
        public void setPort(CommPortIdentifier portID, int portSpeed) throws PortInUseException{
111
                closePort();
112
                serialPort = (SerialPort) portID.open("gvSIG", portSpeed);
113
                try {
114
                        inputStream = serialPort.getInputStream();
115
                        outputStream = serialPort.getOutputStream();
116
                        serialPort.setSerialPortParams(
117
                                                                portSpeed, 
118
                                                                SerialPort.DATABITS_8,
119
                                                                SerialPort.STOPBITS_1,
120
                                                                SerialPort.PARITY_NONE
121
                                                );
122

    
123
                } catch (UnsupportedCommOperationException e) {
124
                        e.printStackTrace();
125
                } catch (IOException e) {
126
                        e.printStackTrace();
127
                }
128
        }
129
        
130
        /**
131
         * Tells the driver to start monitoring and capturing data from the device.
132
         */
133
        public void start() {
134
                eventsEnabled = true;
135
                if (!this.isAlive())
136
                        super.start();
137
        }
138
        
139
        public void run() {
140
                byte[] readBuffer = new byte[2048];
141
                StringBuffer line = new StringBuffer();
142
                try {
143
                        for (int bytes = inputStream.read(readBuffer); bytes>-1; bytes = inputStream.read(readBuffer)){
144
                                // Creates a new buffer to contain the previous readed bytes and the next bunch of bytes
145
                                String str = new String(readBuffer).substring(0, bytes);
146
                                int i = str.indexOf("\n");
147
                                if (i == -1) {
148
                                        line.append(str);
149
                                } else {
150
                                        line.append(str.substring(0,i));
151
                                        analyzeMessage(line.toString());
152
                                        line = new StringBuffer();
153
                                        line.append(str.substring(i+1,str.length()));
154
                                }
155
                        }
156
                } catch (IOException e) {
157
                        e.printStackTrace();
158
                }
159
                try {
160
                        System.err.println("Sending request");
161
                        outputStream.write(new String("$PMCAG,005,1,GGA,001").getBytes());
162
                        for (int bytes = inputStream.read(readBuffer); bytes>-1; bytes = inputStream.read(readBuffer)){
163
                                // Creates a new buffer to contain the previous readed bytes and the next bunch of bytes
164
                                String str = new String(readBuffer).substring(0, bytes);
165
                                int i = str.indexOf("\n");
166
                                if (i == -1) {
167
                                        line.append(str);
168
                                } else {
169
                                        line.append(str.substring(0,i));
170
                                        analyzeMessage(line.toString());
171
                                        try {
172
                                                sleep(rate);
173
                                        } catch (InterruptedException e) {
174
                                                // TODO Auto-generated catch block
175
                                                e.printStackTrace();
176
                                        }
177
                                        line = new StringBuffer();
178
                                        line.append(str.substring(i+1,str.length()));
179
                                }
180
                        }
181
                } catch (IOException e) {
182
                        e.printStackTrace();
183
                }
184
                
185
        }
186
        
187
        private void analyzeMessage(String line) {
188
                try {
189
                        NMEASentence data = NMEASentenceFactory.createFromString(line);
190
                        NMEASentence oldData = (NMEASentence) register.get(data.getName());
191
                        boolean mustNotifyListeners = !data.isEquivalentTo(oldData);
192
                        register.put(data.getName(), data);
193
                        //if (mustNotifyListeners)
194
                                fireEvents();
195
                } catch (IllegalSentenceException e) {
196
//                        if (eventsEnabled && line!=null)
197
//                                NotificationManager.addWarning("Unrecognized sentence: "+line, null);
198
                }
199
                
200
        }
201
        
202
        public void setSampleRate(int millis) {
203
                this.rate = millis;
204
        }
205
        
206
        
207
        public void addEventListener(GPSEventListener l) {
208
                eventListeners.add(l);
209
        }
210
        
211
        private void fireEvents() {
212
                Iterator it = eventListeners.iterator();
213
                while (eventsEnabled && it.hasNext()) {
214
                        GPSEventListener l = (GPSEventListener) it.next();
215
                        if (System.currentTimeMillis() - lastSampleTime  >= rate ) {
216
                                Iterator i = register.keySet().iterator();
217
                                while (i.hasNext()) {
218
                                        NMEASentence aux = (NMEASentence) register.get(i.next());
219
                                        if (isCurrent(aux)) {
220
                                                // This is a valid record
221
                                                if (aux instanceof GGASentence) {
222
                                                        GGASentence s = (GGASentence) aux;
223
                                                        l.newLonLatPositionReceived(s.getLongitude(), s.getLatitude());
224
                                                } else if (aux instanceof RMCSentence) {
225
                                                        // TODO
226
                                                        l.unhandledMessage(aux.toString());
227
                                                } else if (aux instanceof VTGSentence) {
228
                                                        VTGSentence s = (VTGSentence) aux;
229
                                                        l.speedChanged(s.getSpeed(), s.getCourse());
230
                                                } else {
231
                                                        l.unhandledMessage(aux.toString());
232
                                                }
233
                                        } else {
234
                                                // This record is too old.
235
                                                register.remove(aux);
236
                                        }
237
                                }
238

    
239
                                lastSampleTime = System.currentTimeMillis();
240
                        }
241
                }
242
        }
243
        
244
        private boolean isCurrent(NMEASentence n) {
245
                return System.currentTimeMillis() - n.getTime() < timeOut;
246
        }
247
        
248
        /**
249
         * Silences the event firing. To resume the event firing just call <b>start()</b> method.  
250
         */
251
        public void silence() {
252
                eventsEnabled = false;
253
        }
254
        
255
        public static void main(String[] args) {
256
                if (args.length < 1) {
257
                        System.out.print("GPSReader port\n");
258
                        System.exit(-1);
259
                }
260
                Enumeration portList = CommPortIdentifier.getPortIdentifiers();
261
                while (portList.hasMoreElements()) {
262
                        CommPortIdentifier myPortId = (CommPortIdentifier) portList.nextElement();
263
                        if (myPortId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
264
                                if (myPortId.getName().equals(args[0])) {
265
                                        try {
266
                                                GPSDriver reader = GPSDriver.getInstance();
267
                                                reader.setPort(myPortId, 4800);
268
                                                reader.setSampleRate(100);
269
                                                reader.addEventListener(new GPSEventListener() {
270

    
271
                                                        public void unhandledMessage(String msg) {
272
                                                                System.out.println("UNHANDLED: "+msg);
273
                                                        }
274

    
275

    
276
                                                        public void connectionLost() {
277
                                                                System.out.println("CONNECTION LOST");        
278
                                                        }
279

    
280
                                                        public void connectionEstablished() {
281
                                                                System.out.println("CONNECTION ESTABLISHED");
282
                                                        }
283

    
284
                                                        public void newLonLatPositionReceived(double lon, double lat) {
285
                                                                System.out.println("NEW LONLAT POSITION RECEIVED: ("+lon+", "+lat+")");
286
                                                        }
287

    
288
                                                        public void signalLevelChanged(float level) {
289
                                                                System.out.println("NEW SIGNAL LEVEL: "+level);
290
                                                        }
291

    
292
                                                        public void speedChanged(float speed, short course) {
293
                                                                System.out.println("SPEED/COURSE CHANGED: ( "+speed+" Km/h, "+course+" degrees)");
294
                                                        }
295

    
296
                                                        public void estimatedPosErrorChanged(double f) {
297
                                                        }
298

    
299
                                                        public void heightChanged() {
300
                                                        }
301
                                                        
302
                                                });
303
                                                reader.start();
304
                                        } catch (PortInUseException e) {
305
                                                System.err.println("Port busy");
306
                                        }
307
                                        
308
                                }
309
                        }
310
                }
311
        }
312

    
313
        public void closePort() {
314
                if (serialPort != null) {
315
                        serialPort.notifyOnDataAvailable(false);
316
                        serialPort.removeEventListener();
317
                        if (inputStream != null) {
318
                                try {
319
                                        inputStream.close();
320
                                        inputStream = null;
321
                                }
322
                                catch (IOException e) {}
323
                        }
324
                        if (outputStream != null) {
325
                                try {
326
                                        outputStream.close();
327
                                        outputStream = null;
328
                                }
329
                                catch (IOException e) {}
330
                        }
331
                        serialPort.close();
332
                        serialPort = null;
333
                }
334
        }
335
        
336
}