Skip to content

Commit c3cb812

Browse files
authored
Merge pull request #439 from stereolabs/fix_od_service_sigsegv
Fix Object Detection service crash
2 parents fa5ac05 + fa0d236 commit c3cb812

6 files changed

Lines changed: 131 additions & 67 deletions

File tree

zed_components/src/tools/src/sl_win_avg.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ double WinAvg::setNewSize(size_t win_size)
3636
mSumVals -= val;
3737
}
3838

39-
return mSumVals / mVals.size();
39+
return mVals.empty() ? 0.0 : mSumVals / mVals.size();
4040
}
4141

4242
double WinAvg::addValue(double val)
@@ -63,9 +63,11 @@ double WinAvg::getAvg()
6363
{
6464
std::lock_guard<std::mutex> guard(mQueueMux);
6565

66-
double avg = mSumVals / mVals.size();
66+
if (mVals.empty()) {
67+
return 0.0;
68+
}
6769

68-
return avg;
70+
return mSumVals / mVals.size();
6971
}
7072

7173
}

zed_components/src/zed_camera/include/zed_camera_component.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ class ZedCamera : public rclcpp::Node
8989

9090
bool startCamera();
9191
bool startPosTracking();
92+
bool startPosTrackingLocked(); // caller must hold mPtMutex
9293
bool saveAreaMemoryFile(const std::string & filePath);
9394
bool start3dMapping();
9495
void stop3dMapping();
@@ -1030,6 +1031,7 @@ class ZedCamera : public rclcpp::Node
10301031
// <---- Threads and Timers
10311032

10321033
// ----> Thread Sync
1034+
std::mutex mGrabMutex;
10331035
std::mutex mRecMutex;
10341036
std::mutex mDynParMutex;
10351037
std::mutex mMappingMutex;
@@ -1073,9 +1075,9 @@ class ZedCamera : public rclcpp::Node
10731075

10741076
bool mAreaFileExists = false;
10751077
bool mResetOdomFromSrv = false;
1076-
bool mSpatialMappingRunning = false;
1078+
std::atomic<bool> mSpatialMappingRunning{false};
10771079
std::atomic<bool> mObjDetRunning{false};
1078-
bool mBodyTrkRunning = false;
1080+
std::atomic<bool> mBodyTrkRunning{false};
10791081
bool mRgbSubscribed = false;
10801082
bool mGnssMsgReceived = false; // Indicates if a NavSatFix topic has been
10811083
// received, also with invalid position fix

zed_components/src/zed_camera/src/zed_camera_component_bodytrk.cpp

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -200,16 +200,21 @@ bool ZedCamera::startBodyTracking()
200200
bt_p.max_range = mBodyTrkMaxRange;
201201
bt_p.prediction_timeout_s = mBodyTrkPredTimeout;
202202

203-
sl::ERROR_CODE btError = mZed->enableBodyTracking(bt_p);
203+
// ----> Safe enableBodyTracking
204+
{
205+
std::lock_guard<std::mutex> grab_lock(mGrabMutex);
206+
sl::ERROR_CODE btError = mZed->enableBodyTracking(bt_p);
204207

205-
if (btError != sl::ERROR_CODE::SUCCESS) {
206-
RCLCPP_ERROR_STREAM(
207-
get_logger(),
208-
"Body Tracking error: " << sl::toString(btError));
208+
if (btError != sl::ERROR_CODE::SUCCESS) {
209+
RCLCPP_ERROR_STREAM(
210+
get_logger(),
211+
"Body Tracking error: " << sl::toString(btError));
209212

210-
mBodyTrkRunning = false;
211-
return false;
213+
mBodyTrkRunning = false;
214+
return false;
215+
}
212216
}
217+
// <---- Safe enableBodyTracking
213218

214219
DEBUG_BT("Body Tracking enabled");
215220

@@ -233,7 +238,13 @@ void ZedCamera::stopBodyTracking()
233238
RCLCPP_INFO(get_logger(), "=== Stopping Body Tracking ===");
234239
mBodyTrkRunning = false;
235240
mBodyTrkEnabled = false;
236-
mZed->disableBodyTracking();
241+
242+
// ----> Safe disableBodyTracking
243+
{
244+
std::lock_guard<std::mutex> grab_lock(mGrabMutex);
245+
mZed->disableBodyTracking();
246+
}
247+
// <---- Safe disableBodyTracking
237248

238249
// ----> Send an empty message to indicate that no more objects are tracked
239250
// (e.g clean RVIZ2)

zed_components/src/zed_camera/src/zed_camera_component_main.cpp

Lines changed: 81 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -3843,8 +3843,12 @@ void ZedCamera::startFusedPcTimer(double fusedPcRate)
38433843
mFusedPcTimer->cancel();
38443844
}
38453845

