-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathBUILDING
99 lines (61 loc) · 8.19 KB
/
BUILDING
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
SonarGridder: A utility for georeferencing consumer-grade, recreational side scan sonar files.
© 2021 Angular Fish
A C++ utility for simple georeferencing of Humminbird side scan sonar files. Intended for visual substrate classification using side scan sonar records and a GIS program of your choice. Outputs (regular) TIFF files with world files indicating how to stretch and rotate them onto the map. Corrects cross-track distance and poor gps resolution. Tested with the Humminbird 698ci HD, will likely work with other units of the same generation but may require some modification to the header to adjust the sonar header length and the offsets of particular important sonar header values. TIFF files import into QGIS without difficulty, I have not tested them with any other software.
###############################################################################
###############################################################################
###############################################################################
Compiling:
Instructions are provided for gnu-linux based systems. If you know how to do this in Windows or MacOS, please let me know.
Pre-requisites: This code requires the standard C++ libraries and libTIFF. If libTIFF is not installed, please install it first. In ubuntu:
sudo apt-get install libtiff-dev
1. Download the repository.
git clone https://github.com/SonarGridder
-OR-
Download and extract the zip file.
2. Move into the src directory
cd SonarGridder/src
3. If necessary change LD_LIBRARY_PATH in the makefile to the path for libtiff (the path included is valid in the Ubuntu 20.04 x86-64 distribution I'm working from)
find /usr -name tiffio.h
sed -i "s+/usr/include/x86-64-linux-gnu+[location of tiffio.h]+g"
4. Build the program
make
The program will be output to ../bin
###############################################################################
Installing:
You can install the software into /usr/local/bin using make. I'm not sure I'd recommend this course of action, but if you want to do it:
sudo make install
Alternatively (suggested) if you want to keep it local or don't have root access, make a folder to add to $PATH and copy the binary file there:
1. mkdir ~/bin (if it doesn't exist)
2. cp ../bin/sonargridder ~/bin/
3. export PATH=$PATH:~/bin
Alternatively alternatively add the bin folder from the repository to your PATH variable.
###############################################################################
###############################################################################
###############################################################################
To change to a different (Humminbird side-imaging) unit:
BRAVE SOUL: This is likely possible. Very doable even. You will need a hex editor (I use ghex, others are probably fine) and recordings from your particular device. I would first check to see if the offsets built in for this unit work (I have only tested it with a Humminbird 698ci HD combo, but it may work with more ~2014 x98ci HD Combo units). If that fails, your procedure follows.
Humminbird's SON files, to my knowledge, are all laid out in the same basic structure. They are binary files that are appended to every time the unit scans. Each record (here referred to as a line) begins with a start sequence (in this unit 0xC0DE21), followed by a short header containing information about the scan (position in world mercator meters, depth, heading, number of records in the line, etc) and then a long string of bytes containing the return strength. The header information and unit specs may vary from unit to unit (I expect this structure is common to units within generations, mine is a ~2014 Humminbird 698ci HD combo). The relevant information in the header macros is the location of the sentence length (unsigned, 32 bit; LENPOS), the location of the world mercator northing value (signed 32 bit; NORTHINGLOC), the location of the world mercator easting value (signed 32 bit; EASTINGLOC), the location of the depth (unsigned 32 bit, decimeters; DEPTHLOC), sentence length (unsigned 32 bit; LENLOC), heading (unsigned 16 bit, tenths of a degree; HEADINGLOC), and the length of the ping header in bytes (including start sequence; HEADINGLOC).
To determine the structure of your particular unit's files, load one up in a hex editor (side imaging may differ in structure from down imaging, so use B002.SON or B003.SON). If your hex editor can indicate multibyte integers, make sure it's configured for big endian. Signed values are 2's compliment. The start sequence will be the first four bytes (if this is not 0xC0DEAB21, you will need to change parts of the code in fileprocessing.cpp).
LENPOS:
1. Search for the second occurance of the start sequence and record the offset of the first byte.
2. Sentence length for the first line will be S = Oe - H where Oe is the end of the first line (the offset of beginning of the second line minus 1) and H is the header length.
3. Since we don't know the header length yet, search for a number similar to the second offset minus 1, record its offset. This is LENPOS.
HEADERLEN:
1. The header length should be (but sometimes is not) the length of the line (the offset of the second occurance of the start sequence minus one) minus the sentence length. In this generation of unit it is 67.
2. Check the byte prior to the offset of the calculated header length for the scan start byte. On this unit the scan start byte is 0x21. Also check the offset of the line start sequence + the offset of the scan start byte elsewhere in the file to make sure this remains the same.
3. If these conditions are met, you have determined HEADERLEN.
EASTINGLOC:
1. This value is harder to identify, and it's extremely helpful to know the world mercator location of a scan (although for some reason this is not identical to EPSG:3395 (may be EPSG:3857). Look for a signed 32 bit integer corresponding to something that seems reasonable. Also try scans other than the first scan as this is dependent on the GPS being warmed up.
2. On my unit the byte prior to the easting value is always 0x82.
3. Record the offset if you found it as EASTINGLOC.
NORTHINGLOC:
1. On my unit this is separated from the bytes corresponding to EASTINGLOC by a spacer byte (0x83). Check the offset at EASTINGLOC + 5 to see if the offset contains a signed 32 bit integer that seems reasonable for a northing value in world mercator units. Otherwise, check other locations in the header. Also check scans other than the first given that the GPS needs to warm up.
2. Record the offset if you found it as NORTHINGLOC.
DEPTHLOC:
1. If you wrote down the depth when you started recording you are already halfway there. Multiply the recorded depth (in metres) by 10 to get the depth in decimetres.
2. Look for an unsigned 32 bit integer representing the depth (or something similar; or if you don't know the depth, something that seems reasonable) in decimetres (tenths of a metre).
3. Record this offset as DEPTHLOC.
HEADINGLOC:
1. Look for an unsigned 16 bit integer that seems reasonable for a heading in tenths of a degree (should be a value between 0 and 3599 at every corresponding offset in the file). It might be tempting to use the northing and easting values to calculate this, but keep in mind that these are rounded to the nearest metre and the pings are frequent, you may need to skip a few scans to get an accurate idea of heading).
2. Record this offset as HEADINGLOC.
If you've gone through the binary file successfully, congratulations! Save and recompile the program (make clean && make). If LENPOS is incorrect, the program will segfault while running. If EASTINGLOC or NORTHINGLOC are wrong, positions will be nonsensical. If DEPTHLOC is wrong, recorded depths will be nonsensical as will cross-track distances (If range is ~50 m, the TIFF files should be at most 50 m wide). If HEADINGLOC is wrong, the program may divide the track in weird ways (eg skipping turns or fragmenting the course in weird places). You may also need to change SAMPLESPERMETER (see "To change to seawater" above) and the physical properties of the down imaging transducer if you are using the extremely experimental parts of the program.