20
20
21
21
#include " zed_wrapper_nodelet.hpp"
22
22
23
+ #include < boost/date_time/posix_time/posix_time.hpp>
23
24
#include < chrono>
24
25
#include < csignal>
25
26
@@ -472,6 +473,11 @@ void ZEDWrapperNodelet::onInit()
472
473
mPubRawStereo = it_zed.advertise (stereo_raw_topic, 1 );
473
474
NODELET_INFO_STREAM (" Advertised on topic " << mPubRawStereo .getTopic ());
474
475
476
+ if (mUseSimTime )
477
+ {
478
+ mPubSimClock = mNhNs .advertise <rosgraph_msgs::Clock>(" /clock" , 2 );
479
+ }
480
+
475
481
// Confidence Map publisher
476
482
mPubConfMap = mNhNs .advertise <sensor_msgs::Image>(conf_map_topic, 1 ); // confidence map
477
483
NODELET_INFO_STREAM (" Advertised on topic " << mPubConfMap .getTopic ());
@@ -589,7 +595,8 @@ void ZEDWrapperNodelet::onInit()
589
595
590
596
if (!mSvoMode && !mSensTimestampSync )
591
597
{
592
- mFrameTimestamp = ros::Time::now ();
598
+ // init so sensor callback will have a timestamp to work with on first publish
599
+ mFrameTimestamp = getTimestamp ();
593
600
mImuTimer = mNhNs .createTimer (ros::Duration (1.0 / (mSensPubRate * 1.5 )),
594
601
&ZEDWrapperNodelet::callback_pubSensorsData, this );
595
602
mSensPeriodMean_usec .reset (new sl_tools::CSmartMean (mSensPubRate / 2 ));
@@ -626,6 +633,11 @@ void ZEDWrapperNodelet::onInit()
626
633
// Start pool thread
627
634
mDevicePollThread = std::thread (&ZEDWrapperNodelet::device_poll_thread_func, this );
628
635
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
+
629
641
// Start data publishing timer
630
642
mVideoDepthTimer =
631
643
mNhNs .createTimer (ros::Duration (1.0 / mVideoDepthFreq ), &ZEDWrapperNodelet::callback_pubVideoDepth, this );
@@ -866,6 +878,9 @@ void ZEDWrapperNodelet::readParameters()
866
878
mNhNs .param <std::string>(" svo_file" , mSvoFilepath , std::string ());
867
879
NODELET_INFO_STREAM (" * SVO input file: \t\t -> " << mSvoFilepath .c_str ());
868
880
881
+ mNhNs .getParam (" /use_sim_time" , mUseSimTime );
882
+ NODELET_INFO_STREAM (" * Use Sim Time\t\t\t -> " << mUseSimTime );
883
+
869
884
int svo_compr = 0 ;
870
885
mNhNs .getParam (" general/svo_compression" , svo_compr);
871
886
@@ -1776,7 +1791,7 @@ void ZEDWrapperNodelet::publishPose(ros::Time t)
1776
1791
}
1777
1792
}
1778
1793
1779
- void ZEDWrapperNodelet::publishStaticImuFrame ()
1794
+ void ZEDWrapperNodelet::publishStaticImuFrame (const ros::Time& stamp )
1780
1795
{
1781
1796
// Publish IMU TF as static TF
1782
1797
if (!mPublishImuTf )
@@ -1789,7 +1804,8 @@ void ZEDWrapperNodelet::publishStaticImuFrame()
1789
1804
return ;
1790
1805
}
1791
1806
1792
- mStaticImuTransformStamped .header .stamp = ros::Time::now ();
1807
+ NODELET_WARN_STREAM_ONCE (" static imu transform " << stamp);
1808
+ mStaticImuTransformStamped .header .stamp = stamp;
1793
1809
mStaticImuTransformStamped .header .frame_id = mLeftCamFrameId ;
1794
1810
mStaticImuTransformStamped .child_frame_id = mImuFrameId ;
1795
1811
sl::Translation sl_tr = mSlCamImuTransf .getTranslation ();
@@ -1805,7 +1821,7 @@ void ZEDWrapperNodelet::publishStaticImuFrame()
1805
1821
// Publish transformation
1806
1822
mStaticTransformImuBroadcaster .sendTransform (mStaticImuTransformStamped );
1807
1823
1808
- NODELET_INFO_STREAM (" Published static transform '" << mImuFrameId << " ' -> '" << mLeftCamFrameId << " '" );
1824
+ NODELET_INFO_STREAM (" Published static transform '" << mImuFrameId << " ' -> '" << mLeftCamFrameId << " ' " << stamp );
1809
1825
1810
1826
mStaticImuFramePublished = true ;
1811
1827
}
@@ -2700,8 +2716,10 @@ void ZEDWrapperNodelet::callback_pubVideoDepth(const ros::TimerEvent& e)
2700
2716
ros::Time stamp = sl_tools::slTime2Ros (grab_ts);
2701
2717
if (mSvoMode )
2702
2718
{
2703
- stamp = ros::Time::now ();
2719
+ // grab_ts is 0 when in svo playback mode
2720
+ stamp = e.current_real ;
2704
2721
}
2722
+ NODELET_INFO_STREAM_ONCE (" time " << stamp);
2705
2723
// <---- Data ROS timestamp
2706
2724
2707
2725
// ----> Publish sensor data if sync is required by user or SVO
@@ -2875,6 +2893,7 @@ void ZEDWrapperNodelet::callback_pubVideoDepth(const ros::TimerEvent& e)
2875
2893
2876
2894
void ZEDWrapperNodelet::callback_pubPath (const ros::TimerEvent& e)
2877
2895
{
2896
+ NODELET_INFO_STREAM_ONCE (" pub path " << e.current_real );
2878
2897
uint32_t mapPathSub = mPubMapPath .getNumSubscribers ();
2879
2898
uint32_t odomPathSub = mPubOdomPath .getNumSubscribers ();
2880
2899
@@ -3012,6 +3031,7 @@ void ZEDWrapperNodelet::publishSensData(ros::Time t)
3012
3031
3013
3032
sl::SensorsData sens_data;
3014
3033
3034
+ // TODO(lucasw) is a mUseSimTime check needed in here?
3015
3035
if (mSvoMode || mSensTimestampSync )
3016
3036
{
3017
3037
if (mZed .getSensorsData (sens_data, sl::TIME_REFERENCE::IMAGE) != sl::ERROR_CODE::SUCCESS)
@@ -3041,6 +3061,7 @@ void ZEDWrapperNodelet::publishSensData(ros::Time t)
3041
3061
ts_baro = sl_tools::slTime2Ros (sens_data.barometer .timestamp );
3042
3062
ts_mag = sl_tools::slTime2Ros (sens_data.magnetometer .timestamp );
3043
3063
}
3064
+ // TODO(lucasw) in svo mode the above timestamps need to be set to ros::Time::now()?
3044
3065
3045
3066
bool new_imu_data = ts_imu != lastTs_imu;
3046
3067
bool new_baro_data = ts_baro != lastTs_baro;
@@ -3066,7 +3087,7 @@ void ZEDWrapperNodelet::publishSensData(ros::Time t)
3066
3087
3067
3088
if (mPublishImuTf && !mStaticImuFramePublished )
3068
3089
{
3069
- publishStaticImuFrame ();
3090
+ publishStaticImuFrame (ts_imu );
3070
3091
}
3071
3092
}
3072
3093
// <---- Publish odometry tf only if enabled
@@ -3370,6 +3391,51 @@ void ZEDWrapperNodelet::publishSensData(ros::Time t)
3370
3391
// <---- Update Diagnostic
3371
3392
}
3372
3393
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
+
3373
3439
void ZEDWrapperNodelet::device_poll_thread_func ()
3374
3440
{
3375
3441
ros::Rate loop_rate (mCamFrameRate );
@@ -3383,14 +3449,10 @@ void ZEDWrapperNodelet::device_poll_thread_func()
3383
3449
mObjDetPeriodMean_msec .reset (new sl_tools::CSmartMean (mCamFrameRate ));
3384
3450
3385
3451
// 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 ;
3394
3456
3395
3457
mPrevFrameTimestamp = mFrameTimestamp ;
3396
3458
@@ -3429,6 +3491,8 @@ void ZEDWrapperNodelet::device_poll_thread_func()
3429
3491
sl::RuntimeParameters runParams;
3430
3492
runParams.sensing_mode = static_cast <sl::SENSING_MODE>(mCamSensingMode );
3431
3493
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?
3432
3496
// Main loop
3433
3497
while (mNhNs .ok ())
3434
3498
{
@@ -3536,6 +3600,8 @@ void ZEDWrapperNodelet::device_poll_thread_func()
3536
3600
// the zed have been disconnected) and
3537
3601
// re-initialize the ZED
3538
3602
3603
+ // TODO(lucasw) if the status is END OF SVO FILE REACHED then loop it optionally,
3604
+ // or exit.
3539
3605
NODELET_INFO_STREAM_ONCE (toString (mGrabStatus ));
3540
3606
3541
3607
std::this_thread::sleep_for (std::chrono::milliseconds (1 ));
@@ -3631,18 +3697,10 @@ void ZEDWrapperNodelet::device_poll_thread_func()
3631
3697
mGrabPeriodMean_usec ->addValue (elapsed_usec);
3632
3698
3633
3699
// NODELET_INFO_STREAM("Grab time: " << elapsed_usec / 1000 << " msec");
3700
+ mFrameTimestamp = getTimestamp ();
3634
3701
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;
3646
3704
3647
3705
// ----> Camera Settings
3648
3706
if (!mSvoMode && mFrameCount % 5 == 0 )
@@ -3974,7 +4032,7 @@ void ZEDWrapperNodelet::device_poll_thread_func()
3974
4032
if (odomSubnumber > 0 )
3975
4033
{
3976
4034
// Publish odometry message
3977
- publishOdom (mOdom2BaseTransf , mLastZedPose , mFrameTimestamp );
4035
+ publishOdom (mOdom2BaseTransf , mLastZedPose , stamp );
3978
4036
}
3979
4037
3980
4038
mInitOdomWithPose = false ;
@@ -4098,27 +4156,19 @@ void ZEDWrapperNodelet::device_poll_thread_func()
4098
4156
// Publish odometry tf only if enabled
4099
4157
if (mPublishTf )
4100
4158
{
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 ();
4111
4161
4112
- publishOdomFrame (mOdom2BaseTransf , mFrameTimestamp ); // publish the base Frame in odometry frame
4162
+ publishOdomFrame (mOdom2BaseTransf , t ); // publish the base Frame in odometry frame
4113
4163
4114
4164
if (mPublishMapTf )
4115
4165
{
4116
- publishPoseFrame (mMap2OdomTransf , mFrameTimestamp ); // publish the odometry Frame in map frame
4166
+ publishPoseFrame (mMap2OdomTransf , t ); // publish the odometry Frame in map frame
4117
4167
}
4118
4168
4119
4169
if (mPublishImuTf && !mStaticImuFramePublished )
4120
4170
{
4121
- publishStaticImuFrame ();
4171
+ publishStaticImuFrame (t );
4122
4172
}
4123
4173
}
4124
4174
}
0 commit comments