3846+
if (fusedPcRate <= 0.0) {
3847+
return;
3848+
}
3849+
38463850
std::chrono::milliseconds pubPeriod_msec(
3847-
static_cast<int>(1000.0 / (fusedPcRate)));
3851+
static_cast<int>(1000.0 / fusedPcRate));
38483852
mFusedPcTimer = create_wall_timer(
38493853
std::chrono::duration_cast<std::chrono::milliseconds>(pubPeriod_msec),
38503854
std::bind(&ZedCamera::callback_pubFusedPc, this));
@@ -3888,8 +3892,13 @@ void ZedCamera::startPathPubTimer(double pathTimerRate)
38883892

38893893
bool ZedCamera::startPosTracking()
38903894
{
3891-
// Lock on Positional Tracking mutex to avoid race conditions
38923895
std::lock_guard<std::mutex> lock(mPtMutex);
3896+
return startPosTrackingLocked();
3897+
}
3898+
3899+
bool ZedCamera::startPosTrackingLocked()
3900+
{
3901+
// Caller must hold mPtMutex.
38933902

38943903
#if (ZED_SDK_MAJOR_VERSION * 10 + ZED_SDK_MINOR_VERSION) >= 52
38953904
// With ZED SDK v5.2 we can use Positional Tracking `GEN_3` even if depth is
@@ -3905,18 +3914,30 @@ bool ZedCamera::startPosTracking()
39053914
return false;
39063915
}
39073916

3917+
39083918
if (mZed && mZed->isPositionalTrackingEnabled()) {
39093919
if (!mAreaMemoryFilePath.empty() && mSaveAreaMemoryOnClosing) {
3910-
mZed->disablePositionalTracking(mAreaMemoryFilePath.c_str());
3920+
// ----> Safe disablePositionalTracking
3921+
{
3922+
std::lock_guard<std::mutex> grab_lock(mGrabMutex);
3923+
mZed->disablePositionalTracking(mAreaMemoryFilePath.c_str());
3924+
}
3925+
// <---- Safe disablePositionalTracking
39113926
RCLCPP_INFO(
39123927
get_logger(),
39133928
"Area memory updated before restarting the Positional "
39143929
"Tracking module.");
39153930
} else {
3916-
mZed->disablePositionalTracking();
3931+
// ----> Safe disablePositionalTracking
3932+
{
3933+
std::lock_guard<std::mutex> grab_lock(mGrabMutex);
3934+
mZed->disablePositionalTracking();
3935+
}
3936+
// <---- Safe disablePositionalTracking
39173937
}
39183938
}
39193939

3940+
39203941
RCLCPP_INFO(get_logger(), "=== Starting Positional Tracking ===");
39213942

39223943
RCLCPP_INFO(get_logger(), " * Waiting for valid static transformations...");
@@ -4002,15 +4023,21 @@ bool ZedCamera::startPosTracking()
40024023
DEBUG_PT(json.c_str());
40034024
}
40044025

