Skip to content
Permalink
Browse files

PiR43 changes to read GPS data from GPX file for RLV.

  • Loading branch information
davidzof committed May 9, 2015
1 parent 852c1f1 commit b96e4cb348b5a09a2dcb14b03045473f0eb02b16
Binary file not shown.
Binary file not shown.
BIN +2.72 MB lib/track-parser.jar
Binary file not shown.
@@ -1,16 +1,25 @@
package com.wattzap.model;

import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import lt.overdrive.trackparser.domain.Track;
import lt.overdrive.trackparser.domain.TrackPoint;
import lt.overdrive.trackparser.domain.Trail;
import lt.overdrive.trackparser.parsing.ParserException;
import lt.overdrive.trackparser.parsing.tcx.TcxParser;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.jfree.data.xy.XYSeries;
@@ -22,22 +31,24 @@
import com.wattzap.model.dto.TrainingData;
import com.wattzap.model.dto.TrainingItem;


/*
* Wrapper class for Tacx Real Life Video Routes
*
* @author David George (c) Copyright 2013
* @author PiR43
* @date 19 November 2013
*/
@RouteAnnotation
public class RLVReader extends RouteReader {
private static final int RLV_VIDEO_INFO = 2010;
private static final int RLV_FRAME_DISTANCE_MAPPING = 2020;
private static final int RLV_INFOBOX = 2030;
private static final int RLV_COURSE_INFO = 2040;
private static final int RLV_FINGERPRINT = 2000; // RLV (.rlv)
private static final int PGMF_FINGERPRINT = 1000;
private static final int PGMF_INFORMATION = 1010;
private static final int PGMF_PROGRAM = 1020;
public static final int RLV_VIDEO_INFO = 2010;
public static final int RLV_FRAME_DISTANCE_MAPPING = 2020;
public static final int RLV_INFOBOX = 2030;
public static final int RLV_COURSE_INFO = 2040;
public static final int RLV_FINGERPRINT = 2000; // RLV (.rlv)
public static final int PGMF_FINGERPRINT = 1000;
public static final int PGMF_INFORMATION = 1010;
public static final int PGMF_PROGRAM = 1020;

private Charset iso88591charset = Charset.forName("ISO-8859-1");
private double totalDistance = 0.0;
@@ -117,9 +128,10 @@ public double getMinSlope() {

@Override
public void load(String filename) {
//logger.setLevel(Level.DEBUG);
totalDistance = 0.0;
maxSlope = 0;
minSlope = 0; // TODO, if min slope is say 5% then this will give wrong value
minSlope = 0;
maxPower = 0;

filename = filename.substring(0, filename.lastIndexOf('.'));
@@ -128,6 +140,18 @@ public void load(String filename) {

ArrayList<Point> pgmfSegment = readPGMF(filename + ".pgmf");
ArrayList<Point> rlvSegment = readRLV(filename + ".rlv");
ArrayList<Point> tcxSegment = readTCX(filename + ".tcx");

if(tcxSegment != null && tcxSegment.size() > 0){
double pgmfDist = pgmfSegment.get(pgmfSegment.size()-1).getDistanceFromStart();
double tcxDist = tcxSegment.get(tcxSegment.size()-1).getDistanceFromStart();
logger.debug("pgmd Dist: "+pgmfDist+" tcx distance: "+tcxDist);
for(int i=0; i<tcxSegment.size(); i++){
tcxSegment.get(i).setDistanceFromStart(tcxSegment.get(i).getDistanceFromStart()*pgmfDist/tcxDist);
}
tcxDist = tcxSegment.get(tcxSegment.size()-1).getDistanceFromStart();
logger.debug("pgmd Dist: "+pgmfDist+" tcx distance: "+tcxDist);
}

/*
* merge arrays, we basically go through the frame/distance array and
@@ -139,6 +163,7 @@ public void load(String filename) {
long startTime = 0;
switch (timeDist) {
case TIME:
logger.debug("RLV mode TIME " + timeDist);
ArrayList<Point> mergedPoints = new ArrayList<Point>();
TrainingData tData = new TrainingData();
tData.setPwr(true);
@@ -253,7 +278,12 @@ public void load(String filename) {
break;
case DISTANCE:

logger.debug("RLV mode DISTANCE " + timeDist);
int c1 = 0;

Point tcxPoint = null;
Point lastTcxPoint = null;
int c3 = 0;

// for each RLV Point
for (int c2 = 0; c2 < rlvSegment.size(); c2++) {
@@ -266,7 +296,8 @@ public void load(String filename) {

speed = (distance * 3.6 * frameRate) / framesInRecord;
// Merge with PGMF Points


double d = 0;
while (c1 < pgmfSegment.size()) {
Point pgmfPoint = pgmfSegment.get(c1);
if (pgmfPoint.getDistanceFromStart() > (runningDistance + distance)
@@ -277,13 +308,35 @@ public void load(String filename) {
}
pgmfPoint.setSpeed(speed);
// t = d / s
double d = pgmfPoint.getDistanceFromStart()
d = pgmfPoint.getDistanceFromStart()
- runningDistance;
long time = (long) (d * 3600 / speed);

time += startTime;
pgmfPoint.setTime(time);

//put position from tcx
if(tcxSegment != null && tcxSegment.size() > 0){
if(tcxPoint == null) tcxPoint = tcxSegment.get(0);
while(tcxPoint.getDistanceFromStart() < pgmfPoint.getDistanceFromStart() && c3 < tcxSegment.size() -1 ){
lastTcxPoint = tcxPoint;
tcxPoint = tcxSegment.get(++c3);
}
if(lastTcxPoint == null || tcxPoint.getDistanceFromStart() == lastTcxPoint.getDistanceFromStart()){
pgmfPoint.setLatitude(tcxPoint.getLatitude());
pgmfPoint.setLongitude(tcxPoint.getLongitude());
} else {
double dist = tcxPoint.getDistanceFromStart() - lastTcxPoint.getDistanceFromStart();
logger.debug("last: "+lastTcxPoint.getDistanceFromStart()+" pgmf: "+pgmfPoint.getDistanceFromStart()+" point:"+tcxPoint.getDistanceFromStart());
pgmfPoint.setLatitude((tcxPoint.getLatitude()*(dist - (tcxPoint.getDistanceFromStart() - pgmfPoint.getDistanceFromStart())) + lastTcxPoint.getLatitude()*(dist -(pgmfPoint.getDistanceFromStart() - lastTcxPoint.getDistanceFromStart())) )/dist);
pgmfPoint.setLongitude((tcxPoint.getLongitude()*(dist - (tcxPoint.getDistanceFromStart() - pgmfPoint.getDistanceFromStart())) + lastTcxPoint.getLongitude()*(dist-(pgmfPoint.getDistanceFromStart() - lastTcxPoint.getDistanceFromStart())) )/dist);
}
}



logger.debug("c2:"+c2+" c1:"+c1+" frame: "+frame+" distanceFromstart: "+pgmfPoint.getDistanceFromStart()+" time: " + time + " distance (frameInRecord): " + distance+ " framesInRecord: "+framesInRecord+" speed: "+speed+ " lat:"+pgmfPoint.getLatitude()+ " lon:"+pgmfPoint.getLongitude());

c1++;
}// while

@@ -299,6 +352,45 @@ public void load(String filename) {
public void close() {
}

private final ArrayList<Point> readTCX(String fileName) {

ArrayList<Point> pl = new ArrayList<Point>();

try{
TcxParser parser = new TcxParser();
Trail trail = parser.parse(new File(fileName));
logger.debug("tcx tracks: "+trail.getTracks().size());
List<Track> tracks = trail.getTracks();
Point last = null;
for(Track track : tracks){
List<TrackPoint> points = track.getPoints();
for(TrackPoint point : points){
Point p = new Point();
p.setLatitude(point.getLatitude());
p.setLongitude(point.getLongitude());
p.setElevation(point.getAltitude());
if(last != null){
double leg = GPXReader.distance(p.getLatitude(), last.getLatitude(), p.getLongitude(),
last.getLongitude(), last.getElevation(), p.getElevation());
p.setDistanceFromStart(last.getDistanceFromStart()+leg);
} else {
p.setDistanceFromStart(0);
}
pl.add(p);
last = p;
}
}
} catch (ParserException pe) {
StringWriter sw = new StringWriter();
try{
pe.getCause().printStackTrace(new PrintWriter(sw));
} catch(Exception e){}
String exceptionAsString = sw.toString();
logger.error("ParserException : " + pe + ":"+ exceptionAsString + " file:"+fileName);
}
return pl;
}

private final ArrayList<Point> readPGMF(String fileName) {

ArrayList<Point> p = new ArrayList<Point>();
@@ -790,3 +882,4 @@ private String readTacxString(DataInputStream dis, int len)

}
}

@@ -274,7 +274,7 @@ private void loadHeaders() {
+ getUShort(data, 0) + "." + getUShort(data, 2) + " v"
+ getUShort(data, 4) + " " + getUInt(data, 6) + "x"
+ getUInt(data, 10);
logger.info(hdr);
logger.debug(hdr);
fingerprint = getUInt(data, 6);
keyH = encryptHeader(iarr(data), key2);

@@ -305,7 +305,7 @@ private void loadHeaders() {
stringType = StringType.BLOCK;
blockType = getUShort(data, 2);
version = getUShort(data, 4);
logger.info("\nblock type " + blockType + " version "
logger.debug("\nblock type " + blockType + " version "
+ version);
stringId = -1;
break;
@@ -314,14 +314,14 @@ private void loadHeaders() {
int[] decrD = decryptData(iarr(data), keyH);

keyH = null;
logger.info("::");
logger.debug("::");

String result = null;
switch (stringType) {
case CRC:
break;
case IMAGE:
logger.info("[image " + blockType + "." + (stringId - 1000)
logger.debug("[image " + blockType + "." + (stringId - 1000)
+ "]");
try {
result = currentFile + "." + (imageId++) + ".png";
@@ -334,10 +334,10 @@ private void loadHeaders() {
break;
case STRING:
if (strings.containsKey(blockType + stringId)) {
logger.info("[" + strings.get(blockType + stringId)
logger.debug("[" + strings.get(blockType + stringId)
+ "]");
} else {
logger.info("[" + blockType + "." + stringId + "]");
logger.debug("[" + blockType + "." + stringId + "]");
}
StringBuilder str = new StringBuilder();
for (int i = 0; i < decrD.length / 2; i++) {
@@ -351,7 +351,7 @@ private void loadHeaders() {
break;
}
}
logger.info("\n");
logger.debug("\n");
bytes += data.length;
}

@@ -465,17 +465,17 @@ private void segmentRange(int version, byte[] data) {
}
b.append("]");
}
logger.info(b.toString());
logger.debug(b.toString());
}

// segment range; 548300 is 5.483km. What is short value in "old" files?
private void segmentInfo(int version, byte[] data) {
if ((version == 1104) && (data.length == 8)) {
logger.info("[segment range] " + (getUInt(data, 0) / 100000.0)
logger.debug("[segment range] " + (getUInt(data, 0) / 100000.0)
+ "-" + (getUInt(data, 4) / 100000.0));
}
if ((version == 1000) && (data.length == 10)) {
logger.info("[segment range] " + (getUInt(data, 2) / 100000.0)
logger.debug("[segment range] " + (getUInt(data, 2) / 100000.0)
+ "-" + (getUInt(data, 6) / 100000.0) + "/"
+ getUShort(data, 0));
}
@@ -487,9 +487,9 @@ private void trainingType(int version, byte[] data) {
if (version == 1004) {
switch (data[5]) {
case 1:
logger.info("[video type] RLV");
logger.debug("[video type] RLV");
case 2:
logger.info("[video type] ERGO");
logger.debug("[video type] ERGO");
}
}
}
@@ -528,7 +528,7 @@ private void generalInfo(int version, byte[] data) {
trainingType = "unknown training";
break;
}
logger.info("[program type] " + programType + " -> " + trainingType);
logger.debug("[program type] " + programType + " -> " + trainingType);

return;
}
@@ -546,7 +546,7 @@ private void GPSData(int version, byte[] data) {
Route route = routes.get(0);
WaypointGroup path = route.getPath();

logger.info("[" + (data.length / 16) + " gps points]");
logger.debug("[" + (data.length / 16) + " gps points]");
int pointCount = 0;
int lastDistance = 0;
double lastLat = 0;
@@ -633,7 +633,7 @@ private void distanceToFrame(int version, byte[] data) {
* seconds of film - typical with tacx TTS files), if the value is more
* than 100 divide by 10 (typical with RLV files converted to TTS).
*/
logger.info("[" + (data.length / 8) + " video points][last frame "
logger.debug("[" + (data.length / 8) + " video points][last frame "
+ getUInt(data, data.length - 4) + "]");
double dataPoints = (data.length / 8);
double frames = getUInt(data, data.length - 4);
@@ -644,7 +644,7 @@ private void distanceToFrame(int version, byte[] data) {
} else if (frameRate >= 100) {
frameRate = frameRate / 10.0;
}
logger.info("Frame Rate " + frameRate);
logger.debug("Frame Rate " + frameRate);

for (int i = 0; i < data.length / 8; i++) {
Point p = new Point();
@@ -673,7 +673,7 @@ private void programData(int version, byte[] data) {
return;
}

logger.info("[" + (data.length / 6) + " program points]");
logger.debug("[" + (data.length / 6) + " program points]");
long distance = 0;
int pointCount = data.length / 6;
programList = new ProgramPoint[pointCount];
@@ -1,3 +1,14 @@
LIBS="lib:properties:lib/derby.jar:lib/opencsv-2.3.jar:lib/com-sun-tools-visualvm-charts.jar:lib/com-sun-tools-visualvm-uisupport.jar:lib/commons-lang3-3.2.1.jar:lib/gpx-creator-0.1-beta.jar:lib/hamcrest-core-1.3.jar:lib/jcommon-1.0.17.jar:lib/jcommon-1.0.18.jar:lib/jformica_core.jar:lib/jformica_jsr80.jar:lib/jfreechart-1.0.14.jar:lib/jna-3.5.1.jar:lib/junit-4.11.jar:lib/miglayout-core-4.2.jar:lib/miglayout-swing-4.2.jar:lib/org-netbeans-lib-profiler-charts.jar:lib/org-netbeans-lib-profiler-ui.jar:lib/org-openide-util-lookup.jar:lib/org-openide-util.jar:lib/usb-api-1.0.2.jar:lib/usb4java-1.2.0.jar:lib/usb4java-javax-1.2.0.jar:lib/vlcj-2.2.0.jar:lib/log4j-1.2.17.jar:lib/wattzap.jar"
#
#!/bin/bash
#
# WattzAp Linux Startup File
# 6th May 2015
#
SEP=":"
LIBS=$(find lib -maxdepth 1 -name "*.jar" -print | tr '\n' ':')
LIBS="lib:properties:$LIBS"


echo $LIBS

java -Djna.library.path=/Applications/VLC.app/Contents/MacOS/lib -cp $LIBS -Dlog4j.logger.level=INFO com.wattzap.Main

0 comments on commit b96e4cb

Please sign in to comment.
You can’t perform that action at this time.