我正在研究三边测量以找到未知位置的位置,为了找到距离,我使用路径损耗常数为 2,就像文章中一样,我使用 2 部手机和一台笔记本电脑作为发射器和参考。这是代码:
distance1 = (double) Math.pow(10, ((rssi.get(k)-rssi1.get(a))/10*2));
rssi 是距离参考 1m 的 rssi 值,而 rssi1 是未知位置 rssi。
这是三边测量代码,公式来自This:
double r1 = Math.pow(distance1,2 );
double r2 = Math.pow(distance2,2 );
double r3 = Math.pow(distance3,2 );
double x1 = Math.pow(X1,2 );
double x2 = Math.pow(X2,2 );
double x3 = Math.pow(X3,2 );
double y1 = Math.pow(Y1,2 );
double y2 = Math.pow(Y2,2 );
double y3 = Math.pow(Y3,2 );
double A = r1 - r2 - x1+x2 - y1+y2;
double B = r2 - r3 - x2+x3 - y2+y3;
double C = ((-2*X1)+(2*X2));
double D = ((-2*Y1)+(2*Y2));
double E = ((-2*X2)+(2*X3));
double F = ((-2*Y2)+(2*Y3));
double x0 = (((A*F)-(B*D))/((F*C)-(E*D)));
double y0 = (((A*E)-(C*B))/((D*E)-(C*F)));
Log.v("x", String.valueOf(x0));
Log.v("y", String.valueOf(y0));
起初它给出了相当准确的结果,但后来结果没有改变甚至有很大的错误。我想知道为什么结果没有改变是因为什么时候做新的计算之前的结果没有被清除还是什么?或者我的代码中有一些错误?我有点困惑,因为从许多来源进行三边测量的方法不止一种,如下所示:
double delta = 4*((X1-X2)*(Y1-Y3)-(X1-X3)*(Y1-Y2));
double x0 = (1/delta) * ((2*A*(y1-y3))-(2*B*(y1-y2)));
double y0 = (1/delta) * ((2*B*(x1-x2))-(2*A*(x1-x3)));
它使用 delta 来计算我不明白它来自哪里。我理解第一个代码,它是一个线性方程。我计算距离的常数是错误的吗?是否有任何代码可以解释公式进行三边测量?我也试图延长接收 rssi 信号的时间,而不是平均它,但结果仍然很糟糕。
完整代码:
ArrayList<String> buildings;
DatabaseHelper db;
ArrayAdapter<String> arrayAdapter;
ArrayList<PositionData> positionsData;
String building;
TextView result;
TextView result2;
TextView result3;
Button locate;
public void onCreate(Bundle saveInstanceState) {
super.onCreate(saveInstanceState);
setContentView(R.layout.locate_wifi);
db = new DatabaseHelper(this);
buildings = db.getBuildings_wifi();
locate = (Button) findViewById(R.id.locate);
result = (TextView) findViewById(R.id.result);
result2 = (TextView) findViewById(R.id.result2);
result3 = (TextView) findViewById(R.id.result3);
arrayAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, buildings);
locate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Intent intent = new Intent(getApplicationContext(), Scan.class);
intent.putExtra("isLearning", false);
startActivityForResult(intent,0);
}
});
arrayAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, buildings);
// Set The Adapter
if (buildings.size()==0) {
Toast.makeText(this, "No building data available.", Toast.LENGTH_LONG).show();
locate.setEnabled(false);
}
else{
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setCancelable(false);
builder.setTitle("Choose building");
builder.setAdapter(arrayAdapter, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// the user clicked on colors[which]
building = buildings.get(which);
}
});
builder.show();
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode,
Intent intent) {
// TODO Auto-generated method stub
if(resultCode==RESULT_OK){
PositionData positionData = (PositionData) intent
.getSerializableExtra("PositionData");
positionsData=db.getWifiPositions(building);
ArrayList<Router> wifis = db.getFriendlyWifis(building);
HashMap<String, Double> rssi = positionData.getValues();
HashMap<String, Double> rssi1 = positionsData.get(0).getValues();
HashMap<String, Double> rssi2 = positionsData.get(1).getValues();
HashMap<String, Double> rssi3 = positionsData.get(2).getValues();
double X1 = positionsData.get(0).getX();
Double X2 = positionsData.get(1).getX();
Double X3 = positionsData.get(2).getX();
Double Y1 = positionsData.get(0).getY();
Double Y2 = positionsData.get(1).getY();
Double Y3 = positionsData.get(2).getY();
double distance1 = 0;
double distance2 = 0;
double distance3 = 0;
for (String k : rssi.keySet()) {
for (String a : rssi1.keySet()) {
if (k.equals(a)) {
Log.d("value",((Math.pow(10, ((rssi.get(k)-rssi1.get(a))/10*2))))+"");
distance1 = (double) Math.pow(10, ((rssi.get(k)-rssi1.get(a))/10*2));
}
}
for (String b : rssi2.keySet()) {
if (k.equals(b)) {
Log.d("value2",((Math.pow(10, ((rssi.get(k)-rssi2.get(b))/10*2))))+"");
distance2 = (double) Math.pow(10, ((rssi.get(k)-rssi2.get(b))/10*2));
}
}
for (String c : rssi3.keySet()) {
if (k.equals(c)) {
Log.d("value3",((Math.pow(10, ((rssi.get(k)-rssi3.get(c))/10*2))))+"");
distance3 = (double) Math.pow(10, ((rssi.get(k)-rssi3.get(c))/10*2));
}
}
}
double r1 = Math.pow(distance1,2 );
double r2 = Math.pow(distance2,2 );
double r3 = Math.pow(distance3,2 );
double x1 = Math.pow(X1,2 );
double x2 = Math.pow(X2,2 );
double x3 = Math.pow(X3,2 );
double y1 = Math.pow(Y1,2 );
double y2 = Math.pow(Y2,2 );
double y3 = Math.pow(Y3,2 );
double A = r1 - r2 - x1+x2 - y1+y2;
double B = r2 - r3 - x2+x3 - y2+y3;
//double delta = 4*((X1-X2)*(Y1-Y3)-(X1-X3)*(Y1-Y2));
//double x0 = (1/delta) * ((2*A*(y1-y3))-(2*B*(y1-y2)));
//double y0 = (1/delta) * ((2*B*(x1-x2))-(2*A*(x1-x3)));
double C = ((-2*X1)+(2*X2));
double D = ((-2*Y1)+(2*Y2));
double E = ((-2*X2)+(2*X3));
double F = ((-2*Y2)+(2*Y3));
double x0 = (((A*F)-(B*D))/((F*C)-(E*D)));
double y0 = (((A*E)-(C*B))/((D*E)-(C*F)));
Log.v("x", String.valueOf(x0));
Log.v("y", String.valueOf(y0));
result.setText("X: "+ x0);
result2.setText("Y: "+ y0);
super.onActivityResult(requestCode, resultCode, intent);
}
}
public class CustomOnItemSelectedListener implements
AdapterView.OnItemSelectedListener {
public void onItemSelected(AdapterView<?> parent, View view, int pos,
long id) {
building = parent.getItemAtPosition(pos).toString();
locate.setEnabled(true);
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
locate.setEnabled(false);
}
}
}