r587 - in trunk: . sammoa-application sammoa-application/src/main/java/fr/ulr/sammoa/application/device/gps sammoa-application/src/main/java/org/dinopolis/gpstool/gpsinput sammoa-application/src/main/java/org/dinopolis/gpstool/gpsinput/nmea sammoa-ui-swing/src/main/assembly sammoa-ui-swing/src/main/assembly/x64 sammoa-ui-swing/src/main/assembly/x86
Author: fdesbois Date: 2012-09-21 19:18:29 +0200 (Fri, 21 Sep 2012) New Revision: 587 Url: http://forge.codelutin.com/repositories/revision/sammoa/587 Log: fixes #1457 : - use nrjavaserial (rxtx recent fork) instead of rxtx java library - create GPSNRSerialDevice impl for Gpsylon to use nrjavaserial - remove no more used (encapsulated in nrjavaserial) native libraries - improve SafeGPSNmeaDataProcessor to check if processor is opened on all loops (during reading thread) - improve begin state after open (only if we receive data, the state becomes READY) Added: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/gps/GPSNRSerialDevice.java Removed: trunk/sammoa-application/src/main/java/org/dinopolis/gpstool/gpsinput/SafeGPSSerialDevice.java trunk/sammoa-ui-swing/src/main/assembly/sammoa64.bat trunk/sammoa-ui-swing/src/main/assembly/sammoa64.sh trunk/sammoa-ui-swing/src/main/assembly/x64/librxtxSerial.so trunk/sammoa-ui-swing/src/main/assembly/x64/rxtxSerial.dll trunk/sammoa-ui-swing/src/main/assembly/x86/librxtxSerial.so trunk/sammoa-ui-swing/src/main/assembly/x86/rxtxSerial.dll Modified: trunk/pom.xml trunk/sammoa-application/pom.xml trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/gps/GpsHandlerGpsylon.java trunk/sammoa-application/src/main/java/org/dinopolis/gpstool/gpsinput/nmea/SafeGPSNmeaDataProcessor.java trunk/sammoa-ui-swing/src/main/assembly/bin.xml trunk/sammoa-ui-swing/src/main/assembly/sammoa.bat trunk/sammoa-ui-swing/src/main/assembly/sammoa.sh Modified: trunk/pom.xml =================================================================== --- trunk/pom.xml 2012-09-21 13:00:10 UTC (rev 586) +++ trunk/pom.xml 2012-09-21 17:18:29 UTC (rev 587) @@ -399,13 +399,26 @@ <groupId>org.dinopolis.gpstool</groupId> <artifactId>gpsinput</artifactId> <version>0.5.3</version> + <exclusions> + <exclusion> + <groupId>org.rxtx</groupId> + <artifactId>rxtx</artifactId> + </exclusion> + </exclusions> </dependency> + <!--<dependency>--> + <!--<groupId>org.rxtx</groupId>--> + <!--<artifactId>rxtx</artifactId>--> + <!--<version>2.1.7</version>--> + <!--</dependency>--> + <dependency> - <groupId>org.rxtx</groupId> - <artifactId>rxtx</artifactId> - <version>2.1.7</version> + <groupId>com.neuronrobotics</groupId> + <artifactId>nrjavaserial</artifactId> + <version>3.7.5.1</version> </dependency> + </dependencies> </dependencyManagement> Modified: trunk/sammoa-application/pom.xml =================================================================== --- trunk/sammoa-application/pom.xml 2012-09-21 13:00:10 UTC (rev 586) +++ trunk/sammoa-application/pom.xml 2012-09-21 17:18:29 UTC (rev 587) @@ -38,8 +38,8 @@ </dependency> <dependency> - <groupId>org.rxtx</groupId> - <artifactId>rxtx</artifactId> + <groupId>com.neuronrobotics</groupId> + <artifactId>nrjavaserial</artifactId> </dependency> <!-- util dependencies --> Added: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/gps/GPSNRSerialDevice.java =================================================================== --- trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/gps/GPSNRSerialDevice.java (rev 0) +++ trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/gps/GPSNRSerialDevice.java 2012-09-21 17:18:29 UTC (rev 587) @@ -0,0 +1,124 @@ +package fr.ulr.sammoa.application.device.gps; + +import com.google.common.base.Preconditions; +import gnu.io.NRSerialPort; +import gnu.io.NativeResourceException; +import org.dinopolis.gpstool.gpsinput.GPSDevice; +import org.dinopolis.gpstool.gpsinput.GPSException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Hashtable; + +/** + * Created: 21/09/12 + * + * @author fdesbois <florian.desbois@codelutin.com> + */ +public class GPSNRSerialDevice implements GPSDevice { + + /** Logger. */ + private static final Logger logger = LoggerFactory.getLogger(GPSNRSerialDevice.class); + + public final static String PORT_NAME_KEY = "port_name"; + public final static String PORT_SPEED_KEY = "port_speed"; + + protected final static String DEFAULT_PORT_NAME_LINUX = "/dev/ttyS1"; + protected final static String DEFAULT_PORT_NAME_WIN = "COM1"; + protected final static int DEFAULT_PORT_SPEED = 4800; + + protected String serialPortName; + + protected NRSerialPort serialPort; + + @Override + public void init(Hashtable environment) throws GPSException { + + try { + + if (environment.containsKey(PORT_NAME_KEY)) { + serialPortName = (String) environment.get(PORT_NAME_KEY); + + } else if (System.getProperty("os.name").toLowerCase().startsWith("windows")) { + serialPortName = DEFAULT_PORT_NAME_WIN; + + } else { + serialPortName = DEFAULT_PORT_NAME_LINUX; + } + + final int serialPortSpeed; + if (environment.containsKey(PORT_SPEED_KEY)) { + serialPortSpeed = ((Integer) environment.get(PORT_SPEED_KEY)).intValue(); + + } else { + serialPortSpeed = DEFAULT_PORT_SPEED; + } + + serialPort = new NRSerialPort(serialPortName, serialPortSpeed); + + } catch (Exception ex) { + throw new GPSException("Invalid environment set for serial " + + "connection : " + ex.getMessage(), ex); + } + } + + @Override + public void open() throws GPSException { + Preconditions.checkState(serialPort != null, + "Please use init() method to prepare serialDevice"); + + try { + boolean response = serialPort.connect(); + if (!response) { + throw new GPSException("Unable to connect to the SerialPort " + + serialPortName); + } + + if (logger.isInfoEnabled()) { + logger.info("Serial port {} is opened", serialPortName); + } + + } catch (NativeResourceException ex) { + throw new GPSException("Native exception on open SerialPort " + + serialPortName + " : " + ex.getMessage(), ex); + + } catch (Exception ex) { + throw new GPSException("Unexpected exception on open SerialPort " + + serialPortName + " : " + ex.getMessage(), ex); + } + } + + @Override + public void close() throws GPSException { + try { + if (serialPort != null) { + serialPort.disconnect(); + + if (logger.isInfoEnabled()) { + logger.info("Serial port {} is closed", serialPortName); + } + } + + } catch (NativeResourceException ex) { + throw new GPSException("Native exception on close SerialPort " + + serialPortName + " : " + ex.getMessage(), ex); + + } catch (Exception ex) { + throw new GPSException("Unexpected exception on close SerialPort " + + serialPortName + " : " + ex.getMessage(), ex); + } + } + + @Override + public InputStream getInputStream() throws IOException { + return serialPort != null ? serialPort.getInputStream() : null; + } + + @Override + public OutputStream getOutputStream() throws IOException { + return serialPort != null ? serialPort.getOutputStream() : null; + } +} Property changes on: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/gps/GPSNRSerialDevice.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Modified: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/gps/GpsHandlerGpsylon.java =================================================================== --- trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/gps/GpsHandlerGpsylon.java 2012-09-21 13:00:10 UTC (rev 586) +++ trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/device/gps/GpsHandlerGpsylon.java 2012-09-21 17:18:29 UTC (rev 587) @@ -35,7 +35,6 @@ import org.dinopolis.gpstool.gpsinput.GPSDevice; import org.dinopolis.gpstool.gpsinput.GPSException; import org.dinopolis.gpstool.gpsinput.GPSPosition; -import org.dinopolis.gpstool.gpsinput.GPSSerialDevice; import org.dinopolis.gpstool.gpsinput.nmea.SafeGPSNmeaDataProcessor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -80,7 +79,7 @@ @Override public void open() throws DeviceTechnicalException { - if (getState() == DeviceState.READY) { + if (opened) { if (logger.isWarnEnabled()) { logger.warn("GPS already opened"); } @@ -93,11 +92,11 @@ gpsDataProcessor = new SafeGPSNmeaDataProcessor(); - gpsDevice = new GPSSerialDevice(); + gpsDevice = new GPSNRSerialDevice(); Hashtable<String, Object> options = new Hashtable<String, Object>(); - options.put(GPSSerialDevice.PORT_NAME_KEY, getConfig().getDevice()); - options.put(GPSSerialDevice.PORT_SPEED_KEY, getConfig().getSpeed()); + options.put(GPSNRSerialDevice.PORT_NAME_KEY, getConfig().getDevice()); + options.put(GPSNRSerialDevice.PORT_SPEED_KEY, getConfig().getSpeed()); if (logger.isDebugEnabled()) { logger.debug("GPS options: " + options); @@ -111,13 +110,9 @@ logAvailablePorts("beforeOpen"); - gpsDataProcessor.open(); - gpsDataProcessor.addGPSDataChangeListener(gpsDataProcessorListener); - logger.info("Connected to GPS device"); - - setState(DeviceState.READY, null); + gpsDataProcessor.open(); opened = true; logAvailablePorts("openedSuccessful"); @@ -135,7 +130,7 @@ stop(); - if (gpsDataProcessor != null && getState() != DeviceState.UNAVAILABLE) { + if (opened) { logger.info("Closing GPS device..."); try { @@ -317,10 +312,16 @@ String property = evt.getPropertyName(); - if (logger.isTraceEnabled()) { - logger.trace("Gps data received {} {}", property, evt.getNewValue()); + if (logger.isDebugEnabled()) { + logger.debug("Gps data received {} {}", property, evt.getNewValue()); } + if (state == DeviceState.UNAVAILABLE) { + logger.info("Connected to GPS device"); + + setState(DeviceState.READY, null); + } + if (GPSDataProcessor.LOCATION.equals(property)) { lastPositionDate = getDate(); lastPosition = (GPSPosition) evt.getNewValue(); Deleted: trunk/sammoa-application/src/main/java/org/dinopolis/gpstool/gpsinput/SafeGPSSerialDevice.java =================================================================== --- trunk/sammoa-application/src/main/java/org/dinopolis/gpstool/gpsinput/SafeGPSSerialDevice.java 2012-09-21 13:00:10 UTC (rev 586) +++ trunk/sammoa-application/src/main/java/org/dinopolis/gpstool/gpsinput/SafeGPSSerialDevice.java 2012-09-21 17:18:29 UTC (rev 587) @@ -1,60 +0,0 @@ -package org.dinopolis.gpstool.gpsinput; -/* - * #%L - * SAMMOA :: Application - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2012 UMS 3462, Code Lutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/gpl-3.0.html>. - * #L% - */ - -import com.google.common.base.Throwables; - -import java.io.IOException; - -/** - * There is an issue with closing on {@link gnu.io.SerialPort}. See - * <a href="https://forums.oracle.com/forums/thread.jspa?threadID=1292323"> - * https://forums.oracle.com/forums/thread.jspa?threadID=1292323 - * </a> - * - * Proper close. Need to use also {@link org.dinopolis.gpstool.gpsinput.nmea.SafeGPSNmeaDataProcessor} - * which is listener on the serial device - * - * Created: 06/08/12 - * - * @author fdesbois <florian.desbois@codelutin.com> - */ -public class SafeGPSSerialDevice extends GPSSerialDevice { - - @Override - public void close() throws GPSException { - if (serial_port_ != null) { - - serial_port_.removeEventListener(); - try { - serial_port_.getOutputStream().flush(); - serial_port_.getOutputStream().close(); - serial_port_.getInputStream().close(); - } catch (IOException e) { - throw Throwables.propagate(e); - } - serial_port_.close(); - } - } -} Modified: trunk/sammoa-application/src/main/java/org/dinopolis/gpstool/gpsinput/nmea/SafeGPSNmeaDataProcessor.java =================================================================== --- trunk/sammoa-application/src/main/java/org/dinopolis/gpstool/gpsinput/nmea/SafeGPSNmeaDataProcessor.java 2012-09-21 13:00:10 UTC (rev 586) +++ trunk/sammoa-application/src/main/java/org/dinopolis/gpstool/gpsinput/nmea/SafeGPSNmeaDataProcessor.java 2012-09-21 17:18:29 UTC (rev 587) @@ -24,6 +24,8 @@ */ import org.dinopolis.gpstool.gpsinput.GPSException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.IOException; import java.io.OutputStream; @@ -36,6 +38,12 @@ */ public class SafeGPSNmeaDataProcessor extends GPSNmeaDataProcessor { + /** Logger. */ + private static final Logger logger = LoggerFactory.getLogger(SafeGPSNmeaDataProcessor.class); + + protected volatile boolean open_; + + // Override to avoid using daemon for read_thread @Override public void open() throws GPSException { @@ -50,9 +58,7 @@ // start this runnable as thread: read_thread_ = new Thread(this, "GPSNmeaDataProcessor"); - // >> START fix - // Remove daemon line from superclass implementation - + // >> START fix : remove daemon line from superclass implementation // read_thread_.setDaemon(true); // so thread is finished after exit of application // << END fix @@ -68,28 +74,219 @@ } } + // Override to clean read_thread on close @Override public void close() throws GPSException { -// for (Object rawDataListener : raw_data_listener_) { -// removeGPSRawDataListener((GPSRawDataListener) rawDataListener); -// } + + if (gps_device_ == null) { + throw new GPSException("no GPSDevice set!"); + } + + open_ = false; if (read_thread_ != null) { - read_thread_.interrupt(); + try { + read_thread_.join(); + } catch (InterruptedException ex) { + throw new GPSException("Error on thread join", ex); + } read_thread_ = null; } - super.close(); + gps_device_.close(); } + // Override to allow stop loop with open flag @Override + protected void readMessages() + { + if (logger.isDebugEnabled()) { + logger.debug("start reading from GPSDevice..."); + } + + char[] buffer; + int count; + int data; + NMEA0183Sentence message; + try + { + + if (logger.isDebugEnabled()) { + logger.debug("inputstream: " + in_stream_); + } + + if (!readGarbage()) // try to (re)sync with nmea stream + return; + + int loopcount = 0; + // >> START fix : add open_ flag to stop loop on close + while (open_) + // << END fix + { + loopcount++; + count = 0; + buffer = new char[MAX_NMEA_MESSAGE_LENGTH]; + + // >> START fix : add open_ flag to stop loop on close + while (open_ && (data = getNextByte()) != (char) 13) // read data until CR + // << END fix + { + + if (count >= MAX_NMEA_MESSAGE_LENGTH - 1) + { + System.err.println("ERROR: max. message length exceeded! (" + count + "):" + new String(buffer)); + if (!readGarbage()) // try to (re)sync with nmea stream + return; + loopcount++; + count = 0; + buffer = new char[MAX_NMEA_MESSAGE_LENGTH]; + } else + { + if (data != (char) 10) // ignore LF + { + buffer[count] = (char) data; // add data to the buffer + count++; + } + } + } // end of while (read until end of line) + + if (buffer[0] != '$') // no valid nmea sentence + { + if (!readGarbage()) // try to (re)sync with nmea stream + return; + } else + { // valid sentence, no garbage + try + { + message = new NMEA0183Sentence(buffer, 0, count); + + buffer[count] = 13; // add CR from NMEA message + buffer[count + 1] = 10; // add LF from NMEA message + fireRawDataReceived(buffer, 0, count + 2); + if (logger.isDebugEnabled()) + { + logger.debug("message: '" + message + "'"); + logger.debug("sentenceId: '" + message.getSentenceId() + "'"); + } + + if (!message.isValid() && ignore_invalid_checksum_ && print_ignore_warning_) + { + logger.error("ERORR: invalid checksum in NMEA message: " + message); + logger.error("checksum of sentence: " + message.getChecksum() + ", calculated checksum: " + message.getCalculatedChecksum()); + logger.warn("WARNING: As you chose to ingore invalid messages, this message is only printed once!"); + print_ignore_warning_ = false; + } + + if (ignore_invalid_checksum_ || message.isValid() || message.getSentenceId().equals("RFTXT")) + { + try + { + processNmeaSentence(message); + } + catch (Exception e) + { + logger.error("ERROR: Exception thrown on processing of NMEA sentences:"); + logger.error(message.toString()); + e.printStackTrace(); + } + } else + { + logger.error("ERORR: invalid checksum in NMEA message: " + message); + logger.error("checksum of sentence: " + message.getChecksum() + ", calculated checksum: " + message.getCalculatedChecksum()); + } + } + catch (Exception e) + { + logger.error("ERROR: Exception thrown on creation or processing of NMEA sentences:"); + logger.error(new String(buffer)); + e.printStackTrace(); + } + } + + if (delay_time_ > 0) + { + try + { + Thread.sleep(delay_time_); + } + catch (InterruptedException ie) + { + } + } + } + } + catch (IOException ioe) + { + if (open_) // otherwise, this is the reason for the exception! + ioe.printStackTrace(); + } + } + + // Copy from superclass (private access) + protected int getNextByte() throws IOException + { + int data = -1; + // rxtx 2.1.7 on windows has the problem (?) that even if the stream is not ended + // it returns -1 here (happens in between nmea sentences) + // so we just wait a little and then retry to read + + // >> START fix : add open_ flag to stop loop on close + while (open_ && (data = in_stream_.read()) < 0) + // << END fix + { + + try + { + Thread.sleep(50); + } catch (InterruptedException ignore) + { + } + } + return data; + } + + // Override to add open_ flag in loops + @Override + protected boolean readGarbage() + { + int data; + try + { + // >> START fix : add open_ flag to stop loops on close + while (open_) + { + // read until CR/LF> + while (open_ && (data = getNextByte()) != (char) 13) // read data until CR + { + } + // << END fix + + data = getNextByte(); // char after CR + if (data == (char) 10) // linefeed + { + return true; + } + if (logger.isDebugEnabled()) + logger.debug("reading garbage..."); + } + } + catch (IOException ioe) + { + System.err.println("GPS Nmea Reading: IOException on beginning of reading, try once more: " + ioe.getMessage()); + return false; + } + return false; + } + + // Override to fix parse issue with empty String + @Override protected void processGSA(NMEA0183Sentence sentence) { -// if (logger_nmea_.isDebugEnabled()) -// logger_nmea_.debug("GSA detected: " + sentence); + if (logger.isDebugEnabled()) { + logger.debug("GSA detected: " + sentence); + } List data_fields = sentence.getDataFields(); Integer[] satellites_ids = new Integer[12]; String pdop = (String) data_fields.get(14); String hdop = (String) data_fields.get(15); String vdop = (String) data_fields.get(16); -// int valid_fix = Integer.parseInt((String) data_fields.get(1)); for (int i = 0; i < 12; i++) { String id = (String) data_fields.get(i + 2); @@ -98,9 +295,7 @@ } } - // >> START fix - // Resolve NumberFormatException on new Float with empty String - + // >> START fix : resolve NumberFormatException on new Float with empty String changeGPSData(PDOP, pdop.isEmpty() ? 0 : new Float(pdop)); changeGPSData(HDOP, hdop.isEmpty() ? 0 : new Float(hdop)); Modified: trunk/sammoa-ui-swing/src/main/assembly/bin.xml =================================================================== (Binary files differ) Modified: trunk/sammoa-ui-swing/src/main/assembly/sammoa.bat =================================================================== --- trunk/sammoa-ui-swing/src/main/assembly/sammoa.bat 2012-09-21 13:00:10 UTC (rev 586) +++ trunk/sammoa-ui-swing/src/main/assembly/sammoa.bat 2012-09-21 17:18:29 UTC (rev 587) @@ -1,2 +1,2 @@ -java -Xmx1024M -Djava.library.path=x86 -jar ${project.build.finalName}.${project.packaging} %1 %2 %3 %4 %5 %6 %7 %8 %9 +java -Xmx1024M -jar ${project.build.finalName}.${project.packaging} %1 %2 %3 %4 %5 %6 %7 %8 %9 Modified: trunk/sammoa-ui-swing/src/main/assembly/sammoa.sh =================================================================== --- trunk/sammoa-ui-swing/src/main/assembly/sammoa.sh 2012-09-21 13:00:10 UTC (rev 586) +++ trunk/sammoa-ui-swing/src/main/assembly/sammoa.sh 2012-09-21 17:18:29 UTC (rev 587) @@ -1,6 +1,5 @@ #!/bin/bash MEMORY="-Xmx1024M" -JRIARGS="-Djava.library.path=x86" -java $MEMORY $JRIARGS -jar ${project.build.finalName}.${project.packaging} $* +java $MEMORY -jar ${project.build.finalName}.${project.packaging} $* Deleted: trunk/sammoa-ui-swing/src/main/assembly/sammoa64.bat =================================================================== --- trunk/sammoa-ui-swing/src/main/assembly/sammoa64.bat 2012-09-21 13:00:10 UTC (rev 586) +++ trunk/sammoa-ui-swing/src/main/assembly/sammoa64.bat 2012-09-21 17:18:29 UTC (rev 587) @@ -1,2 +0,0 @@ - -java -Xmx1024M -Djava.library.path=x64 -jar ${project.build.finalName}.${project.packaging} %1 %2 %3 %4 %5 %6 %7 %8 %9 Deleted: trunk/sammoa-ui-swing/src/main/assembly/sammoa64.sh =================================================================== --- trunk/sammoa-ui-swing/src/main/assembly/sammoa64.sh 2012-09-21 13:00:10 UTC (rev 586) +++ trunk/sammoa-ui-swing/src/main/assembly/sammoa64.sh 2012-09-21 17:18:29 UTC (rev 587) @@ -1,6 +0,0 @@ -#!/bin/bash - -MEMORY="-Xmx1024M" -JRIARGS="-Djava.library.path=x64" - -java $MEMORY $JRIARGS -jar ${project.build.finalName}.${project.packaging} $* Deleted: trunk/sammoa-ui-swing/src/main/assembly/x64/librxtxSerial.so =================================================================== (Binary files differ) Deleted: trunk/sammoa-ui-swing/src/main/assembly/x64/rxtxSerial.dll =================================================================== (Binary files differ) Deleted: trunk/sammoa-ui-swing/src/main/assembly/x86/librxtxSerial.so =================================================================== (Binary files differ) Deleted: trunk/sammoa-ui-swing/src/main/assembly/x86/rxtxSerial.dll =================================================================== (Binary files differ)
participants (1)
-
fdesbois@users.forge.codelutin.com