Merge pull request #3 from Livox-SDK/support_windows

Support for windows.
This commit was merged in pull request #3.
This commit is contained in:
livox
2019-02-03 09:56:22 +08:00
committed by GitHub
12 changed files with 163 additions and 104 deletions
+64 -91
View File
@@ -1,14 +1,18 @@
# Introduction # 1 Introduction
Livox SDK is the software development kit designed for all Livox products. It is developed based on C/C++ following Livox SDK Communication Protocol, and provides easy-to-use C style API. With Livox SDK, users can quickly connect to Livox products and receive point cloud data. Livox SDK is the software development kit designed for all Livox products. It is developed based on C/C++ following Livox SDK Communication Protocol, and provides easy-to-use C style API. With Livox SDK, users can quickly connect to Livox products and receive point cloud data.
Livox SDK consists of Livox SDK communication protocol, Livox SDK core, Livox SDK API, Linux sample, and ROS demo. Livox SDK consists of Livox SDK communication protocol, Livox SDK core, Livox SDK API, Linux sample, and ROS demo.
# Livox SDK Communication Protocol ## Prerequisites
* Ubuntu 14.04/Ubuntu 16.04, both x86 and ARM (Nvidia TX2)
* Windows 7/10, Visual Studio 2015/2017
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. # 2 Livox SDK Communication Protocol
# Livox SDK Core 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.
# 3 Livox SDK Core
Livox SDK provides the implementation of control commands and point cloud data transmission, as well as the C/C++ API. The basic structure of Livox SDK core is shown as below: Livox SDK provides the implementation of control commands and point cloud data transmission, as well as the C/C++ API. The basic structure of Livox SDK core is shown as below:
@@ -18,106 +22,75 @@ User Datagram Protocol (UDP) is used for communication between Livox SDK and LiD
The Livox LiDAR sensors can be connected to host directly or through the Livox Hub. Livox SDK supports both connection methods. When LiDAR units are connected to host directly, the host will establish communication with each LiDAR unit individually. And if the LiDAR units connect to host through Hub, then the host only communicates with the Livox Hub while the Hub communicates with each LiDAR unit. The Livox LiDAR sensors can be connected to host directly or through the Livox Hub. Livox SDK supports both connection methods. When LiDAR units are connected to host directly, the host will establish communication with each LiDAR unit individually. And if the LiDAR units connect to host through Hub, then the host only communicates with the Livox Hub while the Hub communicates with each LiDAR unit.
# Livox SDK API # 4 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 further information.
## Build Notes
### Dependencies
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.
###### Ubuntu 16.04 LTS
The following package are required (feel free to cut and paste the apt-get command below):
## 4.1 Installation
The installation procedures in Ubuntu 16.04 LTS and Windows 7/10 are shown here as examples.
### 4.1.1 Ubuntu 16.04 LTS
#### Dependencies
Livox SDK requires [CMake 3.0.0+](https://cmake.org/), [Apache Portable Runtime (APR) 1.61+](http://apr.apache.org/) and [Boost 1.54+](https://www.boost.org/) as dependencies. You can install these packages using apt:
``` ```
sudo apt install cmake sudo apt install cmake libapr1-dev libboost-atomic-dev libboost-system-dev
``` ```
#### Compile Livox SDK
###### Use Apt Install In the Livox SDK directory, run the following commands to compile the project:
The following commands can be used to download and install it:
``` ```
sudo apt install \ cd build
libapr1-dev \ cmake ..
libboost-atomic-dev \ make
libboost-system-dev sudo make install
``` ```
### 4.1.2 Windows 7/10
###### Compile the Source Code #### Dependencies
Livox SDK supports Visual Studio 2015/2017 and requires [CMake 3.0.0+](https://cmake.org/), [Apache Portable Runtime (APR) 1.61+](http://apr.apache.org/) and [Boost 1.54+](https://www.boost.org/) as dependencies. [vcpkg](https://github.com/Microsoft/vcpkg) is recommended for building the dependency libraries as follows:
You can download the apr source code from http://apr.apache.org/download.cgi and boost source code from http://sourceforge.net/projects/boost/files/boost/1.54.0/. The following commands can be used to compile and install it.
``` ```
tar zxf apr-1.6.5.tar.gz && \ .\vcpkg install apr
cd apr-1.6.5 && \ .\vcpkg install boost-atomic
./configure --prefix=/usr && \ .\vcpkg install boost-system
make && \ .\vcpkg install boost-thread
make install .\vcpkg integrate install
``` ```
Then, in the Livox SDK directory, run the following commands to create the Visual Studio solution file. Please replace [vcpkgroot] with your vcpkg installation path.
``` ```
tar zxf boost_1_54_0.tar.gz && \ cd build && \
cd boost_1_54_0 && \ cmake .. "-DCMAKE_TOOLCHAIN_FILE=[vcpkgroot]\scripts\buildsystems\vcpkg.cmake"
./bootstrap.sh --with-libraries=atomic,system && \
./b2 install --prefix=/usr
``` ```
#### Compile Livox SDK
###### Compile the Project You can now compile the Livox SDK in Visual Studio.
## 4.2 Run Livox SDK Sample
In the LivoxTech SDK directory (e.g. the checkout root or the archive unpack root), run the following commands to compile the project: 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:
```
mkdir build && cd build && \
cmake .. && \
make -j $(nproc)
```
###### Run the Project
Run the following commands to run the hub or lidar sample:
```
cd sample\hub && \
./hub_sample
```
```
cd sample\lidar && \
./lidar_sample
```
# 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) ![sample](doc/images/sample.png)
# Livox Ros Demo **NOTE**: Please replace the broadcast code lists in the `main.c` for both LiDAR sample ({Livox-SDK}/sample/lidar/main.c) and Hub sample ({Livox-SDK}/sample/hub/main.c) with the broadcast code of your devices before building. The corresponding code section in `main.c` is as follows:
```
#define BROADCAST_CODE_LIST_SIZE 3
char *broadcast_code_list[BROADCAST_CODE_LIST_SIZE] = {
"00000000000002",
"00000000000003",
"00000000000004"
};
```
The broadcast code consists of its serial number and an additional number (1,2, or 3). The serial number can be found on the body of the LiDAR unit (below the QR code). The detailed format is shown as below:
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. ![sample](doc/images/broadcast_code.png)
## Livox ROS Demo User Guide Again, steps for running the samples in Ubuntu 16.04 LTS and Windows 7/10 are shown here as examples.
### 4.2.1 Ubuntu 16.04 LTS
For Ubuntun 16.04 LTS, run the following commands to run the hub or lidar sample:
```
cd sample\hub && ./hub_sample
```
or
```
cd sample\lidar && ./lidar_sample
```
### 4.2.2 Windows 7/10
After compiling the Livox SDK as shown in section 4.1.2, you can find `hub_sample.exe` or `lidar_sample.exe` in the {Livox-SDK}\build\sample\hub\Debug or {Livox-SDK}\build\sample\lidar\Debug folder, respectively, which can be run directly.
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. # 5 Support
You can get support from Livox with the following methods:
1. Download or clone the code from the Livox-SDK/Livox-SDK-ROS repository on GitHub. * Send email to dev@livoxtech.com with a clear description of your problem and your setup
2. Compile the ROS code package under the Livox-SDK-ROS directory by typing the following command in terminal: * Github Issues
`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.
Binary file not shown.
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

+12
View File
@@ -24,7 +24,11 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#ifdef WIN32
#include <windows.h>
#else
#include <unistd.h> #include <unistd.h>
#endif
#include <string.h> #include <string.h>
#include "livox_sdk.h" #include "livox_sdk.h"
@@ -196,10 +200,18 @@ int main(int argc, const char *argv[]) {
SetDeviceStateUpdateCallback(OnDeviceChange); SetDeviceStateUpdateCallback(OnDeviceChange);
if (Start()) { if (Start()) {
#ifdef WIN32
Sleep(20000);
#else
sleep(20); sleep(20);
#endif
HubStopSampling(OnStopSampleCallback, NULL); HubStopSampling(OnStopSampleCallback, NULL);
printf("stop sample\n"); printf("stop sample\n");
#ifdef WIN32
Sleep(10000);
#else
sleep(10); sleep(10);
#endif
} }
Uninit(); Uninit();
+11 -3
View File
@@ -24,7 +24,11 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#ifdef WIN32
#include <windows.h>
#else
#include <unistd.h> #include <unistd.h>
#endif
#include <string.h> #include <string.h>
#include "livox_sdk.h" #include "livox_sdk.h"
@@ -45,9 +49,9 @@ uint32_t data_recveive_count[kMaxLidarCount];
#define BROADCAST_CODE_LIST_SIZE 3 #define BROADCAST_CODE_LIST_SIZE 3
char *broadcast_code_list[BROADCAST_CODE_LIST_SIZE] = { char *broadcast_code_list[BROADCAST_CODE_LIST_SIZE] = {
"00000000000002", "000000000000002",
"00000000000003", "000000000000003",
"00000000000004" "000000000000004"
}; };
/** Receiving point cloud data from Livox LiDAR. */ /** Receiving point cloud data from Livox LiDAR. */
@@ -183,7 +187,11 @@ int main(int argc, const char *argv[]) {
return -1; return -1;
} }
#ifdef WIN32
Sleep(30000);
#else
sleep(30); sleep(30);
#endif
int i = 0; int i = 0;
for (i = 0; i < kMaxLidarCount; ++i) { for (i = 0; i < kMaxLidarCount; ++i) {
+16 -8
View File
@@ -3,25 +3,32 @@ cmake_minimum_required(VERSION 3.0)
set(SDK_LIBRARY ${PROJECT_NAME}_static) set(SDK_LIBRARY ${PROJECT_NAME}_static)
add_library(${SDK_LIBRARY} STATIC "") add_library(${SDK_LIBRARY} STATIC "")
find_package(PkgConfig) if (WIN32)
pkg_check_modules(APR apr-1) 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) if (APR_FOUND)
target_include_directories(${SDK_LIBRARY} target_include_directories(${SDK_LIBRARY}
PRIVATE PRIVATE
${APR_INCLUDE_DIRS}) ${APR_INCLUDE_DIRS})
target_link_libraries(${SDK_LIBRARY} target_link_libraries(${SDK_LIBRARY}
PRIVATE PUBLIC
${APR_LIBRARIES}) ${APR_LIBRARIES})
elseif ()
message("Can't find Apache Runtime Library, please install.")
endif () endif ()
find_package(Boost 1.54 REQUIRED COMPONENTS system) find_package(Boost 1.54 REQUIRED COMPONENTS system)
if (Boost_FOUND AND Boost_VERSION LESS 106900) if (Boost_FOUND AND Boost_VERSION LESS 106900)
target_link_libraries(${SDK_LIBRARY} target_link_libraries(${SDK_LIBRARY}
PRIVATE PUBLIC
${Boost_LIBRARIES}) Boost::boost
Boost::system)
endif () endif ()
target_include_directories(${SDK_LIBRARY} target_include_directories(${SDK_LIBRARY}
@@ -84,3 +91,4 @@ install(TARGETS ${SDK_LIBRARY}
ARCHIVE DESTINATION lib ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib) LIBRARY DESTINATION lib)
+6
View File
@@ -39,8 +39,14 @@ bool IOLoop::Init() {
if (mem_pool_ == NULL) { if (mem_pool_ == NULL) {
return false; return false;
} }
#ifdef WIN32
apr_status_t rv =
apr_pollset_create(&pollset_, kMaxPollCount, mem_pool_, APR_POLLSET_WAKEABLE);
#else
apr_status_t rv = apr_status_t rv =
apr_pollset_create(&pollset_, kMaxPollCount, mem_pool_, APR_POLLSET_THREADSAFE | APR_POLLSET_WAKEABLE); apr_pollset_create(&pollset_, kMaxPollCount, mem_pool_, APR_POLLSET_THREADSAFE | APR_POLLSET_WAKEABLE);
#endif
if (rv != APR_SUCCESS) { if (rv != APR_SUCCESS) {
LOG_ERROR << PrintAPRStatus(rv) << std::endl; LOG_ERROR << PrintAPRStatus(rv) << std::endl;
return false; return false;
+43 -2
View File
@@ -23,7 +23,17 @@
// //
#include "network_util.h" #include "network_util.h"
#ifdef WIN32
#include <boost/scoped_array.hpp>
#include <Winsock2.h>
#include <Iphlpapi.h>
#include <string>
#pragma comment(lib,"Iphlpapi.lib")
#pragma comment(lib,"ws2_32.lib")
#else
#include <ifaddrs.h> #include <ifaddrs.h>
#endif
namespace livox { namespace livox {
namespace util { namespace util {
apr_socket_t *CreateBindSocket(uint16_t port, apr_pool_t *mem_pool, bool nonblock) { 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; 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<uint8_t> pAdapterInfo(new uint8_t[ulOutbufLen]);
DWORD dlRetVal = GetAdaptersInfo(reinterpret_cast<IP_ADAPTER_INFO *>(pAdapterInfo.get()), &ulOutbufLen);
if (dlRetVal == ERROR_BUFFER_OVERFLOW) {
pAdapterInfo.reset(new uint8_t[ulOutbufLen]);
dlRetVal = GetAdaptersInfo(reinterpret_cast<IP_ADAPTER_INFO *>(pAdapterInfo.get()), &ulOutbufLen);
}
IP_ADAPTER_INFO *pAdapter = reinterpret_cast<IP_ADAPTER_INFO *>(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<char *>(str_ip.c_str()));
ULONG host_mask = inet_addr(const_cast<char *>(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) { bool FindLocalIP(const struct sockaddr_in &client_addr, uint32_t &local_ip) {
struct ifaddrs *if_addrs = NULL, *addrs = NULL; struct ifaddrs *if_addrs = NULL, *addrs = NULL;
if (getifaddrs(&if_addrs) == -1) { if (getifaddrs(&if_addrs) == -1) {
@@ -85,6 +126,6 @@ bool FindLocalIP(const struct sockaddr_in &client_addr, uint32_t &local_ip) {
} }
return found; return found;
} }
#endif
} // namespace util } // namespace util
} // namespace livox } // namespace livox
+4
View File
@@ -26,6 +26,10 @@
#define LIVOX_NETWORK_UTIL_H_ #define LIVOX_NETWORK_UTIL_H_
#include <apr_general.h> #include <apr_general.h>
#include <apr_network_io.h> #include <apr_network_io.h>
#ifdef WIN32
#include <stdint.h>
#endif
namespace livox { namespace livox {
namespace util { namespace util {
+4
View File
@@ -30,7 +30,11 @@
#include <vector> #include <vector>
#include "apr_network_io.h" #include "apr_network_io.h"
#include "apr_pools.h" #include "apr_pools.h"
#ifdef WIN32
#include "winsock.h"
#else
#include "arpa/inet.h" #include "arpa/inet.h"
#endif
#include "base/logging.h" #include "base/logging.h"
#include "base/network_util.h" #include "base/network_util.h"
#include "command_handler/command_impl.h" #include "command_handler/command_impl.h"
+3
View File
@@ -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)); strncpy(ite->info.broadcast_code, broadcast_code.c_str(), sizeof(ite->info.broadcast_code));
ite->info.handle = handle; ite->info.handle = handle;
return true; 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; return false;