室内定位系统

最近学校实验要做一个室内定位系统,由于本人计算机无法运行Android虚拟机,而且也不支持外接Android设备(就是这么强),所以自己参照WLAN的API和相关操作制作了一个基于三角定位的程序。A,c参数不通用,要根据实际WiFi信号自己测量,然后用MATLAB进行非线性拟合求出(其实精度要求不大的时候自己算也行)。本程序可以在VS2010上跑通,在7.8m*9.0m的房间内误差为0.7-0.8m左右,有待改进。希望能给需要的人带来帮助,抛砖引玉也未尝不可。


#ifndef UNICODE

#define UNICODE
#endif


#include <windows.h>
#include <wlanapi.h>
#include <objbase.h>
#include <wtypes.h>
#include <math.h>


#include <stdio.h>
#include <stdlib.h>


#pragma comment(lib, "wlanapi.lib")
#pragma comment(lib, "ole32.lib")


typedef struct point 
{
double x;
double y;
double z;
}point,vec;//表示点的坐标或者空间向量


//通过信号强度计算距离
double distance(int rssi)
{
double A=/*418.5276*/103.3688,c=/*-21.11187*/-1.888;
int rssii = abs(rssi);
float power = (rssii - /*59*/A)/(10*/*2.0*/c);
return pow(10,power);
}


//三角定位算法
point  triangulation(point A,point B,point C,double sa,double sb,double sc)//求点P的坐标
{
double ab = sqrt(pow(A.x - B.x,2)+pow(A.y - B.y,2));
double ac = sqrt(pow(A.x - C.x,2)+pow(A.y - C.y,2));
double bc = sqrt(pow(B.x - C.x,2)+pow(B.y - C.y,2));


double a = sa,b = ab,c = ac,d = bc,e = sc,f = sb;


//空间海伦-秦九韶公式
double D = b*b + c*c - d*d;
double E = a*a + c*c - e*e;
double F = a*a + b*b - f*f;

double V = sqrt(4*a*a*b*b*c*c - a*a*D*D - b*b*E*E - c*c*F*F + D*E*F)/12;


//平面海伦-秦九韶公式
double p = (ac + ab + bc)/2;
double S = sqrt(p*(p-a)*(p-b)*(p-c));


double h = V*3/S;


double d1 = sqrt(sa*sa - h*h),d2 = sqrt(sb*sb - h*h), d3 = sqrt(sc*sc - h*h);


double A1 = 2*(B.x - A.x),B1 = 2*(B.y - A.y),C1 = d1*d1 - d2*d2 - A.x*A.x + B.x*B.x - A.y*A.y + B.y*B.y;
double A2 = 2*(C.x - B.x),B2 = 2*(C.y - B.y),C2 = d2*d2 - d3*d3 - B.x*B.x + C.x*C.x - B.y*B.y + C.y*C.y;


point P;
P.x = (B2*C1 - B1*C2)/(A1*B2 - A2*B1);
if(P.x<0.000001) P.x = 0;
P.y = (C1*A2 - C2*A1)/(B1*A2 - B2*A1);
if(P.y<0.000001) P.y = 0;
P.z = A.z;


return P;
}




