定位技术由来已久。通过GPS,百度,谷歌的定位技术,为目前社交网络发展提供了更进一步的精确和方向,同时也会各种智能家具自动化情景模式提供了解决方案。
室内定位在智能化家具的场景协议处理中具有十分有用,如果能精确的了解室主人的精确位置,就能制定更智能化更节约能源的自动化。比如智能电灯或者插座在主人进屋后自动亮灭,智能风扇在主人离开时自动停止,室内的电动门自动开关等等。
利用室内不同地点的无线发射源,比如WIFI,蓝牙,新BLE技术,可以实现室内定位。假设室内有ABC三个无线设备,根据信号误减算出距离,建立坐标,已知某人位于P(x,y)点,这与A(x1,y1),B(x2,y2),C(x3,y3)的距离分别为a,b,c。求P点座标
可以得到三个方程:
( x1 - x )2 + ( y1- y)2 = a2
( x2 - x)2 + ( y2 -y)2 = b2
( x3 - x)2 + ( y3 -y)2 = c2
使用多项式定理,可以化解方程并求解这个二元二次方程。
或者使用解析几何处理,对原坐标系进行旋转和平移,使A点为原点(0,0),B点位于x轴(d,0),C点在新坐标系为(i,j),根据勾定理和圆的解析方程,得到简化方程
方程1:
a2 = x2 + y2
方程2:
b2 = (x - d)2 + y2
方程3:
c2 = (x - i)2 + (y - j)2
1和2相减得到新坐标系中x的值为
x = (r12 - r22+ d2) / 2d
然后得到y值
y = (r12 - r32- x2 + (x - i)2 + j2) / 2j
而d的值为:
d2 = (x2-x1)2 + (y2-y1) 2
I,j的值是(x3,y3)经过平移和旋转后得到
B原本不在x轴,B顺时针旋转B角度后使其位于X轴,
标准的数学模型中,三个圆会完美的相交于一点,但由于使用无线信号,信号强度衰减既与本身物理属相相关,也与室内装修布局有关,所以实际衰减会比理论衰减更多,所以根据理论衰减度与距离的关系方程算出的距离会比实际偏大。这样得到的圆的半径比实际长,三圆没办法相交于或者相切于一点,而可能是相交于一个区域。理论上来讲,用户处于的某一点就在该区域内。
以view左上角为原点,右为x轴,下为y轴,建立坐标系。计算人在室内的相对位置。
屏幕坐标系中点顺时针和逆时针加平移公式,x1,y1原坐标系坐标,x2,y2为新坐标系坐标,逆时针变换后可以顺时针还原
点顺时针或者坐标轴逆时针
X1=x2cosb-y2sinb+x0
Y1=y2cosb+x2sinb-y0
点逆时针或者坐标轴顺时针
X2=(x1-x0)*cosb+(y1-y0)*sinb
Y2=(y1-y0)*cosb-(x1-x0)*sinb
//BLE1 position private int m_x1 = 300; private int m_y1 = 180; //BLE2 position private int m_x2 = 600; //180; private int m_y2 = 420; //580; //BLE3 position private int m_x3 = 180; //600; private int m_y3 = 580; //420; //user position private int m_x = 600; private int m_y = 600; // // private int m_r1 = 130, m_r2 = 300, m_r3 = 300; // private int m_xx = 0; // private int m_yy = 0; /* private int m_x1 = 100; private int m_y1 = 100; //BLE2 position private int m_x2 = 400; //180; private int m_y2 = 100; //580; //BLE3 position private int m_x3 = 100; //600; private int m_y3 = 400; //420; //user position private int m_x = 400; private int m_y = 400; */ // private int times = 10000; //以A为原点 ,B为x轴上的点,转换坐标系 public double getSinx(int x, int y, int x1, int y1) { return (((y-y1)*1.0f)/Math.sqrt((x-x1)*(x-x1)+(y-y1)*(y-y1))); } public double getCosx(int x, int y, int x1, int y1) { return (((x-x1)*1.0f)/Math.sqrt((x-x1)*(x-x1)+(y-y1)*(y-y1))); } //获得B点x坐标 public int getDD(int x1, int y1, int x2, int y2) { return ((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)); } //get new x public int getX(int x1, int y1, int x2, int y2, int x3, int y3, int r1, int r2, int r3) { int x = 0; int dd = getDD(x1, y1, x2, y2); Log.i(tag, "getX d1=" + dd); double d = (Math.sqrt(dd)); Log.i(tag, "getX d=" + d); x = (int) ((r1 * r1 - r2 * r2 + dd) / (2 * d)); Log.i(tag, "getX x=" + x); return x; } //get old x public int getXX(int x, int y, int x2, int y2, int x1, int y1) { int nx = 0; //x=x‘cost-y‘sint+x0, double cosbx = getCosx(x2, y2, x1, y1); double sinbx = getSinx(x2, y2, x1, y1); nx = ((int)(x*cosbx-y*sinbx))+x1; Log.i(tag, "getXX nx=" + nx); return nx; } //get new y public int getY(int x1, int y1, int x2, int y2, int x3, int y3, int r1, int r2, int r3) { int y = 0; // y = (r12 - r32 - x2 + (x - i)2 + j2) / 2j double cosx = getCosx(x2, y2, x1, y1); double sinx = getSinx(x2, y2, x1, y1); Log.i(tag, "getY sinx=" + sinx + "cosx="+cosx); //int i = (int)(((x3*x2+y3*y2)*1.0f)/Math.sqrt(x2*x2+y2*y2))-x1;//x3 - x1; int i = (int)(((x3-x1)*cosx+(y3-y1)*sinx)); Log.i(tag, "getY i=" + i); //int j = (int)(((x2*y3-y2*x3)*1.0f)/Math.sqrt(x2*x2+y2*y2))-y1;//y3 - y1; int j = (int)((y3-y1)*cosx-(x3-x1)*sinx); Log.i(tag, "getY j=" + j); int x = getX(x1, y1, x2, y2, x3, y3, r1, r2, r3); y = (int)((r1 * r1 - r3 * r3 - x * x + (x - i) * (x - i) + j * j) / (2 * j)); Log.i(tag, "getY y=" + y); return y; } //get old y public int getYY(int x, int y, int x2, int y2, int x1, int y1) { int ny = 0; //y=x‘sint+y‘cost+y0. //double cosx = getCosx(x2, y2, x1, y1); //double sinx = getSinx(x2, y2, x1, y1); double cosbx = getCosx(x2, y2, x1, y1); double sinbx = getSinx(x2, y2, x1, y1); ny = (int)((x*sinbx+y*cosbx))+y1; Log.i(tag, "getYY ny=" + ny); return ny; } public int getR1(int x1, int y1, int x, int y) { int r1 = 0; int d1 = (x1 - x) * (x1 - x) + (y1 - y) * (y1 - y); Log.i(tag, "getR1 d1=" + d1); double d = Math.sqrt(d1); Log.i(tag, "getR1 d=" + d); r1 = (int) d; return r1; } public int getR2(int x2, int y2, int x, int y) { int r2 = 0; int d1 = (x2 - x) * (x2 - x) + (y2 - y) * (y2 - y); Log.i(tag, "getR2 d1=" + d1); double d = Math.sqrt(d1); Log.i(tag, "getR2 d=" + d); r2 = (int) d; return r2; } public int getR3(int x3, int y3, int x, int y) { int r3 = 0; int d1 = (x3 - x) * (x3 - x) + (y3 - y) * (y3 - y); Log.i(tag, "getR3 d1=" + d1); double d = Math.sqrt(d1); Log.i(tag, "getR3 d=" + d); r3 = (int) d; return r3; } public Point getManPoint(int x1, int y1, int x2, int y2, int x3, int y3, int r1, int r2, int r3) { Point p = new Point(0,0); for (int j = 0; j < scr_h; j++) { for (int i = 0; i < scr_w; i++) { if (((i - x1) * (i - x1) + (j - y1) * (j - y1) <= r1 * r1) && ((i - x2) * (i - x2) + (j - y2) * (j - y2) <= r2 * r2) && ((i - x3) * (i - x3) + (j - y3) * (j - y3) <= r3 * r3)) { p.set(i, j); return p; } } } return p; } public void setValue(int x1, int y1, int x2, int y2, int x3, int y3, int x, int y) { this.m_x1 = x1; this.m_y1 = y1; this.m_x2 = x2; this.m_y2 = y2; this.m_x3 = x3; this.m_y3 = y3; this.m_x = x; this.m_x = y; this.invalidate(); } void onDrawView(Canvas canvas) { // add and modify Paint p = new Paint(); canvas.drawBitmap(img, 0, 0, p); p.setColor(Color.BLUE); canvas.drawCircle(m_x1, m_y1, 10, p); p.setTextSize(50); canvas.drawText("A", m_x1+10, m_y1+10, p); canvas.drawCircle(m_x2, m_y2, 10, p); canvas.drawText("B", m_x2+10, m_y2+10, p); canvas.drawCircle(m_x3, m_y3, 10, p); canvas.drawText("C", m_x3+10, m_y3+10, p); p.setColor(Color.RED); canvas.drawCircle(m_x, m_y, 20, p); canvas.drawText("P", m_x+20, m_y+20, p); p.setColor(Color.BLUE); p.setStyle(Paint.Style.STROKE);// 设置空心 p.setStrokeWidth(10); /* canvas.drawCircle(m_x1, m_y1, m_r1, p); canvas.drawCircle(m_x2, m_y2, m_r2, p); canvas.drawCircle(m_x3, m_y3, m_r3, p); int x = getX(m_x1, m_y1, m_x2, m_y2, m_x3, m_y3, m_r1, m_r2, m_r3); int y = getY(m_x1, m_y1, m_x2, m_y2, m_x3, m_y3, m_r1, m_r2, m_r3); x = getXX(x, y, m_x2, m_y2, m_x1); y = getYY(x, y, m_x2, m_y2, m_y1); canvas.drawCircle(x, y, 100, p); */ int r1= getR1(m_x1, m_y1, m_x, m_y); int r2= getR1(m_x2, m_y2, m_x, m_y); int r3= getR1(m_x3, m_y3, m_x, m_y); canvas.drawCircle(m_x1, m_y1, r1, p); canvas.drawCircle(m_x2, m_y2, r2, p); canvas.drawCircle(m_x3, m_y3, r3, p); int x = getX(m_x1, m_y1, m_x2, m_y2, m_x3, m_y3, r1+10, r2+10, r3+10); int y = getY(m_x1, m_y1, m_x2, m_y2, m_x3, m_y3, r1+10, r2+10, r3+10); Log.i(tag, "onDrawView x="+x+"y="+y); int xx = getXX(x, y, m_x2, m_y2, m_x1, m_y1); int yy = getYY(x, y, m_x2, m_y2, m_x1, m_y1); Log.i(tag, "onDrawView xx="+xx+"yy="+yy); Log.i(tag, "onDrawView this.m_x="+this.m_x+"this.m_y="+this.m_y); p.setColor(Color.YELLOW); canvas.drawCircle(xx, yy, 30, p); }