From 2742e2fe10c625b5ad39720b38bd70e0d70fc9bd Mon Sep 17 00:00:00 2001 From: HappyZ Date: Thu, 1 Feb 2018 21:30:16 -0600 Subject: [PATCH] adapt to new data format --- calibration_plot.m | 144 ++++++++++++++++++++++++++++++++++----------- iw_parser.py | 44 ++++++++++---- 2 files changed, 143 insertions(+), 45 deletions(-) diff --git a/calibration_plot.m b/calibration_plot.m index 0f9123c..1643681 100644 --- a/calibration_plot.m +++ b/calibration_plot.m @@ -1,48 +1,122 @@ -figure(1); -clf; hold on; +clear all; -% desired_result = [60:30:1200, 120, 170, 200, 430, 1000, 1300:100:2000]; -desired_result = 100:100:2500; -median_result = zeros(size(desired_result)); -mean_result = zeros(size(desired_result)); -diff_result = zeros(size(desired_result)); +folder = 'calibration_data/new_indoor/'; +files = dir(folder); +targets = zeros(1, length(files)); +for i = length(files):-1:1 + if (~contains(files(i).name, 'result') ||... + contains(files(i).name, 'left') ||... + contains(files(i).name, 'right') ||... + contains(files(i).name, 'ap') ||... + contains(files(i).name, 'down') ||... + contains(files(i).name, 'up')) + files(i) = []; + targets(i) = []; + else + targets(i) = sscanf(files(i).name, 'result_%dcm.txt'); + end +end +[targets, orderI] = sort(targets); +files = files(orderI); + +median_result = zeros(1, length(files)); +mean_result = zeros(1, length(files)); all_data = []; -for i = 1:length(desired_result) - dist = desired_result(i); - filename = ['calibration_data/outdoor/result_', num2str(dist), 'cm.txt']; +figure(1); clf; hold on; +for i = 1:length(files) + filename = [folder, files(i).name]; fileID = fopen(filename, 'r'); - sizeData = [9 Inf]; formatSpec = [... 'Target: %x:%x:%x:%x:%x:%x, status: %d, ',... 'rtt: %d psec, distance: %d cm\n'... ]; - data = fscanf(fileID, formatSpec, sizeData); - data(:, data(7, :) ~= 0) = []; - data(:, data(9, :) < -1000) = []; + data = fscanf(fileID, formatSpec, [9 Inf]); fclose(fileID); + if isempty(data) + data = readtable(filename); + if isempty(data) + continue + end + caliDist = table2array(data(:, 2))'; + rawRTT = table2array(data(:, 3))'; + rawRTTVar = table2array(data(:, 4))'; + rawDist = table2array(data(:, 5))'; + rawDistVar = table2array(data(:, 6))'; + rssi = table2array(data(:, 7))'; + time = table2array(data(:, 8))'; + else + % get rid of invalid data + data(:, data(7, :) ~= 0) = []; + data(:, data(9, :) < -1000) = []; + rawDist = data(9, :); + end - fprintf('distance: %d:\n', dist); - fprintf('* mean: %.2fcm\n', mean(data(9, :))); - fprintf('* median: %.2fcm\n', median(data(9, :))); - - cdfplot(data(9, :)); + mean_result(i) = mean(rawDist); + median_result(i) = median(rawDist); - mean_result(i) = mean(data(9, :)); - median_result(i) = median(data(9, :)); - all_data = [all_data, [data(9, :); dist * ones(1, length(data(9, :)))]]; - diff_result(i) = desired_result(i) - median_result(i); + fprintf('distance: %d:\n', targets(i)); + fprintf('* mean: %.2f (uncalibrated)\n', mean_result(i)); + fprintf('* median: %.2f (uncalibrated)\n', median_result(i)); + fprintf('* std: %.2f (uncalibrated)\n', std(rawDist)); + + figure(1); cdfplot(rawDist); + + all_data = [... + all_data,... + [rawDist; targets(i) * ones(1, size(rawDist, 2))]... + ]; end -figure(2); clf; -scatter(all_data(1, :), all_data(2, :), '.'); -params = polyfit(all_data(1, :), all_data(2, :), 1) -fitted_data = params(1) * all_data(1, :) + params(2); -params2 = polyfit(median_result, desired_result, 1) -fitted_data2 = params2(1) * all_data(1, :) + params2(2); -params3 = polyfit(mean_result, desired_result, 1) -fitted_data3 = params3(1) * all_data(1, :) + params3(2); -hold on; -plot(all_data(1, :), fitted_data, '-') -plot(all_data(1, :), fitted_data2, '-') -plot(all_data(1, :), fitted_data3, '-') +% % shuffle +% shuffled_data = all_data(:, randperm(size(all_data, 2))); +% +% % 10-fold cross validation +% step = floor(size(shuffled_data, 2) / 20); +% params = zeros(2, 20); +% mse = zeros(1, 20); +% for i = 1:20 +% from = step * (i - 1) + 1; +% to = step * i; +% train_data = shuffled_data; +% test_data = train_data(:, from:to); +% train_data(:, from:to) = []; +% params(:, i) = polyfit(train_data(1, :), train_data(2, :), 1); +% test_est = params(1, i) * test_data(1, :) + params(2, i); +% mse(i) = sum((test_est - test_data(2, :)).^2) / size(test_data, 2); +% end + +% param(1) = sum(params(1, :)) / size(mse, 2); +% % mse ./ sum(mse) * params(1, :)'; +% param(2) = sum(params(2, :)) / size(mse, 2); +% % mse ./ sum(mse) * params(2, :)'; +% validated_fit_data = param(1) * all_data(1, :) + param(2); +% mstd_1 = sqrt(sum((validated_fit_data - all_data(2, :)).^2) /... +% size(all_data, 2)); + + +figure(2); clf; hold on; +scatter(all_data(1, :), all_data(2, :), 'b.'); +plot(median_result, targets, 'r', 'LineWidth', 2) + +% linear fit +param_linear = polyfit(all_data(1, :), all_data(2, :), 1); +data_linear = param_linear(1) * all_data(1, :) + param_linear(2); +mstd_linear = sqrt(... + sum((data_linear - all_data(2, :)).^2) / size(all_data, 2)); +scatter(all_data(1, :), data_linear, 'c.'); + +% parabolic fit +param_parabolic = polyfit(all_data(1, :), all_data(2, :), 2); +data_parabolic = ... + param_parabolic(1) * all_data(1, :).^2 +... + param_parabolic(2) * all_data(1, :) + ... + param_parabolic(3); +mstd_parabolic = sqrt(... + sum((data_parabolic - all_data(2, :)).^2) / size(all_data, 2)); +scatter(all_data(1, :), data_parabolic, 'k.'); + +fprintf('Std Err:\n'); +fprintf(' linear mode: %.6f\n', mstd_linear); +fprintf(' parabolic mode: %.6f\n', mstd_parabolic); + diff --git a/iw_parser.py b/iw_parser.py index 1f9e470..3d3acd4 100755 --- a/iw_parser.py +++ b/iw_parser.py @@ -7,6 +7,7 @@ import re import argparse from numpy import min, max, median, mean, std +from numpy.random import choice def wrapper(args): @@ -14,26 +15,43 @@ def wrapper(args): return results = [] regex = ( + r"Target: (([0-9a-f]{2}:*){6}), " + + r"status: ([0-9]), rtt: ([0-9\-]+) psec, " + + r"distance: ([0-9\-]+) cm" + ) + regex_new = ( r"Target: (([0-9a-f]{2}:*){6}), " + r"status: ([0-9]), rtt: ([0-9\-]+) \(±([0-9\-]+)\) psec, " + r"distance: ([0-9\-]+) \(±([0-9\-]+)\) cm, rssi: ([0-9\-]+) dBm" ) with open(args['filepath']) as f: - for line in f: + data_ori = f.readlines() + if args['sample'] is None: + data = data_ori + else: + data = choice(data_ori, size=args['sample'], replace=False) + for line in data: + match = re.search(regex_new, line) + if match: + mac = match.group(1) + status = int(match.group(3)) + rtt = int(match.group(4)) + rtt_var = int(match.group(5)) + raw_distance = int(match.group(6)) + raw_distance_var = int(match.group(7)) + rssi = int(match.group(8)) + else: match = re.search(regex, line) if match: mac = match.group(1) status = int(match.group(3)) rtt = int(match.group(4)) - rtt_var = int(match.group(5)) - raw_distance = int(match.group(6)) - raw_distance_var = int(match.group(7)) - rssi = int(match.group(8)) + raw_distance = int(match.group(5)) else: continue - if status is not 0 or raw_distance < -1000: - continue - results.append(raw_distance * args['cali'][0] + args['cali'][1]) + if status is not 0 or raw_distance < -1000: + continue + results.append(raw_distance * args['cali'][0] + args['cali'][1]) print('statics of results') print('* num of valid data: {0}'.format(len(results))) print('* min: {0:.2f}cm'.format(min(results))) @@ -52,10 +70,17 @@ def main(): p.add_argument( '--cali', nargs=2, - default=(0.9234, 534.7103), + default=(0.9376, 558.0551), + # default=(0.9234, 534.7103), type=float, help="calibrate final result" ) + p.add_argument( + '--sample', + default=None, + type=int, + help="if set (an integer), sample data for accuracy testing" + ) try: args = vars(p.parse_args()) except Exception as e: @@ -64,6 +89,5 @@ def main(): wrapper(args) - if __name__ == '__main__': main()