int wmain()
{
    // 声明,初始化变量


/*printf("distance:%f\n",distance(95));
printf("distance:%f\n",distance(92));
printf("distance:%f\n",distance(85));
printf("distance:%f\n",distance(82));
printf("distance:%f\n",distance(84));
printf("distance:%f\n",distance(80));
printf("distance:%f\n",distance(66));
*/
HANDLE hClient = NULL;
    DWORD dwMaxClient = 2;      //    
    DWORD dwCurVersion = 0;
    DWORD dwResult = 0;
    DWORD dwRetVal = 0;
    int iRet = 0;




    
    WCHAR GuidString[39] = {0};
WCHAR name0[] = {'r','u','l','e','r','0'};
WCHAR name1[] = {'r','u','l','e','r','1'};
WCHAR name2[] = {'r','u','l','e','r','2'};
WCHAR temp[10];
DOUBLE sa = 0,sb = 0,sc = 0;
    unsigned int i, j, k;


    /* 用于WLAN枚举界面的变量 */


    PWLAN_INTERFACE_INFO_LIST pIfList = NULL;
    PWLAN_INTERFACE_INFO pIfInfo = NULL;


    PWLAN_AVAILABLE_NETWORK_LIST pBssList = NULL;
    PWLAN_AVAILABLE_NETWORK pBssEntry = NULL;
    
    int iRSSI = 0;


    dwResult = WlanOpenHandle(dwMaxClient, NULL, &dwCurVersion, &hClient);
    if (dwResult != ERROR_SUCCESS) {
        wprintf(L"WlanOpenHandle failed with error: %u\n", dwResult);
        return 1;
    }


    dwResult = WlanEnumInterfaces(hClient, NULL, &pIfList);
    if (dwResult != ERROR_SUCCESS) {
        wprintf(L"WlanEnumInterfaces failed with error: %u\n", dwResult);
        return 1;
    } else {
        for (i = 0; i < (int) pIfList->dwNumberOfItems; i++) {
            pIfInfo = (WLAN_INTERFACE_INFO *) &pIfList->InterfaceInfo[i];
           
            iRet = StringFromGUID2(pIfInfo->InterfaceGuid, (LPOLESTR) &GuidString, 
                sizeof(GuidString)/sizeof(*GuidString)); 
            dwResult = WlanGetAvailableNetworkList(hClient,
                                             &pIfInfo->InterfaceGuid,
                                             0, 
                                             NULL, 
                                             &pBssList);


            if (dwResult != ERROR_SUCCESS) {
                wprintf(L"WlanGetAvailableNetworkList failed with error: %u\n",
                        dwResult);
                dwRetVal = 1;
            } else {
                wprintf(L"界面中可用的无线局域网如下:\n");


                wprintf(L"  Num Entries: %lu\n\n", pBssList->dwNumberOfItems);


                for (j = 0; j < pBssList->dwNumberOfItems; j++) {
                    pBssEntry =
                        (WLAN_AVAILABLE_NETWORK *) & pBssList->Network[j];


                    wprintf(L"  Profile Name[%u]:  %ws\n", j, pBssEntry->strProfileName);
                    
                    wprintf(L"  SSID[%u]:\t\t ", j);
                    if (pBssEntry->dot11Ssid.uSSIDLength == 0)
                        wprintf(L"\n");
                    else {   
                        for (k = 0; k < pBssEntry->dot11Ssid.uSSIDLength; k++) {
                            wprintf(L"%c", (int) pBssEntry->dot11Ssid.ucSSID[k]);
temp[k] = pBssEntry->dot11Ssid.ucSSID[k];

                        }




                        wprintf(L"\n");
                    }
                        
                    wprintf(L"  BSS Network type[%u]:\t ", j);
                    switch (pBssEntry->dot11BssType) {
                    case dot11_BSS_type_infrastructure   :
                        wprintf(L"Infrastructure (%u)\n", pBssEntry->dot11BssType);
                        break;
                    case dot11_BSS_type_independent:
                        wprintf(L"Infrastructure (%u)\n", pBssEntry->dot11BssType);
                        break;
                    default:
                        wprintf(L"Other (%lu)\n", pBssEntry->dot11BssType);
                        break;
                    }
                                
                    printf("  BSSID 数量:\t %u\n", j, pBssEntry->uNumberOfBssids);


                    wprintf(L"  是否可连接:\t ", j);
                    if (pBssEntry->bNetworkConnectable)
                        wprintf(L"是\n");
                    else {
                        wprintf(L"否\n");
                        wprintf(L"  不可连接的原因:\t %u\n", 
                            pBssEntry->wlanNotConnectableReason);
                    }        


                    wprintf(L"  Number of PHY types supported[%u]:\t %u\n", j, pBssEntry->uNumberOfPhyTypes);


                    if (pBssEntry->wlanSignalQuality == 0)
                        iRSSI = -100;
                    else if (pBssEntry->wlanSignalQuality == 100)   
                        iRSSI = -50;
                    else
                        iRSSI = -100 + (pBssEntry->wlanSignalQuality/2);    
                        
                    printf(" 信号强度(RSSI): %i (dBm)\n 距离(distance): %f(M)",  
                        iRSSI,distance(iRSSI));
                    wprintf(L"\n");
                    
                    wprintf(L"\n");


if(!strcmp((const char*)temp,(const char*)name0))
sa = distance(iRSSI);
else if(!strcmp((const char*)temp,(const char*)name1))
sb = distance(iRSSI);
else if(!strcmp((const char*)temp,(const char*)name2))
sc = distance(iRSSI);
else
{


}


                }
            }
        }


    }


//wprintf(L"sa:%f,sb:%f,sc:%f",sa,sb,sc);


point a,b,c;
a.x = 0;a.y = 0 ;a.z = 2.2;
b.x = 7.8;b.y = 0 ;b.z = 2.2;
c.x = 0;c.y = 9.0;c.z = 2.2;  
point P = triangulation(a,b,c,sa,sb,sc);
printf("目标所在坐标为:\n X:%.4f Y:%.4f",P.x,P.y);




//释放空间
    if (pBssList != NULL) {
        WlanFreeMemory(pBssList);
        pBssList = NULL;
    }


    if (pIfList != NULL) {
        WlanFreeMemory(pIfList);
        pIfList = NULL;
    }
system("pause");
    return dwRetVal;
}
 
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值