Commit 44c105e7 authored by Sigurd M. Albrektsen's avatar Sigurd M. Albrektsen
Browse files

Merge branch 'develop' into 'master'

Develop

See merge request enfo/sentiboard-utils!12
parents d7c27900 5d962718
Loading
Loading
Loading
Loading

.gitlab-ci.yml

deleted100644 → 0
+0 −50
Changes for .gitlab-ci.yml: 0 added lines, 50 removed lines.
Original line number Diff line number Diff line
image: gcc-cpplint-cmake-gcov

build:
  stage: build
  script: 
    - make -C parsers tests -j 4
  artifacts:
    paths:
      - parsers/build/sentiboard_utils_test
  cache:
    paths:
      - parsers/build/

lint:
  stage: build
  script:
    - make -C parsers lint

test:
  stage: test
  script:
    - ./parsers/build/sentiboard_utils_test

coverage:
  stage: test
  script:
    - make -C parsers coverage
  coverage: '/lines[.: ]*\d+.\d+%/'
  artifacts:
    paths:
      - parsers/build_coverage/sentiboard_utils_test
      - parsers/coverage/
  cache:
    paths:
      - parsers/build_coverage/
      - parsers/coverage/

branch-coverage:
  stage: test
  script:
    - make -C parsers coverage
  coverage: '/branches[.: ]*\d+.\d+%/'
  artifacts:
    paths:
      - parsers/build_coverage/sentiboard_utils_test
      - parsers/coverage/
  cache:
    paths:
      - parsers/build_coverage/
      - parsers/coverage/
+0 −8
Changes for README.md: 0 added lines, 8 removed lines.
Original line number Diff line number Diff line
Sentiboard Utils
================

Status
------

