@@ -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
38893893bool 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
0 commit comments