Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/filters.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ The required resolution of the mask is sensor-dependent:
| PandarXT32 | 2000 x 32 |
| PandarXT32M | 2000 x 32 |
| PandarAT128 | 1200 x 128 |
| AT128P | 1200 x 128 |
| PandarQT64 | 600 x 64 |
| PandarQT128 | 900 x 128 |
| Pandar128E4X | 3600 x 128 |
Expand Down
1 change: 1 addition & 0 deletions docs/parameters/vendors/hesai/at128p.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{ json_to_markdown("src/nebula_hesai/nebula_hesai/schema/AT128P.schema.json") }}
1 change: 1 addition & 0 deletions docs/parameters/vendors/hesai/ftx140.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{ json_to_markdown("src/nebula_hesai/nebula_hesai/schema/FTX140.schema.json") }}
4 changes: 4 additions & 0 deletions docs/supported_sensors.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,14 @@ The `sensor_model` parameter below decides which sensor driver is launched.
| Pandar QT64 | PandarQT64 | PandarQT64.param.yaml | ✅ |
| Pandar QT128 | PandarQT128 | PandarQT128.param.yaml | ✅ |
| Pandar AT128 | PandarAT128 | PandarAT128.param.yaml | ✅\* |
| AT128P | AT128P | AT128P.param.yaml | ⚠️ |
| FTX140 | FTX140 | FTX140.param.yaml | ⚠️\*\* |
| Pandar OT128 | Pandar128E4X | Pandar128E4X.param.yaml | ✅ |

\*: AT128 needs software version 3.50.8 or newer for the `scan_angle` setting to work correctly.

\*\*: For the FTX140, only single return modes (`First`, `Last`, `Strongest`) are supported, and `setup_sensor` only sets the return mode, the destination and the PTP config (automotive profile). Points are output in the coordinate frame of the Hesai SDK.

## Velodyne LiDARs

