magazino / move_base_flex

Move Base Flex: a backwards-compatible replacement for move_base
https://uos.github.io/mbf_docs/
BSD 3-Clause "New" or "Revised" License
422 stars 153 forks source link

How to plan in `map` and control in `odom` #156

Open Rayman opened 4 years ago

Rayman commented 4 years ago

Hi, thanks for this awesome package.

I want to run the planner in map frame a controller in odom frame. These are the available parameters I've found that influences this:

/move_base_flex/global_costmap/global_frame = map
/move_base_flex/global_costmap/robot_base_frame = base_link

/move_base_flex/local_costmap/global_frame = odom
/move_base_flex/local_costmap/robot_base_frame = base_link

/move_base_flex/global_frame = ???
/move_base_flex/map_frame = ???
/move_base_flex/robot_frame = base_link

I'm not sure how to configure the parameters that I've marked with ???.

The parameter map_frame (default map) is used in both the planner and controller executing. It determines in which frame to look up the robot position. I want to set it to odom ONLY for the controllers, so that the robot_pose I get in the computeVelocityCmd callback is in the odom frame. How can I do this?

corot commented 4 years ago

Same as #113. We need to think this carefully.

corot commented 4 years ago

Not a final solution, but I think it makes sense: I made a branch removing the last three parameters and taking them from the costmap:

https://github.com/magazino/move_base_flex/tree/less_params

@Rayman, could you give it a try and provide any feedback? Thanks a lot!

Rayman commented 4 years ago

On that branch, move_base_flex crashes immediately. I could not find out why. The initialization sequence looks good to me

Tested on kinetic

Thread 1 "mbf_costmap_nav" received signal SIGSEGV, Segmentation fault.
0x00007ffff7b529f0 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Alloc_hider::_Alloc_hider (__a=..., __dat=<optimized out>, this=<optimized out>)
    at /usr/include/c++/5/bits/basic_string.h:109
109             : allocator_type(__a), _M_p(__dat) { }

Backtrace:

(gdb) bt
#0  0x00007ffff7b529f0 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Alloc_hider::_Alloc_hider (__a=..., __dat=<optimized out>, this=<optimized out>)
    at /usr/include/c++/5/bits/basic_string.h:109
#1  std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string (__str=<error reading variable: Cannot access memory at address 0x68>, this=0x7fffffffcd40)
    at /usr/include/c++/5/bits/basic_string.h:399
#2  costmap_2d::Costmap2DROS::getBaseFrameID[abi:cxx11]() (this=0x10) at /opt/ros/kinetic/include/costmap_2d/costmap_2d_ros.h:148
#3  mbf_costmap_nav::CostmapNavigationServer::CostmapNavigationServer (this=0x6373b0, tf_listener_ptr=...)
    at /home/user/ros/common/src/move_base_flex/mbf_costmap_nav/src/mbf_costmap_nav/costmap_navigation_server.cpp:61
#4  0x0000000000407d6b in boost::make_shared<mbf_costmap_nav::CostmapNavigationServer, boost::shared_ptr<tf::TransformListener> > (a1=...) at /usr/include/boost/smart_ptr/make_shared_object.hpp:808
#5  0x0000000000406714 in main (argc=1, argv=<optimized out>) at /home/user/ros/common/src/move_base_flex/mbf_costmap_nav/src/move_base_server_node.cpp:76
(gdb)

So getBaseFrameID gets called before the costmap is initialized... strange

corot commented 4 years ago

:see_no_evil: ouch,,,, looks like C++ always calls the parent constructor first, regardles of the order in initialization list. I tried to fix it with boost::base_from_member but didn't manage. Will try to rethink how to do better,,, but I'll take some time, though, sorry.

spuetz commented 4 years ago

@Rayman What you should do is to transform the pose from it's frame which should be (usually) "map" into "odom" in the controller plugin using tf. In general one has the transformation tree like this: global_frame -> map_frame -> odom_frame -> robot_frame. But be careful odom accumulates errors which are corrected by map_frame -> odom_frame, e.g., by using AMCL. Doing the planning on the map and then using another coordinate system for following that path is strange. But maybe there is a use case. Would be interesting to know about your use case.

reinzor commented 4 years ago

A use case would be a controller that accepts odom (without localization) plans and map plans. Now this is not possible.

Let's say the odom to base_link tf is continuous (should be) and the map to odom frame jumps due to poor localization. Then you still want to be able to path follow in your odom frame without first transforming it to map.

Rayman commented 4 years ago

In fact, this is possible in the master version by:

global_frame: map
map_frame: odom

It looks a bit strange, but it works.

reinzor commented 4 years ago

Also in relation with https://github.com/magazino/move_base_flex/issues/113. For me, a frame for the planner and a frame for the controller would be sufficient.

corot commented 4 years ago

A use case would be a controller that accepts odom (without localization) plans and map plans. Now this is not possible.

Let's say the odom to base_link tf is continuous (should be) and the map to odom frame jumps due to poor localization. Then you still want to be able to path follow in your odom frame without first transforming it to map.

that means that your controller operates in a local costmap with reference odom, right?

To my understanding, map_frame and robot_frame should come from the costmaps, when using mbf_costmap_nav, and be different for planners and controllers.