├── .gitignore
├── .gitmodules
├── CMakeLists.txt
├── LICENSE
├── config
├── calibration.yml
├── calibration.yml.bak
└── correction.csv
├── launch
└── p40.launch
├── package.xml
├── readme.md
└── src
└── main.cc
/.gitignore:
--------------------------------------------------------------------------------
1 | build
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "src/HesaiLidarSDK"]
2 | path = src/HesaiLidarSDK
3 | url = https://github.com/HesaiTechnology/HesaiLidarSDK.git
4 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8.3)
2 | project(hesai_lidar)
3 |
4 | # Compile as C++11, supported in ROS Kinetic and newer
5 | add_compile_options(-std=c++11)
6 |
7 |
8 |
9 | find_package(catkin REQUIRED COMPONENTS
10 | cv_bridge
11 | image_transport
12 | sensor_msgs
13 | )
14 | find_package( Boost REQUIRED )
15 | find_package(PCL REQUIRED )
16 |
17 |
18 |
19 | catkin_package()
20 |
21 | add_subdirectory(src/HesaiLidarSDK)
22 | add_executable(hesai_lidar_node
23 | src/main.cc
24 | )
25 |
26 | include_directories(
27 | src/HesaiLidarSDK/include
28 | ${PCL_INCLUDE_DIRS}
29 | ${catkin_INCLUDE_DIRS}
30 | ${Boost_INCLUDE_DIRS}
31 | )
32 |
33 |
34 |
35 | target_link_libraries(hesai_lidar_node
36 | ${catkin_LIBRARIES}
37 | hesaiLidarSDK
38 | )
39 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD 3-Clause License
2 |
3 | Copyright (c) 2018, HesaiTechnology
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are met:
8 |
9 | * Redistributions of source code must retain the above copyright notice, this
10 | list of conditions and the following disclaimer.
11 |
12 | * Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | * Neither the name of the copyright holder nor the names of its
17 | contributors may be used to endorse or promote products derived from
18 | this software without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
--------------------------------------------------------------------------------
/config/calibration.yml:
--------------------------------------------------------------------------------
1 | 3:
2 | K: [587.9607639513098, 0, 641.1987547312688, 0, 589.7411916647718, 350.4665310559093, 0, 0, 1]
3 | D: [-0.3417634136072756, 0.163717393424974, 3.550306333579257e-05, -2.269502070408432e-05, -0.0467970999032102]
4 | 2:
5 | K: [588.2508959163868, 0, 647.292862980063, 0, 590.1733006978851, 357.5000621554299, 0, 0, 1]
6 | D: [-0.33792847429469, 0.15497147097907, 6.687273279031831e-05, -6.474133626990794e-06, -0.04056624381332481]
7 | 1:
8 | K: [586.3259663840066, 0, 636.2924066352238, 0, 588.4623137129338, 366.0670100830787, 0, 0, 1]
9 | D: [-0.3372234945379695, 0.1539569085130269, 8.516331936573671e-06, -2.37919172198999e-05, -0.04026038638740984]
10 | 4:
11 | K: [586.9208412885432, 0, 639.4036213157253, 0, 588.9533517337975, 372.2792209901052, 0, 0, 1]
12 | D: [-0.3385481906291727, 0.1560329273732019, -0.0002525352067705174, 0.0001712995534017639, -0.04111459154475255]
13 | 0:
14 | K: [1411.077090949719, 0, 615.9434135330476, 0, 1414.323243925144, 334.4885997587672, 0, 0, 1]
15 | D: [-0.4576995011452611, 0.2804187482132228, -0.0008824335077850593, -0.002560567254523004, -0.3683570521877889]
16 |
17 |
--------------------------------------------------------------------------------
/config/calibration.yml.bak:
--------------------------------------------------------------------------------
1 | 0:
2 | K: [1411.077090949719, 0, 615.9434135330476, 0, 1414.323243925144, 334.4885997587672, 0, 0, 1]
3 | D: [-0.4576995011452611, 0.2804187482132228, -0.0008824335077850593, -0.002560567254523004, -0.3683570521877889]
4 | 1:
5 | K: [342.5400328255074, 0, 640.460699031343, 0, 339.4331965071486, 356.3038964572869, 0, 0, 1]
6 | D: [-0.1753591484498331, 0.02762625329264434, 1.990356823116969e-05, 0.0005212335592411709, -0.001774133391009368]
7 | 2:
8 | K: [330.0496139729793, 0, 637.0246798503467, 0, 326.7090363074088, 350.7881295175944, 0, 0, 1]
9 | D: [-0.1846577791624761, 0.03366866480811935, 0.0003070812977140898, 0.0003952438640611272, -0.002608423745777319]
10 | 3:
11 | K: [373.8054674494855, 0, 637.7349082069506, 0, 369.6542050863838, 349.0390592833846, 0, 0, 1]
12 | D: [-0.2458410838367304, 0.06611616265915085, 0.0003872523163950329, 0.0002377539327965119, -0.007809619928009832]
13 | 4:
14 | K: [363.9737360031555, 0, 652.4764949793846, 0, 359.6935815957517, 345.7881319794952, 0, 0, 1]
15 | D: [-0.2190493660809663, 0.04707086193025265, 0.0004825870412562302, -0.0004784635496621562, -0.004180118405907018]
16 |
--------------------------------------------------------------------------------
/config/correction.csv:
--------------------------------------------------------------------------------
1 | Laser id,Elevation,Azimuth
2 | 1,7.143,-0.025
3 | 2,6.142,-0.025
4 | 3,5.136,-0.026
5 | 4,4.128,-0.026
6 | 5,3.115,-2.54
7 | 6,2.102,-2.541
8 | 7,1.767,2.49
9 | 8,1.421,-5.042
10 | 9,1.087,-2.541
11 | 10,0.752,2.49
12 | 11,0.406,-5.042
13 | 12,0.071,-2.541
14 | 13,-0.268,2.49
15 | 14,-0.606,-5.042
16 | 15,-0.945,-0.026
17 | 16,-1.284,2.49
18 | 17,-1.621,-5.042
19 | 18,-1.96,-0.026
20 | 19,-2.298,4.998
21 | 20,-2.636,-2.541
22 | 21,-2.974,-0.026
23 | 22,-3.311,4.998
24 | 23,-3.648,-2.54
25 | 24,-3.986,-0.026
26 | 25,-4.319,4.997
27 | 26,-4.661,-2.54
28 | 27,-4.995,2.49
29 | 28,-5.326,4.997
30 | 29,-5.667,-2.539
31 | 30,-6,2.49
32 | 31,-7.001,2.49
33 | 32,-7.997,2.49
34 | 33,-8.987,-0.024
35 | 34,-9.971,-0.023
36 | 35,-10.948,-0.023
37 | 36,-11.917,-0.022
38 | 37,-12.874,-2.528
39 | 38,-13.825,-2.526
40 | 39,-14.766,-2.523
41 | 40,-15.696,-2.521
42 |
--------------------------------------------------------------------------------
/launch/p40.launch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | hesai_lidar
4 | 0.0.0
5 | The hesai_lidar package
6 |
7 |
8 |
9 |
10 | yy
11 |
12 |
13 |
14 |
15 |
16 | TODO
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 | catkin
43 | cv_bridge
44 | image_transport
45 | roscpp
46 | sensor_msgs
47 | std_msgs
48 | pandar_msgs
49 | pandar_msgs
50 | message_runtime
51 | cv_bridge
52 | image_transport
53 | roscpp
54 | sensor_msgs
55 | std_msgs
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # Pandar40_ROS
2 |
3 | ## About the project
4 | Pandar40_ROS project includes the ROS Driver for **Pandar40** LiDAR sensor manufactured by Hesai Technology.
5 | Note: For the driver of Pandar40P and other modules, please go to [HesaiLidar_General_ROS](https://github.com/HesaiTechnology/HesaiLidar_General_ROS)
6 |
7 | Developed based on [Pandar40_SDK](https://github.com/HesaiTechnology/Pandar40_SDK), after launched, the project will monitor UDP packets from Pandar40 Lidar, parse data and publish point cloud frames into ROS under topic: ```/pandar```. It can also be used as an official demo showing how to work with Pandar40_SDK.
8 |
9 | ## Environment and Dependencies
10 | **System environment requirement: Linux + ROS**
11 |
12 | Recommanded:
13 | Ubuntu 16.04 - with ROS kinetic desktop-full installed or
14 | Ubuntu 18.04 - with ROS melodic desktop-full installed
15 | Check resources on http://ros.org for installation guide
16 |
17 | **Library Dependencies: libpcap-dev + libyaml-cpp-dev**
18 | ```
19 | $sudo apt install libpcap-dev libyaml-cpp-dev
20 | ```
21 |
22 | ## Download and Build
23 |
24 | **Install `catkin_tools`**
25 | ```
26 | $ sudo apt-get update
27 | $ sudo apt-get install python-catkin-tools
28 | ```
29 | **Download code**
30 | ```
31 | $ mkdir -p rosworkspace/src
32 | $ cd rosworkspace/src
33 | $ git clone https://github.com/HesaiTechnology/Pandar40_ROS.git --recursive
34 | ```
35 | **Build**
36 | ```
37 | $ cd ..
38 | $ catkin_make
39 | ```
40 |
41 | ## Configuration
42 | ```
43 | $ gedit src/launch/p40.launch
44 | ```
45 | **Reciving data from connected Lidar: config lidar ip&port, leave the pcap_file empty**
46 | |Parameter | Default Value|
47 | |---------|---------------|
48 | |server_ip |192.168.1.201|
49 | |lidar_recv_port |2368|
50 | |gps_recv_port |10110|
51 | |laser_return_type| 0 |
52 | |pcap_file ||
53 |
54 | Data source will be from connected Lidar when "pcap_file" set to empty
55 | Make sure the parameters above set to the same with Lidar setting
56 | Note: (laser_return_type: for single return set to 1, for dural return set to 1)
57 |
58 | **Reciving data from pcap file: config pcap_file and correction file path**
59 | |Parameter | Value|
60 | |---------|---------------|
61 | |pcap_file |pcap file path|
62 | |lidar_correction_file |lidar correction file path|
63 | |laser_return_type| return type of lidar in pcap file |
64 |
65 | Data source will be from pcap file once "pcap_file" not empty
66 |
67 |
68 | ## Run
69 |
70 | 1. Make sure current path in the `rosworkspace` directory
71 | ```
72 | $ source devel/setup.bash
73 | $ roslaunch hesai_lidar p40.launch
74 | ```
75 | 2. The driver will publish PointCloud messages to the topic `/pandar_points`
76 | 3. Open Rviz and add display by topic
77 | 4. Change fixed frame to `pandar` to view published point clouds
78 |
--------------------------------------------------------------------------------
/src/main.cc:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | #include "hesaiLidarSDK.h"
8 | using namespace std;
9 |
10 | class HesaiLidarClient
11 | {
12 | public:
13 | HesaiLidarClient(ros::NodeHandle node, ros::NodeHandle nh)
14 | {
15 | lidarPublisher = node.advertise("pandar_points", 10);
16 |
17 | string serverIp;
18 | int serverPort;
19 | string calibrationFile;
20 | int lidarRecvPort;
21 | int gpsPort;
22 | double startAngle;
23 | string lidarCorrectionFile;
24 | int laserReturnType;
25 | int laserCount;
26 | int pclDataType;
27 | string pcapFile;
28 | image_transport::ImageTransport it(nh);
29 |
30 |
31 | nh.getParam("pcap_file", pcapFile);
32 | nh.getParam("server_ip", serverIp);
33 | nh.getParam("server_port", serverPort);
34 | nh.getParam("calibration_file", calibrationFile);
35 | nh.getParam("lidar_recv_port", lidarRecvPort);
36 | nh.getParam("gps_port", gpsPort);
37 | nh.getParam("start_angle", startAngle);
38 | nh.getParam("lidar_correction_file", lidarCorrectionFile);
39 | nh.getParam("laser_return_type", laserReturnType);
40 | nh.getParam("laser_count", laserCount);
41 | nh.getParam("pcldata_type", pclDataType);
42 |
43 | // pcapFile = "/home/pandora/Desktop/pandar40p.pcap";
44 |
45 | if(!pcapFile.empty())
46 | {
47 | hsdk = new HesaiLidarSDK(pcapFile, lidarCorrectionFile, (HesaiLidarRawDataSturct)laserReturnType, laserCount, (HesaiLidarPCLDataType)pclDataType,
48 | boost::bind(&HesaiLidarClient::lidarCallback, this, _1, _2));
49 | }
50 | else if(!serverIp.empty())
51 | {
52 |
53 | hsdk = new HesaiLidarSDK(lidarRecvPort, gpsPort, startAngle, lidarCorrectionFile,
54 | boost::bind(&HesaiLidarClient::lidarCallback, this, _1, _2),
55 | NULL, (HesaiLidarRawDataSturct)laserReturnType, laserCount, (HesaiLidarPCLDataType)pclDataType);
56 | }
57 |
58 | hsdk->start();
59 | }
60 |
61 | void cameraCallback(boost::shared_ptr matp, double timestamp, int pic_id)
62 | {
63 |
64 | sensor_msgs::ImagePtr imgMsg;
65 |
66 | switch (pic_id)
67 | {
68 | case 0:
69 | imgMsg = cv_bridge::CvImage(std_msgs::Header(), "bgr8", *matp).toImageMsg();
70 | break;
71 | case 1:
72 | case 2:
73 | case 3:
74 | case 4:
75 | imgMsg = cv_bridge::CvImage(std_msgs::Header(), "bgr8", *matp).toImageMsg();
76 | break;
77 | default:
78 | ROS_INFO("picid wrong in getImageToPub");
79 | return;
80 | }
81 | imgMsg->header.stamp = ros::Time(timestamp);
82 | imgPublishers[pic_id].publish(imgMsg);
83 | }
84 |
85 | void lidarCallback(boost::shared_ptr cld, double timestamp)
86 | {
87 | pcl_conversions::toPCL(ros::Time(timestamp), cld->header.stamp);
88 | sensor_msgs::PointCloud2 output;
89 | pcl::toROSMsg(*cld, output);
90 | lidarPublisher.publish(output);
91 | }
92 |
93 |
94 | private:
95 | ros::Publisher lidarPublisher;
96 | image_transport::Publisher imgPublishers[5];
97 | HesaiLidarSDK* hsdk;
98 | };
99 |
100 |
101 | int main(int argc, char **argv)
102 | {
103 | ros::init(argc, argv, "pandora_ros");
104 | ros::NodeHandle nh("~");
105 | ros::NodeHandle node;
106 | HesaiLidarClient pandoraClient(node, nh);
107 |
108 | ros::spin();
109 | return 0;
110 | }
111 |
--------------------------------------------------------------------------------