| Model | `sensor_model` | Configuration file | Test status |
Expand Down
2 changes: 2 additions & 0 deletions src/nebula/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ if(BUILD_TESTING)
PandarQT128
Pandar128E4X
PandarAT128
AT128P
FTX140
PandarXT16
PandarXT32
PandarXT32M
Expand Down
2 changes: 2 additions & 0 deletions src/nebula/launch/nebula_launch.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
"Pandar64",
"Pandar128E4X",
"PandarAT128",
"AT128P",
"FTX140",
"PandarQT64",
"PandarQT128",
"PandarXT16",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,8 @@ enum class SensorModel : uint8_t {
HESAI_PANDARXT32,
HESAI_PANDARXT32M,
HESAI_PANDARAT128,
HESAI_AT128P,
HESAI_FTX140,
HESAI_PANDAR128_E3X,
HESAI_PANDAR128_E4X,
VELODYNE_VLS128,
Expand Down Expand Up @@ -251,6 +253,12 @@ inline std::ostream & operator<<(std::ostream & os, nebula::drivers::SensorModel
case SensorModel::HESAI_PANDARAT128:
os << "PandarAT128";
break;
case SensorModel::HESAI_AT128P:
os << "AT128P";
break;
case SensorModel::HESAI_FTX140:
os << "FTX140";
break;
case SensorModel::HESAI_PANDAR128_E3X:
os << "Pandar128_E3X";
break;
Expand Down Expand Up @@ -406,6 +414,8 @@ inline SensorModel sensor_model_from_string(const std::string & sensor_model)
if (sensor_model == "PandarXT32") return SensorModel::HESAI_PANDARXT32;
if (sensor_model == "PandarXT32M") return SensorModel::HESAI_PANDARXT32M;
if (sensor_model == "PandarAT128") return SensorModel::HESAI_PANDARAT128;
if (sensor_model == "AT128P") return SensorModel::HESAI_AT128P;
if (sensor_model == "FTX140") return SensorModel::HESAI_FTX140;
if (sensor_model == "PandarQT64") return SensorModel::HESAI_PANDARQT64;
if (sensor_model == "PandarQT128") return SensorModel::HESAI_PANDARQT128;
if (sensor_model == "Pandar128E4X") return SensorModel::HESAI_PANDAR128_E4X;
Expand Down Expand Up @@ -445,6 +455,10 @@ inline std::string sensor_model_to_string(const SensorModel & sensor_model)
return "PandarXT32M";
case SensorModel::HESAI_PANDARAT128:
return "PandarAT128";
case SensorModel::HESAI_AT128P:
return "AT128P";
case SensorModel::HESAI_FTX140:
return "FTX140";
case SensorModel::HESAI_PANDARQT64:
return "PandarQT64";
case SensorModel::HESAI_PANDARQT128:
Expand Down
15 changes: 15 additions & 0 deletions src/nebula_hesai/nebula_hesai/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,21 @@ if(BUILD_TESTING)
-D_SRC_CALIBRATION_DIR_PATH="${CMAKE_CURRENT_SOURCE_DIR}/../nebula_hesai_decoders/calibration/"
)

# AT128P sensor definition test
ament_add_gtest(test_hesai_at128p tests/test_hesai_at128p.cpp)
target_link_libraries(test_hesai_at128p
nebula_hesai_decoders::nebula_hesai_decoders)

# Fault message handling test
ament_add_gtest(test_hesai_fault_message tests/test_hesai_fault_message.cpp)
target_link_libraries(test_hesai_fault_message
nebula_hesai_decoders::nebula_hesai_decoders)

# FTX140 calibration and decoder test
ament_add_gtest(test_hesai_ftx140 tests/test_hesai_ftx140.cpp)
target_link_libraries(test_hesai_ftx140
nebula_hesai_decoders::nebula_hesai_decoders)

# Functional safety test
ament_add_gtest(test_hesai_functional_safety
tests/test_hesai_functional_safety.cpp)
Expand Down
42 changes: 42 additions & 0 deletions src/nebula_hesai/nebula_hesai/config/AT128P.param.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**:
ros__parameters:
host_ip: 192.168.1.10
sensor_ip: 192.168.1.201
multicast_ip: ""
data_port: 2368
gnss_port: 10110
udp_socket_receive_buffer_size_bytes: 5400000
packet_mtu_size: 1500
launch_hw: true
setup_sensor: true
udp_only: false
frame_id: hesai
diag_span: 1000
correction_file: $(find-pkg-share nebula_hesai_decoders)/calibration/$(var sensor_model).dat
min_range: 0.3
max_range: 300.0
cloud_min_angle: 30
cloud_max_angle: 150
sync_angle: 30
cut_angle: 150.0
sensor_model: AT128P
calibration_download_enabled: true
rotation_speed: 200
return_mode: Dual
ptp_profile: automotive
ptp_domain: 0
ptp_transport_type: L2
ptp_switch_type: TSN
ptp_lock_threshold: 100
retry_hw: true
dual_return_distance_threshold: 0.1
diagnostics:
pointcloud_publish_rate:
frequency_ok:
min_hz: 9.5
max_hz: 10.5
frequency_warn:
min_hz: 9.0
max_hz: 11.0
packet_loss:
error_threshold: 10
42 changes: 42 additions & 0 deletions src/nebula_hesai/nebula_hesai/config/FTX140.param.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**:
ros__parameters:
host_ip: 192.168.1.10
sensor_ip: 192.168.1.201
multicast_ip: ""
data_port: 2368
gnss_port: 10110
udp_socket_receive_buffer_size_bytes: 5400000
packet_mtu_size: 1500
launch_hw: true
setup_sensor: false
udp_only: false
frame_id: hesai
diag_span: 1000
correction_file: $(find-pkg-share nebula_hesai_decoders)/calibration/$(var sensor_model).dat
min_range: 0.3
max_range: 300.0
cloud_min_angle: 0
cloud_max_angle: 360
sync_angle: 0
cut_angle: 0.0
sensor_model: FTX140
calibration_download_enabled: true
rotation_speed: 600
return_mode: First
ptp_profile: automotive
ptp_domain: 0
ptp_transport_type: L2
ptp_switch_type: TSN
ptp_lock_threshold: 100
retry_hw: true
dual_return_distance_threshold: 0.1
diagnostics:
pointcloud_publish_rate:
frequency_ok:
min_hz: 9.5
max_hz: 10.5
frequency_warn:
min_hz: 9.0
max_hz: 11.0
packet_loss:
error_threshold: 10
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ HesaiRosOfflineExtractBag::HesaiRosOfflineExtractBag(
sensor_cfg_ptr_ = std::make_shared<drivers::HesaiSensorConfiguration>(sensor_configuration);

RCLCPP_INFO_STREAM(this->get_logger(), this->get_name() << ". Driver ");
if (sensor_configuration.sensor_model == drivers::SensorModel::HESAI_PANDARAT128) {
if (
sensor_configuration.sensor_model == drivers::SensorModel::HESAI_PANDARAT128 ||
sensor_configuration.sensor_model == drivers::SensorModel::HESAI_AT128P) {
correction_cfg_ptr_ = std::make_shared<drivers::HesaiCorrection>(correction_configuration);
wrapper_status_ = initialize_driver(
std::const_pointer_cast<drivers::SensorConfigurationBase>(sensor_cfg_ptr_),
Expand Down Expand Up @@ -131,7 +133,9 @@ Status HesaiRosOfflineExtractBag::get_parameters(

calibration_configuration.calibration_file =
this->declare_parameter<std::string>("calibration_file", "", param_read_only());
if (sensor_configuration.sensor_model == drivers::SensorModel::HESAI_PANDARAT128) {
if (
sensor_configuration.sensor_model == drivers::SensorModel::HESAI_PANDARAT128 ||
sensor_configuration.sensor_model == drivers::SensorModel::HESAI_AT128P) {
correction_file_path_ =
this->declare_parameter<std::string>("correction_file", "", param_read_only());
}
Expand Down Expand Up @@ -172,7 +176,9 @@ Status HesaiRosOfflineExtractBag::get_parameters(
return cal_status;
}
}
if (sensor_configuration.sensor_model == drivers::SensorModel::HESAI_PANDARAT128) {
if (
sensor_configuration.sensor_model == drivers::SensorModel::HESAI_PANDARAT128 ||
sensor_configuration.sensor_model == drivers::SensorModel::HESAI_AT128P) {
if (correction_file_path_.empty()) {
return Status::INVALID_CALIBRATION_FILE;
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ HesaiRosOfflineExtractSample::HesaiRosOfflineExtractSample(
sensor_cfg_ptr_ = std::make_shared<drivers::HesaiSensorConfiguration>(sensor_configuration);

RCLCPP_INFO_STREAM(this->get_logger(), this->get_name() << ". Driver ");
if (sensor_configuration.sensor_model == drivers::SensorModel::HESAI_PANDARAT128) {
if (
sensor_configuration.sensor_model == drivers::SensorModel::HESAI_PANDARAT128 ||
sensor_configuration.sensor_model == drivers::SensorModel::HESAI_AT128P) {
correction_cfg_ptr_ = std::make_shared<drivers::HesaiCorrection>(correction_configuration);
wrapper_status_ = initialize_driver(
std::const_pointer_cast<drivers::SensorConfigurationBase>(sensor_cfg_ptr_),
Expand Down Expand Up @@ -114,7 +116,9 @@ Status HesaiRosOfflineExtractSample::get_parameters(

calibration_configuration.calibration_file =
declare_parameter<std::string>("calibration_file", "", param_read_only());
if (sensor_configuration.sensor_model == drivers::SensorModel::HESAI_PANDARAT128) {
if (
sensor_configuration.sensor_model == drivers::SensorModel::HESAI_PANDARAT128 ||
sensor_configuration.sensor_model == drivers::SensorModel::HESAI_AT128P) {
correction_file_path_ =
declare_parameter<std::string>("correction_file", "", param_read_only());
}
Expand Down Expand Up @@ -146,7 +150,9 @@ Status HesaiRosOfflineExtractSample::get_parameters(
return cal_status;
}
}
if (sensor_configuration.sensor_model == drivers::SensorModel::HESAI_PANDARAT128) {
if (
sensor_configuration.sensor_model == drivers::SensorModel::HESAI_PANDARAT128 ||
sensor_configuration.sensor_model == drivers::SensorModel::HESAI_AT128P) {
if (correction_file_path_.empty()) {
return Status::INVALID_CALIBRATION_FILE;
} else {
Expand Down
2 changes: 2 additions & 0 deletions src/nebula_hesai/nebula_hesai/launch/hesai_launch_all_hw.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
<choice value="Pandar64" />
<choice value="Pandar128E4X" />
<choice value="PandarAT128" />
<choice value="AT128P" />
<choice value="FTX140" />
<choice value="PandarQT64" />
<choice value="PandarQT128" />
<choice value="PandarXT16" />
Expand Down
2 changes: 1 addition & 1 deletion src/nebula_hesai/nebula_hesai/launch/hesai_offline.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
<launch>
<arg name="sensor_model" description="Pandar64|Pandar40P|PandarXT16|PandarXT32|PandarXT32M|PandarAT128|PandarQT64"/>
<arg name="sensor_model" description="Pandar64|Pandar40P|PandarXT16|PandarXT32|PandarXT32M|PandarAT128|AT128P|FTX140|PandarQT64"/>
<arg name="return_mode" default="Dual" description="See readme for supported return modes"/>
<arg name="frame_id" default="hesai"/>
<arg name="scan_phase" default="0.0" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<arg name="forward_packets_to_rosbag" default="false" description="Whether to copy the input packets to the output RosBag"/>

<!-- sensor related configuration -->
<arg name="sensor_model" description="Pandar64|Pandar40P|PandarXT16|PandarXT32|PandarXT32M|PandarAT128|PandarQT64|Pandar128E4X"/>
<arg name="sensor_model" description="Pandar64|Pandar40P|PandarXT16|PandarXT32|PandarXT32M|PandarAT128|AT128P|FTX140|PandarQT64|Pandar128E4X"/>
<arg name="lidar_parameter_file" default="$(find-pkg-share nebula_hesai)/config/$(var sensor_model).param.yaml" description="Path: LiDAR configuration yaml"/>

<!-- output sample number configuration -->
Expand Down
Loading
Loading