[![build status](https://kyb.guru/gitlab/enfo/sentiboard-utils/badges/master/pipeline.svg)](https://kyb.guru/gitlab/enfo/sentiboard-utils/commits/master)
 Lines: [![coverage report](https://kyb.guru/gitlab/enfo/sentiboard-utils/badges/master/coverage.svg?job=coverage)](https://kyb.guru/gitlab/enfo/sentiboard-utils/commits/master)
 Branches: [![coverage report](https://kyb.guru/gitlab/enfo/sentiboard-utils/badges/master/coverage.svg?job=branch-coverage)](https://kyb.guru/gitlab/enfo/sentiboard-utils/commits/master)


Usage
=====

connectors/README.md

0 → 100644
+2 −0
Changes for connectors/README.md: 2 added lines, 0 removed lines.
Original line number Diff line number Diff line
Note that the UART connector is pin-equal to the RS-232 connector, except that
the CTS and RTS pins are not connected.

converters/pos2kml.py

0 → 100755
+147 −0
Changes for converters/pos2kml.py: 147 added lines, 0 removed lines.
Original line number Diff line number Diff line
# -*- coding: utf-8 -*-
"""
Created on Fri May  4 21:08:58 2018

@author: Enfenion
"""

import argparse
import os
import rtk
import datetime

kml_start='''<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
  <Document>
    <name>Paths</name>
    <description>Examples of paths. Note that the tessellate tag is by default
      set to 0. If you want to create tessellated lines, they must be authored
      (or edited) directly in KML.</description>
    <Style id="yellowLineGreenPoly">
      <LineStyle>
        <color>7f00ffff</color>
        <width>4</width>
      </LineStyle>
      <PolyStyle>
        <color>7f00ff00</color>
      </PolyStyle>
    </Style>
    <Placemark>
      <name>Absolute Extruded</name>
      <description>Transparent green wall with yellow outlines</description>
      <styleUrl>#yellowLineGreenPoly</styleUrl>
      <LineString>
        <extrude>1</extrude>
        <tessellate>1</tessellate>
        <altitudeMode>absolute</altitudeMode>
        <coordinates>
'''
kml_end='''        </coordinates>
      </LineString>
    </Placemark>
  </Document>
</kml>
'''

kml2_start='''<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
<Document>
	<name>UAV-icons.kml</name>
	<Style id="sn_airports">
		<IconStyle>
			<color>ffffaa00</color>
			<scale>1.2</scale>
			<Icon>
				<href>http://maps.google.com/mapfiles/kml/shapes/airports.png</href>
			</Icon>
			<hotSpot x="0.5" y="0" xunits="fraction" yunits="fraction"/>
		</IconStyle>
		<ListStyle>
		</ListStyle>
		<LineStyle>
			<color>99ffaa00</color>
			<width>6</width>
		</LineStyle>
	</Style>
	<StyleMap id="msn_airports">
		<Pair>
			<key>normal</key>
			<styleUrl>#sn_airports</styleUrl>
		</Pair>
		<Pair>
			<key>highlight</key>
			<styleUrl>#sh_airports</styleUrl>
		</Pair>
	</StyleMap>
	<Style id="sh_airports">
		<IconStyle>
			<color>ffffaa00</color>
			<scale>1.4</scale>
			<Icon>
				<href>http://maps.google.com/mapfiles/kml/shapes/airports.png</href>
			</Icon>
			<hotSpot x="0.5" y="0" xunits="fraction" yunits="fraction"/>
		</IconStyle>
		<ListStyle>
		</ListStyle>
		<LineStyle>
			<color>99ffaa00</color>
			<width>8</width>
		</LineStyle>
	</Style>
	<Placemark>
		<name>UAV</name>
		<styleUrl>#msn_airports</styleUrl>
		<gx:Track>
			<altitudeMode>relativeToGround</altitudeMode>
'''
kml2_end='''		</gx:Track>
	</Placemark>
</Document>
</kml>
'''


def create_kml(data, destname, interval):
    lats, lons, alts = data['latitude'], data['longitude'], data['height']
    gpsweek, gpsseconds = data['week'], data['gpst']
    mode=2
    leapseconds = 0
    last = datetime.datetime(1980, 1, 6, 0, 0, 0)
    with open(destname, 'w') as f:
        if mode == 1:
            f.write(kml_start)
            for ix in range(len(lats)):
                f.write('%.9f,%.9f,%.2f\n' % (lons[ix], lats[ix], alts[ix]))
            f.write(kml_end)
        else:
            f.write(kml2_start)
            for ix in range(len(lats)):
                d = rtk.weeksecondstoutc(gpsweek[ix],gpsseconds[ix],leapseconds)
                if (d - last).total_seconds() < interval:
                    continue
                last = d

                f.write('<when>%s</when>\n' % d.strftime("%Y-%m-%dT%H:%M:%SZ"))
                f.write('<gx:coord>')
                f.write('%.9f,%.9f,%.2f' % (lons[ix], lats[ix], alts[ix]))
                f.write('</gx:coord>\n')
            f.write(kml2_end)
    print('Stored .kml to %s' % destname)

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Convert an RTK .pos-file to a .kml for Google Earth')
    parser.add_argument('pos', help='RTK .pos-file')
    parser.add_argument('--output', '-O', dest='dest', help='Optional destination file (default *.kml)')
    parser.add_argument('--interval', '-d', dest='interval', type=float, help='Interval between each data point', default=1)
    args = parser.parse_args()

    filename = args.pos

    if args.dest:
        destname = args.dest
    else:
        destname = os.path.splitext(filename)[0] + '.kml'

    data, names = rtk.parse_file(filename)
    create_kml(data, destname, args.interval)

converters/rtk.py

0 → 100755
+117 −0
Changes for converters/rtk.py: 117 added lines, 0 removed lines.
Original line number Diff line number Diff line
# -*- coding: utf-8 -*-
"""
Created on Fri May  4 21:44:51 2018

@author: Enfenion
"""
import re
import datetime


def weeksecondstoutc(gpsweek,gpsseconds,leapseconds):
    epoch = datetime.datetime(1980, 1, 6, 0, 0, 0)
    elapsed = datetime.timedelta(days=(gpsweek * 7), seconds=(gpsseconds + leapseconds))
    return epoch + elapsed

def split_line(line):
    if '|' in line:
        return line.split('|')
    if '\t' in line:
        return line.split('\t')
    return re.sub(' +', ' ', line).split(' ')

def parseline(line, names):
    values = split_line(line)
    converters = [int] + [float]*4 + [int]*2 + [float]*8
    conv_vals = [c(v) for c, v in zip(converters, values) ]
    return dict(zip(names, conv_vals))

def count_lines(f):
    n_lines = 0
    for line in f:
        if line.startswith('%'):
            continue
        n_lines += 1
    f.seek(0)
    return n_lines

def handle_name(name):
    name = name.strip().lower()
    if '(' in name:
        name = name[:name.index('(')]
    name = name.replace('-', '_')

    return name

def extract_data(f, n_lines):
    names = ['week', 'tow', 'ecef_x', 'ecef_y', 'ecef_z', 'Q', 'ns',
             'sdx', 'sdy', 'sdz', 'sdxy', 'sdyz', 'sdzx', 'age', 'ratio']
    ref_pos = None
    tmpbuf = [0] * n_lines
    print('Found %d lines' % n_lines)
    data = {}
    c_line = 0
    for line in f:
        if line.startswith('%'):
            if 'age' in line:
                names = [handle_name(name) for name in split_line(line.strip('% '))]
                if names[0] == 'gpst':
                    names.insert(0, 'week')
            if 'ref pos' in line:
                data_start = line.index(':', 1)
                ref_pos = [float(p) for p in split_line(line[data_start+1:].strip())]
            continue
        data_line = parseline(line, names)
        for key, val in data_line.items():
            try:
                data[key][c_line] = val
            except KeyError:
                data[key] = list(tmpbuf)
                data[key][c_line] = val
        c_line += 1
    f.seek(0)
    return data, names, ref_pos

def parse_file(infile):
    ref_pos = None
    with open(infile, 'rU') as f:
        n_lines = count_lines(f)

        data, names, ref_pos = extract_data(f, n_lines)

    if 'ecef_x' in names:
        try:
            from pymap3d import ecef2geodetic
            print('Adding latlon')
            lat, lon, height = ecef2geodetic(data['ecef_x'], data['ecef_y'], data['ecef_z'])
            data['latitude'] = lat
            data['longitude'] = lon
            data['height'] = height
            names += ['latitude', 'longitude', 'height']
        except ImportError:
            print('Install pymap3d to automatically add enu solution')

    if 'latitude' in names and ref_pos is not None:
        try:
            from pymap3d import geodetic2enu
            print('Adding enu')
            east, north, up = geodetic2enu(data['latitude'], data['longitude'], data['height'], *ref_pos)
            data['e_baseline'] = east
            data['n_baseline'] = north
            data['u_baseline'] = up
            names += ['e_baseline', 'n_baseline', 'u_baseline']
        except ImportError:
            print('Install pymap3d to automatically add enu solution')
    elif 'e_baseline' in names:
        try:
            from pymap3d import enu2geodetic
            print('Adding latlon')
            lat, lon, height = enu2geodetic(data['e_baseline'], data['n_baseline'], data['u_baseline'], *ref_pos)
            data['latitude'] = lat
            data['longitude'] = lon
            data['height'] = height
            names += ['latitude', 'longitude', 'height']
        except ImportError:
            print('Install pymap3d to automatically add enu solution')

    return data, names
 No newline at end of file
Loading