Skip to content

Mobile Platform Sensing LiDAR

Dahye Park edited this page Sep 26, 2021 · 17 revisions

Notice

사용한 LiDAR : Ouster 3D LiDAR OS1

ouster github : https://github.com/ouster-lidar/ouster_example를 참고하여 /service/ouster 를 구성하였다.

💫 라이더의 이더넷 연결은 잘 되었는데 코드가 실행이 되지 않는 경우

  1. /service/ouster중 ouster github 업데이트 내용 확인하기 ⇒ ouster_client 위주로
  2. firmware image 업데이트 ⇒ LiDAR setting(os1_host 10.5.5.1)이 리셋되므로 신중하게 결정

Ethernet Setting

Settings > Netwrok > Wired > IPv4

IPv4 Method : Manual Addresses : 10.5.5.2(Address) 255.255.255.0(Netmask)


동작방식

LiDAR_SensingThread.cpp

1. LiDAR initialize

if (USE_LiDAR == 1)
    {
        cout << "Configuring sensor: " << os1_host
             << " UDP Destination:" << os1_udp_dest << std::endl;
        cli = ouster::sensor::init_client(os1_host, os1_udp_dest, mode,
                                          ouster::sensor::TIME_FROM_INTERNAL_OSC, lidar_port, imu_port);
        cout << "init_client" << endl;
    }
  • os1_host : 10.5.5.1
  • os1_udp_dest : 10.5.5.2

2. poll_client

LiDAR 데이터가 읽을 준비가 되어있거나, 에러가 발생했지 client_state s를 리턴한다.

  • if lidar data is ready to read : (s & LIDAR_DATA) = TRUE
  • if an error occured : (s & ERROR) = TRUE

3. read_lidar_packet

LiDAR로 부터 데이터를 읽어온다.

4. WritePCD

Point Cloud에 LiDAR에서 취득한 point들을 담는다.


5. savePCDFile

WritePCD에서 담았던 cloud를 PCD파일로 저장한다.

//[ save PCD ]
sprintf(cSn, "%04d%02d%02d%02d%02d%02d%03d", ts->tm_year + 1900, ts->tm_mon + 1, ts->tm_mday, ts->tm_hour, string ttt(cSn);
string name = "/home/diva2/DIVA2data/"+timestamp+"_0/LiDAR/PCD/LiDAR_" + ttt + ".pcd";
pcl::io::savePCDFile(name, *mLiDAR_Sensing.cloud, true);

6. VoxelGrid

leaf size로 downsampling 정도를 조절한다.

// [ downsampling ]
pcl::VoxelGrid<pcl::PointXYZ> sor;
sor.setInputCloud(mLiDAR_Sensing.cloud);          //입력
sor.setLeafSize(leaf_size, leaf_size, leaf_size); //leaf size 조절
sor.filter(*mLiDAR_Sensing.cloud_filtered);       //출력

leaf size는 아래와 같이 main.cpp에서 sensingthread_LiDAR의 파라미터로 조절 가능하다.

//main.cpp
...

LiDAR_SensingThread mLiDARSensingThread;
thread sensingthread_LiDAR(mLiDARSensingThread.run, &socket, ref(m), 0.1f); //0.1f = leaf_size
...

7. Parsing to Protocol Buffer and Serialization

// [Parsing to Proto]
pLiDAR.set_size(mLiDAR_Sensing.cloud_filtered->size());

...

// <Serialization>
int data_len = pLiDAR.ByteSize();
unsigned char data[data_len] = "\0";
pLiDAR.SerializeToArray(data, data_len);

8. Send to Visualization using ZeroMQ

// <Send>
zmq::message_t zmqData(data_len);
memcpy((void *)zmqData.data(), data, data_len);
m.lock();
s_send_idx(*socket, SENSOR_LIDAR);
s_send(*socket, zmqData);
m.unlock();

CMakeLists.txt 🚀link

1. PCL & Boost

## Boost
set(Boost_USE_MULTITHREADED ON)
find_package(Boost 1.47.0 COMPONENTS system filesystem thread REQUIRED )
set(INCLUDES ${INCLUDES} ${Boost_INCLUDE_DIRS} )
set(LIBS ${LIBS} ${Boost_LIBRARIES} )

## Use PCL
find_package(Eigen3 REQUIRED)
find_package(PCL 1.11.1 REQUIRED)
include_directories(${PCL_INCLUDE_DIRS} ${PCL_LIBRARIES}) #헤더 디렉토리 지정(-I)
link_directories(${PCL_LIBRARY_DIRS}) #라이브러리 디렉토리 지정 (-L)
add_definitions(${PCL_DEFINITIONS}) #전처리기 메크로 추가 (-D)

2. ouster helper

add_library(ouster_helper STATIC ../../service/ouster/client.cpp 
                          ../../service/ouster/os1_util.cpp 
                          ../../service/ouster/impl/netcompat.cpp 
                          ../../service/ouster/types.cpp)
set_target_properties(ouster_helper PROPERTIES POSITION_INDEPENDENT_CODE ON)
target_link_libraries(ouster_helper jsoncpp)
target_include_directories(ouster_helper PUBLIC include)
target_include_directories(ouster_helper SYSTEM PRIVATE ${jsoncpp_INCLUDE_DIRS})

3. LiDAR 실행파일

set(SOURCE_MP_sensing 
    main.cpp 
    ...
    LiDAR_SensingThread.cpp LiDAR_Sensing.cpp
)