diff --git a/corelib/src/CameraRGBD.cpp b/corelib/src/CameraRGBD.cpp index 685a4e99..2d310567 100644 --- a/corelib/src/CameraRGBD.cpp +++ b/corelib/src/CameraRGBD.cpp @@ -62,6 +62,7 @@ namespace rtabmap CameraRGBD::CameraRGBD(float imageRate, const Transform & localTransform, float fx, float fy, float cx, float cy) : _imageRate(imageRate), _localTransform(localTransform), + _mirroring(false), _frameRateTimer(new UTimer()), _fx(fx), _fy(fy), diff --git a/corelib/src/toro3d/posegraph2.cpp b/corelib/src/toro3d/posegraph2.cpp index 311c5045..71a798d9 100644 --- a/corelib/src/toro3d/posegraph2.cpp +++ b/corelib/src/toro3d/posegraph2.cpp @@ -50,6 +50,7 @@ using namespace std; namespace AISNavigation { +typedef unsigned int uint; #define LINESIZE 81920 diff --git a/corelib/src/toro3d/treeoptimizer2.cpp b/corelib/src/toro3d/treeoptimizer2.cpp index 56324091..a650a8a5 100644 --- a/corelib/src/toro3d/treeoptimizer2.cpp +++ b/corelib/src/toro3d/treeoptimizer2.cpp @@ -46,6 +46,7 @@ #include #include +typedef unsigned int uint; using namespace std; namespace AISNavigation { diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index fe6261d1..44412837 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -4,10 +4,10 @@ ADD_SUBDIRECTORY( BOWMapping ) IF(TARGET rtabmap_gui) ADD_SUBDIRECTORY( RGBDMapping ) - # Only on Linux - IF(NOT WIN32 AND NOT APPLE) + # Only on Linux and Windows + IF(NOT APPLE) ADD_SUBDIRECTORY( WifiMapping ) - ENDIF(NOT WIN32 AND NOT APPLE) + ENDIF(NOT APPLE) ELSE() MESSAGE(STATUS "RTAB-Map GUI lib is not built, the RGBDMapping and WifiMapping examples will not be built...") diff --git a/examples/WifiMapping/MapBuilderWifi.h b/examples/WifiMapping/MapBuilderWifi.h index 95640f91..24e7b86f 100644 --- a/examples/WifiMapping/MapBuilderWifi.h +++ b/examples/WifiMapping/MapBuilderWifi.h @@ -32,6 +32,24 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 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 { Q_OBJECT @@ -124,10 +142,7 @@ protected slots: else { // Make a line with points - int level = -iter->second.first; - 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 + int quality = dBm2Quality(iter->second.first)/10; pcl::PointCloud::Ptr cloud(new pcl::PointCloud); 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)) pcl::PointXYZRGB pt; pt.z = float(i+1)*0.02f; - if(i -#include -#include +#ifdef _WIN32 + #ifndef UNICODE + #define UNICODE + #endif + + #include + #include + #include // for DOT11_SSID struct + #include + #include + + #include + #include + + // Need to link with Wlanapi.lib and Ole32.lib + #pragma comment(lib, "wlanapi.lib") + #pragma comment(lib, "ole32.lib") +#else + #include + #include + #include +#endif #include #include +// 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 { public: @@ -49,6 +87,79 @@ private: uSleep(1000/rate_); 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 //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) { //signal is measured in dBm and is valid for us to use - int level = ((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 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); + dBm = ((iw_statistics *)req.u.data.pointer)->qual.level - 256; } else { @@ -95,6 +198,18 @@ private: } 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 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); + } } } diff --git a/examples/WifiMapping/main.cpp b/examples/WifiMapping/main.cpp index fbcb596f..353ab696 100644 --- a/examples/WifiMapping/main.cpp +++ b/examples/WifiMapping/main.cpp @@ -35,14 +35,17 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include "MapBuilderWifi.h" + #include "WifiThread.h" void showUsage() { printf("\nUsage:\n" - "rtabmap-wifi_mapping interface_name [driver]\n" - " interface_name Wifi interface name (e.g. \"eth0\")\n" - " driver Driver number to use: 0=OpenNI-PCL, 1=OpenNI2, 2=Freenect, 3=OpenNI-CV, 4=OpenNI-CV-ASUS\n\n"); + "rtabmap-wifi_mapping [options]\n" + "Options:\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); } @@ -52,33 +55,52 @@ int main(int argc, char * argv[]) ULogger::setType(ULogger::kTypeConsole); ULogger::setLevel(ULogger::kWarning); - std::string interfaceName; + std::string interfaceName = "eth0"; int driver = 0; - if(argc < 2) + bool mirroring = false; + + // parse options + for(int i = 1; i 2) - { - driver = atoi(argv[2]); - if(driver < 0 || driver > 4) + ++i; + if(i < argc) + { + interfaceName = argv[i]; + } + else { - UERROR("driver should be between 0 and 4."); 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: @@ -129,6 +151,11 @@ int main(int argc, char * argv[]) camera = new rtabmap::CameraOpenni("", 0, opticalRotation); } + if(mirroring) + { + camera->setMirroringEnabled(true); + } + CameraThread cameraThread(camera); if(!cameraThread.init()) { diff --git a/guilib/src/DatabaseViewer.cpp b/guilib/src/DatabaseViewer.cpp index 1949b0f9..fd2d289e 100644 --- a/guilib/src/DatabaseViewer.cpp +++ b/guilib/src/DatabaseViewer.cpp @@ -916,7 +916,7 @@ void DatabaseViewer::generateTOROGraph() return; } 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) { @@ -968,7 +968,7 @@ void DatabaseViewer::view3DMap() if(optimizedPoses.size() > 0) { rtabmap::DetailedProgressDialog progressDialog(this); - progressDialog.setMaximumSteps(optimizedPoses.size()); + progressDialog.setMaximumSteps((int)optimizedPoses.size()); progressDialog.show(); // create a window @@ -2342,11 +2342,11 @@ void DatabaseViewer::updateGraphView() } if(graphes_.size()) { - ui_->horizontalSlider_iterations->setMaximum(graphes_.size()-1); - ui_->horizontalSlider_iterations->setValue(graphes_.size()-1); + ui_->horizontalSlider_iterations->setMaximum((int)graphes_.size()-1); + ui_->horizontalSlider_iterations->setValue((int)graphes_.size()-1); ui_->horizontalSlider_iterations->setEnabled(true); ui_->spinBox_optimizationsFrom->setEnabled(true); - sliderIterationsValueChanged(graphes_.size()-1); + sliderIterationsValueChanged((int)graphes_.size()-1); } else { diff --git a/lib/.empty b/lib/.empty deleted file mode 100644 index e69de29b..00000000