Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(hesai): set PTP lock offset on sensor configuration #239

Merged
merged 10 commits into from
Dec 3, 2024
Merged
8 changes: 8 additions & 0 deletions docs/parameters/vendors/hesai/common.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ While this is not found in the PTP standards, this influences how often the sens
Set this to `TSN` if your switch supports gPTP or the AutoSAR protocol, and `NON_TSN` if the switch does not.
In the latter case, the sensor will measure more often.

### `ptp_lock_threshold`

_Only applies to `OT128` and `QT128`_

The maximum difference between the sensor and PTP master that will still be considered `locked` by the sensor, in microseconds.
When this threshold is crossed, the sensor will report its synchronization state to be `tracking`.
Nebula's hardware monitor treats only the `locked` state as `OK`, `tracking` as `WARNING` and `frozen` and `free run` as `ERROR`.

## Scan Cutting and Field of View

Scan cutting influences the time stamps of points and the point cloud headers.
Expand Down
4 changes: 3 additions & 1 deletion nebula_common/include/nebula_common/hesai/hesai_common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ struct HesaiSensorConfiguration : public LidarConfigurationBase
uint8_t ptp_domain;
PtpTransportType ptp_transport_type;
PtpSwitchType ptp_switch_type;
uint8_t ptp_lock_threshold;
};
/// @brief Convert HesaiSensorConfiguration to string (Overloading the << operator)
/// @param os
Expand All @@ -71,7 +72,8 @@ inline std::ostream & operator<<(std::ostream & os, HesaiSensorConfiguration con
os << "PTP Profile: " << arg.ptp_profile << '\n';
os << "PTP Domain: " << std::to_string(arg.ptp_domain) << '\n';
os << "PTP Transport Type: " << arg.ptp_transport_type << '\n';
os << "PTP Switch Type: " << arg.ptp_switch_type;
os << "PTP Switch Type: " << arg.ptp_switch_type << '\n';
os << "PTP Lock Threshold: " << std::to_string(arg.ptp_lock_threshold);
return os;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ const uint8_t g_ptc_command_set_lidar_range = 0x22;
const uint8_t g_ptc_command_get_lidar_range = 0x23;
const uint8_t g_ptc_command_set_ptp_config = 0x24;
const uint8_t g_ptc_command_get_ptp_config = 0x26;
const uint8_t g_ptp_command_set_ptp_lock_offset = 0x39;
const uint8_t g_ptp_command_get_ptp_lock_offset = 0x3a;
const uint8_t g_ptc_command_reset = 0x25;
const uint8_t g_ptc_command_set_rotate_direction = 0x2a;
const uint8_t g_ptc_command_lidar_monitor = 0x27;
Expand Down Expand Up @@ -342,6 +344,11 @@ class HesaiHwInterface
/// @brief Getting data with PTC_COMMAND_GET_PTP_CONFIG
/// @return Resulting status
HesaiPtpConfig get_ptp_config();

Status set_ptp_lock_offset(uint8_t lock_offset);

uint8_t get_ptp_lock_offset();

/// @brief Sending command with PTC_COMMAND_RESET
/// @return Resulting status
Status send_reset();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "nebula_common/hesai/hesai_common.hpp"
#include "nebula_common/hesai/hesai_status.hpp"
#include "nebula_common/loggers/logger.hpp"
#include "nebula_common/nebula_common.hpp"
#include "nebula_common/nebula_status.hpp"
#include "nebula_hw_interfaces/nebula_hw_interfaces_hesai/hesai_cmd_response.hpp"
Expand Down Expand Up @@ -700,6 +701,24 @@
return hesai_ptp_config;
}

Status HesaiHwInterface::set_ptp_lock_offset(uint8_t lock_offset_us)

Check warning on line 704 in nebula_hw_interfaces/src/nebula_hesai_hw_interfaces/hesai_hw_interface.cpp

View check run for this annotation

Codecov / codecov/patch

nebula_hw_interfaces/src/nebula_hesai_hw_interfaces/hesai_hw_interface.cpp#L704