4005-
sl::ERROR_CODE err = mZed->enablePositionalTracking(ptParams);
4026+
// ----> Safe enablePositionalTracking
4027+
sl::ERROR_CODE err;
4028+
{
4029+
std::lock_guard<std::mutex> grab_lock(mGrabMutex);
4030+
err = mZed->enablePositionalTracking(ptParams);
40064031

4007-
if (err != sl::ERROR_CODE::SUCCESS) {
4008-
mPosTrackingStarted = false;
4009-
RCLCPP_WARN(
4010-
get_logger(), "Pos. Tracking not started: %s",
4011-
sl::toString(err).c_str());
4012-
return false;
4032+
if (err != sl::ERROR_CODE::SUCCESS) {
4033+
mPosTrackingStarted = false;
4034+
RCLCPP_WARN(
4035+
get_logger(), "Pos. Tracking not started: %s",
4036+
sl::toString(err).c_str());
4037+
return false;
4038+
}
40134039
}
4040+
// <---- Safe enablePositionalTracking
40144041

40154042
DEBUG_PT("Positional Tracking started");
40164043

@@ -4038,18 +4065,23 @@ bool ZedCamera::startPosTracking()
40384065

40394066
fusion_params.gnss_calibration_parameters = gnss_par;
40404067

4041-
sl::FUSION_ERROR_CODE fus_err =
4042-
mFusion.enablePositionalTracking(fusion_params);
4068+
// ----> Safe enablePositionalTracking/disablePositionalTracking
4069+
{
4070+
std::lock_guard<std::mutex> grab_lock(mGrabMutex);
4071+
sl::FUSION_ERROR_CODE fus_err =
4072+
mFusion.enablePositionalTracking(fusion_params);
40434073

4044-
if (fus_err != sl::FUSION_ERROR_CODE::SUCCESS) {
4045-
mPosTrackingStarted = false;
4046-
RCLCPP_WARN(
4047-
get_logger(), "Fusion Pos. Tracking not started: %s",
4048-
sl::toString(fus_err).c_str());
4049-
mZed->disablePositionalTracking();
4050-
return false;
4074+
if (fus_err != sl::FUSION_ERROR_CODE::SUCCESS) {
4075+
mPosTrackingStarted = false;
4076+
RCLCPP_WARN(
4077+
get_logger(), "Fusion Pos. Tracking not started: %s",
4078+
sl::toString(fus_err).c_str());
4079+
mZed->disablePositionalTracking();
4080+
return false;
4081+
}
4082+
DEBUG_GNSS("Fusion Positional Tracking started");
40514083
}
4052-
DEBUG_GNSS("Fusion Positional Tracking started");
4084+
// <---- Safe enablePositionalTracking/disablePositionalTracking
40534085
}
40544086
// <---- Enable Fusion Positional Tracking if required
40554087

@@ -4869,7 +4901,7 @@ void ZedCamera::threadFunc_zedGrab()
48694901

48704902
// Dummy grab
48714903
mZed->grab();
4872-
#endif
4904+
#endif
48734905
continue;
48744906
} else {
48754907
mGrabOnce = false; // Reset the flag and grab once
@@ -5007,14 +5039,19 @@ void ZedCamera::threadFunc_zedGrab()
50075039
}
50085040
// <---- Params Debug info
50095041

