├── base
├── srv
│ └── Control.srv
├── package.xml
└── CMakeLists.txt
├── bluesea-ros2
├── params
│ ├── other
│ ├── uart_lidar.yaml
│ ├── vpc_lidar.yaml
│ ├── LDS-U50C-S.yaml
│ ├── LDS-U80C-S.yaml
│ ├── dual_udp_lidar.yaml
│ └── udp_lidar.yaml
├── script
│ ├── LHLiDAR.rules
│ └── help.txt
├── package.xml
├── sdk
│ ├── include
│ │ ├── algorithmAPI.h
│ │ ├── alarm.h
│ │ ├── bluesea.h
│ │ ├── parser.h
│ │ ├── reader.h
│ │ ├── usererror.h
│ │ └── common_data.h
│ └── src
│ │ ├── uart.c
│ │ ├── tcp_reader.cpp
│ │ ├── algorithmAPI.cpp
│ │ ├── bluesea.cpp
│ │ ├── udp_reader.cpp
│ │ ├── uart_reader.cpp
│ │ └── parser.cpp
├── launch
│ ├── heart_check.launch
│ ├── LDS-U50C-S.launch
│ ├── LDS-U80C-S.launch
│ ├── uart_lidar.launch
│ ├── udp_lidar.launch
│ ├── vpc_lidar.launch
│ └── dual_udp_lidar.launch
├── src
│ ├── client.cpp
│ ├── heart_check.cpp
│ └── node.cpp
├── CMakeLists.txt
└── rviz
│ └── demo.rviz
├── README_CN.md
└── README.md
/base/srv/Control.srv:
--------------------------------------------------------------------------------
1 | string topic
2 | string func
3 | int8 flag
4 | string params
5 | ---
6 | int32 code
7 | string value
--------------------------------------------------------------------------------
/bluesea-ros2/params/other:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FITTER#
4 | # filter_open: false #滤波生效开关
5 | # max_range: 20.0 #滤波生效的最大距离
6 | # min_range: 0.5 #滤波生效的最小距离
7 | # max_range_difference: 0.1 #离异点判断的物理范围
8 | # filter_window: 1 #判断离异点下标的范围
--------------------------------------------------------------------------------
/bluesea-ros2/script/LHLiDAR.rules:
--------------------------------------------------------------------------------
1 | KERNEL=="ttyUSB*", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", MODE:="0666", SYMLINK+="LHLiDAR"
2 | KERNEL=="ttyUSB*", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", MODE:="0666", SYMLINK+="LHLiDAR"
3 |
--------------------------------------------------------------------------------
/bluesea-ros2/script/help.txt:
--------------------------------------------------------------------------------
1 | 1.lsusb
2 | Find the list of serial ports that require fixed mapping and find the VID and PID
3 | 2.vim /etc/udev/rules.d
4 | open the file that need to edit,and Content reference LHLiDAR.rules
5 | 3.sudo service udev reload
6 | 4.sudo service udev restart
7 |
8 |
9 |
10 | for example
11 | cmd:lsusb
12 | print:Bus 003 Device 007: ID 1a86:7523 QinHeng Electronics HL-340 USB-Serial adapter
13 | need write:KERNEL=="ttyUSB*", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", MODE:="0666", SYMLINK+="LHLiDAR"
--------------------------------------------------------------------------------
/bluesea-ros2/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | bluesea2
4 | 1.0.0
5 | The bluesea2 package
6 | zr
7 | TODO
8 |
9 | ament_cmake
10 |
11 | rclcpp
12 | rclcpp_components
13 | std_msgs
14 | sensor_msgs
15 | geometry_msgs
16 | base
17 |
18 |
19 | ament_cmake
20 |
21 |
22 |
--------------------------------------------------------------------------------
/bluesea-ros2/sdk/include/algorithmAPI.h:
--------------------------------------------------------------------------------
1 | #ifndef _ALGORITHMAPI_
2 | #define _ALGORITHMAPI_
3 | #include"common_data.h"
4 |
5 |
6 | //离异点过滤
7 | bool checkWindowValid2(std::vectorscan, size_t idx, size_t window, double max_distance,double angle_increment);
8 | bool filter(std::vector& output_scan,double max_range,double min_range,double max_range_difference,unsigned int filter_window,double angle_increment);
9 | //判定一圈的点数中距离为0的点位的比例是否符合要求
10 | bool checkZeroDistance(std::vectorcomsume,float error_scale);
11 | //CRC算法
12 | unsigned int stm32crc(unsigned int *ptr, unsigned int len);
13 | //软采样设置
14 | void resample(RawData *dat, int NN);
15 | #endif
16 |
--------------------------------------------------------------------------------
/base/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | base
5 | 0.0.0
6 | TODO: Package description
7 | spragunr
8 | TODO: License declaration
9 |
10 | ament_cmake
11 |
12 | ament_lint_auto
13 | ament_lint_common
14 |
15 | rosidl_default_generators
16 |
17 | rosidl_default_runtime
18 |
19 | rosidl_interface_packages
20 |
21 |
22 | ament_cmake
23 |
24 |
25 |
--------------------------------------------------------------------------------
/base/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.5)
2 | project(base)
3 |
4 | # Default to C99
5 | if(NOT CMAKE_C_STANDARD)
6 | set(CMAKE_C_STANDARD 99)
7 | endif()
8 |
9 | # Default to C++14
10 | if(NOT CMAKE_CXX_STANDARD)
11 | set(CMAKE_CXX_STANDARD 17)
12 | endif()
13 |
14 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
15 | add_compile_options(-Wall -Wextra -Wpedantic)
16 | endif()
17 |
18 | # find dependencies
19 | find_package(ament_cmake REQUIRED)
20 | find_package(geometry_msgs REQUIRED)
21 |
22 | find_package(rosidl_default_generators REQUIRED)
23 |
24 | rosidl_generate_interfaces(${PROJECT_NAME}
25 | "srv/Control.srv"
26 | )
27 |
28 | if(BUILD_TESTING)
29 | find_package(ament_lint_auto REQUIRED)
30 | set(ament_cmake_copyright_FOUND TRUE)
31 | set(ament_cmake_cpplint_FOUND TRUE)
32 | ament_lint_auto_find_test_dependencies()
33 |
34 | endif()
35 |
36 | ament_package()
--------------------------------------------------------------------------------
/bluesea-ros2/params/uart_lidar.yaml:
--------------------------------------------------------------------------------
1 | bluesea_node:
2 | ros__parameters:
3 | #ROS2#
4 | frame_id: "map"
5 | scan_topic: "scan"
6 | cloud_topic: "cloud"
7 | #DATA#
8 | dev_id: -1
9 | raw_bytes: 3
10 | output_360: true
11 | output_scan: true
12 | output_cloud2: false
13 | with_angle_filter: false
14 | min_angle: -3.1415926
15 | max_angle: 3.1415926
16 | # mask1: "0,3.14"
17 | # mask2: "-3,-2"
18 | hard_resample: false
19 | soft_resample: false
20 | with_checksum: true
21 | reversed: false
22 | min_dist: 0.1
23 | max_dist: 50.0
24 | error_circle: 3
25 | error_scale: 0.9
26 | #CONNECT#
27 | type: "uart"
28 | port: "/dev/ttyUSB0"
29 | baud_rate: -1
30 | #GET#
31 | uuid: -1
32 | #SET#
33 | resample_res: -1.0
34 | with_confidence: -1
35 | with_smooth: -1
36 | with_deshadow: -1
37 | alarm_msg: -1
38 | rpm: -1
--------------------------------------------------------------------------------
/bluesea-ros2/sdk/src/uart.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | // #include
8 |
9 | int ioctl(int fd, unsigned long request, ...);
10 |
11 | int change_baud(int fd, unsigned int baud)
12 | {
13 | struct termios2 t;
14 | if (ioctl(fd, TCGETS2, &t))
15 | {
16 | return -1;
17 | }
18 | t.c_cflag &= ~CBAUD;
19 | t.c_cflag |= BOTHER;
20 | t.c_ispeed = baud;
21 | t.c_ospeed = baud;
22 |
23 | if (ioctl(fd, TCSETS2, &t))
24 | {
25 | return -2;
26 | }
27 |
28 | #if 1
29 | if (ioctl(fd, TCGETS2, &t) == 0)
30 | {
31 | if (abs((int)(t.c_ospeed - baud)) <= 20000)
32 | {
33 | //printf("reported %d\n", t.c_ospeed);
34 | }
35 | else
36 | {
37 | //printf("reported err set:%d result:%d\n", baud, t.c_ospeed);
38 | return -3;
39 | }
40 | }
41 | #endif
42 |
43 | return 0;
44 | }
45 |
--------------------------------------------------------------------------------
/bluesea-ros2/params/vpc_lidar.yaml:
--------------------------------------------------------------------------------
1 | bluesea_node:
2 | ros__parameters:
3 | #ROS2
4 | frame_id: "map"
5 | scan_topic: "scan"
6 | cloud_topic: "cloud"
7 | #DATA#
8 | dev_id: -1
9 | raw_bytes: 3
10 | output_360: true
11 | output_scan: true
12 | output_cloud2: false
13 | with_angle_filter: false
14 | min_angle: -3.14159
15 | max_angle: 3.14159
16 | # mask1: "0,3.14"
17 | # mask2: "-3,-2"
18 | hard_resample: false
19 | soft_resample: false
20 | with_checksum: true
21 | reversed: false
22 | min_dist: 0.1
23 | max_dist: 50.0
24 | error_circle: 3
25 | error_scale: 0.9
26 | #CONNECT#
27 | type: "vpc"
28 | port: "/dev/ttyACM0"
29 | #GET#
30 | uuid: -1
31 | #SET#
32 | resample_res: -1.0
33 | with_confidence: -1
34 | with_smooth: -1
35 | with_deshadow: -1
36 | alarm_msg: -1
37 | rpm: -1
38 | direction: -1
39 | ats: 1
--------------------------------------------------------------------------------
/bluesea-ros2/params/LDS-U50C-S.yaml:
--------------------------------------------------------------------------------
1 | bluesea_node:
2 | ros__parameters:
3 | #ROS2#
4 | frame_id: "map"
5 | scan_topic: "scan"
6 | cloud_topic: "cloud"
7 | #DATA#
8 | dev_id: -1
9 | raw_bytes: 3
10 | output_360: true
11 | output_scan: true
12 | output_cloud2: false
13 | with_angle_filter: false
14 | min_angle: -1.0
15 | max_angle: 2.0
16 | # mask1: "0,3.14"
17 | # mask2: "-3,-2"
18 | hard_resample: false
19 | soft_resample: false
20 | with_checksum: true
21 | reversed: false
22 | min_dist: 0.01
23 | max_dist: 40.0
24 | error_circle: 3
25 | error_scale: 0.9
26 | with_confidence: 1
27 | unit_is_mm: 0
28 | #CONNECT#
29 | type: "udp"
30 | lidar_ip: "192.168.158.98"
31 | lidar_port: 6543
32 | local_port: 6668
33 | group_ip: "224.1.2.3"
34 | #GET#
35 | uuid: -1
36 | #SET#
37 | resample_res: -1.0
38 | with_confidence: -1
39 | with_smooth: -1
40 | with_deshadow: -1
41 | alarm_msg: -1
42 | rpm: -1
43 | direction: -1
44 | ats: -1
45 |
--------------------------------------------------------------------------------
/bluesea-ros2/params/LDS-U80C-S.yaml:
--------------------------------------------------------------------------------
1 | bluesea_node:
2 | ros__parameters:
3 | #ROS2#
4 | frame_id: "map"
5 | scan_topic: "scan"
6 | cloud_topic: "cloud"
7 | #DATA#
8 | dev_id: -1
9 | raw_bytes: 3
10 | output_360: true
11 | output_scan: true
12 | output_cloud2: false
13 | with_angle_filter: false
14 | min_angle: -1.0
15 | max_angle: 2.0
16 | # mask1: "0,3.14"
17 | # mask2: "-3,-2"
18 | hard_resample: false
19 | soft_resample: false
20 | with_checksum: true
21 | reversed: false
22 | min_dist: 0.01
23 | max_dist: 80.0
24 | error_circle: 3
25 | error_scale: 0.9
26 | with_confidence: 1
27 | unit_is_mm: 0
28 | #CONNECT#
29 | type: "udp"
30 | lidar_ip: "192.168.158.98"
31 | lidar_port: 6543
32 | local_port: 6668
33 | group_ip: "224.1.2.3"
34 | #GET#
35 | uuid: -1
36 | #SET#
37 | resample_res: -1.0
38 | with_confidence: -1
39 | with_smooth: -1
40 | with_deshadow: -1
41 | alarm_msg: -1
42 | rpm: -1
43 | direction: -1
44 | ats: -1
45 |
--------------------------------------------------------------------------------
/bluesea-ros2/params/dual_udp_lidar.yaml:
--------------------------------------------------------------------------------
1 | bluesea_node:
2 | ros__parameters:
3 | #ROS2#
4 | frame_id: "map"
5 | scan_topic: "scan"
6 | cloud_topic: "cloud"
7 | scan_topic1: "scan1"
8 | cloud_topic1: "cloud1"
9 | #DATA#
10 | dev_id: -1
11 | raw_bytes: 3
12 | output_360: true
13 | output_scan: true
14 | output_cloud2: false
15 | with_angle_filter: false
16 | min_angle: -3.14159
17 | max_angle: 3.14159
18 | # mask1: "0,3.14"
19 | # mask2: "-3,-2"
20 | hard_resample: false
21 | soft_resample: false
22 | with_checksum: true
23 | reversed: false
24 | min_dist: 0.1
25 | max_dist: 50.0
26 | error_circle: 3
27 | error_scale: 0.9
28 | #CONNECT#
29 | type: "udp"
30 | number: 2
31 | lidar_ip: "192.168.158.98"
32 | lidar_port: 6543
33 | lidar1_ip: "192.168.158.99"
34 | lidar1_port: 6543
35 | local_port: 6668
36 | group_ip: "224.1.2.3"
37 | #GET#
38 | uuid: -1
39 | #SET#
40 | resample_res: -1.0
41 | with_confidence: -1
42 | with_smooth: -1
43 | with_deshadow: -1
44 | alarm_msg: -1
45 | rpm: -1
46 | direction: -1
47 | ats: -1
48 |
--------------------------------------------------------------------------------
/bluesea-ros2/params/udp_lidar.yaml:
--------------------------------------------------------------------------------
1 | bluesea_node:
2 | ros__parameters:
3 | #ROS2#
4 | frame_id: "map"
5 | scan_topic: "scan"
6 | cloud_topic: "cloud"
7 | #DATA#
8 | dev_id: -1
9 | raw_bytes: 3
10 | output_360: true
11 | output_scan: true
12 | output_cloud2: false
13 | with_angle_filter: false
14 | min_angle: -3.1415926
15 | max_angle: 3.1415926
16 | # mask1: "0,3.14"
17 | # mask2: "-3,-2"
18 | hard_resample: false
19 | soft_resample: false
20 | with_checksum: true
21 | reversed: false
22 | min_dist: 0.01
23 | max_dist: 50.0
24 | error_circle: 3
25 | error_scale: 0.9
26 | log_enable: false
27 | log_path: "/tmp/ros2_log.txt"
28 | #CONNECT#
29 | type: "udp"
30 | lidar_ip: "192.168.158.98"
31 | lidar_port: 6543
32 | local_port: 6668
33 | group_ip: "224.1.2.3"
34 | #GET#
35 | uuid: -1
36 | #SET#
37 | resample_res: -1.0
38 | with_confidence: -1
39 | with_smooth: -1
40 | with_deshadow: -1
41 | alarm_msg: -1
42 | rpm: -1
43 | direction: -1
44 | ats: -1
45 | #NTP
46 | ntp_ip: "192.168.158.50"
47 | ntp_port: 5678
48 | ntp_enable: -1
49 |
--------------------------------------------------------------------------------
/bluesea-ros2/sdk/include/alarm.h:
--------------------------------------------------------------------------------
1 | #ifndef _ALARM_
2 | #define _ALARM_
3 |
4 | #define LMSG_ERROR 1
5 | #define LMSG_INFO 2
6 | #define LMSG_DEBUG 4
7 | #define LMSG_ALARM 0x100
8 |
9 |
10 | #define LERR_LOW_POWER 1
11 | #define LERR_MOTOR 2
12 | #define LERR_RANGER_HI 4
13 | #define LERR_NETWORK 8
14 | #define LERR_RANGER_IDLE 0x10
15 | #define LERR_ZERO_MISS 0x20
16 | #include
17 | struct LidarMsgHdr
18 | {
19 | char dev_sn[20];
20 | uint32_t dev_id; //
21 | uint32_t timestamp;//
22 | uint32_t type;
23 | uint32_t data;
24 | };
25 |
26 | struct LidarAlarm
27 | {
28 | char sign[4]; // must be "LMSG"
29 | uint32_t proto_version; // 0x101
30 | LidarMsgHdr hdr;
31 | uint16_t id;
32 | uint16_t extra;
33 | uint32_t zone_actived;
34 | uint8_t all_states[32];
35 | uint32_t reserved[11];
36 | };
37 | #pragma pack (push,1)
38 | typedef struct
39 | {
40 | char sign[2]; /* AM */
41 | uint8_t dev_id; /* 设备序号 */
42 | uint32_t timestamp; /* 时间戳 */
43 | uint16_t id; /* 消息序号 */
44 | uint32_t events; /* 报警事件 */
45 | uint32_t zone_actived; /* 当前激活防区 */
46 | uint8_t reserved[11];
47 | uint32_t crc;
48 | }PROCOTOL_HOST_ALARM_ST;
49 | #pragma pack (pop)
50 | #endif
51 |
--------------------------------------------------------------------------------
/bluesea-ros2/sdk/include/bluesea.h:
--------------------------------------------------------------------------------
1 | #include"alarm.h"
2 | #include"algorithmAPI.h"
3 | #include"parser.h"
4 | #include"reader.h"
5 | #include"usererror.h"
6 |
7 |
8 | #define BLUESEA2_VERSION "2.6.4"
9 |
10 | class BlueSeaLidarDriver
11 | {
12 | public:
13 | BlueSeaLidarDriver();
14 | ~BlueSeaLidarDriver();
15 | //Get the instructions that need to be executed for initialization
16 | void getInitCmds(ArgData &argdata);
17 | void openLidarThread();
18 | //void openHeartThread();
19 |
20 | bool sendCmd(std::string topic,std::string cmd,int proto);
21 | bool sendUdpCmd2(char *ip, int len, char *cmd);
22 |
23 | PubHub*getHub(int i);
24 | Parser*getParser(int i);
25 | bool checkIsRun(int i);
26 | int GetAllFans(PubHub* pub, ArgData argdata, int8_t &counterclockwise);
27 | bool GetFan(PubHub* pub, bool with_resample, double resample_res, RawData **fans);
28 |
29 | double ROSAng(double ang);
30 | int GetCount(std::vector data, double min_deg, double max_deg, double &min_pos, double &max_pos);
31 | private:
32 |
33 | private:
34 | HReader m_reader;//NULL
35 | CommandList m_cmdlist;//init need run cmds
36 | //std::string m_type;//"uart"
37 | Parser *m_parsers[MAX_LIDARS];
38 | PubHub *m_hubs[MAX_LIDARS];
39 | ArgData m_argdata;
40 | int m_counterclockwise;
41 | };
42 | bool judgepcIPAddrIsValid(const char *pcIPAddr);
43 |
--------------------------------------------------------------------------------
/bluesea-ros2/launch/heart_check.launch:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python3
2 |
3 | from ament_index_python.packages import get_package_share_directory
4 |
5 | from launch import LaunchDescription
6 | from launch_ros.actions import LifecycleNode
7 | from launch_ros.actions import Node
8 | from launch.actions import DeclareLaunchArgument
9 | from launch.substitutions import LaunchConfiguration
10 | from launch.actions import LogInfo
11 |
12 | import lifecycle_msgs.msg
13 | import os
14 |
15 |
16 | def generate_launch_description():
17 | share_dir = get_package_share_directory('bluesea2')
18 | parameter_file = LaunchConfiguration('params_file')
19 | node_name = 'bluesea_heart_check'
20 |
21 | #对多版本的兼容性处理 首字母e以及之前为18.04或更早,之后为20.04或更晚
22 | ROS_DISTRO=''
23 | ROS_DISTRO = os.getenv('ROS_DISTRO')
24 | print("Current ROS2 Version: ",ROS_DISTRO)
25 | if ROS_DISTRO[0] <= 'e':
26 | try:
27 | driver_node = LifecycleNode( node_name='bluesea_heart_check', node_namespace='/', package='bluesea2', node_executable='bluesea2_heart_check', output='screen')
28 | except:
29 | pass
30 | else :
31 | try:
32 | driver_node = LifecycleNode( name='bluesea_heart_check', namespace='/', package='bluesea2', executable='bluesea2_heart_check', output='screen', emulate_tty=True)
33 | except:
34 | pass
35 |
36 |
37 | return LaunchDescription([
38 | driver_node
39 | ])
40 |
--------------------------------------------------------------------------------
/bluesea-ros2/sdk/include/parser.h:
--------------------------------------------------------------------------------
1 | #ifndef _PARSER_
2 | #define _PARSER_
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include"common_data.h"
11 | #include"usererror.h"
12 | #include"alarm.h"
13 |
14 | Parser* ParserOpen(int raw_bytes, bool with_chksum,int dev_id,
15 | int error_circle, double error_scale, bool from_zero,int time_mode,CommandList cmd, char *ip, int port);
16 |
17 | int strip(const char *s, char *buf);
18 | //int ParserClose(HParser);
19 | int ParserRunStream(Parser*, int len, unsigned char *buf, RawData *fans[]);
20 | int ParserRun(LidarNode, int len, unsigned char *buf, RawData *fans[]);
21 |
22 | void SetTimeStamp(RawData *);
23 | //void saveLog(const char *logPath, int type, const char *ip, const int port, const unsigned char *buf, unsigned int len);
24 | int mkpathAll(std::string s, mode_t mode);
25 | unsigned int stm32crc(unsigned int *ptr, unsigned int len);
26 | int alarmProc(unsigned char *buf, int len);
27 | //int autoGetFirstAngle(RawData raw, bool from_zero, std::vector &raws,std::string &result);
28 |
29 | std::string stringfilter(char *str, int num);
30 | int getFirstidx(RawData raw, int angle);
31 | void timestampMode(int type);
32 |
33 | //中断进程
34 | void closeSignal(int sig);
35 | // //指定编号雷达发送指令
36 | // bool SendCmd(int len, char *cmd, int index);
37 | // //获取一帧第一个点所在的扇区,以及该点所在扇区的位置
38 | // bool autoGetFirstAngle2(PubHub* pub, bool from_zero);
39 | //对读取的数据进行解析 参数:实际获取的数据 配置文件对应的参数
40 | //int GetAllFans(HPublish pub,ArgData argdata,uint8_t &counterclockwise);
41 |
42 | void PublishData(PubHub* pub, int n, RawData **fans);
43 |
44 | void redirect_stdout_to_log(const char *path) ;
45 |
46 | #endif
47 |
--------------------------------------------------------------------------------
/bluesea-ros2/launch/LDS-U50C-S.launch:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python3
2 |
3 | from ament_index_python.packages import get_package_share_directory
4 |
5 | from launch import LaunchDescription
6 | from launch_ros.actions import LifecycleNode
7 | from launch_ros.actions import Node
8 | from launch.actions import DeclareLaunchArgument
9 | from launch.substitutions import LaunchConfiguration
10 | from launch.actions import LogInfo
11 |
12 | import lifecycle_msgs.msg
13 | import os
14 |
15 |
16 | def generate_launch_description():
17 | share_dir = get_package_share_directory('bluesea2')
18 | parameter_file = LaunchConfiguration('params_file')
19 | node_name = 'bluesea_node'
20 |
21 | params_declare = DeclareLaunchArgument('params_file',
22 | default_value=os.path.join(
23 | share_dir, 'params', 'LDS-U50C-S.yaml'),
24 | description='FPath to the ROS2 parameters file to use.')
25 |
26 | #对多版本的兼容性处理 首字母e以及之前为18.04或更早,之后为20.04或更晚
27 | ROS_DISTRO=''
28 | ROS_DISTRO = os.getenv('ROS_DISTRO')
29 | print("Current ROS2 Version: ",ROS_DISTRO)
30 | if ROS_DISTRO[0] <= 'e':
31 | try:
32 | driver_node = LifecycleNode( node_name='bluesea_node', node_namespace='/', package='bluesea2', node_executable='bluesea2_node', output='screen', parameters=[parameter_file])
33 | except:
34 | pass
35 | else :
36 | try:
37 | driver_node = LifecycleNode( name='bluesea_node', namespace='/', package='bluesea2', executable='bluesea2_node', output='screen', emulate_tty=True, parameters=[parameter_file])
38 | except:
39 | pass
40 |
41 |
42 | return LaunchDescription([
43 | params_declare,
44 | driver_node
45 | ])
46 |
--------------------------------------------------------------------------------
/bluesea-ros2/launch/LDS-U80C-S.launch:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python3
2 |
3 | from ament_index_python.packages import get_package_share_directory
4 |
5 | from launch import LaunchDescription
6 | from launch_ros.actions import LifecycleNode
7 | from launch_ros.actions import Node
8 | from launch.actions import DeclareLaunchArgument
9 | from launch.substitutions import LaunchConfiguration
10 | from launch.actions import LogInfo
11 |
12 | import lifecycle_msgs.msg
13 | import os
14 |
15 |
16 | def generate_launch_description():
17 | share_dir = get_package_share_directory('bluesea2')
18 | parameter_file = LaunchConfiguration('params_file')
19 | node_name = 'bluesea_node'
20 |
21 | params_declare = DeclareLaunchArgument('params_file',
22 | default_value=os.path.join(
23 | share_dir, 'params', 'LDS-U80C-S.yaml'),
24 | description='FPath to the ROS2 parameters file to use.')
25 |
26 | #对多版本的兼容性处理 首字母e以及之前为18.04或更早,之后为20.04或更晚
27 | ROS_DISTRO=''
28 | ROS_DISTRO = os.getenv('ROS_DISTRO')
29 | print("Current ROS2 Version: ",ROS_DISTRO)
30 | if ROS_DISTRO[0] <= 'e':
31 | try:
32 | driver_node = LifecycleNode( node_name='bluesea_node', node_namespace='/', package='bluesea2', node_executable='bluesea2_node', output='screen', parameters=[parameter_file])
33 | except:
34 | pass
35 | else :
36 | try:
37 | driver_node = LifecycleNode( name='bluesea_node', namespace='/', package='bluesea2', executable='bluesea2_node', output='screen', emulate_tty=True, parameters=[parameter_file])
38 | except:
39 | pass
40 |
41 |
42 | return LaunchDescription([
43 | params_declare,
44 | driver_node
45 | ])
46 |
--------------------------------------------------------------------------------
/bluesea-ros2/launch/uart_lidar.launch:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python3
2 |
3 | from ament_index_python.packages import get_package_share_directory
4 |
5 | from launch import LaunchDescription
6 | from launch_ros.actions import LifecycleNode
7 | from launch_ros.actions import Node
8 | from launch.actions import DeclareLaunchArgument
9 | from launch.substitutions import LaunchConfiguration
10 | from launch.actions import LogInfo
11 |
12 | import lifecycle_msgs.msg
13 | import os
14 |
15 |
16 | def generate_launch_description():
17 | share_dir = get_package_share_directory('bluesea2')
18 | parameter_file = LaunchConfiguration('params_file')
19 | node_name = 'bluesea_node'
20 |
21 | params_declare = DeclareLaunchArgument('params_file',
22 | default_value=os.path.join(
23 | share_dir, 'params', 'uart_lidar.yaml'),
24 | description='FPath to the ROS2 parameters file to use.')
25 |
26 | #对多版本的兼容性处理 首字母e以及之前为18.04或更早,之后为20.04或更晚
27 | ROS_DISTRO=''
28 | ROS_DISTRO = os.getenv('ROS_DISTRO')
29 | print("Current ROS2 Version: ",ROS_DISTRO)
30 | if ROS_DISTRO[0] <= 'e':
31 | try:
32 | driver_node = LifecycleNode( node_name='bluesea_node', node_namespace='/', package='bluesea2', node_executable='bluesea2_node', output='screen', parameters=[parameter_file])
33 | except:
34 | pass
35 | else :
36 | try:
37 | driver_node = LifecycleNode( name='bluesea_node', namespace='/', package='bluesea2', executable='bluesea2_node', output='screen', emulate_tty=True, parameters=[parameter_file])
38 | except:
39 | pass
40 |
41 |
42 | return LaunchDescription([
43 | params_declare,
44 | driver_node
45 | ])
46 |
--------------------------------------------------------------------------------
/bluesea-ros2/launch/udp_lidar.launch:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python3
2 |
3 | from ament_index_python.packages import get_package_share_directory
4 |
5 | from launch import LaunchDescription
6 | from launch_ros.actions import LifecycleNode
7 | from launch_ros.actions import Node
8 | from launch.actions import DeclareLaunchArgument
9 | from launch.substitutions import LaunchConfiguration
10 | from launch.actions import LogInfo
11 |
12 | import lifecycle_msgs.msg
13 | import os
14 |
15 |
16 | def generate_launch_description():
17 | share_dir = get_package_share_directory('bluesea2')
18 | parameter_file = LaunchConfiguration('params_file')
19 | node_name = 'bluesea_node'
20 |
21 | params_declare = DeclareLaunchArgument('params_file',
22 | default_value=os.path.join(
23 | share_dir, 'params', 'udp_lidar.yaml'),
24 | description='FPath to the ROS2 parameters file to use.')
25 |
26 | #对多版本的兼容性处理 首字母e以及之前为18.04或更早,之后为20.04或更晚
27 | ROS_DISTRO=''
28 | ROS_DISTRO = os.getenv('ROS_DISTRO')
29 | print("Current ROS2 Version: ",ROS_DISTRO)
30 | if ROS_DISTRO[0] <= 'e':
31 | try:
32 | driver_node = LifecycleNode( node_name='bluesea_node', node_namespace='/', package='bluesea2', node_executable='bluesea2_node', output='screen', parameters=[parameter_file])
33 | except:
34 | pass
35 | else :
36 | try:
37 | driver_node = LifecycleNode( name='bluesea_node', namespace='/', package='bluesea2', executable='bluesea2_node', output='screen', emulate_tty=True, parameters=[parameter_file])
38 | except:
39 | pass
40 |
41 |
42 | return LaunchDescription([
43 | params_declare,
44 | driver_node
45 | ])
46 |
--------------------------------------------------------------------------------
/bluesea-ros2/launch/vpc_lidar.launch:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python3
2 |
3 | from ament_index_python.packages import get_package_share_directory
4 |
5 | from launch import LaunchDescription
6 | from launch_ros.actions import LifecycleNode
7 | from launch_ros.actions import Node
8 | from launch.actions import DeclareLaunchArgument
9 | from launch.substitutions import LaunchConfiguration
10 | from launch.actions import LogInfo
11 |
12 | import lifecycle_msgs.msg
13 | import os
14 |
15 |
16 | def generate_launch_description():
17 | share_dir = get_package_share_directory('bluesea2')
18 | parameter_file = LaunchConfiguration('params_file')
19 | node_name = 'bluesea_node'
20 |
21 | params_declare = DeclareLaunchArgument('params_file',
22 | default_value=os.path.join(
23 | share_dir, 'params', 'vpc_lidar.yaml'),
24 | description='FPath to the ROS2 parameters file to use.')
25 |
26 | #对多版本的兼容性处理 首字母e以及之前为18.04或更早,之后为20.04或更晚
27 | ROS_DISTRO=''
28 | ROS_DISTRO = os.getenv('ROS_DISTRO')
29 | print("Current ROS2 Version: ",ROS_DISTRO)
30 | if ROS_DISTRO[0] <= 'e':
31 | try:
32 | driver_node = LifecycleNode( node_name='bluesea_node', node_namespace='/', package='bluesea2', node_executable='bluesea2_node', output='screen', parameters=[parameter_file])
33 | except:
34 | pass
35 | else :
36 | try:
37 | driver_node = LifecycleNode( name='bluesea_node', namespace='/', package='bluesea2', executable='bluesea2_node', output='screen', emulate_tty=True, parameters=[parameter_file])
38 | except:
39 | pass
40 |
41 |
42 | return LaunchDescription([
43 | params_declare,
44 | driver_node
45 | ])
46 |
--------------------------------------------------------------------------------
/bluesea-ros2/launch/dual_udp_lidar.launch:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python3
2 |
3 | from ament_index_python.packages import get_package_share_directory
4 |
5 | from launch import LaunchDescription
6 | from launch_ros.actions import LifecycleNode
7 | from launch_ros.actions import Node
8 | from launch.actions import DeclareLaunchArgument
9 | from launch.substitutions import LaunchConfiguration
10 | from launch.actions import LogInfo
11 |
12 | import lifecycle_msgs.msg
13 | import os
14 |
15 |
16 | def generate_launch_description():
17 | share_dir = get_package_share_directory('bluesea2')
18 | parameter_file = LaunchConfiguration('params_file')
19 | node_name = 'bluesea_node'
20 |
21 | params_declare = DeclareLaunchArgument('params_file',
22 | default_value=os.path.join(
23 | share_dir, 'params', 'dual_udp_lidar.yaml'),
24 | description='FPath to the ROS2 parameters file to use.')
25 |
26 | #对多版本的兼容性处理 首字母e以及之前为18.04或更早,之后为20.04或更晚
27 | ROS_DISTRO=''
28 | ROS_DISTRO = os.getenv('ROS_DISTRO')
29 | print("Current ROS2 Version: ",ROS_DISTRO)
30 | if ROS_DISTRO[0] <= 'e':
31 | try:
32 | driver_node = LifecycleNode( node_name='bluesea_node', node_namespace='/', package='bluesea2', node_executable='bluesea2_node', output='screen', parameters=[parameter_file])
33 | except:
34 | pass
35 | else :
36 | try:
37 | driver_node = LifecycleNode( name='bluesea_node', namespace='/', package='bluesea2', executable='bluesea2_node', output='screen', emulate_tty=True, parameters=[parameter_file])
38 | except:
39 | pass
40 |
41 |
42 | return LaunchDescription([
43 | params_declare,
44 | driver_node
45 | ])
46 |
--------------------------------------------------------------------------------
/bluesea-ros2/sdk/include/reader.h:
--------------------------------------------------------------------------------
1 | #ifndef _READER_
2 | #define _READER_
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include "parser.h"
23 |
24 | HReader StartUartReader(const char* type ,const char* port, int baudrate, Parser*hParser, PubHub*);
25 | bool SendUartCmd(HReader, int len, char*);
26 | bool SendVpcCmd(HReader hr, int len, char* cmd);
27 |
28 | HReader StartUDPReader(const char* type,unsigned short listen_port, bool is_group_listener, const char* group_ip,
29 | int lidar_count, const LidarInfo* lidars);
30 |
31 |
32 | bool SendUdpCmd(HReader hr, std::string lidarIp,int port,std::string cmd,int proto);
33 | HReader StartTCPReader(const char* lidar_ip, unsigned short lidar_port, Parser* hParser, PubHub* hPub);
34 |
35 | bool SendTcpCmd(HReader hr, int len, char* cmd);
36 |
37 | void StopUartReader(HReader hr);
38 | void StopUDPReader(HReader hr);
39 | void StopTCPReader(HReader hr);
40 |
41 |
42 | //UART
43 | int open_serial_port(const char *port, int baudrate);
44 | bool uart_talk(int fd, int n, const char* cmd, int nhdr, const char* hdr_str, int nfetch, char* fetch,int waittime=10,int cachelength=4096);
45 | int GetComBaud(std::string uartname);
46 |
47 |
48 | //VPC
49 | bool vpc_talk(int hcom, int mode, short sn, int len, const char* cmd, int nfetch, void* result);
50 |
51 |
52 | //udp
53 | bool setup_lidar_udp(int handle,Parser* hP, EEpromV101 ¶m);
54 | void send_cmd_udp(int fd_udp, const char* dev_ip, int dev_port, int cmd, int sn, int len, const void* snd_buf);
55 | bool udp_talk_S_PACK(int fd_udp, const char* ip, int port, int n, const char* cmd, void* result);
56 | bool udp_talk_C_PACK(int fd_udp, const char* lidar_ip, int lidar_port,int n, const char* cmd,int nhdr, const char* hdr_str,int nfetch, char* fetch);
57 | bool udp_talk_GS_PACK(int fd_udp, const char *ip, int port, int n, const char *cmd, void *result);
58 |
59 | //common
60 | void PublishData(PubHub* pub, int n, RawData **fans);
61 |
62 | #endif
63 |
--------------------------------------------------------------------------------
/bluesea-ros2/src/client.cpp:
--------------------------------------------------------------------------------
1 | #include "rclcpp/clock.hpp"
2 | #include "rclcpp/rclcpp.hpp"
3 | #include "rclcpp/time_source.hpp"
4 | #include "sensor_msgs/msg/laser_scan.hpp"
5 | #include "base/srv/control.hpp"
6 | int main(int argc, char **argv)
7 | {
8 | if (argc != 3&&argc != 4)
9 | {
10 | RCLCPP_INFO(rclcpp::get_logger("rclcpp"),"usage: ros2 run bluesea2 bluesea2_client scan start arg1 is topic arg2 is action(start/stop)");
11 | RCLCPP_INFO(rclcpp::get_logger("rclcpp"),"usage: ros2 run bluesea2 bluesea2_client scan switchZone 0 arg1 is topic arg2 is action(switchZone) arg3 is select zone id");
12 | RCLCPP_INFO(rclcpp::get_logger("rclcpp"),"usage: ros2 run bluesea2 bluesea2_client scan rpm 600 arg1 is topic arg2 is action(set rpm) arg3 is rpm value");
13 | RCLCPP_INFO(rclcpp::get_logger("rclcpp"),"usage: ros2 run bluesea2 bluesea2_client heart check 1 arg1 is service name arg2 is action(check) arg3 is print / not print");
14 | return 1;
15 | }
16 | rclcpp::init(argc, argv);
17 | std::shared_ptr node = rclcpp::Node::make_shared("bluesea_node_client");
18 | char serviceName[64] = {0};
19 | sprintf(serviceName,"/%s_motor",argv[1]);
20 |
21 | rclcpp::Client::SharedPtr client = node->create_client(serviceName); // CHANGE
22 | //Retain four universal parameters
23 | auto request = std::make_shared();
24 | request->topic=argv[1];
25 | request->func=argv[2];
26 | if(strcmp(argv[2],"start")==0||strcmp(argv[2],"stop")==0)
27 | {
28 | }
29 | else if(strcmp(argv[2],"switchZone")==0)
30 | {
31 | request->flag=atoi(argv[3]);
32 | }
33 | else if(strcmp(argv[2],"rpm")==0)
34 | {
35 | request->params=argv[3];
36 |
37 | }
38 | else if(strcmp(argv[2],"check")==0)
39 | {
40 | request->flag=atoi(argv[3]);
41 | }
42 |
43 | while (!client->wait_for_service(std::chrono::seconds(1)))
44 | {
45 | if (!rclcpp::ok())
46 | {
47 | RCLCPP_ERROR(rclcpp::get_logger("rclcpp"), "Interrupted while waiting for the service. Exiting.");
48 | return 0;
49 | }
50 | RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "service not available, waiting again...");
51 | }
52 |
53 | auto result = client->async_send_request(request);
54 | #ifdef ROS_DISTRO_F
55 | if(rclcpp::spin_until_future_complete(node, result)==rclcpp::FutureReturnCode::SUCCESS)
56 | #elif defined ROS_DISTRO_E
57 | //ros2 eloquent 18.04 and lower
58 | if(rclcpp::spin_until_future_complete(node, result)==rclcpp::executor::FutureReturnCode::SUCCESS)
59 | #endif
60 | {
61 | RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "client OK");
62 | }
63 | else
64 | {
65 | RCLCPP_ERROR(rclcpp::get_logger("rclcpp"), "Failed to call ctrl_service "); // CHANGE
66 | }
67 |
68 | rclcpp::shutdown();
69 | return 0;
70 | }
71 |
72 |
--------------------------------------------------------------------------------
/bluesea-ros2/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.8)
2 | project(bluesea2)
3 |
4 |
5 | # Default to C99
6 | if(NOT CMAKE_C_STANDARD)
7 | set(CMAKE_C_STANDARD 99)
8 | endif()
9 |
10 | # Default to C++14
11 | if(NOT CMAKE_CXX_STANDARD)
12 | set(CMAKE_CXX_STANDARD 17)
13 | endif()
14 |
15 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
16 | add_compile_options(-Wall -Wextra -Wpedantic)
17 | endif()
18 |
19 | # Get ROS2 version information (initial letter) from environment variables
20 | string(SUBSTRING $ENV{ROS_DISTRO} 0 1 tmp)
21 | #MESSAGE("ROS_DISTRO2:${tmp}")
22 |
23 | string(COMPARE LESS_EQUAL ${tmp} "e" flag)
24 | #MESSAGE("flag:${flag}")
25 |
26 |
27 | if( ${flag} STREQUAL 1)
28 | add_definitions(-DROS_DISTRO_E)
29 | else()
30 | add_definitions(-DROS_DISTRO_F)
31 | endif()
32 |
33 | # find dependencies
34 | find_package(ament_cmake REQUIRED)
35 | #find_package(rmw REQUIRED)
36 | find_package(rclcpp REQUIRED)
37 | find_package(sensor_msgs REQUIRED)
38 | find_package(visualization_msgs REQUIRED)
39 | find_package(geometry_msgs REQUIRED)
40 | find_package(base REQUIRED)
41 | find_package(std_srvs REQUIRED)
42 |
43 | include_directories(${sensor_msgs_INCLUDE_DIRS})
44 |
45 | set(BLUESEA_SDK_PATH "./sdk/")
46 | FILE(GLOB BLUESEA_SDK_SRC "${BLUESEA_SDK_PATH}/src/*.cpp" "${BLUESEA_SDK_PATH}/src/*.c")
47 |
48 |
49 |
50 | add_executable(${PROJECT_NAME}_node ./src/node.cpp ${BLUESEA_SDK_SRC})
51 | add_executable(${PROJECT_NAME}_client ./src/client.cpp)
52 | add_executable(${PROJECT_NAME}_heart_check ./src/heart_check.cpp)
53 |
54 |
55 | ament_target_dependencies(${PROJECT_NAME}_node rclcpp sensor_msgs visualization_msgs std_srvs geometry_msgs base)
56 | ament_target_dependencies(${PROJECT_NAME}_client rclcpp geometry_msgs base)
57 | ament_target_dependencies(${PROJECT_NAME}_heart_check rclcpp geometry_msgs std_srvs base)
58 |
59 |
60 |
61 | # target_compile_features(${PROJECT_NAME}_node PUBLIC c_std_99 cxx_std_17) # Require C99 and C++17
62 | # target_compile_features(${PROJECT_NAME}_client PUBLIC c_std_99 cxx_std_17) # Require C99 and C++17
63 | # target_compile_features(${PROJECT_NAME}_heart_check PUBLIC c_std_99 cxx_std_17) # Require C99 and C++17
64 |
65 |
66 | # target_include_directories(${PROJECT_NAME}_node PUBLIC
67 | # $
68 | # $)
69 |
70 |
71 | # target_link_libraries(${PROJECT_NAME}_node ${catkin_LIBRARIES})
72 | # target_link_libraries(${PROJECT_NAME}_client ${catkin_LIBRARIES})
73 | # target_link_libraries(${PROJECT_NAME}_heart_check ${catkin_LIBRARIES})
74 |
75 | install(TARGETS ${PROJECT_NAME}_node ${PROJECT_NAME}_client ${PROJECT_NAME}_heart_check DESTINATION lib/${PROJECT_NAME})
76 | install(DIRECTORY launch params DESTINATION share/${PROJECT_NAME})
77 |
78 | if(BUILD_TESTING)
79 | find_package(ament_lint_auto REQUIRED)
80 | ament_lint_auto_find_test_dependencies()
81 | endif()
82 | ament_package()
83 |
84 |
--------------------------------------------------------------------------------
/bluesea-ros2/sdk/src/tcp_reader.cpp:
--------------------------------------------------------------------------------
1 | #include "../include/reader.h"
2 |
3 | struct TCPInfo
4 | {
5 | Parser* hParser;
6 | PubHub* hPublish;
7 | int fd_tcp;
8 | int lidar_port;
9 | char lidar_ip[32];
10 | //int listen_port;
11 | //char group_ip[32];
12 | pthread_t thr;
13 | };
14 |
15 | int tcp_reader(int sock, Parser* hParser, PubHub* hPublish)
16 | {
17 | RawData* fans[MAX_FANS];
18 |
19 | while (1)
20 | {
21 | fd_set fds;
22 | FD_ZERO(&fds);
23 |
24 | FD_SET(sock, &fds);
25 |
26 | struct timeval to = { 5, 5 };
27 | int ret = select(sock+1, &fds, NULL, NULL, &to);
28 |
29 | if (ret == 0) {
30 |
31 | }
32 |
33 | if (ret < 0) {
34 | printf("select error\n");
35 | continue;
36 | }
37 |
38 | // read TCP data
39 | if (FD_ISSET(sock, &fds))
40 | {
41 | unsigned char buf[1024];
42 | int nr = recv(sock, buf, sizeof(buf), 0);
43 | if (nr <= 0) {
44 | printf("read tcp error %d\n", nr);
45 | break;
46 | }
47 | else
48 | {
49 | int nfan = ParserRunStream(hParser, nr, buf, &(fans[0]));
50 | if (nfan > 0) {
51 | PublishData(hPublish, nfan, fans);
52 | }
53 | }
54 | }
55 | }
56 |
57 | return 0;
58 | }
59 |
60 | void* TcpThreadProc(void* p)
61 | {
62 | TCPInfo* info = (TCPInfo*)p;
63 |
64 | while (1)
65 | {
66 | // open TCP
67 | int sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
68 | if (sock < 0) {
69 | printf("socket TCP failed\n");
70 | return 0;
71 | }
72 |
73 | struct sockaddr_in addr;
74 | memset(&addr, 0, sizeof(addr)); /* Zero out structure */
75 | addr.sin_family = AF_INET; /* Internet address family */
76 |
77 | addr.sin_addr.s_addr = inet_addr(info->lidar_ip);
78 | addr.sin_port = htons(info->lidar_port);
79 |
80 | int ret = connect(sock, (struct sockaddr *) &addr, sizeof(addr));
81 |
82 | if (ret != 0)
83 | {
84 | printf("connect (%s:%d) failed", info->lidar_ip, info->lidar_port);
85 | close(sock);
86 | //sleep(15);
87 | continue;
88 | }
89 | info->fd_tcp = sock;
90 | printf("connect (%s:%d) ok", info->lidar_ip, info->lidar_port);
91 |
92 | tcp_reader(sock, info->hParser, info->hPublish);
93 |
94 | printf("disconnect (%s:%d)\n", info->lidar_ip, info->lidar_port);
95 |
96 | info->fd_tcp = 0;
97 | close(sock);
98 | }
99 | return NULL;
100 | }
101 |
102 | #if 0
103 | void* TcpSrvProc(void* p)
104 | {
105 | TCPInfo* info = (TCPInfo*)p;
106 |
107 | // open TCP port
108 | int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
109 | sockaddr_in addr;
110 | addr.sin_family = AF_INET;
111 | addr.sin_port = htons(info->listen_port);
112 | addr.sin_addr.s_addr = htonl(INADDR_ANY);
113 |
114 | int rt = ::bind(info->fd_tcp, (struct sockaddr *)&addr, sizeof(addr));
115 |
116 | if (rt != 0)
117 | {
118 | printf("bind port %d failed\n", info->listen_port);
119 | return NULL;
120 | }
121 |
122 | printf("start tcp server %s:%d\n", lidar_ip, lidar_port);
123 |
124 |
125 | while (1) {
126 |
127 |
128 | }
129 |
130 | return NULL;
131 | }
132 |
133 |
134 | HReader StartTCPServer(unsigned short listen_port, HParser hParser, HPublish hPub)
135 | {
136 | signal(SIGPIPE, SIG_IGN);
137 |
138 | TCPInfo* info = new TCPInfo;
139 | info->hParser = hParser;
140 | info->hPublish = hPub;
141 | info->listen_port = listen_port;
142 |
143 | pthread_create(&info->thr, NULL, TcpSrvProc, info);
144 |
145 | return info;
146 | }
147 | #endif
148 |
149 | HReader StartTCPReader(const char* lidar_ip, unsigned short lidar_port, Parser *hParser, PubHub* hPub)
150 | {
151 | signal(SIGPIPE, SIG_IGN);
152 |
153 | TCPInfo* info = new TCPInfo;
154 | info->hParser = hParser;
155 | info->hPublish = hPub;
156 | info->lidar_port = lidar_port;
157 | strcpy(info->lidar_ip, lidar_ip);
158 | //strcpy(info->group_ip, group_ip);
159 | //printf("start udp %s:%d udp %d\n", lidar_ip, lidar_port, info->fd_tcp);
160 |
161 | pthread_create(&info->thr, NULL, TcpThreadProc, info);
162 |
163 | return info;
164 | }
165 |
166 | bool SendTcpCmd(HReader hr, int len, char* cmd)
167 | {
168 | TCPInfo* info = (TCPInfo*)hr;
169 | if (!info || info->fd_tcp <= 0)
170 | return false;
171 |
172 | return send(info->fd_tcp, cmd, len, 0) == len;
173 | }
174 |
175 |
176 | void StopTCPReader(HReader hr)
177 | {
178 | TCPInfo* info = (TCPInfo*)hr;
179 | //info->should_exit = true;
180 | //sleep(1);
181 | pthread_join(info->thr, NULL);
182 | delete info;
183 | }
184 |
--------------------------------------------------------------------------------
/bluesea-ros2/sdk/src/algorithmAPI.cpp:
--------------------------------------------------------------------------------
1 |
2 | #include "../include/algorithmAPI.h"
3 | #include
4 | #include
5 |
6 | bool checkWindowValid2(std::vector scan, size_t idx, size_t window, double max_distance,double angle_increment)
7 | {
8 |
9 | unsigned int num_neighbors = 0;
10 | const float r1 = scan.at(idx).distance; // 当前点云的距离数据
11 | float r2 = 0.; // 范围内点云的数据
12 | // Look around the current point until either the window is exceeded
13 | // or the number of neighbors was found.
14 | for (int y = -(int)window; y < (int)window + 1 && num_neighbors = static_cast(scan.size())||idx == (size_t)j)
18 | {
19 | continue;
20 | }
21 | r2 = scan.at(j).distance;
22 | if(r2==0)
23 | continue;
24 | // delete the re in the result
25 | const float d = sqrt(pow(r1, 2) + pow(r2, 2) -(2 * r1 * r2 * cosf(y * angle_increment)));
26 | if (d <= max_distance)
27 | {
28 | num_neighbors++;
29 | }
30 | }
31 | //printf("%s %d %d %d\n", __FUNCTION__, __LINE__,num_neighbors,window);
32 | // consider the window to be the number of neighbors we need
33 | if (num_neighbors < window)
34 | // if(num_neighbors == 0)//only the window is one
35 | {
36 | return false; // invalid
37 | }
38 | else
39 | {
40 | return true; // effective
41 | }
42 | }
43 |
44 | bool filter(std::vector &output_scan, double max_range, double min_range, double max_range_difference, unsigned int filter_window,double angle_increment)
45 | {
46 | std::vector valid_ranges;
47 | /*Check if range size is big enough to use7 the filter window */
48 | if (output_scan.size() <= filter_window + 1)
49 | {
50 | printf("Scan ranges size is too small: size = %ld", output_scan.size());
51 | return false;
52 | }
53 | size_t i = 0;
54 | size_t i_max = output_scan.size();
55 | valid_ranges.clear();
56 | while (i < i_max)
57 | {
58 | bool out_of_range = ((output_scan.at(i).distance > max_range) || (output_scan.at(i).distance < min_range));
59 | // ROS_INFO("%lf", min_range);
60 | valid_ranges.push_back(out_of_range);
61 | ++i;
62 | }
63 | i = 0;
64 | i_max = output_scan.size() - filter_window + 1;
65 | while (i < i_max)
66 | {
67 | bool window_valid = checkWindowValid2(output_scan, i, filter_window, max_range_difference,angle_increment);
68 |
69 | if (window_valid)
70 | {
71 | size_t j = i, j_max = i + filter_window;
72 | do
73 | {
74 | valid_ranges[j++] = true;
75 | } while (j < j_max);
76 | }
77 | ++i;
78 | }
79 | i = 0;
80 | i_max = valid_ranges.size();
81 | int errnum=0;
82 | while (i < i_max)
83 | {
84 | if (!valid_ranges[i])
85 | {
86 | output_scan[i].distance = std::numeric_limits::infinity();
87 | errnum++;
88 | }
89 | ++i;
90 | }
91 | //printf("%ld not valid num:%d\n",i,errnum);
92 | return true;
93 | }
94 | bool checkZeroDistance(std::vectordata,float error_scale)
95 | {
96 | int lengthZeroNum = 0;
97 | for(unsigned int i=0;i>= 1;
133 | }
134 | }
135 | return crc32;
136 | }
137 |
138 |
139 | void resample(RawData *dat, int NN)
140 | {
141 | int *index = new int[NN];
142 | double *errs = new double[NN];
143 |
144 | for (int i = 0; i < NN; i++)
145 | index[i] = -1;
146 |
147 | for (int i = 0; i < dat->N; i++)
148 | {
149 | if (dat->points[i].distance == 0)
150 | continue;
151 |
152 | int idx = round(double(i * NN) / dat->N);
153 | if (idx < NN)
154 | {
155 | double err = fabs(double(dat->span * i) / dat->N - double(dat->span * idx) / NN);
156 | if (index[idx] == -1 || err < errs[idx])
157 | {
158 | index[idx] = i;
159 | errs[idx] = err;
160 | }
161 | }
162 | }
163 |
164 | for (int i = 1; i < NN; i++)
165 | {
166 | if (index[i] != -1)
167 | {
168 | dat->points[i] = dat->points[index[i]];
169 | }
170 | else
171 | {
172 | dat->points[i].distance = 0;
173 | dat->points[i].confidence = 0;
174 | }
175 | dat->points[i].degree = dat->angle / 10.0 + (dat->span * i) / (10.0 * NN);
176 | }
177 |
178 | dat->N = NN;
179 |
180 | delete index;
181 | delete errs;
182 | }
--------------------------------------------------------------------------------
/README_CN.md:
--------------------------------------------------------------------------------
1 | # 蓝海光电ROS2驱动程序V2.6(bluesea2_ros2_driver)
2 |
3 | ## 概述
4 | ----------
5 | 蓝海光电ROS2驱动程序是专门用于连接本公司生产的lidar产品。该驱动程序可以在安装了 ROS2 环境的操作系统中运行,主要支持ubuntu系列操作系统(18.04LTS-最新)。经测试可以运行该ROS驱动程序的硬件平台包括:intel x86 主流 cpu 平台,部分 ARM64 硬件平台(如 英伟达、瑞芯微,树莓派等,可能需要更新cp210x驱动)。
6 |
7 | ## 注意事项
8 | 请保证路径中不带中文字符,否则会编译失败
9 |
10 | ## 获取并构建蓝海ROS驱动包
11 | 1.从Github获取蓝海ROS2驱动程序,并部署对应位置
12 |
13 | mkdir bluesea2 //创建一个文件夹,自定义即可
14 | cd bluesea2 //进入该文件夹
15 | git clone https://github.com/BlueSeaLidar/bluesea-ros2.git src //下载驱动包并且重命名为src
16 |
17 | 2.构建
18 |
19 | colcon build
20 | 3.更新当前ROS2包环境
21 |
22 | source ./install/setup.sh
23 |
24 |
25 | 4.使用ROS2 launch运行驱动
26 |
27 | sudo chmod 777 /dev/ttyUSB0 (非网络款) //这里的/dev/ttyUSB0指的是串口名称,如果是串口/虚拟串口款,需要赋权
28 |
29 | ros2 launch bluesea2 [launch file] //具体launch文件说明如下
30 |
31 | ## 驱动包launch配置文件说明
32 | 说明:[launch file]指的是src/launch文件夹下的配置文件,以功能类别区分
33 |
34 | - uart_lidar.launch: 串口连接方式的激光雷达
35 | - udp_lidar.launch: udp网络通讯的激光雷达
36 | - vpc_lidar.launch: 虚拟串口连接方式的激光雷达
37 | - dual_udp_lidar.launch: 多个udp网络通讯的激光雷达
38 | - template.launch: 全部参数定义模版
39 | - LDS-U50C-S(only).launch:老款雷达,仅支持数据通讯
40 | - LDS-U80C-S(only).launch:老款雷达,仅支持数据通讯
41 | -
42 | 主要参数配置说明:
43 |
44 | #ROS2#(框架必须的参数)
45 | #发布scan话题
46 | #发布cloud话题
47 | #标志坐标系的名称
48 | #DATA#(驱动自定义数据层面的限制参数)
49 | #最小点云距离(m)
50 | #最大点云距离(m)
51 | #帧起始角度是否从0开始(false 为180)
52 | #二维扫描数据(默认)
53 | #三维空间数据
54 | #三维空间数据 输出格式2
55 | #按帧输出
56 | #发布数据角度参数反置(angle_min,angle_max,angle_increment)
57 | #发布数据点云数据倒转(从最后一个点排到第一个点)
58 | #硬采样系数(前提需要雷达支持该指令)
59 | #软采样系数(前提需要点云大于软采样的最小点数)
60 | #角度过滤开关
61 | #最小可用角度
62 | [-3.14,3.14]#屏蔽该区间角度的数据
64 | #数据包的时间戳来源(默认0系统时间,1是雷达时间同步的时间)
65 | #多段屏蔽该区间角度的数据,mask往上+1
66 | #CUSTOM#(驱动自定义功能)
67 | #判断距离为0的点的比重 连续三圈
68 | #每圈距离为0的点占据90% 则报错
69 | #仅用于监听组播数据(需要上位机修改雷达的上传地址,并且固定上传,然后该驱动监听数据)
70 | #监听的组播ip
71 | #FITTER#(雷达不同角分辨率的参数不同,需定制)
72 | #滤波生效开关
73 | #滤波生效的最小距离
75 | #离异点判断的物理范围
76 | #判断离异点下标的范围
77 | #CONNECT#(驱动连接雷达的参数)
78 |
79 |
80 |
81 |
82 | #GET#(驱动发送给雷达的查询指令开关)
83 | #查询雷达SN号,-1不查询,>=0查询
84 | #SET#(驱动发送给雷达的设置指令开关)
85 | #设置角分辨率(不同型号雷达可支持的角分辨率不相同,具体查看该型号的说明书),-1不设置 0原始数据 1角度修正
87 | #设置去拖点,-1不设置 0关闭 1打开
88 | #设置滤波,-1不设置 0关闭 1打开
89 | #设置报警信息,-1不设置 0关闭 1打开
90 | #设置旋转方向(仅支持该指令的雷达使用),-1不设置 0关闭 1打开
91 | #NTP#
92 | # NTP 服务器地址
93 | #NTP 服务器端口
94 | #使能开关
95 | ## 驱动客户端功能说明
96 | 源码位于src/client.cpp
97 | 启停旋转:
98 |
99 | ros2 run bluesea2 bluesea2_client scan start
100 | 参数1 是话题 参数2是动作(start/stop)
101 | 切换防区:
102 |
103 | ros2 run bluesea2 bluesea2_client scan switchZone 0
104 | 参数1 是话题 参数2是动作(switchZone) 参数3是选择防区编号(0)
105 |
106 |
107 | 设置转速:
108 |
109 | ros2 run bluesea2 bluesea2_client scan rpm 600
110 | 参数1 是话题 参数2是动作(set rpm) 参数3是设置rpm的值(600)
111 |
112 | 打开/关闭心跳包检测:
113 |
114 | ros2 run bluesea2 bluesea2_client heart check 1
115 | 参数1是service name 参数2是动作(check) 参数3是是否打印(1/0)
116 |
117 |
118 | ## rosbag包操作说明
119 |
120 | ros2 topic list 获取话题列表,驱动默认的话题名称为 /lidar1/scan
121 | ros2 bag record /lidar1/scan 开始录制数据
122 |
123 | 录制好的文件以时间戳来命名,要停止录制,在当前终端CTRL+C
124 |
125 | ros2 bag play 数据包名称
126 |
127 | 在存放数据包的路径下查看录制的数据包,若提示failed connect master异常,则先ros master后在rosbag play
128 |
129 | ## 商务支持
130 |
131 | 具体使用问题请通过官网联系技术支持(https://pacecat.com/)
132 |
--------------------------------------------------------------------------------
/bluesea-ros2/sdk/include/usererror.h:
--------------------------------------------------------------------------------
1 | #ifndef _USERERROR_H
2 | #define _USERERROR_H
3 |
4 | #include
5 | #include