Added line #L704 was not covered by tests
{
std::vector<uint8_t> request_payload;
request_payload.emplace_back(lock_offset_us);

Check warning on line 707 in nebula_hw_interfaces/src/nebula_hesai_hw_interfaces/hesai_hw_interface.cpp

View check run for this annotation

Codecov / codecov/patch

nebula_hw_interfaces/src/nebula_hesai_hw_interfaces/hesai_hw_interface.cpp#L707

Added line #L707 was not covered by tests

auto response_or_err = send_receive(g_ptp_command_set_ptp_lock_offset, request_payload);
response_or_err.value_or_throw(pretty_print_ptc_error(response_or_err.error_or({})));
return Status::OK;

Check warning on line 711 in nebula_hw_interfaces/src/nebula_hesai_hw_interfaces/hesai_hw_interface.cpp

View check run for this annotation

Codecov / codecov/patch

nebula_hw_interfaces/src/nebula_hesai_hw_interfaces/hesai_hw_interface.cpp#L709-L711

Added lines #L709 - L711 were not covered by tests
}

uint8_t HesaiHwInterface::get_ptp_lock_offset()

Check warning on line 714 in nebula_hw_interfaces/src/nebula_hesai_hw_interfaces/hesai_hw_interface.cpp

View check run for this annotation

Codecov / codecov/patch

nebula_hw_interfaces/src/nebula_hesai_hw_interfaces/hesai_hw_interface.cpp#L714

Added line #L714 was not covered by tests
{
auto response_or_err = send_receive(g_ptp_command_get_ptp_lock_offset);

Check warning on line 716 in nebula_hw_interfaces/src/nebula_hesai_hw_interfaces/hesai_hw_interface.cpp

View check run for this annotation

Codecov / codecov/patch

nebula_hw_interfaces/src/nebula_hesai_hw_interfaces/hesai_hw_interface.cpp#L716

Added line #L716 was not covered by tests
auto response =
response_or_err.value_or_throw(pretty_print_ptc_error(response_or_err.error_or({})));
return check_size_and_parse<uint8_t>(response);

Check warning on line 719 in nebula_hw_interfaces/src/nebula_hesai_hw_interfaces/hesai_hw_interface.cpp

View check run for this annotation

Codecov / codecov/patch

nebula_hw_interfaces/src/nebula_hesai_hw_interfaces/hesai_hw_interface.cpp#L718-L719

Added lines #L718 - L719 were not covered by tests
}