5010-
if (isDepthRequired() || isPosTrackingRequired()) {
5011-
DEBUG_STREAM_GRAB("Grab thread: grabbing...");
5012-
mGrabStatus = mZed->grab(mRunParams); // Process the full pipeline with depth
5042+
// ----> Safe grab
5043+
{
5044+
std::lock_guard<std::mutex> grab_lock(mGrabMutex);
5045+
if (isDepthRequired() || isPosTrackingRequired()) {
5046+
DEBUG_STREAM_GRAB("Grab thread: grabbing...");
5047+
mGrabStatus = mZed->grab(mRunParams); // Process the full pipeline with depth
50135048

5014-
} else {
5015-
DEBUG_GRAB("Grab thread: reading...");
5016-
mGrabStatus = mZed->read(); // Image and sensor data reading with no depth processing
5049+
} else {
5050+
DEBUG_GRAB("Grab thread: reading...");
5051+
mGrabStatus = mZed->read(); // Image and sensor data reading with no depth processing
5052+
}
50175053
}
5054+
// <---- Safe grab
50185055

50195056
DEBUG_GRAB("Grab thread: frame grabbed");
50205057

@@ -5041,8 +5078,8 @@ void ZedCamera::threadFunc_zedGrab()
50415078
mOdomPath.clear();
50425079
mPosePath.clear();
50435080

5044-
// Restart tracking
5045-
startPosTracking();
5081+
// Restart tracking — mPtMutex is already held by the grab loop
5082+
startPosTrackingLocked();
50465083
}
50475084
continue;
50485085
} else {
@@ -5192,22 +5229,23 @@ void ZedCamera::threadFunc_zedGrab()
51925229

51935230
// ----> Check recording status
51945231
DEBUG_STREAM_GRAB("Grab thread: checking recording status");
5195-
mRecMutex.lock();
5196-
if (mRecording) {
5197-
mRecStatus = mZed->getRecordingStatus();
5198-
static int svo_rec_err_count = 0;
5199-
if (mRecStatus.is_recording && !mRecStatus.status) {
5200-
if (++svo_rec_err_count > 3) {
5201-
rclcpp::Clock steady_clock(RCL_STEADY_TIME);
5202-
RCLCPP_WARN_THROTTLE(
5203-
get_logger(), steady_clock, 1000.0,
5204-
"Error saving frame to SVO");
5232+
{
5233+
std::lock_guard<std::mutex> rec_lock(mRecMutex);
5234+
if (mRecording) {
5235+
mRecStatus = mZed->getRecordingStatus();
5236+
static int svo_rec_err_count = 0;
5237+
if (mRecStatus.is_recording && !mRecStatus.status) {
5238+
if (++svo_rec_err_count > 3) {
5239+
rclcpp::Clock steady_clock(RCL_STEADY_TIME);
5240+
RCLCPP_WARN_THROTTLE(
5241+
get_logger(), steady_clock, 1000.0,
5242+
"Error saving frame to SVO");
5243+
}
5244+
} else {
5245+
svo_rec_err_count = 0;
52055246
}
5206-
} else {
5207-
svo_rec_err_count = 0;
52085247
}
52095248
}
5210-
mRecMutex.unlock();
52115249
// <---- Check recording status
52125250

52135251
// ----> Retrieve Image/Depth data if someone has subscribed to

zed_components/src/zed_camera/src/zed_camera_component_objdet.cpp

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -976,14 +976,19 @@ bool ZedCamera::startObjDetect()
976976
od_p.custom_onnx_file = mYoloOnnxPath;
977977
}
978978

979-
sl::ERROR_CODE objDetError = mZed->enableObjectDetection(od_p);
980-
if (objDetError != sl::ERROR_CODE::SUCCESS) {
981-
RCLCPP_ERROR_STREAM(
982-
get_logger(), "Object detection error: " << sl::toString(objDetError));
979+
// ----> Safe enableObjectDetection
980+
{
981+
std::lock_guard<std::mutex> grab_lock(mGrabMutex);
982+
sl::ERROR_CODE objDetError = mZed->enableObjectDetection(od_p);
983+
if (objDetError != sl::ERROR_CODE::SUCCESS) {
984+
RCLCPP_ERROR_STREAM(
985+
get_logger(), "Object detection error: " << sl::toString(objDetError));
983986

984-
mObjDetRunning = false;
985-
return false;
987+
mObjDetRunning = false;
988+
return false;
989+
}
986990
}
991+
// <---- Safe enableObjectDetection
987992

988993
if (!mPubObjDet) {
989994
mPubObjDet = create_publisher<zed_msgs::msg::ObjectsStamped>(
@@ -1003,7 +1008,13 @@ void ZedCamera::stopObjDetect()
10031008
RCLCPP_INFO(get_logger(), "=== Stopping Object Detection ===");
10041009
mObjDetRunning = false;
10051010
mObjDetEnabled = false;
1006-
mZed->disableObjectDetection();
1011+
1012+
// ----> Safe disableObjectDetection
1013+
{
1014+
std::lock_guard<std::mutex> grab_lock(mGrabMutex);
1015+
mZed->disableObjectDetection();
1016+
}
1017+
// <---- Safe disableObjectDetection
10071018

10081019
// ----> Send an empty message to indicate that no more objects are tracked
10091020
// (e.g clean RVIZ2)

zed_components/src/zed_camera/src/zed_camera_component_video_depth.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1591,10 +1591,10 @@ void ZedCamera::processVideoDepth()
15911591
#endif
15921592
retrieveVideoDepth(gpu);
15931593

1594-
// Signal Video/Depth thread that a new pointcloud is ready
1595-
mVdDataReadyCondVar.notify_one();
1594+
// Signal Video/Depth thread that new data is ready
15961595
mVdDataReady = true;
15971596
mVdPublishing = true;
1597+
mVdDataReadyCondVar.notify_one();
15981598
} else {
15991599
DEBUG_VD(" * [processVideoDepth] vd_lock not locked");
16001600
}
@@ -2706,10 +2706,10 @@ void ZedCamera::processPointCloud()
27062706
" * [processPointCloud] Retrieved point cloud size: " << mMatCloud.getWidth() << "x" <<
27072707
mMatCloud.getHeight());
27082708

2709-
// Signal Pointcloud thread that a new pointcloud is ready
2710-
mPcDataReadyCondVar.notify_one();
2709+
// Signal Pointcloud thread that new data is ready
27112710
mPcDataReady = true;
27122711
mPcPublishing = true;
2712+
mPcDataReadyCondVar.notify_one();
27132713

27142714
DEBUG_STREAM_PC(
27152715
" * [processPointCloud] Extracted point cloud: " << mMatCloud.getInfos().c_str() );

0 commit comments

Comments
 (0)