-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Amcl auto localization #504
Conversation
Can you add images of the BTs? You should be able to create the image in Groot or your tool of choice. You could either check in the image where the xml file is, or just add it to the PR description |
|
||
// Naive way to check if the robot has been localized | ||
// TODO(mhpanah): come up with a method to properly check particles convergence | ||
if (current_pose->pose.covariance[0] < 0.25 && |
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.
We shouldnt be hard coding magic numbers, can we parameterize this? This covariance value as localized is highly tied to the amcl or particle filter configuration
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.
Agreed. However, currently I haven't decide how to pass these parameters yet (i.e. from xml file or parameter server). This will be addressed in a different PR. Also, this BT branch is designed to work with AMCL and differential type robots and I have a TODO to make this more generic. Basically, for now this is an additional feature for AMCL.
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.
You can make it a parameter on the node to start with. That way all you have to do is a simple get_parameter_or
during initialization to get the configurable parameters. The non-configurable parameters, like the covariance array indexes perhaps, can just be constants you define - maybe in the class definition in this case.
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.
Looks good to me, I agree about parameterizing the covariance values in future PR. Looks like the build isn't passing yet though.
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
#ifndef NAV2_TASKS__GLOBAL_LOCLIZATION_SERVICE_CLIENT_HPP_ |
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.
Typo in this line
@@ -16,6 +16,7 @@ | |||
#include <memory> | |||
#include <fstream> | |||
#include <streambuf> | |||
#include <set> |
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.
Looks like you're not using set
but including it to remove the linter error. Use `\ NOLINT' instead.
@@ -52,6 +53,7 @@ BtNavigator::navigateToPose(const nav2_tasks::NavigateToPoseCommand::SharedPtr c | |||
// Set the shared data (commands/results) | |||
blackboard->set<nav2_tasks::ComputePathToPoseCommand::SharedPtr>("goal", command); | |||
blackboard->set<nav2_tasks::ComputePathToPoseResult::SharedPtr>("path", path); // NOLINT | |||
blackboard->set<bool>("initial_pose", task_server_->hasInitialPoseReceived()); |
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.
Add \\ NOLINT
at the end of the line, see line 55.
|
||
robot_ = std::make_unique<nav2_robot::Robot>(node_); | ||
|
||
onInit(); |
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 don't think this is needed. Unless you're planning on having other classes derived from IsLocalizedCondition
.
// Get the required items from the blackboard | ||
node_ = blackboard()->template get<rclcpp::Node::SharedPtr>("node"); | ||
|
||
node_loop_timeout_ = |
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.
Do you need this variable?
|
||
} // namespace nav2_tasks | ||
|
||
#endif // NAV2_TASKS__GLOBAL_LOCLIZATION_SERVICE_CLIENT_HPP_ |
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.
Typo in this line.
namespace nav2_tasks | ||
{ | ||
|
||
class globalLocalizationServiceClient : public ServiceClient<std_srvs::srv::Empty> |
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.
Can we clarify a bit more what this service is doing? I see we are sending and receiving empty messages.
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 sends an empty msg request to invoke amcl's global localization service call.
} | ||
} | ||
|
||
BT::NodeStatus NavigateToPoseBehaviorTree::initialPoseReceived(BT::TreeNode & tree_node) |
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 first node ticked on the BT, it seems that with this logic it will always returns FAILURE
. Are we checking somewhere else if the user has set the initial position elsewhere? for example in RVIZ.
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.
It will return Success, when there is an initial pose. This method will be updated once we enable reading initial pose from parameter server.
|
||
BT::NodeStatus NavigateToPoseBehaviorTree::initialPoseReceived(BT::TreeNode & tree_node) | ||
{ | ||
auto initPose = tree_node.blackboard()->template get<bool>("initial_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.
Eventually I think we should check if the initial pose was received through the robot class.
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'm halting adding any new code in robot class until team decides what to do with robot class.
@@ -39,22 +40,46 @@ class NavigateToPoseTaskServer : public TaskServer<NavigateToPoseCommand, Naviga | |||
goal_sub_ = node_->create_subscription<geometry_msgs::msg::PoseStamped>("move_base_simple/goal", | |||
std::bind(&NavigateToPoseTaskServer::onGoalPoseReceived, this, std::placeholders::_1)); | |||
|
|||
initial_pose_received_ = false; | |||
initial_pose_sub_ = node_->create_subscription<geometry_msgs::msg::PoseWithCovarianceStamped>( |
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.
Maybe this could be done through the robot class.
void onGoalPoseReceived(const geometry_msgs::msg::PoseStamped::SharedPtr pose) | ||
{ | ||
self_client_->sendCommand(pose); | ||
} | ||
void onInitialPoseReceived(const geometry_msgs::msg::PoseWithCovarianceStamped::SharedPtr /*msg*/) | ||
{ |
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.
Why not store the message with the initial pose we've received?
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 initial pose msg is not needed here.
return false; | ||
} | ||
|
||
void setInitialPose(bool initial_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.
if initial_pose_
is false, we don't need to pass an argument to make it true.
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.
In this case we do. When AutoLocalization is done, this flags needs to be changed so that on next cycle we know that the robot has already been localized.
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've made some minor recommendations.
|
||
BT::NodeStatus NavigateToPoseBehaviorTree::initialPoseReceived(BT::TreeNode & tree_node) | ||
{ | ||
auto initPose = tree_node.blackboard()->template get<bool>("initial_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.
These variables - initPose
and "initial_pose"
sound like they contain a pose, not a boolean. Can we change them to something like initial_pose_received" or something?
// A client that we'll use to send a command message to our own task server | ||
self_client_ = std::make_unique<nav2_tasks::NavigateToPoseTaskClient>(node_); | ||
} | ||
|
||
NavigateToPoseTaskServer() = delete; | ||
|
||
bool hasInitialPoseReceived() |
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'd go for isInitialPoseReceieved rather than has. I think that is more standard for a function that returns a boolean.
|
||
// Naive way to check if the robot has been localized | ||
// TODO(mhpanah): come up with a method to properly check particles convergence | ||
if (current_pose->pose.covariance[0] < 0.25 && |
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.
You can make it a parameter on the node to start with. That way all you have to do is a simple get_parameter_or
during initialization to get the configurable parameters. The non-configurable parameters, like the covariance array indexes perhaps, can just be constants you define - maybe in the class definition in this case.
@mhpanah How will this fit into the overall btNavigator? How does this interact with manually setting the initial pose in rviz? How does this interact with loading the initial pose from a parameter server? |
|
59468e6
to
e5134e4
Compare
* update docs Signed-off-by: gg <[email protected]> * updates Signed-off-by: gg <[email protected]> --------- Signed-off-by: gg <[email protected]>
Basic Info
Description of contribution in a few bullet points
Note: I will fix the CI failure before merge.
Implemented Simple AutoLocalization with BT for differential type robots.
Figure below shows the AutoLocalization BT branch.
Future work that may be required in bullet points
Expand it to other type of robots
Currently the spin and back_up motion primitives are time based. Will need to modify the tree once the motion primitives support distance and angle.