Status HesaiHwInterface::send_reset()
{
auto response_or_err = send_receive(g_ptc_command_reset);
Expand Down Expand Up @@ -1069,6 +1088,19 @@
t.join();
logger_->debug("Thread finished");

if (
sensor_configuration_->sensor_model == SensorModel::HESAI_PANDAR128_E4X ||

Check warning on line 1092 in nebula_hw_interfaces/src/nebula_hesai_hw_interfaces/hesai_hw_interface.cpp

View check run for this annotation

Codecov / codecov/patch

nebula_hw_interfaces/src/nebula_hesai_hw_interfaces/hesai_hw_interface.cpp#L1092

Added line #L1092 was not covered by tests
sensor_configuration_->sensor_model == SensorModel::HESAI_PANDARQT128) {
uint8_t sensor_ptp_lock_threshold = get_ptp_lock_offset();

Check warning on line 1094 in nebula_hw_interfaces/src/nebula_hesai_hw_interfaces/hesai_hw_interface.cpp

View check run for this annotation

Codecov / codecov/patch

nebula_hw_interfaces/src/nebula_hesai_hw_interfaces/hesai_hw_interface.cpp#L1094

Added line #L1094 was not covered by tests
if (sensor_ptp_lock_threshold != sensor_configuration_->ptp_lock_threshold) {
NEBULA_LOG_STREAM(

Check warning on line 1096 in nebula_hw_interfaces/src/nebula_hesai_hw_interfaces/hesai_hw_interface.cpp

View check run for this annotation

Codecov / codecov/patch

nebula_hw_interfaces/src/nebula_hesai_hw_interfaces/hesai_hw_interface.cpp#L1096

Added line #L1096 was not covered by tests
logger_->info, "changing sensor PTP lock offset from "
<< static_cast<int>(sensor_ptp_lock_threshold) << " to "
<< static_cast<int>(sensor_configuration_->ptp_lock_threshold));
set_ptp_lock_offset(sensor_configuration_->ptp_lock_threshold);

Check warning on line 1100 in nebula_hw_interfaces/src/nebula_hesai_hw_interfaces/hesai_hw_interface.cpp

View check run for this annotation

Codecov / codecov/patch

nebula_hw_interfaces/src/nebula_hesai_hw_interfaces/hesai_hw_interface.cpp#L1100

Added line #L1100 was not covered by tests
}
}

std::this_thread::sleep_for(wait_time);
} else { // AT128 only supports PTP setup via HTTP
logger_->info("Trying to set SyncAngle via HTTP");
Expand Down
1 change: 1 addition & 0 deletions nebula_ros/config/lidar/hesai/Pandar128E4X.param.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@
ptp_domain: 0
ptp_transport_type: L2
ptp_switch_type: TSN
ptp_lock_threshold: 100
retry_hw: true
dual_return_distance_threshold: 0.1
1 change: 1 addition & 0 deletions nebula_ros/config/lidar/hesai/Pandar40P.param.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@
ptp_domain: 0
ptp_transport_type: UDP
ptp_switch_type: TSN
ptp_lock_threshold: 100
retry_hw: true
dual_return_distance_threshold: 0.1
1 change: 1 addition & 0 deletions nebula_ros/config/lidar/hesai/Pandar64.param.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@
ptp_domain: 0
ptp_transport_type: UDP
ptp_switch_type: TSN
ptp_lock_threshold: 100
retry_hw: true
dual_return_distance_threshold: 0.1
1 change: 1 addition & 0 deletions nebula_ros/config/lidar/hesai/PandarAT128.param.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,6 @@
ptp_domain: 0
ptp_transport_type: UDP
ptp_switch_type: TSN
ptp_lock_threshold: 100
retry_hw: true
dual_return_distance_threshold: 0.1
1 change: 1 addition & 0 deletions nebula_ros/config/lidar/hesai/PandarQT128.param.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@
ptp_domain: 0
ptp_transport_type: UDP
ptp_switch_type: TSN
ptp_lock_threshold: 100
retry_hw: true
dual_return_distance_threshold: 0.1
1 change: 1 addition & 0 deletions nebula_ros/config/lidar/hesai/PandarQT64.param.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@
ptp_domain: 0
ptp_transport_type: UDP
ptp_switch_type: TSN
ptp_lock_threshold: 100
retry_hw: true
dual_return_distance_threshold: 0.1
1 change: 1 addition & 0 deletions nebula_ros/config/lidar/hesai/PandarXT32.param.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@
ptp_domain: 0
ptp_transport_type: UDP
ptp_switch_type: TSN
ptp_lock_threshold: 100
retry_hw: true
dual_return_distance_threshold: 0.1
1 change: 1 addition & 0 deletions nebula_ros/config/lidar/hesai/PandarXT32M.param.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@
ptp_domain: 0
ptp_transport_type: UDP
ptp_switch_type: TSN
ptp_lock_threshold: 100
retry_hw: true
dual_return_distance_threshold: 0.1
4 changes: 4 additions & 0 deletions nebula_ros/schema/Pandar128E4X.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@
"ptp_switch_type": {
"$ref": "sub/lidar_hesai.json#/definitions/ptp_switch_type"
},
"ptp_lock_threshold": {
"$ref": "sub/lidar_hesai.json#/definitions/ptp_lock_threshold"
},
"retry_hw": {
"$ref": "sub/hardware.json#/definitions/retry_hw"
},
Expand Down Expand Up @@ -130,6 +133,7 @@
"ptp_domain",
"ptp_transport_type",
"ptp_switch_type",
"ptp_lock_threshold",
"retry_hw",
"dual_return_distance_threshold"
],
Expand Down
4 changes: 4 additions & 0 deletions nebula_ros/schema/Pandar40P.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@
"ptp_switch_type": {
"$ref": "sub/lidar_hesai.json#/definitions/ptp_switch_type"
},
"ptp_lock_threshold": {
"$ref": "sub/lidar_hesai.json#/definitions/ptp_lock_threshold"
},
"retry_hw": {
"$ref": "sub/hardware.json#/definitions/retry_hw"
},
Expand Down Expand Up @@ -121,6 +124,7 @@
"ptp_domain",
"ptp_transport_type",
"ptp_switch_type",
"ptp_lock_threshold",
"retry_hw",
"dual_return_distance_threshold"
],
Expand Down
4 changes: 4 additions & 0 deletions nebula_ros/schema/Pandar64.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@
"ptp_switch_type": {
"$ref": "sub/lidar_hesai.json#/definitions/ptp_switch_type"
},
"ptp_lock_threshold": {
"$ref": "sub/lidar_hesai.json#/definitions/ptp_lock_threshold"
},
"retry_hw": {
"$ref": "sub/hardware.json#/definitions/retry_hw"
},
Expand Down Expand Up @@ -121,6 +124,7 @@
"ptp_domain",
"ptp_transport_type",
"ptp_switch_type",
"ptp_lock_threshold",
"retry_hw",
"dual_return_distance_threshold"
],
Expand Down
4 changes: 4 additions & 0 deletions nebula_ros/schema/PandarAT128.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@
"ptp_switch_type": {
"$ref": "sub/lidar_hesai.json#/definitions/ptp_switch_type"
},
"ptp_lock_threshold": {
"$ref": "sub/lidar_hesai.json#/definitions/ptp_lock_threshold"
},
"retry_hw": {
"$ref": "sub/hardware.json#/definitions/retry_hw"
},
Expand Down Expand Up @@ -142,6 +145,7 @@
"ptp_domain",
"ptp_transport_type",
"ptp_switch_type",
"ptp_lock_threshold",
"retry_hw",
"dual_return_distance_threshold"
],
Expand Down
4 changes: 4 additions & 0 deletions nebula_ros/schema/PandarQT128.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@
"ptp_switch_type": {
"$ref": "sub/lidar_hesai.json#/definitions/ptp_switch_type"
},
"ptp_lock_threshold": {
"$ref": "sub/lidar_hesai.json#/definitions/ptp_lock_threshold"
},
"retry_hw": {
"$ref": "sub/hardware.json#/definitions/retry_hw"
},
Expand Down Expand Up @@ -124,6 +127,7 @@
"ptp_domain",
"ptp_transport_type",
"ptp_switch_type",
"ptp_lock_threshold",
"retry_hw",
"dual_return_distance_threshold"
],
Expand Down
4 changes: 4 additions & 0 deletions nebula_ros/schema/PandarQT64.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@
"ptp_switch_type": {
"$ref": "sub/lidar_hesai.json#/definitions/ptp_switch_type"
},
"ptp_lock_threshold": {
"$ref": "sub/lidar_hesai.json#/definitions/ptp_lock_threshold"
},
"retry_hw": {
"$ref": "sub/hardware.json#/definitions/retry_hw"
},
Expand Down Expand Up @@ -121,6 +124,7 @@
"ptp_domain",
"ptp_transport_type",
"ptp_switch_type",
"ptp_lock_threshold",
"retry_hw",
"dual_return_distance_threshold"
],
Expand Down
4 changes: 4 additions & 0 deletions nebula_ros/schema/PandarXT32.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@
"ptp_switch_type": {
"$ref": "sub/lidar_hesai.json#/definitions/ptp_switch_type"
},
"ptp_lock_threshold": {
"$ref": "sub/lidar_hesai.json#/definitions/ptp_lock_threshold"
},
"retry_hw": {
"$ref": "sub/hardware.json#/definitions/retry_hw"
},
Expand Down Expand Up @@ -124,6 +127,7 @@
"ptp_domain",
"ptp_transport_type",
"ptp_switch_type",
"ptp_lock_threshold",
"retry_hw",
"dual_return_distance_threshold"
],
Expand Down
4 changes: 4 additions & 0 deletions nebula_ros/schema/PandarXT32M.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@
"ptp_switch_type": {
"$ref": "sub/lidar_hesai.json#/definitions/ptp_switch_type"
},
"ptp_lock_threshold": {
"$ref": "sub/lidar_hesai.json#/definitions/ptp_lock_threshold"
},
"retry_hw": {
"$ref": "sub/hardware.json#/definitions/retry_hw"
},
Expand Down Expand Up @@ -124,6 +127,7 @@
"ptp_domain",
"ptp_transport_type",
"ptp_switch_type",
"ptp_lock_threshold",
"retry_hw",
"dual_return_distance_threshold"
],
Expand Down
7 changes: 7 additions & 0 deletions nebula_ros/schema/sub/lidar_hesai.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,13 @@
],
"description": "For automotive profile,'TSN' or 'NON_TSN'."
},
"ptp_lock_threshold": {
"type": "integer",
"default": "100",
"minimum": 1,
"maximum": 100,
"description": "The maximum sensor clock offset in microseconds from the master clock which will still be treated as being locked."
},
"sync_angle": {
"type": "integer",
"minimum": 0,
Expand Down
21 changes: 13 additions & 8 deletions nebula_ros/src/hesai/hesai_ros_wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,32 +174,37 @@
config.calibration_path =
declare_parameter<std::string>(calibration_parameter_name, param_read_write());

auto _ptp_profile = declare_parameter<std::string>("ptp_profile", param_read_only());
config.ptp_profile = drivers::ptp_profile_from_string(_ptp_profile);
auto ptp_profile = declare_parameter<std::string>("ptp_profile", param_read_only());
config.ptp_profile = drivers::ptp_profile_from_string(ptp_profile);

Check warning on line 178 in nebula_ros/src/hesai/hesai_ros_wrapper.cpp

View check run for this annotation

Codecov / codecov/patch

nebula_ros/src/hesai/hesai_ros_wrapper.cpp#L177-L178

Added lines #L177 - L178 were not covered by tests

auto _ptp_transport = declare_parameter<std::string>("ptp_transport_type", param_read_only());
config.ptp_transport_type = drivers::ptp_transport_type_from_string(_ptp_transport);
auto ptp_transport = declare_parameter<std::string>("ptp_transport_type", param_read_only());
config.ptp_transport_type = drivers::ptp_transport_type_from_string(ptp_transport);

Check warning on line 181 in nebula_ros/src/hesai/hesai_ros_wrapper.cpp

View check run for this annotation

Codecov / codecov/patch

nebula_ros/src/hesai/hesai_ros_wrapper.cpp#L180-L181

Added lines #L180 - L181 were not covered by tests

if (
config.ptp_transport_type != drivers::PtpTransportType::L2 &&
config.ptp_profile != drivers::PtpProfile::IEEE_1588v2 &&
config.ptp_profile != drivers::PtpProfile::UNKNOWN_PROFILE) {
RCLCPP_WARN_STREAM(
get_logger(), "PTP transport was set to '" << _ptp_transport << "' but PTP profile '"
<< _ptp_profile
get_logger(), "PTP transport was set to '" << ptp_transport << "' but PTP profile '"
<< ptp_profile
<< "' only supports 'L2'. Setting it to 'L2'.");
config.ptp_transport_type = drivers::PtpTransportType::L2;
set_parameter(rclcpp::Parameter("ptp_transport_type", "L2"));
}

auto _ptp_switch = declare_parameter<std::string>("ptp_switch_type", param_read_only());
config.ptp_switch_type = drivers::ptp_switch_type_from_string(_ptp_switch);
auto ptp_switch = declare_parameter<std::string>("ptp_switch_type", param_read_only());
config.ptp_switch_type = drivers::ptp_switch_type_from_string(ptp_switch);

Check warning on line 196 in nebula_ros/src/hesai/hesai_ros_wrapper.cpp

View check run for this annotation

Codecov / codecov/patch

nebula_ros/src/hesai/hesai_ros_wrapper.cpp#L195-L196

Added lines #L195 - L196 were not covered by tests

{
rcl_interfaces::msg::ParameterDescriptor descriptor = param_read_only();
descriptor.integer_range = int_range(0, 127, 1);
config.ptp_domain = declare_parameter<uint8_t>("ptp_domain", descriptor);
}
{
rcl_interfaces::msg::ParameterDescriptor descriptor = param_read_only();
descriptor.integer_range = int_range(1, 100, 1);
config.ptp_lock_threshold = declare_parameter<uint8_t>("ptp_lock_threshold", descriptor);
}

Check warning on line 207 in nebula_ros/src/hesai/hesai_ros_wrapper.cpp

View check run for this annotation

Codecov / codecov/patch

nebula_ros/src/hesai/hesai_ros_wrapper.cpp#L204-L207

Added lines #L204 - L207 were not covered by tests

auto new_cfg_ptr = std::make_shared<const nebula::drivers::HesaiSensorConfiguration>(config);
return validate_and_set_config(new_cfg_ptr);
Expand Down
Loading