diff --git a/doc/Tutorials.md b/doc/Tutorials.md index a868597..3ea6508 100755 --- a/doc/Tutorials.md +++ b/doc/Tutorials.md @@ -7,6 +7,7 @@ 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) @@ -14,6 +15,8 @@ If you are new to Linux/windows: You may find it helpful to first do a quick tut ## 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) diff --git a/doc/tutorials/writing_lidar_network_adapter_tutorial_c++.md b/doc/tutorials/writing_lidar_network_adapter_tutorial_c++.md new file mode 100644 index 0000000..635e629 --- /dev/null +++ b/doc/tutorials/writing_lidar_network_adapter_tutorial_c++.md @@ -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 +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).