Fixed Windows build, implemented wifi mapping example in Windows

This commit is contained in:
Mathieu Labbé
2015-03-25 16:30:05 -04:00
parent 19d6da9035
commit 2cc853b507
9 changed files with 208 additions and 48 deletions

View File

@@ -62,6 +62,7 @@ namespace rtabmap
CameraRGBD::CameraRGBD(float imageRate, const Transform & localTransform, float fx, float fy, float cx, float cy) : CameraRGBD::CameraRGBD(float imageRate, const Transform & localTransform, float fx, float fy, float cx, float cy) :
_imageRate(imageRate), _imageRate(imageRate),
_localTransform(localTransform), _localTransform(localTransform),
_mirroring(false),
_frameRateTimer(new UTimer()), _frameRateTimer(new UTimer()),
_fx(fx), _fx(fx),
_fy(fy), _fy(fy),

View File

@@ -50,6 +50,7 @@ using namespace std;
namespace AISNavigation { namespace AISNavigation {
typedef unsigned int uint;
#define LINESIZE 81920 #define LINESIZE 81920

View File

@@ -46,6 +46,7 @@
#include <sstream> #include <sstream>
#include <string> #include <string>
typedef unsigned int uint;
using namespace std; using namespace std;
namespace AISNavigation { namespace AISNavigation {

View File

@@ -4,10 +4,10 @@ ADD_SUBDIRECTORY( BOWMapping )
IF(TARGET rtabmap_gui) IF(TARGET rtabmap_gui)
ADD_SUBDIRECTORY( RGBDMapping ) ADD_SUBDIRECTORY( RGBDMapping )
# Only on Linux # Only on Linux and Windows
IF(NOT WIN32 AND NOT APPLE) IF(NOT APPLE)
ADD_SUBDIRECTORY( WifiMapping ) ADD_SUBDIRECTORY( WifiMapping )
ENDIF(NOT WIN32 AND NOT APPLE) ENDIF(NOT APPLE)
ELSE() ELSE()
MESSAGE(STATUS "RTAB-Map GUI lib is not built, the RGBDMapping and WifiMapping examples will not be built...") MESSAGE(STATUS "RTAB-Map GUI lib is not built, the RGBDMapping and WifiMapping examples will not be built...")

View File

@@ -32,6 +32,24 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace rtabmap; using namespace rtabmap;
// A percentage value that represents the signal quality
// of the network. WLAN_SIGNAL_QUALITY is of type ULONG.
// This member contains a value between 0 and 100. A value
// of 0 implies an actual RSSI signal strength of -100 dbm.
// A value of 100 implies an actual RSSI signal strength of -50 dbm.
// You can calculate the RSSI signal strength value for wlanSignalQuality
// values between 1 and 99 using linear interpolation.
inline int dBm2Quality(int dBm)
{
// dBm to Quality:
if(dBm <= -100)
return 0;
else if(dBm >= -50)
return 100;
else
return 2 * (dBm + 100);
}
class MapBuilderWifi : public MapBuilder class MapBuilderWifi : public MapBuilder
{ {
Q_OBJECT Q_OBJECT
@@ -124,10 +142,7 @@ protected slots:
else else
{ {
// Make a line with points // Make a line with points
int level = -iter->second.first; int quality = dBm2Quality(iter->second.first)/10;
level = level < 30 ? 0 : level > 80 ? 50: level - 30; // set between 0 and 50
level/=5; // set between 0 and 10
level = 10 - level; // make higher level to 10
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>); pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
for(int i=0; i<10; ++i) for(int i=0; i<10; ++i)
{ {
@@ -135,7 +150,7 @@ protected slots:
// the number of points depends on the dBm (which varies from -30 (near) to -80 (far)) // the number of points depends on the dBm (which varies from -30 (near) to -80 (far))
pcl::PointXYZRGB pt; pcl::PointXYZRGB pt;
pt.z = float(i+1)*0.02f; pt.z = float(i+1)*0.02f;
if(i<level) if(i<quality)
{ {
// yellow // yellow
pt.r = 255; pt.r = 255;

View File

@@ -28,12 +28,50 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef WIFITHREAD_H_ #ifndef WIFITHREAD_H_
#define WIFITHREAD_H_ #define WIFITHREAD_H_
#include <sys/socket.h> #ifdef _WIN32
#include <linux/wireless.h> #ifndef UNICODE
#include <sys/ioctl.h> #define UNICODE
#endif
#include <windows.h>
#include <wlanapi.h>
#include <Windot11.h> // for DOT11_SSID struct
#include <objbase.h>
#include <wtypes.h>
#include <stdio.h>
#include <stdlib.h>
// Need to link with Wlanapi.lib and Ole32.lib
#pragma comment(lib, "wlanapi.lib")
#pragma comment(lib, "ole32.lib")
#else
#include <sys/socket.h>
#include <linux/wireless.h>
#include <sys/ioctl.h>
#endif
#include <rtabmap/core/UserDataEvent.h> #include <rtabmap/core/UserDataEvent.h>
#include <rtabmap/utilite/UTimer.h> #include <rtabmap/utilite/UTimer.h>
// A percentage value that represents the signal quality
// of the network. WLAN_SIGNAL_QUALITY is of type ULONG.
// This member contains a value between 0 and 100. A value
// of 0 implies an actual RSSI signal strength of -100 dbm.
// A value of 100 implies an actual RSSI signal strength of -50 dbm.
// You can calculate the RSSI signal strength value for wlanSignalQuality
// values between 1 and 99 using linear interpolation.
inline int quality2dBm(int quality)
{
// Quality to dBm:
if(quality <= 0)
return -100;
else if(quality >= 100)
return -50;
else
return (quality / 2) - 100;
}
class WifiThread : public UThread, public UEventsSender class WifiThread : public UThread, public UEventsSender
{ {
public: public:
@@ -49,6 +87,79 @@ private:
uSleep(1000/rate_); uSleep(1000/rate_);
if(!this->isKilled()) if(!this->isKilled())
{ {
int dBm = 0;
#ifdef _WIN32
//From https://msdn.microsoft.com/en-us/library/windows/desktop/ms706765(v=vs.85).aspx
// Declare and initialize variables.
HANDLE hClient = NULL;
DWORD dwMaxClient = 2; //
DWORD dwCurVersion = 0;
DWORD dwResult = 0;
// variables used for WlanEnumInterfaces
PWLAN_INTERFACE_INFO_LIST pIfList = NULL;
PWLAN_INTERFACE_INFO pIfInfo = NULL;
// variables used for WlanQueryInterfaces for opcode = wlan_intf_opcode_current_connection
PWLAN_CONNECTION_ATTRIBUTES pConnectInfo = NULL;
DWORD connectInfoSize = sizeof(WLAN_CONNECTION_ATTRIBUTES);
WLAN_OPCODE_VALUE_TYPE opCode = wlan_opcode_value_type_invalid;
dwResult = WlanOpenHandle(dwMaxClient, NULL, &dwCurVersion, &hClient);
if (dwResult != ERROR_SUCCESS)
{
UERROR("WlanOpenHandle failed with error: %u\n", dwResult);
}
else
{
dwResult = WlanEnumInterfaces(hClient, NULL, &pIfList);
if (dwResult != ERROR_SUCCESS)
{
UERROR("WlanEnumInterfaces failed with error: %u\n", dwResult);
}
else
{
// take the first interface found
int i = 0;
pIfInfo = (WLAN_INTERFACE_INFO *) & pIfList->InterfaceInfo[i];
if(pIfInfo->isState == wlan_interface_state_connected)
{
dwResult = WlanQueryInterface(hClient,
&pIfInfo->InterfaceGuid,
wlan_intf_opcode_current_connection,
NULL,
&connectInfoSize,
(PVOID *) &pConnectInfo,
&opCode);
if (dwResult != ERROR_SUCCESS)
{
UERROR("WlanQueryInterface failed with error: %u\n", dwResult);
}
else
{
int quality = pConnectInfo->wlanAssociationAttributes.wlanSignalQuality;
dBm = quality2dBm(quality);
}
}
else
{
UERROR("Interface not connected!");
}
}
}
if (pConnectInfo != NULL)
{
WlanFreeMemory(pConnectInfo);
pConnectInfo = NULL;
}
if (pIfList != NULL)
{
WlanFreeMemory(pIfList);
pIfList = NULL;
}
#else
// Code inspired from http://blog.ajhodges.com/2011/10/using-ioctl-to-gather-wifi-information.html // Code inspired from http://blog.ajhodges.com/2011/10/using-ioctl-to-gather-wifi-information.html
//have to use a socket for ioctl //have to use a socket for ioctl
@@ -79,15 +190,7 @@ private:
else if(((iw_statistics *)req.u.data.pointer)->qual.updated & IW_QUAL_DBM) else if(((iw_statistics *)req.u.data.pointer)->qual.updated & IW_QUAL_DBM)
{ {
//signal is measured in dBm and is valid for us to use //signal is measured in dBm and is valid for us to use
int level = ((iw_statistics *)req.u.data.pointer)->qual.level - 256; dBm = ((iw_statistics *)req.u.data.pointer)->qual.level - 256;
double stamp = UTimer::now();
// Create user data [level, stamp] with the value (int = 4 bytes) and a timestamp (double = 8 bytes)
std::vector<unsigned char> data(sizeof(int) + sizeof(double));
memcpy(data.data(), &level, sizeof(int));
memcpy(data.data()+sizeof(int), &stamp, sizeof(double));
this->post(new UserDataEvent(data));
//UWARN("posting level %d dBm", level);
} }
else else
{ {
@@ -95,6 +198,18 @@ private:
} }
close(sockfd); close(sockfd);
#endif
if(dBm != 0)
{
double stamp = UTimer::now();
// Create user data [level, stamp] with the value (int = 4 bytes) and a timestamp (double = 8 bytes)
std::vector<unsigned char> data(sizeof(int) + sizeof(double));
memcpy(data.data(), &dBm, sizeof(int));
memcpy(data.data()+sizeof(int), &stamp, sizeof(double));
this->post(new UserDataEvent(data));
//UWARN("posting level %d dBm", dBm);
}
} }
} }

View File

@@ -35,14 +35,17 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <stdio.h> #include <stdio.h>
#include "MapBuilderWifi.h" #include "MapBuilderWifi.h"
#include "WifiThread.h" #include "WifiThread.h"
void showUsage() void showUsage()
{ {
printf("\nUsage:\n" printf("\nUsage:\n"
"rtabmap-wifi_mapping interface_name [driver]\n" "rtabmap-wifi_mapping [options]\n"
" interface_name Wifi interface name (e.g. \"eth0\")\n" "Options:\n"
" driver Driver number to use: 0=OpenNI-PCL, 1=OpenNI2, 2=Freenect, 3=OpenNI-CV, 4=OpenNI-CV-ASUS\n\n"); " -i \"name\" Wifi interface name (e.g. \"eth0\"). Only required on Linux.\n"
" -m Enable mirroring of the camera image.\n"
" -d # Driver number to use: 0=OpenNI-PCL, 1=OpenNI2, 2=Freenect, 3=OpenNI-CV, 4=OpenNI-CV-ASUS\n\n");
exit(1); exit(1);
} }
@@ -52,33 +55,52 @@ int main(int argc, char * argv[])
ULogger::setType(ULogger::kTypeConsole); ULogger::setType(ULogger::kTypeConsole);
ULogger::setLevel(ULogger::kWarning); ULogger::setLevel(ULogger::kWarning);
std::string interfaceName; std::string interfaceName = "eth0";
int driver = 0; int driver = 0;
if(argc < 2) bool mirroring = false;
// parse options
for(int i = 1; i<argc; ++i)
{ {
showUsage(); if(strcmp(argv[i], "-i") == 0)
}
else
{
interfaceName = argv[1];
if(interfaceName.size() == 0)
{ {
UERROR("Interface name invalid!"); ++i;
showUsage(); if(i < argc)
} {
else interfaceName = argv[i];
{ }
printf("Using Wifi interface \"%s\"\n", interfaceName.c_str()); else
}
if(argc > 2)
{
driver = atoi(argv[2]);
if(driver < 0 || driver > 4)
{ {
UERROR("driver should be between 0 and 4.");
showUsage(); showUsage();
} }
continue;
} }
if(strcmp(argv[i], "-m") == 0)
{
mirroring = true;
continue;
}
if(strcmp(argv[i], "-d") == 0)
{
++i;
if(i < argc)
{
driver = atoi(argv[i]);
if(driver < 0 || driver > 4)
{
UERROR("driver should be between 0 and 4.");
showUsage();
}
}
else
{
showUsage();
}
continue;
}
UERROR("Option \"%s\" not recognized!", argv[i]);
showUsage();
} }
// Here is the pipeline that we will use: // Here is the pipeline that we will use:
@@ -129,6 +151,11 @@ int main(int argc, char * argv[])
camera = new rtabmap::CameraOpenni("", 0, opticalRotation); camera = new rtabmap::CameraOpenni("", 0, opticalRotation);
} }
if(mirroring)
{
camera->setMirroringEnabled(true);
}
CameraThread cameraThread(camera); CameraThread cameraThread(camera);
if(!cameraThread.init()) if(!cameraThread.init())
{ {

View File

@@ -916,7 +916,7 @@ void DatabaseViewer::generateTOROGraph()
return; return;
} }
bool ok = false; bool ok = false;
int id = QInputDialog::getInt(this, tr("Which iteration?"), tr("Iteration (0 -> %1)").arg((int)graphes_.size()-1), (int)graphes_.size()-1, 0, graphes_.size()-1, 1, &ok); int id = QInputDialog::getInt(this, tr("Which iteration?"), tr("Iteration (0 -> %1)").arg((int)graphes_.size()-1), (int)graphes_.size()-1, 0, (int)graphes_.size()-1, 1, &ok);
if(ok) if(ok)
{ {
@@ -968,7 +968,7 @@ void DatabaseViewer::view3DMap()
if(optimizedPoses.size() > 0) if(optimizedPoses.size() > 0)
{ {
rtabmap::DetailedProgressDialog progressDialog(this); rtabmap::DetailedProgressDialog progressDialog(this);
progressDialog.setMaximumSteps(optimizedPoses.size()); progressDialog.setMaximumSteps((int)optimizedPoses.size());
progressDialog.show(); progressDialog.show();
// create a window // create a window
@@ -2342,11 +2342,11 @@ void DatabaseViewer::updateGraphView()
} }
if(graphes_.size()) if(graphes_.size())
{ {
ui_->horizontalSlider_iterations->setMaximum(graphes_.size()-1); ui_->horizontalSlider_iterations->setMaximum((int)graphes_.size()-1);
ui_->horizontalSlider_iterations->setValue(graphes_.size()-1); ui_->horizontalSlider_iterations->setValue((int)graphes_.size()-1);
ui_->horizontalSlider_iterations->setEnabled(true); ui_->horizontalSlider_iterations->setEnabled(true);
ui_->spinBox_optimizationsFrom->setEnabled(true); ui_->spinBox_optimizationsFrom->setEnabled(true);
sliderIterationsValueChanged(graphes_.size()-1); sliderIterationsValueChanged((int)graphes_.size()-1);
} }
else else
{ {

View File