...
 
Commits (2)
......@@ -4,11 +4,25 @@
BASE=base
UAV=uav
ONLINE_MODE=true
FINAL_OUTPUT_DIR=.
FINAL_OUTPUT_FILE=$FINAL_OUTPUT_DIR/uav.pos
INTERM_DIR="rtk_interm"
BASE_FILE=${BASE}.ubx
UAV_FILE=${UAV}.ubx
FINAL_OUTPUT_OPTIONS="-c -s | -d 5"
FINAL_MODE=2 #RTK
EUREF_URL='ftp://igs.bkg.bund.de/EUREF/obs'
# Intermediate files
UAV_INTERM="$INTERM_DIR/${UAV}"
BASE_INTERM="$INTERM_DIR/${BASE}"
# Programs:
SCRIPT_DIR=`dirname $0`
RNX2RTKP=${SCRIPT_DIR}/bin/rnx2rtkp
......@@ -19,6 +33,7 @@ RTKLIB2AVG=${SCRIPT_DIR}/scripts/rtklib2avg.py
CLOSEST_BS=${SCRIPT_DIR}/scripts/get_closest_basestation.py
EUREF_URL_GENERATOR=${SCRIPT_DIR}/scripts/get_euref_urls.py
INPUT_FILE_EXT=".obs .nav .eph .sp3 .sbs"
# Define colors:
YELLOW="\e[33m"
RED="\e[31m"
......@@ -28,7 +43,7 @@ DEFAULT="\e[39m"
set -o pipefail
# Check if we have a local base
if [ -e "${BASE}" ]; then
if [ -e "${BASE_FILE}" ]; then
HAS_BASE=true
else
HAS_BASE=false
......@@ -37,8 +52,10 @@ else
echo
fi
mkdir -p $INTERM_DIR
# Convert observations to RINEX
${CONVBIN} ${UAV_FILE} -ts 2000/01/01 00:00:00
${CONVBIN} ${UAV_FILE} -ts 2000/01/01 00:00:00 -d "$INTERM_DIR"
if [ ! $? -eq 0 ]; then
echo
echo -e "${RED}Error:${DEFAULT} Could not convert ${UAV_FILE}.";
......@@ -46,7 +63,7 @@ if [ ! $? -eq 0 ]; then
fi
if $HAS_BASE; then
${CONVBIN} ${BASE_FILE} -ts 2000/01/01 00:00:00
${CONVBIN} ${BASE_FILE} -ts 2000/01/01 00:00:00 -d "$INTERM_DIR"
if [ ! $? -eq 0 ]; then
echo
echo -e "${YELLOW}Warning:${DEFAULT} Could not convert ${UAV_FILE}.";
......@@ -55,18 +72,29 @@ if $HAS_BASE; then
fi
fi
# Get generate RNX file names
UAV_RNX_FILES=""
BASE_RNX_FILES=""
for ext in $INPUT_FILE_EXT; do
fname=$UAV_INTERM$ext
if [ -e "$fname" ]; then
UAV_RNX_FILES+="$fname "
fi
fname=$BASE_INTERM$ext
if [ -e "$fname" ]; then
BASE_RNX_FILES+="$fname "
fi
done
# Get public observations
if $HAS_BASE; then
MODE=3 # Static position
INPUT_FILES="$BASE.*"
INPUT_FILES="$BASE_RNX_FILES"
else
MODE=0 # Single position
INPUT_FILES="$UAV.*"
INPUT_FILES="$UAV_RNX_FILES"
fi
# Get single position from observations
${RNX2RTKP} -p $MODE -o single.pos $INPUT_FILES
${RNX2RTKP} -p 0 -s "|" -o $INTERM_DIR/single.pos $INPUT_FILES
if [ ! $? -eq 0 ]; then
echo
echo -e "${RED}Error:${DEFAULT} could not analyze ${INPUT_FILES}.";
......@@ -74,7 +102,7 @@ if [ ! $? -eq 0 ]; then
fi
# Get average single position from pos-file
llh=$(${RTKLIB2AVG} single.pos 5 6 | tail -n1)
AVG_SINGLE_LLH=$(${RTKLIB2AVG} $INTERM_DIR/single.pos 5 6 | tail -n1)
if [ ! $? -eq 0 ]; then
echo
echo "${RED}Error:${DEFAULT} Could not find single position.";
......@@ -82,75 +110,83 @@ if [ ! $? -eq 0 ]; then
fi
echo
echo "Average single pos lat long: " ${llh}
echo "Average single pos lat long: " ${AVG_SINGLE_LLH}
echo
# Find the closest base station ID
BS=$(${CLOSEST_BS} ${llh} | tail -n2)
if [ ! $? -eq 0 ]; then
if $ONLINE_MODE; then
# Find the closest base station ID
BS=$(${CLOSEST_BS} ${AVG_SINGLE_LLH} | tail -n2)
if [ ! $? -eq 0 ]; then
echo
echo -e "${RED}Error:${DEFAULT} Could not find basestation ID.";
exit -1;
fi
echo "Closest base station: " ${BS}
BSID=$(echo $BS | rev | cut -f 1 -d ' ' | rev )
echo "ID:" $BSID
echo
echo -e "${RED}Error:${DEFAULT} Could not find basestation ID.";
exit -1;
fi
echo "Closest base station: " ${BS}
BSID=$(echo $BS | rev | cut -f 1 -d ' ' | rev )
echo "ID:" $BSID
echo
# Find the start and end-file of the uav
awk_string='{ printf "%04d-%02d-%02dT%02d:%02d:%02.6f",$1,$2,$3,$4,$5,$6; }'
FIRST_OBS=$(head -n 100 ${UAV}.obs | grep "FIRST OBS" |
awk "${awk_string}")
LAST_OBS=$(head -n 100 ${UAV}.obs | grep "LAST OBS" |
awk "${awk_string}")
# Find the start and end-file of the uav
awk_string='{ printf "%04d-%02d-%02dT%02d:%02d:%02.6f",$1,$2,$3,$4,$5,$6; }'
FIRST_OBS=$(head -n 100 $INTERM_DIR/${UAV}.obs | grep "FIRST OBS" |
awk "${awk_string}")
LAST_OBS=$(head -n 100 $INTERM_DIR/${UAV}.obs | grep "LAST OBS" |
awk "${awk_string}")
echo "First observation: " ${FIRST_OBS}
echo "Last observation: " ${LAST_OBS}
echo "First observation: " ${FIRST_OBS}
echo "Last observation: " ${LAST_OBS}
echo
# Generate the proper URL
BS_URL=$(${EUREF_URL_GENERATOR} ${EUREF_URL} ${BSID} ${FIRST_OBS} ${LAST_OBS})
if [ ! $? -eq 0 ]; then
echo
echo -e "${RED}Error:${DEFAULT} Could not generate url.";
exit -1;
fi
BS_ZIPPEDNAME=$(echo $BS_URL | awk -F '/' '{ print $(NF) }')
BS_BASENAME=${BS_ZIPPEDNAME%.crx.gz}
BS_FILENAME=${BS_BASENAME}.rnx
# Download and unzip basestation file
cache_dir=basestations
mkdir -p $cache_dir
if [ ! -e "$cache_dir/$BS_FILENAME" ]; then
if [ ! -e "$cache_dir/$BS_BASENAME.crx" ]; then
if [ ! -e "$cache_dir/$BS_ZIPPEDNAME" ]; then
wget $BS_URL -P $cache_dir
# Generate the proper URL
BS_URL=$(${EUREF_URL_GENERATOR} ${EUREF_URL} ${BSID} ${FIRST_OBS} ${LAST_OBS})
if [ ! $? -eq 0 ]; then
echo
echo -e "${RED}Error:${DEFAULT} Could not generate url.";
exit -1;
fi
BS_ZIPPEDNAME=$(echo $BS_URL | awk -F '/' '{ print $(NF) }')
BS_BASENAME=${BS_ZIPPEDNAME%.crx.gz}
BS_FILENAME=${BS_BASENAME}.rnx
# Download and unzip basestation file
cache_dir=basestations
mkdir -p $cache_dir
if [ ! -e "$cache_dir/$BS_FILENAME" ]; then
if [ ! -e "$cache_dir/$BS_BASENAME.crx" ]; then
if [ ! -e "$cache_dir/$BS_ZIPPEDNAME" ]; then
wget $BS_URL -P $cache_dir
if [ ! $? -eq 0 ]; then
echo -e "${RED}Warning:${DEFAULT} Could not download '$BS_URL' to '$cache_dir'.";
ONLINE_MODE=false
fi
fi
if $ONLINE_MODE; then
gunzip -f $cache_dir/$BS_ZIPPEDNAME
if [ ! $? -eq 0 ]; then
echo -e "${YELLOW}Warning:${DEFAULT} Could not unzip '$cache_dir/$BS_ZIPPEDNAME'.";
fi
fi
fi
if $ONLINE_MODE; then
${CRX2RNX} $cache_dir/$BS_BASENAME.crx
if [ ! $? -eq 0 ]; then
echo -e "${RED}Error:${DEFAULT} Could not download '$BS_URL' to '$cache_dir'.";
echo -e "${RED}Error:${DEFAULT} Could not convert '$cache_dir/$BS_BASENAME.crx'.";
exit -1;
fi
fi
gunzip -f $cache_dir/$BS_ZIPPEDNAME
if [ ! $? -eq 0 ]; then
echo -e "${YELLOW}Warning:${DEFAULT} Could not unzip '$cache_dir/$BS_ZIPPEDNAME'.";
fi
fi
${CRX2RNX} $cache_dir/$BS_BASENAME.crx
if [ ! $? -eq 0 ]; then
echo -e "${RED}Error:${DEFAULT} Could not convert '$cache_dir/$BS_BASENAME.crx'.";
exit -1;
fi
fi
# Calculate UAV position from basestation if we do not have local base
MODE=2 # Kinematic
if [ $HAS_BASE == false ]; then
MODE=2 # Kinematic
INPUT_FILES="uav.*"
if ! $ONLINE_MODE; then
echo "${RED}Error:${DEFAULT} can not get RTK solution without a base."
exit -1;
fi
INPUT_FILES=${UAV_RNX_FILES}
BASE_STATION_FILES="$cache_dir/$BS_FILENAME"
OPTIONS="-c -s | -d 5"
${RNX2RTKP} -o $UAV.pos -p ${MODE} $OPTIONS $INPUT_FILES $BASE_STATION_FILES
${RNX2RTKP} -o "$FINAL_OUTPUT_FILE" -p ${MODE} $FINAL_OUTPUT_OPTIONS $INPUT_FILES $BASE_STATION_FILES
if [ ! $? -eq 0 ]; then
echo -e "${RED}Error:${DEFAULT} RTK analysis failed";
exit -1;
......@@ -160,5 +196,35 @@ if [ $HAS_BASE == false ]; then
exit 0
fi
echo "Local base station not implemented yet"
exit -1
if $ONLINE_MODE; then
echo "Getting local base RTK solution"
BASE_STATION_FILES="$cache_dir/$BS_FILENAME"
${RNX2RTKP} -o "$INTERM_DIR/base.pos" -p 2 -c -s "|" ${BASE_RNX_FILES} $BASE_STATION_FILES
if [ ! $? -eq 0 ]; then
echo
echo -e "${RED}Error:${DEFAULT} could not get base pos rtk fix.";
exit -1;
fi
BASE_STATION_POSITION=$(${RTKLIB2AVG} $INTERM_DIR/base.pos 1 6 | tail -n1)
if [ ! $? -eq 0 ]; then
echo
echo "${YELLOW}Warning:${DEFAULT} Could not find Q=1 base position, switching to Q=2.";
BASE_STATION_POSITION=$(${RTKLIB2AVG} $INTERM_DIR/base.pos 2 5 | tail -n1)
if [ ! $? -eq 0 ]; then
echo
echo "${RED}Error:${DEFAULT} Could not find accurate base station position.";
exit -1;
fi
fi
else
echo "Using base llh: average of single position"
BASE_STATION_POSITION=$AVG_SINGLE_LLH
fi
${RNX2RTKP} -o "$FINAL_OUTPUT_FILE" -p ${FINAL_MODE} -l $BASE_STATION_POSITION $FINAL_OUTPUT_OPTIONS $UAV_RNX_FILES $BASE_RNX_FILES $BASE_STATION_FILES
if [ $? -eq 0 ]; then
echo "Sucessfully created rtk solution file: $FINAL_OUTPUT_FILE"
else
echo "${RED}Error:${DEFAULT} could not generate rtk position"
fi
......@@ -2,6 +2,7 @@
import sys
import os
import re
import numpy as np
dir_path = os.path.dirname(os.path.realpath(__file__))
sys.path.append(os.path.join(dir_path, '..'))
......@@ -11,8 +12,15 @@ def print_usage():
print(' python rtklib2matlab.py [rover.pos]')
sys.exit(1)
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 = line.split()
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))
......@@ -53,7 +61,7 @@ if __name__ == '__main__':
for line in f:
if line.startswith('%'):
if 'ratio' in line:
names = [fix_name(name) for name in line[1:].split()]
names = [fix_name(name) for name in split_line(line.strip('% '))]
if 'gpst' in names:
names.insert(0, 'week')
continue
......@@ -93,6 +101,7 @@ if __name__ == '__main__':
name_start_ix = ix
break
print('')
print('Std : %s' % np.std(valid_arr, axis=1)[:3])
print('Mean:')
print('\t'.join(names[name_start_ix:name_start_ix+3]))
llh = np.mean(valid_arr, axis=1)[:3]
......