From 08d5f7b0a0b24c042aa5976f66bf3a1b5b754478 Mon Sep 17 00:00:00 2001 From: Richard Zahoransky Date: Mon, 7 Nov 2011 16:29:56 +0100 Subject: Localization Code. How-To will follow... --- lookup/BTSLut.java | 200 +++++++++++++++++++++++++++++++++++++++++++++++ lookup/GSMLut.java | 88 +++++++++++++++++++++ lookup/ILut.java | 18 +++++ lookup/RatioLut.java | 41 ++++++++++ lookup/ResultScore.java | 101 ++++++++++++++++++++++++ lookup/ScoreElement.java | 44 +++++++++++ 6 files changed, 492 insertions(+) create mode 100644 lookup/BTSLut.java create mode 100644 lookup/GSMLut.java create mode 100644 lookup/ILut.java create mode 100644 lookup/RatioLut.java create mode 100644 lookup/ResultScore.java create mode 100644 lookup/ScoreElement.java (limited to 'lookup') diff --git a/lookup/BTSLut.java b/lookup/BTSLut.java new file mode 100644 index 0000000..6abfcb8 --- /dev/null +++ b/lookup/BTSLut.java @@ -0,0 +1,200 @@ +package lookup; + +import helper.ListGPS; + +import java.util.LinkedList; +import java.util.List; +import java.util.ListIterator; + +import DataStructure.GPScoordinate; +import DataStructure.GSMMap; +import DataStructure.SingleBTS; + +/** + * No longer used! + * + * @author richy + * + */ +public class BTSLut implements ILut { + private LinkedList[] possible_coords_DL = new LinkedList[69]; + private LinkedList[] possible_coords_UL = new LinkedList[69]; + public int bts; // which bts does this Object store + public int threshold_dB; + public int threshold_m; + + /** + * create empty LUT + * + * @param ARFCN + * set BTS-ARFCN this object will take measurements and requests + */ + public BTSLut(int ARFCN, int threshold_dB, int threshold_m) { + this.bts = ARFCN; + this.threshold_dB = threshold_dB; + this.threshold_m = threshold_m; + // initialize strength array: -47 ... -115 + for (int i = 0; i < 69; i++) { + possible_coords_DL[i] = new LinkedList(); + possible_coords_UL[i] = new LinkedList(); + } + + } + + public BTSLut(int ARFCN, GSMMap map, int threshold, int threshold_m) { + this.bts = ARFCN; + this.threshold_dB = threshold; + this.threshold_m = threshold_m; + for (int i = 0; i < 69; i++) { + possible_coords_DL[i] = new LinkedList(); + possible_coords_UL[i] = new LinkedList(); + } + // fill the LUT + for (int x = 0; x < map.Xcoords.length; x++) { + for (int y = 0; y < map.Ycoords.length; y++) { + fill(map.getCoord(x, y), map.map[x][y]); + } + } + + } + + @Override + public LinkedList get(SingleBTS MR) { + // hier muss noch das threshold_dB berücksichtigt werden! + if (MR == null) + return null; + LinkedList result = new LinkedList(); + for (int i = threshold_dB * (-1); i <= threshold_dB; i++) { + try { + if (MR.fullBTS && MR.getDLcount() > 0) { + // get coords for DL and UL and do a intersection + // fix: do no intersection + LinkedList listUL = new LinkedList(); + LinkedList listDL = new LinkedList(); + listUL = possible_coords_UL[getIndex(MR.getUldB() + + threshold_dB)]; + listDL = possible_coords_DL[getIndex(MR.getDldB() + + threshold_dB)]; + listUL = ListGPS.removeNullElements(listUL); + listDL = ListGPS.removeNullElements(listDL); + // result.addAll(helper.ListGPS.intersect(listDL, + // listUL,threshold_m)); + result.addAll(listUL); + result.addAll(listDL); + } else { + result.addAll(possible_coords_DL[(getIndex(MR.getDldB() + + threshold_dB))]); + } + } catch (Exception e) { + // only index out of bound... ignore + + } + } + return result; + + } + + /** + * Takes list. Returns the lookup. Result is the intersection between all + * SingleBTSs in MR. That is, only Coordinates that are in common are + * returned + */ + + @SuppressWarnings("unused") + public LinkedList get(List MR) { + // create result list for each function call + LinkedList list = new LinkedList(); + // create a nested-linked-list in order to compute the intersection + LinkedList> nestedlist = new LinkedList>(); + + // one list for all + LinkedList resultset = new LinkedList(); + + ListIterator itr = MR.listIterator(); + while (itr.hasNext()) { + SingleBTS current = itr.next(); + resultset.addAll(get(current)); + } + if (true) + return resultset; + + for (SingleBTS current : MR) { + // clear list + list = new LinkedList(); + // save results in that list. do that list into the list-list + list.addAll(get(current)); + list = ListGPS.removeNullElements(list); + if (list != null && !list.isEmpty()) + nestedlist.addLast(list); + } + + // ------- + // from here on only calculating intersect + // ------- + + // reuse list. take it to store final result + nestedlist = ListGPS.removeAllNullElements(nestedlist); + if (list != null) + list.clear(); + if (nestedlist == null || nestedlist.isEmpty()) + return null; + if (nestedlist.size() == 1) + return nestedlist.getFirst(); + // nestedlist has at least 2 elements. do intersect with both. Store in + // list. + list.addAll(ListGPS.intersect(nestedlist.removeFirst(), + nestedlist.removeLast(), threshold_m)); + // now do intersect with the rest. This could get a speedup by using + // pairwise intersection. would be O(log n) then. + while (!nestedlist.isEmpty()) { + list = ListGPS.intersect(list, nestedlist.removeFirst(), + threshold_m); + } + // TODO: only null elements are here! + return list; + + } + + /** + * Returns index where the strength (dBm) is stored in the array + * + * @param strength + * . Gets rounded + * @return + */ + private int getIndex(double strength) { + int rounded = (int) Math.round(strength); + // this could be done with math.abs + if (strength < 0) { + return -47 - rounded; + } else { + return rounded - 47; + } + + } + + @Override + public void fill(GPScoordinate where, SingleBTS what) { + if (what == null || what.ARFCN != bts) + return; + int hit = 0; + if (what.getDldB() != 0) { + hit = getIndex(what.getDldB()); + possible_coords_DL[hit].add(where); + } + if (what.getUldB() != 0) { + hit = getIndex(what.getUldB()); + possible_coords_UL[hit].add(where); + } + + } + + public void fill(GPScoordinate where, List what) { + if (what == null) + return; + for (SingleBTS current : what) { + fill(where, current); + } + } + +} diff --git a/lookup/GSMLut.java b/lookup/GSMLut.java new file mode 100644 index 0000000..7b87001 --- /dev/null +++ b/lookup/GSMLut.java @@ -0,0 +1,88 @@ +package lookup; + +import helper.ListGPS; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.ListIterator; + +import DataStructure.GPScoordinate; +import DataStructure.GSMMap; +import DataStructure.SingleBTS; + +/** + * Throw in one or more MR (BTS-list). Get Score Element with possible + * Coordinates. This GSMLut uses ScoreElements to represent coordinates and + * their possibility. NOT USED!!!! + * + * @author richy + * + */ +public class GSMLut { + // private GSMMap map; + private SingleBTS[] content; + private ArrayList lookups = new ArrayList(); + + /** + * Create inverse of map + * + * @param map + * GSMmap to use + */ + public GSMLut(GSMMap map) { + // this.map = map; + content = map.getUniqueBTSlist(); // check if content also contains + // E-Plus arfcn! + for (SingleBTS current : content) { + // create a LUT for every BTS + lookups.add(new BTSLut(current.ARFCN, map, 20, 20)); + // traverse the whole GSMmap, add values to BTSLut + } + + } + + public LinkedList find(List MR) { + // traverse lookups. Build result array + // LinkedList> set = new + // LinkedList>(); + LinkedList set = new LinkedList(); + for (ILut lut : lookups) { + set.addAll(lut.get(MR)); + // set.add(lut.get(MR)); + } + // no intersect + // return ListGPS.intersect(set); + return set; + } + + /** + * Returns Score Elements. No intersect is done. Only common Coordinates are + * counted. This should be a better way to start! + * + * @param MR + * @return + */ + public LinkedList findWithScore(List MR) { + LinkedList resultset = find(MR); + // get unique coords + GPScoordinate[] unique = ListGPS.content(resultset); + ArrayList scores = new ArrayList( + unique.length); + for (GPScoordinate coord : unique) { + scores.add(new ScoreElement(coord)); + } + // score elements are initialized. traverse the whole result set now + ListIterator itr = resultset.listIterator(); + for (int i = 0; i < scores.size(); i++) { + while (itr.hasNext()) { + + } + // reset itr + } + + return null; + + } + +} diff --git a/lookup/ILut.java b/lookup/ILut.java new file mode 100644 index 0000000..854f5e3 --- /dev/null +++ b/lookup/ILut.java @@ -0,0 +1,18 @@ +package lookup; + +import java.util.LinkedList; +import java.util.List; + +import DataStructure.GPScoordinate; +import DataStructure.SingleBTS; + +interface ILut { + int bts = 0; + + public LinkedList get(SingleBTS MR); + + public void fill(GPScoordinate where, SingleBTS what); + + public LinkedList get(List MR); + +} diff --git a/lookup/RatioLut.java b/lookup/RatioLut.java new file mode 100644 index 0000000..9ead05e --- /dev/null +++ b/lookup/RatioLut.java @@ -0,0 +1,41 @@ +package lookup; + +import java.util.LinkedList; +import java.util.List; + +import DataStructure.GPScoordinate; +import DataStructure.SingleBTS; + +/** + * there should be as many RatioLuts as there are entries in arfcn table. For + * every OpenBSC BTS one! + * + * @author richy + * + */ +public class RatioLut implements ILut { + public int bts; // to where are the ratios calculated + + public RatioLut(int ARFCN) { + this.bts = ARFCN; + } + + @Override + public LinkedList get(SingleBTS MR) { + // TODO Auto-generated method stub + return null; + } + + @Override + public void fill(GPScoordinate where, SingleBTS what) { + // TODO Auto-generated method stub + + } + + @Override + public LinkedList get(List MR) { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/lookup/ResultScore.java b/lookup/ResultScore.java new file mode 100644 index 0000000..2044fda --- /dev/null +++ b/lookup/ResultScore.java @@ -0,0 +1,101 @@ +//OUTDATED: no longer used: 06.06.2011 + +package lookup; + +import helper.ListBTS; +import helper.ListGPS; + +import java.util.ArrayList; +import java.util.List; + +import DataStructure.GPScoordinate; +import DataStructure.GSMMap; +import DataStructure.SingleBTS; + +public class ResultScore { + ArrayList scores = new ArrayList(); + GSMMap map; + + /** + * Gets score for every Coordinate + * + * @param list + */ + public ResultScore(GSMMap map) { + this.map = map; + + } + + public ArrayList find(List MR, double thresholdDBm) { + // looks like threshold_dB has to be as high as 25dBm + ArrayList places = map.find(MR, thresholdDBm); + GPScoordinate[] content = ListGPS.content(places); + for (GPScoordinate curr_content : content) { + // take every Coordinate once. Build a ScoreElement with it.Traverse + // all found places + ScoreElement curr_score = new ScoreElement(curr_content); + for (GPScoordinate curr_place : places) { + // count how often this place got marked + curr_score.inc_occurence(curr_place); + } + scores.add(curr_score); + + // traverse every coordinate from gsm.find. check every tile if all + // mesurements match. if not, score gets low + + // then, check BTS relations! + + } + + // check scores. compare it with map + + // HACK: hardcoded ratio between 877 and 880 + for (int i = 0; i < scores.size(); i++) { + ScoreElement score_at_i = scores.get(i); + scores.set(i, ratioboost(score_at_i, MR)); + + } + + return scores; + } + + private ScoreElement ratioboost(ScoreElement place, List MR) { + // MR are the measured values during a call + // ArrayList list = map.getBTSList(place.gps); + // compare list with MR. Ratio between 877 and 880 + + while (ListBTS.contains(MR, 880) && ListBTS.contains(MR, 877)) { + SingleBTS r880 = ListBTS.removeARFCN(MR, 880); + SingleBTS r877 = ListBTS.removeARFCN(MR, 877); + if (r880.getDldB() > -46 || r877.getDldB() > -46) { + continue; + } + double ratio_MR = r880.getDldB() - r877.getDldB(); + // compare ratio with gsmmap. Get a number between 100 and 0 % + // double ratioscore = 0; // zero means absolutly no match + ArrayList maplist = map.getBTSList(place.gps); + // check if map has both BTS at this place + if (ListBTS.contains(maplist, 880) + && ListBTS.contains(maplist, 877)) { + double ratio_map = ListBTS.getARFCN(maplist, 880).getDldB() + - ListBTS.getARFCN(maplist, 877).getDldB(); + // calculate distance in % + if (ratio_MR >= ratio_map) { + place.occurrence += (ratio_map / ratio_MR * 100); + } else if (ratio_MR < ratio_map) { + place.occurrence += (ratio_MR / ratio_map * 100); + } + + } + + } + + return place; + } + +} + +class ratio { + SingleBTS first; + SingleBTS second; +} diff --git a/lookup/ScoreElement.java b/lookup/ScoreElement.java new file mode 100644 index 0000000..cd7dc09 --- /dev/null +++ b/lookup/ScoreElement.java @@ -0,0 +1,44 @@ +package lookup; + +import DataStructure.GPScoordinate; + +/** + * Saves a GPS coordinate from the Lookup. Also stores how often that coordinate + * was chosen or hit. + * + * @author richy + * + */ +public class ScoreElement implements Comparable { + public int occurrence; // how often was this coordinate chosen based on + // Signalstrength + public int ratio_hit; // how often was this coordinate chosen based on + // SignalRatio + public GPScoordinate gps; + private double score; // 0-1 + + public ScoreElement(GPScoordinate reference) { + gps = reference; + } + + public void inc_occurence(GPScoordinate gps) { + if (this.gps.equals(gps)) { + occurrence++; + } + + } + + public String toString() { + return ("Hits:" + occurrence + " Coord:" + gps.coord1 + "," + gps.coord2); + } + + public int compareTo(ScoreElement e) { + if (occurrence < e.occurrence) + return -1; + else if (occurrence > e.occurrence) + return 1; + else + return 0; + + } +} -- cgit v1.2.3-55-g7522