2020
2121#include " zed_wrapper_nodelet.hpp"
2222
23+ #include < boost/date_time/posix_time/posix_time.hpp>
2324#include < chrono>
2425#include < csignal>
2526
@@ -472,6 +473,11 @@ void ZEDWrapperNodelet::onInit()
472473 mPubRawStereo = it_zed.advertise (stereo_raw_topic, 1 );
473474 NODELET_INFO_STREAM (" Advertised on topic " << mPubRawStereo .getTopic ());
474475
476+ if (mUseSimTime )
477+ {
478+ mPubSimClock = mNhNs .advertise <rosgraph_msgs::Clock>(" /clock" , 2 );
479+ }
480+
475481 // Confidence Map publisher
476482 mPubConfMap = mNhNs .advertise <sensor_msgs::Image>(conf_map_topic, 1 ); // confidence map
477483 NODELET_INFO_STREAM (" Advertised on topic " << mPubConfMap .getTopic ());
@@ -589,7 +595,8 @@ void ZEDWrapperNodelet::onInit()
589595
590596 if (!mSvoMode && !mSensTimestampSync )
591597 {
592- mFrameTimestamp = ros::Time::now ();
598+ // init so sensor callback will have a timestamp to work with on first publish
599+ mFrameTimestamp = getTimestamp ();
593600 mImuTimer = mNhNs .createTimer (ros::Duration (1.0 / (mSensPubRate * 1.5 )),
594601 &ZEDWrapperNodelet::callback_pubSensorsData, this );
595602 mSensPeriodMean_usec .reset (new sl_tools::CSmartMean (mSensPubRate / 2 ));
@@ -626,6 +633,11 @@ void ZEDWrapperNodelet::onInit()
626633 // Start pool thread
627634 mDevicePollThread = std::thread (&ZEDWrapperNodelet::device_poll_thread_func, this );
628635
636+ if (mUseSimTime ) {
637+ // TODO(lucasw) 0.02-0.05 are probably fine
638+ wall_timer_ = mNhNs .createWallTimer (ros::WallDuration (0.01 ), &ZEDWrapperNodelet::sim_clock_update, this );
639+ }
640+
629641 // Start data publishing timer
630642 mVideoDepthTimer =
631643 mNhNs .createTimer (ros::Duration (1.0 / mVideoDepthFreq ), &ZEDWrapperNodelet::callback_pubVideoDepth, this );
@@ -866,6 +878,9 @@ void ZEDWrapperNodelet::readParameters()
866878 mNhNs .param <std::string>(" svo_file" , mSvoFilepath , std::string ());
867879 NODELET_INFO_STREAM (" * SVO input file: \t\t -> " << mSvoFilepath .c_str ());
868880
881+ mNhNs .getParam (" /use_sim_time" , mUseSimTime );
882+ NODELET_INFO_STREAM (" * Use Sim Time\t\t\t -> " << mUseSimTime );
883+
869884 int svo_compr = 0 ;
870885 mNhNs .getParam (" general/svo_compression" , svo_compr);
871886
@@ -1776,7 +1791,7 @@ void ZEDWrapperNodelet::publishPose(ros::Time t)
17761791 }
17771792}
17781793
1779- void ZEDWrapperNodelet::publishStaticImuFrame ()
1794+ void ZEDWrapperNodelet::publishStaticImuFrame (const ros::Time& stamp )
17801795{
17811796 // Publish IMU TF as static TF
17821797 if (!mPublishImuTf )
@@ -1789,7 +1804,8 @@ void ZEDWrapperNodelet::publishStaticImuFrame()
17891804 return ;
17901805 }
17911806
1792- mStaticImuTransformStamped .header .stamp = ros::Time::now ();
1807+ NODELET_WARN_STREAM_ONCE (" static imu transform " << stamp);
1808+ mStaticImuTransformStamped .header .stamp = stamp;
17931809 mStaticImuTransformStamped .header .frame_id = mLeftCamFrameId ;
17941810 mStaticImuTransformStamped .child_frame_id = mImuFrameId ;
17951811 sl::Translation sl_tr = mSlCamImuTransf .getTranslation ();
@@ -1805,7 +1821,7 @@ void ZEDWrapperNodelet::publishStaticImuFrame()
18051821 // Publish transformation
18061822 mStaticTransformImuBroadcaster .sendTransform (mStaticImuTransformStamped );
18071823
1808- NODELET_INFO_STREAM (" Published static transform '" << mImuFrameId << " ' -> '" << mLeftCamFrameId << " '" );
1824+ NODELET_INFO_STREAM (" Published static transform '" << mImuFrameId << " ' -> '" << mLeftCamFrameId << " ' " << stamp );
18091825
18101826 mStaticImuFramePublished = true ;
18111827}
@@ -2700,8 +2716,10 @@ void ZEDWrapperNodelet::callback_pubVideoDepth(const ros::TimerEvent& e)
27002716 ros::Time stamp = sl_tools::slTime2Ros (grab_ts);
27012717 if (mSvoMode )
27022718 {
2703- stamp = ros::Time::now ();
2719+ // grab_ts is 0 when in svo playback mode
2720+ stamp = e.current_real ;
27042721 }
2722+ NODELET_INFO_STREAM_ONCE (" time " << stamp);
27052723 // <---- Data ROS timestamp
27062724
27072725 // ----> Publish sensor data if sync is required by user or SVO
@@ -2875,6 +2893,7 @@ void ZEDWrapperNodelet::callback_pubVideoDepth(const ros::TimerEvent& e)
28752893
28762894void ZEDWrapperNodelet::callback_pubPath (const ros::TimerEvent& e)
28772895{
2896+ NODELET_INFO_STREAM_ONCE (" pub path " << e.current_real );
28782897 uint32_t mapPathSub = mPubMapPath .getNumSubscribers ();
28792898 uint32_t odomPathSub = mPubOdomPath .getNumSubscribers ();
28802899
@@ -3012,6 +3031,7 @@ void ZEDWrapperNodelet::publishSensData(ros::Time t)
30123031
30133032 sl::SensorsData sens_data;
30143033
3034+ // TODO(lucasw) is a mUseSimTime check needed in here?
30153035 if (mSvoMode || mSensTimestampSync )
30163036 {
30173037 if (mZed .getSensorsData (sens_data, sl::TIME_REFERENCE::IMAGE) != sl::ERROR_CODE::SUCCESS)
@@ -3041,6 +3061,7 @@ void ZEDWrapperNodelet::publishSensData(ros::Time t)
30413061 ts_baro = sl_tools::slTime2Ros (sens_data.barometer .timestamp );
30423062 ts_mag = sl_tools::slTime2Ros (sens_data.magnetometer .timestamp );
30433063 }
3064+ // TODO(lucasw) in svo mode the above timestamps need to be set to ros::Time::now()?
30443065
30453066 bool new_imu_data = ts_imu != lastTs_imu;
30463067 bool new_baro_data = ts_baro != lastTs_baro;
@@ -3066,7 +3087,7 @@ void ZEDWrapperNodelet::publishSensData(ros::Time t)
30663087
30673088 if (mPublishImuTf && !mStaticImuFramePublished )
30683089 {
3069- publishStaticImuFrame ();
3090+ publishStaticImuFrame (ts_imu );
30703091 }
30713092 }
30723093 // <---- Publish odometry tf only if enabled
@@ -3370,6 +3391,51 @@ void ZEDWrapperNodelet::publishSensData(ros::Time t)
33703391 // <---- Update Diagnostic
33713392}
33723393
3394+ void ZEDWrapperNodelet::publishSimClock (const ros::Time& stamp)
3395+ {
3396+ {
3397+ boost::posix_time::ptime posix_time = stamp.toBoost ();
3398+ const std::string iso_time_str = boost::posix_time::to_iso_extended_string (posix_time);
3399+ // NODELET_INFO_STREAM_THROTTLE(1.0, "time " << iso_time_str);
3400+ NODELET_INFO_STREAM_ONCE (" time " << iso_time_str);
3401+ }
3402+
3403+ NODELET_WARN_STREAM_ONCE (" using sim clock " << stamp);
3404+ rosgraph_msgs::Clock clock;
3405+ clock.clock = stamp;
3406+ mPubSimClock .publish (clock);
3407+ }
3408+
3409+ ros::Time ZEDWrapperNodelet::getTimestamp ()
3410+ {
3411+ ros::Time stamp;
3412+ if (mSvoMode && !mUseSimTime )
3413+ {
3414+ // TODO(lucasw) does it matter which one?
3415+ stamp = ros::Time::now ();
3416+ // mFrameTimestamp = sl_tools::slTime2Ros(mZed.getTimestamp(sl::TIME_REFERENCE::CURRENT));
3417+ NODELET_WARN_STREAM_ONCE (" Using current time instead of image time " << stamp);
3418+ }
3419+ else
3420+ {
3421+ // TODO(lucasw) if no images have arrived yet, this is zero, or something else?
3422+ // In the svo file it appears to be something else, slightly in advance of the first
3423+ // frame.
3424+ stamp = sl_tools::slTime2Ros (mZed .getTimestamp (sl::TIME_REFERENCE::IMAGE));
3425+ NODELET_WARN_STREAM_ONCE (" Using zed image time " << stamp);
3426+ }
3427+ return stamp;
3428+ }
3429+
3430+ void ZEDWrapperNodelet::sim_clock_update (const ros::WallTimerEvent& e)
3431+ {
3432+ // TODO(lucasw) mutex
3433+ publishSimClock (sim_clock_base_time);
3434+ // TODO(lucasw) have ability to roll forward faster than real time
3435+ sim_clock_base_time += ros::Duration (0.001 );
3436+ std::this_thread::sleep_for (std::chrono::milliseconds (1 ));
3437+ }
3438+
33733439void ZEDWrapperNodelet::device_poll_thread_func ()
33743440{
33753441 ros::Rate loop_rate (mCamFrameRate );
@@ -3383,14 +3449,10 @@ void ZEDWrapperNodelet::device_poll_thread_func()
33833449 mObjDetPeriodMean_msec .reset (new sl_tools::CSmartMean (mCamFrameRate ));
33843450
33853451 // Timestamp initialization
3386- if (mSvoMode )
3387- {
3388- mFrameTimestamp = ros::Time::now ();
3389- }
3390- else
3391- {
3392- mFrameTimestamp = sl_tools::slTime2Ros (mZed .getTimestamp (sl::TIME_REFERENCE::CURRENT));
3393- }
3452+ mFrameTimestamp = getTimestamp ();
3453+
3454+ // TODO(lucasw) mutex
3455+ sim_clock_base_time = mFrameTimestamp ;
33943456
33953457 mPrevFrameTimestamp = mFrameTimestamp ;
33963458
@@ -3429,6 +3491,8 @@ void ZEDWrapperNodelet::device_poll_thread_func()
34293491 sl::RuntimeParameters runParams;
34303492 runParams.sensing_mode = static_cast <sl::SENSING_MODE>(mCamSensingMode );
34313493
3494+ // TODO(lucasw) is there a call to mZed in here that rolls it forward a frame in mSvoMode, or does it
3495+ // have a timer and keeps time independently, can only do real time?
34323496 // Main loop
34333497 while (mNhNs .ok ())
34343498 {
@@ -3536,6 +3600,8 @@ void ZEDWrapperNodelet::device_poll_thread_func()
35363600 // the zed have been disconnected) and
35373601 // re-initialize the ZED
35383602
3603+ // TODO(lucasw) if the status is END OF SVO FILE REACHED then loop it optionally,
3604+ // or exit.
35393605 NODELET_INFO_STREAM_ONCE (toString (mGrabStatus ));
35403606
35413607 std::this_thread::sleep_for (std::chrono::milliseconds (1 ));
@@ -3631,18 +3697,10 @@ void ZEDWrapperNodelet::device_poll_thread_func()
36313697 mGrabPeriodMean_usec ->addValue (elapsed_usec);
36323698
36333699 // NODELET_INFO_STREAM("Grab time: " << elapsed_usec / 1000 << " msec");
3700+ mFrameTimestamp = getTimestamp ();
36343701
3635- // Timestamp
3636- if (mSvoMode )
3637- {
3638- mFrameTimestamp = ros::Time::now ();
3639- }
3640- else
3641- {
3642- mFrameTimestamp = sl_tools::slTime2Ros (mZed .getTimestamp (sl::TIME_REFERENCE::IMAGE));
3643- }
3644-
3645- ros::Time stamp = mFrameTimestamp ; // Timestamp
3702+ const ros::Time stamp = mFrameTimestamp ; // Timestamp
3703+ sim_clock_base_time = stamp;
36463704
36473705 // ----> Camera Settings
36483706 if (!mSvoMode && mFrameCount % 5 == 0 )
@@ -3974,7 +4032,7 @@ void ZEDWrapperNodelet::device_poll_thread_func()
39744032 if (odomSubnumber > 0 )
39754033 {
39764034 // Publish odometry message
3977- publishOdom (mOdom2BaseTransf , mLastZedPose , mFrameTimestamp );
4035+ publishOdom (mOdom2BaseTransf , mLastZedPose , stamp );
39784036 }
39794037
39804038 mInitOdomWithPose = false ;
@@ -4098,27 +4156,19 @@ void ZEDWrapperNodelet::device_poll_thread_func()
40984156 // Publish odometry tf only if enabled
40994157 if (mPublishTf )
41004158 {
4101- ros::Time t;
4102-
4103- if (mSvoMode )
4104- {
4105- t = ros::Time::now ();
4106- }
4107- else
4108- {
4109- t = sl_tools::slTime2Ros (mZed .getTimestamp (sl::TIME_REFERENCE::CURRENT));
4110- }
4159+ // TODO(lucasw) or just ust mFrameTimestamp?
4160+ const ros::Time t = getTimestamp ();
41114161
4112- publishOdomFrame (mOdom2BaseTransf , mFrameTimestamp ); // publish the base Frame in odometry frame
4162+ publishOdomFrame (mOdom2BaseTransf , t ); // publish the base Frame in odometry frame
41134163
41144164 if (mPublishMapTf )
41154165 {
4116- publishPoseFrame (mMap2OdomTransf , mFrameTimestamp ); // publish the odometry Frame in map frame
4166+ publishPoseFrame (mMap2OdomTransf , t ); // publish the odometry Frame in map frame
41174167 }
41184168
41194169 if (mPublishImuTf && !mStaticImuFramePublished )
41204170 {
4121- publishStaticImuFrame ();
4171+ publishStaticImuFrame (t );
41224172 }
41234173 }
41244174 }
0 commit comments