[Gpsbabel-code] [Fwd: Skytraq Venus based GPS datalogger]
GPSBabel converts and transfers data like waypoints, tracks & routes.
Brought to you by:
robertl
|
From: Jean-Christophe H. <jea...@di...> - 2008-12-16 17:54:40
|
Hello,
I did not realise there was a different list dedicated to development.
Some of you might have seen my post on the -misc ML, my apologies for the cross-posting.
I went on implementing some missing functionality for my Keymate STV-5.
Now the user can:
* erase the data in the logger after download with the "erase" option
* set up the time interval between points with the "timeinterval" option
* set up distance interval between points with the "distanceinterval"
option
* set up the speed threshold before the device starts to log with the
"speedthreshold" option
* change the behavior to overwrite old logs when memory is full with the
"overwrite" option
* get the device status and current setup with the "status" option.
I have no documentation about the extra setup features so everything was
done by reverse-engineering (AN0003_v3.pdf does not mention the requests
related to the log) and I still miss the meaning of some of the fields
in various structures. Thanks to Mathias who did the hardest part of
converting the GPS data log format, the following could easily be
figured out.
The device manages its internal memory in chunks of 4096 bytes. When
there isn’t enough space left in a chunk, the remaining bytes are filled
with 0xFF.
Trackpoints are logged in two formats : full and compact. The full
version is 18 bytes long, and contains X,Y,Z coordinates and time. The
compact version is 8 bytes long and is a delta which reports to the
previous trackpoint. Every 4096-byte chunk starts with a full record.
The first two bytes contain the trackpoint type and the current speed.
Here I spotted a problem in the original code which assumes the first
byte is the trackpoint type and the second the speed. According to the
specs of the GPS chip, max. supported speed is 515 km/h, which requires
more than one byte. I actually saw it due to a lucky bug from my
reciever which wrote in the first byte (no I didn’t really drive over
255 km/h ;) BTW, speed tags in gpx are in m/s, right ?
Therefore I guess the 4 first bits are used for the trackpoint type
(4=full, 8=compact) and the 12 other for the speed. In my unit there is
also a third type (6) which is the same structure as (4) but denotes a
point of interest. Support for this type has been implemented by adding
a waypoint.
While the device manages its memory in chunks, it is possible to read
more than 4096 bytes at once, but the previous implementation only read
chunk-per-chunk. I added support to read many blocks at once.
The read request is as follows:
A0 A1 Header
00 05 Data length
1D Read request message ID
HH LL Offset in 4096-byte chunk
HH LL # of chunks to read
XX Checksum
0D 0A Trailer
Note that HH is always 0 since there are only 254 blocks on my unit
(maybe there will be units with more memory in the future). The windows
app seems to read up to 16 in a row. I don’t know if this is a "safe
value", since reading 32 blocs at once works as well. I didn’t try
higher values, however.
Before reading the data it is a good idea to query the device about its
status (with opcode 0x17). The device will respond:
A0 A1 Header
00 29 Data length
94 Status response message ID
XX XX XX XX Last log pointer (littleendian)
XX XX Free block count (le)
XX XX Total block count (le)
10 0E 00 00 Purpose unknown (3600 le)
XX XX XX XX Current time interval between points (le)
E8 03 00 00 Purpose unknown (1000 le)
XX XX XX XX Current distance interval (le)
E8 03 00 00 Purpose unknown (1000 le)
XX XX XX XX Speed threshold (le)
01 Purpose unknown
XX Overwrite feature (1 or 0)
LL HH POI count (le)
00 00 00 00 Purpose unknown
E4 Checksum
0D 0A Trailer
Some of the unknown constants could be base multipliers for the
settings. I couldn’t do detailed tests about that yet. The original code
only expects data until the total block count. I don’t know if Mathias’
device doesn’t have the rest of the structure.
It is also worth noting that my device has the log pointer reset to
0x2000 when cleared, which seemed to confuse the code that calculated
which blocks to download.
I had some other issues with the reading algorithm: when the device was
nearly full (free blocks=1), it suddenly rolled back to 2 (I was trying
the log rollover feature, which didn’t work).
However, the device seems to always blank (to 0xFF’s) the sector next to
the one currently written.
Therefore, I changed the algorithm to: unless at least 4096 bytes of
FF’s are found or the last possible block has been read, try to read
some sectors in a row (32 by default), if there aren’t enough according
to the free counter, read as much as possible, but at least one.
I still have to discover how the rolling log works, which will certainly
invalidate that algorithm.
The setup request is as follows :
A0 A1 Header
00 1B Data length
18 Setup message ID
00 00 0E 10 Purpose unknown (3600 bigendian)
XX XX XX XX Time interval between points in seconds (be)
00 00 03 E8 Purpose unknown (be)
XX XX XX XX Distance interval in meters (be)
00 00 03 E8 Speed threshold (be)
01 Purpose unknown
XX Overwrite feature (1 or 0)
62 Checksum
0D 0A Trailer
Surprisingly the request doesn’t use the same endianness as the response
message. It also seems that the unknown fields can be set (and re-read
correctly by request 0x17) but I couldn’t figure out their effect on the
device yet.
My device says it has 254 sectors, but sector 254 and 255 can be read:
they contain the values returned by the status request, plus some more.
I saw this structure at the end of the skytraq module. Should I set the
waypoint field to ff_cap_read, since I can create some ?
ff_vecs_t skytraq_vecs = {
ff_type_serial,
{
ff_cap_none /* waypoints */,
ff_cap_read /* tracks */,
ff_cap_none /* routes */
},
[…]
};
The attached patch (against 1.3.6) is based on the previous work from
Mathias. I tried to address some of the issues Robert pointed out and
added the features described above.
Comments welcome as usual.
JC
|