-
Notifications
You must be signed in to change notification settings - Fork 451
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
Add reset mapping (and pose) service #87
Add reset mapping (and pose) service #87
Conversation
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.
left personal comments to aid in the review process
hector_mapping/CMakeLists.txt
Outdated
## Generate services in the 'srv' folder | ||
add_service_files( | ||
FILES | ||
HectorManagement.srv |
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.
new service to manage hector processing
generate_messages( | ||
DEPENDENCIES | ||
geometry_msgs |
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.
the service above has geometry_msgs::Pose
as an argument, so it needs to use geometry_msgs
as a dependency
static double getYawFromQuat(const geometry_msgs::Quaternion &quat) | ||
{ | ||
return tf::getYaw(tf::Quaternion(quat.x, quat.y, quat.z, quat.w)); | ||
} |
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.
added this new utility function that helps getting yaw from a quaternion... this is useful when resetting pose
@@ -157,7 +157,8 @@ HectorMappingRos::HectorMappingRos() | |||
tmp.dynamicMapServiceServer_ = node_.advertiseService("dynamic_map", &HectorMappingRos::mapCallback, this); | |||
} | |||
|
|||
// Initialize services to reset map, and toggle scan pause | |||
// Initialize services | |||
hector_management_service_ = node_.advertiseService("hector_management", &HectorMappingRos::hectorManagementCallback, this); |
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.
new service declaration
hector_mapping::HectorManagement::Response &res) | ||
{ | ||
// Pause/unpause | ||
this->toggleMappingPause(req.pause); |
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.
call function to toggle mapping
ROS_INFO("HectorSM Mapping no longer paused"); | ||
} | ||
pause_scan_processing_ = req.data; | ||
this->toggleMappingPause(req.data); |
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.
because this chunk of code would be identical in restartHectorCallback
and pauseMapCallback
, I created the function toggleMappingPause
that has the very same chunk of code
tf::poseMsgToTF(msg->pose.pose, pose); | ||
initial_pose_ = Eigen::Vector3f(msg->pose.pose.position.x, msg->pose.pose.position.y, tf::getYaw(pose.getRotation())); | ||
ROS_INFO("Setting initial pose with world coords x: %f y: %f yaw: %f", initial_pose_[0], initial_pose_[1], initial_pose_[2]); | ||
this->resetPose(msg->pose.pose); |
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.
because this chunk of code would be identical in restartHectorCallback
and initialPoseCallback
, I created the function resetPose
that contains that chunk of code
{ | ||
// Pause/unpause | ||
if (pause && !pause_scan_processing_) | ||
{ | ||
ROS_INFO("[HectorSM]: Mapping paused"); | ||
} | ||
else if (!pause && pause_scan_processing_) | ||
{ | ||
ROS_INFO("[HectorSM]: Mapping no longer paused"); | ||
} | ||
pause_scan_processing_ = pause; |
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.
this is the exact same code that was in pauseMapCallback
, just brought it here
void HectorMappingRos::resetPose(const geometry_msgs::Pose &pose) | ||
{ | ||
initial_pose_set_ = true; | ||
initial_pose_ = Eigen::Vector3f(pose.position.x, pose.position.y, util::getYawFromQuat(pose.orientation)); | ||
ROS_INFO("[HectorSM]: Setting initial pose with world coords x: %f y: %f yaw: %f", | ||
initial_pose_[0], initial_pose_[1], initial_pose_[2]); | ||
} |
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.
this is an adaptation of what was in initialPoseCallback
. The difference is that I made use of util::getYawFromQuat
instead of declaring the following variable to extract yaw:
tf::Pose pose;
tf::poseMsgToTF(msg->pose.pose, pose);
@@ -0,0 +1,16 @@ | |||
# Service definition for hector processing management |
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.
these comments make the service definition self-explanatory
Thank you for your PR! |
@StefanFabian thank you for your review!
So the combination of these functionalities is rather useful for
If we are to call three separate services, we would have to have three service clients, check whether the service call succeeded three times, and check the return value three times. It certainly is doable, just not as concise |
Hm, I would be okay with having a restart service that as a side-effect always unpauses. |
// Initialize services to reset map, and toggle scan pause | ||
reset_map_service_ = node_.advertiseService("reset_map", &HectorMappingRos::resetMapCallback, this); | ||
toggle_scan_processing_service_ = node_.advertiseService("pause_mapping", &HectorMappingRos::pauseMapCallback, this); |
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.
my bad in the previous PR: I had placed this inside a for
loop, so I'm bringing it out of that loop
setServiceGetMapData(tmp.map_, slamProcessor->getGridMap(i)); | ||
|
||
if ( i== 0){ | ||
mapPubContainer[i].mapMetadataPublisher_.publish(mapPubContainer[i].map_.map.info); | ||
} | ||
} | ||
|
||
// Initialize services | ||
reset_map_service_ = node_.advertiseService("reset_map", &HectorMappingRos::resetMapCallback, this); | ||
restart_hector_service_ = node_.advertiseService("restart_hector", &HectorMappingRos::restartHectorCallback, this); |
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.
new service that:
- resets the map
- resets the initial pose
- unpauses the execution
Any suggestions of a better name for the service? Or is restart_hector
good enough?
@@ -389,18 +390,28 @@ bool HectorMappingRos::resetMapCallback(std_srvs::Trigger::Request &req, | |||
return true; | |||
} | |||
|
|||
bool HectorMappingRos::restartHectorCallback(hector_mapping::SetInitialPose::Request &req, |
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.
self-explanatory callback
@StefanFabian I have implemented as per your request! Let me know if there is anything else you'd want changed. If approved, I'll move on to update the wiki |
Thank you for the update. |
I hope these updates address all your concerns! Please let me know if you'd like to suggest any more improvements |
Looks like we had a misunderstanding. I meant the service msg
There are use cases where it may make sense since a service call will also return false if it couldn't reach the service server but I think in our case, the user is only interested in whether the call succeeded or not.
The example you're linked is just because of the template specialization. Const references are passed for better performance but in the case of simple value types, the reference is often larger than the value type so it makes no sense to not simply pass a copy. |
I have renamed the service definition, but I don't fully agree with your reasoning. In any case, let me know if you'd want any further updates in this PR, I'll be happy to do it =) |
Yes, that is the intention. ROS messages and services should have a semantic meaning which means it is intended that you may have to define another message with the exact same members for a different purpose. Anyway, I have changed the bool parameter from const reference to pass by value and it's good to merge now. |
Thank you very much, @StefanFabian . My bad on the boolean reference, I really thought I had pushed a change to remove the reference. |
* add service to reset the mapping with a new initial pose
* add service to reset the mapping with a new initial pose
This PR introduces a new service (to rule them all) for managing hector in a single service call in terms of:
Note: This PR is backward-compatible, as it doesn't change any behavior for code that interfaces with
hector_mapping
, it only adds a new service that can be used when interfacing with itcloses #88