diff --git a/README.md b/README.md index 3cbbf15..930eba1 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Livox SDK consists of Livox SDK communication protocol, Livox SDK core, Livox SD # Livox SDK Communication Protocol -Livox SDK communication protocol opens to all users. It is the communication protocol between user programs and Livox products. The protocol consists of control commands and data format. Please refer to the [Livox SDK Communication Protocol](https://www.livoxtech.com/sdk/downloads) for detailed information. +Livox SDK communication protocol opens to all users. It is the communication protocol between user programs and Livox products. The protocol consists of control commands and data format. Please refer to the [Livox SDK Communication Protocol](doc/Livox_SDK_Communication_Protocol_EN_20190117.pdf) for detailed information. # Livox SDK Core @@ -20,7 +20,7 @@ The Livox LiDAR sensors can be connected to host directly or through the Livox H # Livox SDK API -Livox SDK API provides a set of C style functions which can be conveniently integrated in C/C++ programs. Please refer to the [Livox SDK API Reference](https://www.livoxtech.com/sdk/downloads) for detailed information. +Livox SDK API provides a set of C style functions which can be conveniently integrated in C/C++ programs. Please refer to the [Livox SDK API Reference](doc/Livox_LiDAR_SDK_API_Reference.pdf) for detailed information. ## Build Notes @@ -28,9 +28,9 @@ Livox SDK API provides a set of C style functions which can be conveniently inte LivoxTech SDK requires cmake 3.0.0+, Apache Portable Runtime (APR) 1.61+ and Boost 1.54+. -Here we use the Ubuntu 16.04 LTS system as an example to show you how to compile LivoxTech sdk's dependency libraries using apt or direct compiling the source code of apr and boost lib. +Here we use the Ubuntu 16.04 LTS system and Windows 7,10 as an example to show you how to compile LivoxTech sdk's dependency libraries using apt or direct compiling the source code of apr and boost lib. -###### Ubuntu 16.04 LTS +##### Ubuntu 16.04 LTS The following package are required (feel free to cut and paste the apt-get command below): @@ -58,7 +58,7 @@ tar zxf apr-1.6.5.tar.gz && \ cd apr-1.6.5 && \ ./configure --prefix=/usr && \ make && \ -make install +sudo make install ``` ``` @@ -75,7 +75,7 @@ In the LivoxTech SDK directory (e.g. the checkout root or the archive unpack roo ``` mkdir build && cd build && \ cmake .. && \ -make -j $(nproc) +make ``` ###### Run the Project @@ -92,32 +92,57 @@ cd sample\lidar && \ ./lidar_sample ``` +##### Windows +We test Livox SDK with Visual Studio 2015/2017 on Windows 7/10. + +###### Build with Vcpkg + +We recommend using [Vcpkg](https://github.com/Microsoft/vcpkg) to build our project. You need to install the following libraries first. + +``` +.\vcpkg install apr && \ +.\vcpkg install boost-atomic && \ +.\vcpkg install boost-system && \ +.\vcpkg install boost-thread && \ +.\vcpkg integrate install +``` + +In the LivoxTech SDK directory, run the following commands to create the Visual Studio solution file. Please replace vcpkgroot with your vcpkg installation location. + +``` +mkdir build && \ +cd build && \ +cmake .. "-DCMAKE_TOOLCHAIN_FILE=[vcpkgroot]\scripts\buildsystems\vcpkg.cmake" +``` + +Then you can open the livox_sdk.sln project in Visual Studio. + +###### Run the Project + +In the LivoxTech SDK directory, run the following commands to run the Hub or LiDAR sample: + +``` +cd build\sample\hub\Debug && \ +./hub_sample.exe +``` + +``` +cd build\sample\lidar\Debug && \ +./lidar_sample.exe +``` + # Livox SDK Linux Sample Two samples are provided in Sample/Lidar and Sample/Hub, which demonstrate how to configure Livox LiDAR units and receive the point cloud data when directly connecting Livox-SDK to LiDAR units or by using a Livox Hub, respectively. The sequence diagram is shown as below: ![sample](doc/images/sample.png) -# Livox Ros Demo - -Livox ROS demo is an application software running under ROS environment. It supports point cloud display using rviz. The Livox ROS demo includes two software packages, which are applicable when the host is connected to LiDAR sensors directly or when a Livox Hub is in use, respectively. This Livox ROS demo supports Ubuntu 14.04/Ubuntu 16.04, both x86 and ARM. It has been tested on Intel i7 and Nvidia TX2. - -## Livox ROS Demo User Guide - -The Livox-SDK-ROS directory is organized in the form of ROS workspace, and is fully compatible with ROS workspace. Only a subfolder named src can be found under the Livox-SDK-ROS directory. Inside the src directory, there are two ROS software packages: display_lidar_points and display_hub_points. - -1. Download or clone the code from the Livox-SDK/Livox-SDK-ROS repository on GitHub. -2. Compile the ROS code package under the Livox-SDK-ROS directory by typing the following command in terminal: - `catkin_make` -3. Run the compiled ROS nodes: - `rosrun display_lidar_points display_lidar_points_node` - or - `rosrun display_hub_points display_hub_points_node` -4. Open a new terminal, and run roscore under the Livox-SDK-ROS directory: - `roscore` -5. Open another new terminal, and run rviz under the Livox-SDK-ROS directory: - `rosrun rviz rviz` -6. Set ROS RVIZ: - 1. Create new visualization by display type, and select PointCloud; - 2. Set the Fixed Frame to “sensor_frame” in Global Options and set Frame Rate to 20; - 3. Select “/cloud” in Topic under the newly created PointCLoud. +**NOTE**: Please replace the broadcast code lists in the `main.c` for both LiDAR sample and Hub sample with the broadcast code of your devices before running. You can find the following code section in `main.c`: +``` +#define BROADCAST_CODE_LIST_SIZE 3 +char *broadcast_code_list[BROADCAST_CODE_LIST_SIZE] = { + "00000000000002", + "00000000000003", + "00000000000004" +}; +``` diff --git a/doc/Livox_LiDAR_SDK_API_Reference.pdf b/doc/Livox_LiDAR_SDK_API_Reference.pdf new file mode 100644 index 0000000..bc2c2c1 Binary files /dev/null and b/doc/Livox_LiDAR_SDK_API_Reference.pdf differ diff --git a/doc/Livox_SDK_Communication_Protocol_EN_20190117.pdf b/doc/Livox_SDK_Communication_Protocol_EN_20190117.pdf new file mode 100644 index 0000000..260197a Binary files /dev/null and b/doc/Livox_SDK_Communication_Protocol_EN_20190117.pdf differ diff --git a/sample/hub/main.c b/sample/hub/main.c index c40fddc..e2748e4 100644 --- a/sample/hub/main.c +++ b/sample/hub/main.c @@ -24,7 +24,11 @@ #include #include +#ifdef WIN32 +#include +#else #include +#endif #include #include "livox_sdk.h" @@ -196,10 +200,18 @@ int main(int argc, const char *argv[]) { SetDeviceStateUpdateCallback(OnDeviceChange); if (Start()) { +#ifdef WIN32 + Sleep(20000); +#else sleep(20); +#endif HubStopSampling(OnStopSampleCallback, NULL); printf("stop sample\n"); +#ifdef WIN32 + Sleep(10000); +#else sleep(10); +#endif } Uninit(); diff --git a/sample/lidar/main.c b/sample/lidar/main.c index 64e8849..42a233e 100644 --- a/sample/lidar/main.c +++ b/sample/lidar/main.c @@ -24,7 +24,11 @@ #include #include +#ifdef WIN32 +#include +#else #include +#endif #include #include "livox_sdk.h" @@ -45,9 +49,9 @@ uint32_t data_recveive_count[kMaxLidarCount]; #define BROADCAST_CODE_LIST_SIZE 3 char *broadcast_code_list[BROADCAST_CODE_LIST_SIZE] = { - "00000000000002", - "00000000000003", - "00000000000004" + "000000000000002", + "000000000000003", + "000000000000004" }; /** Receiving point cloud data from Livox LiDAR. */ @@ -183,7 +187,11 @@ int main(int argc, const char *argv[]) { return -1; } +#ifdef WIN32 + Sleep(30000); +#else sleep(30); +#endif int i = 0; for (i = 0; i < kMaxLidarCount; ++i) { diff --git a/sdk_core/CMakeLists.txt b/sdk_core/CMakeLists.txt index 3b5d7c3..66b1b81 100644 --- a/sdk_core/CMakeLists.txt +++ b/sdk_core/CMakeLists.txt @@ -3,25 +3,32 @@ cmake_minimum_required(VERSION 3.0) set(SDK_LIBRARY ${PROJECT_NAME}_static) add_library(${SDK_LIBRARY} STATIC "") -find_package(PkgConfig) -pkg_check_modules(APR apr-1) +if (WIN32) + find_path(APR_INCLUDE_DIRS apr.h) + find_library(APR_LIBRARIES libapr-1) + if (APR_LIBRARIES AND APR_INCLUDE_DIRS) + set(APR_FOUND "YES") + endif (APR_LIBRARIES AND APR_INCLUDE_DIRS) +else (WIN32) + find_package(PkgConfig) + pkg_check_modules(APR apr-1) +endif (WIN32) + if (APR_FOUND) target_include_directories(${SDK_LIBRARY} PRIVATE ${APR_INCLUDE_DIRS}) target_link_libraries(${SDK_LIBRARY} - PRIVATE + PUBLIC ${APR_LIBRARIES}) -elseif () - message("Can't find Apache Runtime Library, please install.") endif () - find_package(Boost 1.54 REQUIRED COMPONENTS system) if (Boost_FOUND AND Boost_VERSION LESS 106900) target_link_libraries(${SDK_LIBRARY} - PRIVATE - ${Boost_LIBRARIES}) + PUBLIC + Boost::boost + Boost::system) endif () target_include_directories(${SDK_LIBRARY} @@ -84,3 +91,4 @@ install(TARGETS ${SDK_LIBRARY} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib) + diff --git a/sdk_core/src/base/io_loop.cpp b/sdk_core/src/base/io_loop.cpp index 1dc1129..5cf2e33 100644 --- a/sdk_core/src/base/io_loop.cpp +++ b/sdk_core/src/base/io_loop.cpp @@ -39,8 +39,14 @@ bool IOLoop::Init() { if (mem_pool_ == NULL) { return false; } +#ifdef WIN32 + apr_status_t rv = + apr_pollset_create(&pollset_, kMaxPollCount, mem_pool_, APR_POLLSET_WAKEABLE); +#else apr_status_t rv = apr_pollset_create(&pollset_, kMaxPollCount, mem_pool_, APR_POLLSET_THREADSAFE | APR_POLLSET_WAKEABLE); +#endif + if (rv != APR_SUCCESS) { LOG_ERROR << PrintAPRStatus(rv) << std::endl; return false; diff --git a/sdk_core/src/base/network_util.cpp b/sdk_core/src/base/network_util.cpp index 75f9932..2c636da 100644 --- a/sdk_core/src/base/network_util.cpp +++ b/sdk_core/src/base/network_util.cpp @@ -23,7 +23,17 @@ // #include "network_util.h" +#ifdef WIN32 +#include +#include +#include +#include +#pragma comment(lib,"Iphlpapi.lib") +#pragma comment(lib,"ws2_32.lib") +#else #include +#endif + namespace livox { namespace util { apr_socket_t *CreateBindSocket(uint16_t port, apr_pool_t *mem_pool, bool nonblock) { @@ -55,6 +65,37 @@ apr_socket_t *CreateBindSocket(uint16_t port, apr_pool_t *mem_pool, bool nonbloc return s; } +#ifdef WIN32 +bool FindLocalIP(const struct sockaddr_in &client_addr, uint32_t &local_ip) { + bool found = false; + ULONG ulOutbufLen = sizeof(IP_ADAPTER_INFO); + boost::scoped_array pAdapterInfo(new uint8_t[ulOutbufLen]); + DWORD dlRetVal = GetAdaptersInfo(reinterpret_cast(pAdapterInfo.get()), &ulOutbufLen); + if (dlRetVal == ERROR_BUFFER_OVERFLOW) { + pAdapterInfo.reset(new uint8_t[ulOutbufLen]); + dlRetVal = GetAdaptersInfo(reinterpret_cast(pAdapterInfo.get()), &ulOutbufLen); + } + + IP_ADAPTER_INFO *pAdapter = reinterpret_cast(pAdapterInfo.get()); + if (NO_ERROR == dlRetVal && pAdapter != NULL) { + while (pAdapterInfo) { + std::string str_ip = pAdapter->IpAddressList.IpAddress.String; + std::string str_mask = pAdapter->IpAddressList.IpMask.String; + ULONG host_ip = inet_addr(const_cast(str_ip.c_str())); + ULONG host_mask = inet_addr(const_cast(str_mask.c_str())); + + if ((host_ip & host_mask) == + (client_addr.sin_addr.S_un.S_addr & host_mask)) { + local_ip = host_ip; + found = true; + break; + } + pAdapter = pAdapter->Next; + } + } + return found; +} +#else bool FindLocalIP(const struct sockaddr_in &client_addr, uint32_t &local_ip) { struct ifaddrs *if_addrs = NULL, *addrs = NULL; if (getifaddrs(&if_addrs) == -1) { @@ -85,6 +126,6 @@ bool FindLocalIP(const struct sockaddr_in &client_addr, uint32_t &local_ip) { } return found; } - +#endif } // namespace util -} // namespace livox +} // namespace livox \ No newline at end of file diff --git a/sdk_core/src/base/network_util.h b/sdk_core/src/base/network_util.h index 54ee1ed..fd1fb7a 100644 --- a/sdk_core/src/base/network_util.h +++ b/sdk_core/src/base/network_util.h @@ -26,6 +26,10 @@ #define LIVOX_NETWORK_UTIL_H_ #include #include +#ifdef WIN32 +#include +#endif + namespace livox { namespace util { diff --git a/sdk_core/src/device_discovery.cpp b/sdk_core/src/device_discovery.cpp index fed9dd4..d6deb21 100644 --- a/sdk_core/src/device_discovery.cpp +++ b/sdk_core/src/device_discovery.cpp @@ -30,7 +30,11 @@ #include #include "apr_network_io.h" #include "apr_pools.h" +#ifdef WIN32 +#include "winsock.h" +#else #include "arpa/inet.h" +#endif #include "base/logging.h" #include "base/network_util.h" #include "command_handler/command_impl.h" diff --git a/sdk_core/src/device_manager.cpp b/sdk_core/src/device_manager.cpp index cc4cc4f..9c94ca2 100644 --- a/sdk_core/src/device_manager.cpp +++ b/sdk_core/src/device_manager.cpp @@ -172,6 +172,9 @@ bool DeviceManager::AddListeningDevice(const string &broadcast_code, DeviceMode strncpy(ite->info.broadcast_code, broadcast_code.c_str(), sizeof(ite->info.broadcast_code)); ite->info.handle = handle; return true; + } else if (strncmp(ite->info.broadcast_code, broadcast_code.c_str(), sizeof(ite->info.broadcast_code)) == 0) { + handle = ite->info.handle; + return true; } } return false;