mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-02 01:20:25 +08:00
Fixed Windows build, implemented wifi mapping example in Windows
This commit is contained in:
@@ -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),
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ using namespace std;
|
|||||||
namespace AISNavigation {
|
namespace AISNavigation {
|
||||||
|
|
||||||
|
|
||||||
|
typedef unsigned int uint;
|
||||||
#define LINESIZE 81920
|
#define LINESIZE 81920
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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...")
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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_
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#ifndef UNICODE
|
||||||
|
#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 <sys/socket.h>
|
||||||
#include <linux/wireless.h>
|
#include <linux/wireless.h>
|
||||||
#include <sys/ioctl.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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
{
|
||||||
|
++i;
|
||||||
|
if(i < argc)
|
||||||
|
{
|
||||||
|
interfaceName = argv[i];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
interfaceName = argv[1];
|
|
||||||
if(interfaceName.size() == 0)
|
|
||||||
{
|
|
||||||
UERROR("Interface name invalid!");
|
|
||||||
showUsage();
|
showUsage();
|
||||||
}
|
}
|
||||||
else
|
continue;
|
||||||
{
|
|
||||||
printf("Using Wifi interface \"%s\"\n", interfaceName.c_str());
|
|
||||||
}
|
}
|
||||||
if(argc > 2)
|
if(strcmp(argv[i], "-m") == 0)
|
||||||
{
|
{
|
||||||
driver = atoi(argv[2]);
|
mirroring = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(strcmp(argv[i], "-d") == 0)
|
||||||
|
{
|
||||||
|
++i;
|
||||||
|
if(i < argc)
|
||||||
|
{
|
||||||
|
driver = atoi(argv[i]);
|
||||||
if(driver < 0 || driver > 4)
|
if(driver < 0 || driver > 4)
|
||||||
{
|
{
|
||||||
UERROR("driver should be between 0 and 4.");
|
UERROR("driver should be between 0 and 4.");
|
||||||
showUsage();
|
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())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user