Skip to content

Commit

Permalink
add network adapter tutorial
Browse files Browse the repository at this point in the history
  • Loading branch information
yangfuyuan committed Mar 20, 2020
1 parent a2f19ff commit d8d402d
Show file tree
Hide file tree
Showing 2 changed files with 368 additions and 0 deletions.
3 changes: 3 additions & 0 deletions doc/Tutorials.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@ If you are new to Linux/windows: You may find it helpful to first do a quick tut
# Table of Contents
- [Beginner Level](#Beginner-level)
- [Writing a Simple Lidar Turorial (C++)](#writing-a-simple-lidar-tutorial-(c++))
- [Writing a Simple Lidar Network Adapter Turorial (C++)](#writing-a-simple-lidar-network-adapter-tutorial-(c++))
- [Writing a Simple Lidar Turorial (Python)](#writing-a-simple-lidar-tutorial-(python))
- [Writing a Simple Lidar Turorial (C)](#writing-a-simple-lidar-tutorial-(c))
- [Examining the simple lidar tutorial](#examining-the-simple-lidar-tutorial)

## Beginner Level
### [Writing a Simple Lidar Tutorial (C++)](tutorials/writing_lidar_tutorial_c++.md)
This tutorial covers how to write a lidar tutorial in C++.
### [Writing a Simple Lidar Network Adapter Tutorial (C++)](tutorials/writing_lidar_network_adapter_tutorial_c++.md)
This tutorial covers how to write a lidar network adapter tutorial in C++.
### [Writing a Simple Lidar Tutorial (Python)](tutorials/writing_lidar_tutorial_python.md)
This tutorial covers how to write a lidar tutorial in Python.
### [Writing a Simple Lidar Tutorial (C)](tutorials/writing_lidar_tutorial_c.md)
Expand Down
365 changes: 365 additions & 0 deletions doc/tutorials/writing_lidar_network_adapter_tutorial_c++.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,365 @@
# WritingLidarNetworkAdapterTutorial(c++)
Description: This tutorial covers how to write a lidar network adapter tutorial in C++.
Tutorial Level: BEGINNER
Next Tutorial: [Examining the simple lidar tutorial](examine_the_simple_lidar_tutorial.md)

## Table of Contents

- [Writing a Simple lidar tutorial (C++)](#writing-a-simple-lidar-tutorial-(C++))
- [create beginner_tutorials directories](#create-beginner_tutorials-directories)
- [The Code Explained](#the-code-explained)
- [Building your project](#building-your-project)

## Writing a Simple lidar tutorial (C++)
Description: This tutorial covers how to write a LiDAR network adapter data console program in C++.
Tutorial Level: BEGINNER

### create beginner_tutorials directories
```shell
mkdir beginner_tutorials
cd beginner_tutorials
```
### Create the lidar_tutorial.cpp file within the beginner_tutorials project and paste the following inside it:
[https://github.com/YDLIDAR/ydlidar_tutorials/blob/master/cpp_tutorials/lidar_tutorial/lidar_tutorial.cpp](https://github.com/YDLIDAR/ydlidar_tutorials/blob/master/cpp_tutorials/lidar_tutorial/lidar_tutorial.cpp)

```c++
#include "CYdLidar.h"
#include <string>
using namespace std;
using namespace ydlidar;

#if defined(_MSC_VER)
#pragma comment(lib, "ydlidar_sdk.lib")
#endif

int main(int argc, char *argv[]) {
// init system signal
ydlidar::os_init();

CYdLidar laser;
//////////////////////string property/////////////////
/// Lidar ports
std::string port = "192.168.31.200;
/// lidar port
laser.setlidaropt(LidarPropSerialPort, port.c_str(), port.size());
/// ignore array
std::string ignore_array;
ignore_array.clear();
laser.setlidaropt(LidarPropIgnoreArray, ignore_array.c_str(),
ignore_array.size());

//////////////////////int property/////////////////
/// lidar port
int optval = 8000;
laser.setlidaropt(LidarPropSerialBaudrate, &optval, sizeof(int));
/// tof lidar
optval = TYPE_TRIANGLE;
laser.setlidaropt(LidarPropLidarType, &optval, sizeof(int));
/// device type
optval = YDLIDAR_TYPE_TCP;
laser.setlidaropt(LidarPropDeviceType, &optval, sizeof(int));
/// sample rate
optval = 9;
laser.setlidaropt(LidarPropSampleRate, &optval, sizeof(int));
/// abnormal count
optval = 4;
laser.setlidaropt(LidarPropAbnormalCheckCount, &optval, sizeof(int));

//////////////////////bool property/////////////////
/// fixed angle resolution
bool b_optvalue = false;
laser.setlidaropt(LidarPropFixedResolution, &b_optvalue, sizeof(bool));
/// rotate 180
laser.setlidaropt(LidarPropReversion, &b_optvalue, sizeof(bool));
/// Counterclockwise
laser.setlidaropt(LidarPropInverted, &b_optvalue, sizeof(bool));
b_optvalue = true;
laser.setlidaropt(LidarPropAutoReconnect, &b_optvalue, sizeof(bool));
/// one-way communication
b_optvalue = false;
laser.setlidaropt(LidarPropSingleChannel, &b_optvalue, sizeof(bool));
/// intensity
b_optvalue = false;
laser.setlidaropt(LidarPropIntenstiy, &b_optvalue, sizeof(bool));
/// Motor DTR
b_optvalue = false;
laser.setlidaropt(LidarPropSupportMotorDtrCtrl, &b_optvalue, sizeof(bool));

//////////////////////float property/////////////////
/// unit: °
float f_optvalue = 180.0f;
laser.setlidaropt(LidarPropMaxAngle, &f_optvalue, sizeof(float));
f_optvalue = -180.0f;
laser.setlidaropt(LidarPropMinAngle, &f_optvalue, sizeof(float));
/// unit: m
f_optvalue = 16.f;
laser.setlidaropt(LidarPropMaxRange, &f_optvalue, sizeof(float));
f_optvalue = 0.1f;
laser.setlidaropt(LidarPropMinRange, &f_optvalue, sizeof(float));
/// unit: Hz
f_optvalue = 10.f;
laser.setlidaropt(LidarPropScanFrequency, &f_optvalue, sizeof(float));

// initialize SDK and LiDAR
bool ret = laser.initialize();
if (ret) {//success
//Start the device scanning routine which runs on a separate thread and enable motor.
ret = laser.turnOn();
} else {
fprintf(stderr, "%s\n", laser.DescribeError());
fflush(stderr);
}

// Turn On success and loop
while (ret && ydlidar::os_isOk()) {
LaserScan scan;
if (laser.doProcessSimple(scan)) {
fprintf(stdout, "Scan received[%llu]: %u ranges is [%f]Hz\n",
scan.stamp,
(unsigned int)scan.points.size(), 1.0 / scan.config.scan_time);
fflush(stdout);
} else {
fprintf(stderr, "Failed to get Lidar Data\n");
fflush(stderr);
}
}
// Stop the device scanning thread and disable motor.
laser.turnOff();
// Uninitialize the SDK and Disconnect the LiDAR.
laser.disconnecting();
return 0;
}
```
Note: The difference form the serial port is the following three properties
* LidarPropSerialPort
* LidarPropSerialBaudrate
* LidarPropDeviceType
When the network adapter board is connected to the lidar, `LidarPropSerialPort` is the lidar IP address and `LidarPropSerialBaudrate` is the lidar network port.
The device type `LidarPropDeviceType` value is changed from the `YDLIDAR_TYPE_SERIAL` to `YDLIDAR_TYPE_TCP`.
### The Code Explained
Now, let's break the code down.
```c++
#include "CYdLidar.h"
```
CYdLidar.h is a convenience include that includes all the headers necessary to use the most common public pieces of the YDLIDAR SDK.

```c++
ydlidar::os_init();
```
Initialize system signal. install a SIGINT handler which provides Ctrl-C handling

```c++
CYdLidar laser;
```
Create a handle to this Lidar.

```c++
//////////////////////string property/////////////////
/// Lidar ports
std::string port = "192.168.31.200";
```
Query avaliable Lidar IP .


```c++
/// lidar port
laser.setlidaropt(LidarPropSerialPort, port.c_str(), port.size());
/// ignore array
std::string ignore_array;
ignore_array.clear();
laser.setlidaropt(LidarPropIgnoreArray, ignore_array.c_str(),
ignore_array.size());
```
Set Lidar string property paramters.

```c++
//////////////////////int property/////////////////
/// lidar port
int optval = 8000;
laser.setlidaropt(LidarPropSerialBaudrate, &optval, sizeof(int));
/// tof lidar
optval = TYPE_TRIANGLE;
laser.setlidaropt(LidarPropLidarType, &optval, sizeof(int));
/// device type
optval = YDLIDAR_TYPE_TCP;
laser.setlidaropt(LidarPropDeviceType, &optval, sizeof(int));
/// sample rate
optval = 9;
laser.setlidaropt(LidarPropSampleRate, &optval, sizeof(int));
/// abnormal count
optval = 4;
laser.setlidaropt(LidarPropAbnormalCheckCount, &optval, sizeof(int));

```
Set Lidar string int paramters.


```c++
//////////////////////bool property/////////////////
/// fixed angle resolution
bool b_optvalue = false;
laser.setlidaropt(LidarPropFixedResolution, &b_optvalue, sizeof(bool));
/// rotate 180
laser.setlidaropt(LidarPropReversion, &b_optvalue, sizeof(bool));
/// Counterclockwise
laser.setlidaropt(LidarPropInverted, &b_optvalue, sizeof(bool));
b_optvalue = true;
laser.setlidaropt(LidarPropAutoReconnect, &b_optvalue, sizeof(bool));
/// one-way communication
b_optvalue = false;
laser.setlidaropt(LidarPropSingleChannel, &b_optvalue, sizeof(bool));
/// intensity
b_optvalue = false;
laser.setlidaropt(LidarPropIntenstiy, &b_optvalue, sizeof(bool));
/// Motor DTR
b_optvalue = false;
laser.setlidaropt(LidarPropSupportMotorDtrCtrl, &b_optvalue, sizeof(bool));

```
Set Lidar bool property paramters.


```c++
//////////////////////float property/////////////////
/// unit: °
float f_optvalue = 180.0f;
laser.setlidaropt(LidarPropMaxAngle, &f_optvalue, sizeof(float));
f_optvalue = -180.0f;
laser.setlidaropt(LidarPropMinAngle, &f_optvalue, sizeof(float));
/// unit: m
f_optvalue = 16.f;
laser.setlidaropt(LidarPropMaxRange, &f_optvalue, sizeof(float));
f_optvalue = 0.1f;
laser.setlidaropt(LidarPropMinRange, &f_optvalue, sizeof(float));
/// unit: Hz
f_optvalue = 10.f;
laser.setlidaropt(LidarPropScanFrequency, &f_optvalue, sizeof(float));
```
Set Lidar float property paramters.

```c++
// initialize SDK and LiDAR
bool ret = laser.initialize();
```
Initialize the SDK and LiDAR.

`initialize` will return false if:
+ Serial port does not correspond to the actual Lidar.
+ Serial port does not have read and write permissions.
+ Lidar baud rate settings error.
+ Incorrect Lidar type setting.

```c++
if (ret) {//success
//Start the device scanning routine which runs on a separate thread and enable motor.
ret = laser.turnOn();
} else {
fprintf(stderr, "%s\n", laser.DescribeError());
fflush(stderr);
}
```
Start the device scanning routine which runs on a separate thread and enable motor.
`turnOn` will return false if:
+ Lidar stall.
+ Lidar power suppy is unstable.
```c++
// Turn On success and loop
while (ret && ydlidar::os_isOk()) {
```
By `ydlidar::os_init()` will install a SIGINT handler which provides Ctrl-C handling which will cause `ydlidar::os_isOk()` to return false if that happens.

`ydlidar::os_isOk()` will return false if:
+ a SIGINT is received (Ctrl-C)
+ ydlidar::os_shutdown() has been called by another part of the application.

Once `ydlidar::os_isOk()` returns false, Loop exit.

```c++
LaserScan scan;
if (laser.doProcessSimple(scan)) {
fprintf(stdout, "Scan received[%llu]: %u ranges is [%f]Hz\n",
scan.stamp,
(unsigned int)scan.points.size(), 1.0 / scan.config.scan_time);
fflush(stdout);
} else {
fprintf(stderr, "Failed to get Lidar Data\n");
fflush(stderr);
}
```
Get the LiDAR Scan Data.
```c++
// Stop the device scanning thread and disable motor.
laser.turnOff();
```
Stop the device scanning thread and disable motor.

```c++
// Uninitialize the SDK and Disconnect the LiDAR.
laser.disconnecting();
```
Uninitialize the SDK and Disconnect the LiDAR.

## Building your project
You need to create a CMakeLists.txt file.

The generated CMakeLists.txt should look like this:
[https://github.com/YDLIDAR/ydlidar_tutorials/blob/master/cpp_tutorials/lidar_tutorial/CMakeLists.txt](https://github.com/YDLIDAR/ydlidar_tutorials/blob/master/cpp_tutorials/lidar_tutorial/CMakeLists.txt)

```cmake
cmake_minimum_required(VERSION 2.8)
PROJECT(lidar_tutorial)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
add_definitions(-std=c++11) # Use C++11
#Include directories
include_directories(
${CMAKE_SOURCE_DIR}
)
############## YDLIDAR SDK START#####################################
#find ydlidar_sdk package
find_package(ydlidar_sdk REQUIRED)
#Include directories
include_directories(
${YDLIDAR_SDK_INCLUDE_DIRS}
)
#link library directories
link_directories(${YDLIDAR_SDK_LIBRARY_DIRS})
add_executable(${PROJECT_NAME} lidar_tutorial.cpp)
#Link your project to ydlidar_sdk library.
target_link_libraries(${PROJECT_NAME} ${YDLIDAR_SDK_LIBRARIES})
############## YDLIDAR SDK END#####################################
```
This will create one executable, lidar_tutorial, which by default will go into package directory of your build space.

Linux:
* `YDLIDAR_SDK_LIBRARIES` includes `ydlidar_sdk pthread rt`
* If you need the pthread library at the end of the compilation flag,
you need to put `YDLIDAR_SDK_LIBRARIES` at the end.


you can use the following variable to depend on all necessary targets:

```cmake
target_link_libraries(${PROJECT_NAME} ${YDLIDAR_SDK_LIBRARIES})
```
Now run cmake:
```cmake
# In your project directory
mkdir build
cd build
cmake ..
make j4
```
Now that you have written a simple lidar tutorial, let's [examine the simple lidar tutorial](examine_the_simple_lidar_tutorial.md).

0 comments on commit d8d402d

Please sign in to comment.