Skip to content

Commit ea8b2cc

Browse files
committed
feat: add connect timeout parameter and watchdog for lidar connection
1 parent a8a6df0 commit ea8b2cc

3 files changed

Lines changed: 48 additions & 0 deletions

File tree

launch/mid360_launch.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ def _launch_setup(context, *args, **kwargs):
205205
name=node_name,
206206
namespace=ns_arg,
207207
output='screen',
208+
respawn=True,
208209
parameters=[
209210
{'xfer_format': int(LaunchConfiguration('xfer_format').perform(context))},
210211
{'multi_topic': int(LaunchConfiguration('multi_topic').perform(context))},
@@ -214,6 +215,7 @@ def _launch_setup(context, *args, **kwargs):
214215
{'frame_id': frame_id},
215216
{'user_config_path': config_path},
216217
{'cmdline_input_bd_code': ''},
218+
{'connect_timeout_s': float(LaunchConfiguration('connect_timeout_s').perform(context))},
217219
],
218220
remappings=[
219221
(f'livox/lidar_{ip_suffix}', points_dst),
@@ -282,6 +284,15 @@ def generate_launch_description():
282284
default_value='livox_lidar',
283285
description='ROS node name for the driver instance',
284286
),
287+
DeclareLaunchArgument(
288+
'connect_timeout_s',
289+
default_value='5.0',
290+
description=(
291+
'Seconds to wait for any lidar to respond after SDK init. '
292+
'If no callback is received within this time the node shuts '
293+
'down (and is respawned by the launch system).'
294+
),
295+
),
285296

286297
# --- namespace / connectivity ----------------------------------------
287298
DeclareLaunchArgument(

src/driver_node.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ class DriverNode final : public rclcpp::Node {
7070
std::shared_ptr<std::thread> imudata_poll_thread_;
7171
std::shared_future<void> future_;
7272
std::promise<void> exit_signal_;
73+
/** One-shot timer: fires if no lidar connects within connect_timeout_s. */
74+
rclcpp::TimerBase::SharedPtr watchdog_timer_;
7375
};
7476
#endif
7577

src/livox_ros_driver2.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ DriverNode::DriverNode(const rclcpp::NodeOptions & node_options)
137137
this->declare_parameter("user_config_path", "path_default");
138138
this->declare_parameter("cmdline_input_bd_code", "000000000000001");
139139
this->declare_parameter("lvx_file_path", "/home/livox/livox_test.lvx");
140+
this->declare_parameter("connect_timeout_s", 10.0);
140141

141142
this->get_parameter("xfer_format", xfer_format);
142143
this->get_parameter("multi_topic", multi_topic);
@@ -174,6 +175,40 @@ DriverNode::DriverNode(const rclcpp::NodeOptions & node_options)
174175

175176
if ((read_lidar->InitLdsLidar(user_config_path))) {
176177
DRIVER_INFO(*this, "Init lds lidar success!");
178+
179+
// Watchdog: if no lidar contacts us within connect_timeout_s, the
180+
// hardware is unreachable. Shut down so the node can be respawned.
181+
double connect_timeout_s;
182+
this->get_parameter("connect_timeout_s", connect_timeout_s);
183+
Lds* lds = lddc_ptr_->lds_;
184+
watchdog_timer_ = this->create_wall_timer(
185+
std::chrono::duration<double>(connect_timeout_s),
186+
[this, lds, connect_timeout_s]() {
187+
watchdog_timer_->cancel(); // one-shot
188+
bool any_connected = false;
189+
for (uint32_t i = 0; i < kMaxSourceLidar; i++) {
190+
if (lds->lidars_[i].lidar_type != 0 &&
191+
lds->lidars_[i].connect_state.load(std::memory_order_acquire)
192+
!= kConnectStateOff) {
193+
any_connected = true;
194+
break;
195+
}
196+
}
197+
if (!any_connected) {
198+
RCLCPP_FATAL(this->get_logger(),
199+
"No lidar connected within %.1f s — hardware unreachable or "
200+
"not responding on the network. Shutting down for respawn.",
201+
connect_timeout_s);
202+
// Escalating shutdown in a detached thread so the timer callback
203+
// returns immediately: SIGTERM first (gives rclcpp a chance to
204+
// clean up), then SIGKILL after 5 s to guarantee the process exits.
205+
std::thread([]() {
206+
raise(SIGTERM);
207+
std::this_thread::sleep_for(std::chrono::seconds(5));
208+
raise(SIGKILL);
209+
}).detach();
210+
}
211+
});
177212
} else {
178213
DRIVER_ERROR(*this, "Init lds lidar fail!");
179214
}

0 commit comments

Comments
 (0)