-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix: /tf and /static_tf topics' inconsistencies #2676
Changes from 9 commits
ec8023a
b092f35
f032edb
1e38de7
ce50027
f36c390
31f3cac
dce6b74
7ebd9ce
82eb970
3e87a6c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -121,15 +121,6 @@ BaseRealSenseNode::BaseRealSenseNode(rclcpp::Node& node, | |
ROS_INFO("Intra-Process communication enabled"); | ||
} | ||
|
||
// intra-process do not support latched QoS, so we need to disable intra-process for this topic | ||
rclcpp::PublisherOptionsWithAllocator<std::allocator<void>> options; | ||
options.use_intra_process_comm = rclcpp::IntraProcessSetting::Disable; | ||
#ifndef DASHING | ||
_static_tf_broadcaster = std::make_shared<tf2_ros::StaticTransformBroadcaster>(node, tf2_ros::StaticBroadcasterQoS(), std::move(options)); | ||
#else | ||
_static_tf_broadcaster = std::make_shared<tf2_ros::StaticTransformBroadcaster>(node, rclcpp::QoS(100), std::move(options)); | ||
#endif | ||
|
||
_image_format[1] = CV_8UC1; // CVBridge type | ||
_image_format[2] = CV_16UC1; // CVBridge type | ||
_image_format[3] = CV_8UC3; // CVBridge type | ||
|
@@ -855,6 +846,37 @@ tf2::Quaternion BaseRealSenseNode::rotationMatrixToQuaternion(const float rotati | |
return tf2::Quaternion(q.x(), q.y(), q.z(), q.w()); | ||
} | ||
|
||
void BaseRealSenseNode::unpublish_static_tf(const std::string& frame_id, | ||
const std::string& child_frame_id) | ||
{ | ||
std::vector<geometry_msgs::msg::TransformStamped>::iterator it; | ||
struct find_tf | ||
{ | ||
const std::string& frame_id; | ||
const std::string& child_frame_id; | ||
|
||
// Struct Constructor | ||
find_tf(const std::string& frame_id, const std::string& child_frame_id) : | ||
frame_id(frame_id), child_frame_id(child_frame_id) {} | ||
|
||
bool operator()(const geometry_msgs::msg::TransformStamped &static_tf_msg) const | ||
{ | ||
return (static_tf_msg.header.frame_id == frame_id && | ||
static_tf_msg.child_frame_id == child_frame_id); | ||
} | ||
}; | ||
|
||
// Find whether there is any TF with given 'frame_id' and 'child_frame_id' | ||
it = std::find_if(_static_tf_msgs.begin(), _static_tf_msgs.end(), | ||
find_tf(frame_id, child_frame_id)); | ||
|
||
// If found, erase that specific TF | ||
if (it != std::end(_static_tf_msgs)) | ||
{ | ||
_static_tf_msgs.erase(it); | ||
} | ||
} | ||
|
||
void BaseRealSenseNode::publish_static_tf(const rclcpp::Time& t, | ||
const float3& trans, | ||
const tf2::Quaternion& q, | ||
|
@@ -981,28 +1003,42 @@ void BaseRealSenseNode::SetBaseStream() | |
_base_profile = available_profiles[*base_stream]; | ||
} | ||
|
||
void BaseRealSenseNode::publishStaticTransforms(std::vector<rs2::stream_profile> profiles) | ||
void BaseRealSenseNode::publishStaticTransforms() | ||
{ | ||
// Publish static transforms | ||
if (_publish_tf) | ||
// Since the _static_tf_broadcaster is a latched topic, the old transforms will | ||
// be alive even if the sensors are dynamically disabled. So, reset the | ||
// broadcaster everytime and publish the transforms of enabled sensors alone. | ||
if (_static_tf_broadcaster) | ||
{ | ||
for (auto &profile : profiles) | ||
{ | ||
calcAndPublishStaticTransform(profile, _base_profile); | ||
} | ||
if (_static_tf_broadcaster) | ||
_static_tf_broadcaster->sendTransform(_static_tf_msgs); | ||
_static_tf_broadcaster.reset(); | ||
} | ||
|
||
// intra-process do not support latched QoS, so we need to disable intra-process for this topic | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would move this part from line 1008 to line 1024 into a seperate function |
||
rclcpp::PublisherOptionsWithAllocator<std::allocator<void>> options; | ||
options.use_intra_process_comm = rclcpp::IntraProcessSetting::Disable; | ||
|
||
#ifndef DASHING | ||
_static_tf_broadcaster = std::make_shared<tf2_ros::StaticTransformBroadcaster>(_node, tf2_ros::StaticBroadcasterQoS(), std::move(options)); | ||
#else | ||
_static_tf_broadcaster = std::make_shared<tf2_ros::StaticTransformBroadcaster>(_node, rclcpp::QoS(100), std::move(options)); | ||
#endif | ||
|
||
_static_tf_broadcaster->sendTransform(_static_tf_msgs); | ||
} | ||
|
||
void BaseRealSenseNode::startDynamicTf() | ||
{ | ||
if (!_publish_tf) | ||
{ | ||
ROS_WARN("Since the param 'publish_tf' is set to 'false'," | ||
"the value set on the param 'tf_publish_rate' won't have any effect"); | ||
return; | ||
} | ||
if (_tf_publish_rate > 0) | ||
{ | ||
ROS_WARN("Publishing dynamic camera transforms (/tf) at %g Hz", _tf_publish_rate); | ||
if (!_tf_t) | ||
{ | ||
_dynamic_tf_broadcaster = std::make_shared<tf2_ros::TransformBroadcaster>(_node); | ||
_tf_t = std::make_shared<std::thread>([this]() | ||
{ | ||
publishDynamicTransforms(); | ||
|
@@ -1016,12 +1052,22 @@ void BaseRealSenseNode::startDynamicTf() | |
_tf_t->join(); | ||
_tf_t.reset(); | ||
_dynamic_tf_broadcaster.reset(); | ||
ROS_WARN("Stopped publishing dynamic camera transforms (/tf)"); | ||
} | ||
else | ||
{ | ||
ROS_WARN("Currently not publishing dynamic camera transforms (/tf)"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just a question, can you remind me when we will get to here ? In which scenario ? |
||
} | ||
} | ||
} | ||
|
||
void BaseRealSenseNode::publishDynamicTransforms() | ||
{ | ||
if (!_dynamic_tf_broadcaster) | ||
{ | ||
_dynamic_tf_broadcaster = std::make_shared<tf2_ros::TransformBroadcaster>(_node); | ||
} | ||
|
||
// Publish transforms for the cameras | ||
std::unique_lock<std::mutex> lock(_publish_dynamic_tf_mutex); | ||
while (rclcpp::ok() && _is_running && _tf_publish_rate > 0) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,7 +37,6 @@ void BaseRealSenseNode::getParameters() | |
startDynamicTf(); | ||
}); | ||
_parameters_names.push_back(param_name); | ||
startDynamicTf(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this change the behavior from default start publishing to not? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
||
param_name = std::string("diagnostics_period"); | ||
_diagnostics_period = _parameters->setParam<double>(param_name, DIAGNOSTICS_PERIOD); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -195,6 +195,26 @@ void BaseRealSenseNode::stopPublishers(const std::vector<stream_profile>& profil | |
} | ||
_metadata_publishers.erase(sip); | ||
_extrinsics_publishers.erase(sip); | ||
|
||
if (_publish_tf) | ||
{ | ||
std::lock_guard<std::mutex> lock_guard(_publish_tf_mutex); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this part from line 201 to line 217 should be in a separate function. |
||
|
||
unpublish_static_tf(_base_frame_id, FRAME_ID(sip)); | ||
unpublish_static_tf(FRAME_ID(sip), OPTICAL_FRAME_ID(sip)); | ||
|
||
if (profile.is<rs2::video_stream_profile>() && profile.stream_type() != RS2_STREAM_DEPTH && profile.stream_index() == 1) | ||
{ | ||
unpublish_static_tf(_base_frame_id, ALIGNED_DEPTH_TO_FRAME_ID(sip)); | ||
unpublish_static_tf(ALIGNED_DEPTH_TO_FRAME_ID(sip), OPTICAL_FRAME_ID(sip)); | ||
} | ||
|
||
if ((_imu_sync_method > imu_sync_method::NONE) && (profile.stream_type() == RS2_STREAM_GYRO)) | ||
{ | ||
unpublish_static_tf(FRAME_ID(sip), IMU_FRAME_ID); | ||
unpublish_static_tf(IMU_FRAME_ID, IMU_OPTICAL_FRAME_ID); | ||
} | ||
} | ||
} | ||
} | ||
|
||
|
@@ -330,10 +350,13 @@ void BaseRealSenseNode::updateSensors() | |
{ | ||
startPublishers(wanted_profiles, *sensor); | ||
updateProfilesStreamCalibData(wanted_profiles); | ||
if (_publish_tf) | ||
{ | ||
std::lock_guard<std::mutex> lock_guard(_publish_tf_mutex); | ||
_static_tf_msgs.clear(); | ||
publishStaticTransforms(wanted_profiles); | ||
for (auto &profile : wanted_profiles) | ||
{ | ||
calcAndPublishStaticTransform(profile, _base_profile); | ||
} | ||
} | ||
|
||
if(is_profile_changed) | ||
|
@@ -351,6 +374,11 @@ void BaseRealSenseNode::updateSensors() | |
} | ||
} | ||
} | ||
if (_publish_tf) | ||
{ | ||
std::lock_guard<std::mutex> lock_guard(_publish_tf_mutex); | ||
publishStaticTransforms(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if we publish static transforms only at this point, then I think we should change |
||
} | ||
} | ||
catch(const std::exception& ex) | ||
{ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is better to move this struct outside this method.
and maybe name it with another name since using find_tf with find_if might be confusing while reading the code.