Skip to content
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

Feat/smac planner include orientation flexibility #4127

Draft
wants to merge 51 commits into
base: main
Choose a base branch
from

Conversation

stevedanomodolor
Copy link
Contributor

@stevedanomodolor stevedanomodolor commented Feb 20, 2024


Basic Info

Info Please fill out this column
Ticket(s) this addresses (add tickets here #4019)
Primary OS tested on (Ubuntu, MacOS, Windows)
Robotic platform tested on (Steve's Robot, gazebo simulation of Tally, hardware turtlebot)
Does this PR contain AI generated software? (No; Yes and it is marked inline in the code)

Description of contribution in a few bullet points

  • tackles issue [Smac Planner] Enable goal orientation non-specificity #3789
  • Includes the possibility for the user to determine whether they want the goal heading should be default(the one defined in the goal), bidirectional (user defined + 180 degrees), or all_direction. This way, the user can save time calling the planner multiple times when the angle of the goal does not have to be fixed and has a bit of flexibility.
  • Results can be seen.
Success rate for  ALL_DIRECTION_SmacHybrid  is:  98.33333333333333 %
Success rate for  ALL_DIRECTION_SmacLattice  is:  97.66666666666667 %
Success rate for  ALL_DIRECTION_Smac2d  is:  100.0 %
Success rate for  BIDIRECTIONAL_SmacHybrid  is:  98.33333333333333 %
Success rate for  BIDIRECTIONAL_SmacLattice  is:  97.66666666666667 %
Success rate for  BIDIRECTIONAL_Smac2d  is:  100.0 %
Success rate for  DEFAULT_SmacHybrid  is:  96.66666666666667 %
Success rate for  DEFAULT_SmacLattice  is:  95.0 %
Success rate for  DEFAULT_Smac2d  is:  100.0 %
Success rate for  NORMAL_SmacHybrid  is:  96.66666666666667 %
Success rate for  NORMAL_SmacLattice  is:  95.0 %
Success rate for  NORMAL_Smac2d  is:  100.0 %
**********************Results Goal heading mode Default **********************
Read data
-------------------  -----------------------  -------------------  ------------------  ------------------
Planner              Average path length (m)  Average Time (s)     Average cost        Max cost
DEFAULT_SmacHybrid   48.59179172137297        0.08409778965140845  1.0656706399532687  54.59154929577465
DEFAULT_SmacLattice  49.30762557367365        0.4135887128204226   0.8137733557552133  53.813380281690144
DEFAULT_Smac2d       48.52958672840513        0.12046826587323943  0.7580233687132835  65.47183098591549
-------------------  -----------------------  -------------------  ------------------  ------------------
**********************Results Goal heading mode bidrectional **********************
Read data
-------------------------  -----------------------  -------------------  ------------------  -----------------
Planner                    Average path length (m)  Average Time (s)     Average cost        Max cost
BIDIRECTIONAL_SmacHybrid   48.72823963695479        0.03030190022535211  1.0223910481559262  54.13028169014085
BIDIRECTIONAL_SmacLattice  49.50773050762388        0.17851250328169013  0.7209227860091986  51.23943661971831
BIDIRECTIONAL_Smac2d       48.52960037283171        0.12235441819718311  0.7580233687132835  65.47183098591549
-------------------------  -----------------------  -------------------  ------------------  -----------------
**********************Results Goal heading mode all direction **********************
Read data
-------------------------  -----------------------  --------------------  ------------------  -----------------
Planner                    Average path length (m)  Average Time (s)      Average cost        Max cost
ALL_DIRECTION_SmacHybrid   48.72823963695479        0.031168896616197185  1.0223910481559262  54.13028169014085
ALL_DIRECTION_SmacLattice  49.50773050762388        0.18361958839788733   0.7209227860091986  51.23943661971831
ALL_DIRECTION_Smac2d       48.52960037283171        0.12754024430633804   0.7580233687132835  65.47183098591549


**********************Results Goal heading mode NO changes **********************
Read data
-----------  -----------------------  -------------------  ------------------  ------------------
Planner      Average path length (m)  Average Time (s)     Average cost        Max cost
SmacHybrid   48.59179172137297        0.0930492549330986   1.0656706399532687  54.59154929577465
SmacLattice  49.30762557367365        0.44674316980633805  0.8137733557552133  53.813380281690144
Smac2d       48.52958672840513        0.12973642600352114  0.7580233687132835  65.47183098591549
-----------  -----------------------  -------------------  ------------------  ------------------

Description of documentation updates required from your changes


How to run


Future work that may be required in bullet points

For Maintainers:

  • Check that any new parameters added are updated in navigation.ros.org
  • Check that any significant change is added to the migration guide
  • Check that any new features OR changes to existing behaviors are reflected in the tuning guide
  • Check that any new functions have Doxygen added
  • Check that any new features have test coverage
  • Check that any new plugins is added to the plugins page
  • If BT Node, Additionally: add to BT's XML index of nodes for groot, BT package's readme table, and BT library lists

@stevedanomodolor stevedanomodolor marked this pull request as draft February 20, 2024 19:14
@SteveMacenski
Copy link
Member

SteveMacenski commented Feb 21, 2024

@stevedanomodolor what's the status here - do you want me to review in detail, have gaps that are TODO, or have some questions to discuss? I don't want to go through and nitpick some small issues if you're really looking for feedback elsewhere right now.

Copy link
Member

@SteveMacenski SteveMacenski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't review the analytic expansions yet, pending your answer to my above question. But overall from what I read so far, very few notes. This is very good and I couldn't have done it better myself!

nav2_smac_planner/include/nav2_smac_planner/constants.hpp Outdated Show resolved Hide resolved
nav2_smac_planner/CMakeLists.txt Outdated Show resolved Hide resolved
nav2_smac_planner/src/a_star.cpp Outdated Show resolved Hide resolved
nav2_smac_planner/src/a_star.cpp Show resolved Hide resolved
nav2_smac_planner/src/a_star.cpp Outdated Show resolved Hide resolved
nav2_smac_planner/src/smac_planner_hybrid.cpp Outdated Show resolved Hide resolved
nav2_smac_planner/src/smac_planner_hybrid.cpp Outdated Show resolved Hide resolved
nav2_smac_planner/src/smac_planner_hybrid.cpp Outdated Show resolved Hide resolved
nav2_smac_planner/src/smac_planner_hybrid.cpp Outdated Show resolved Hide resolved
@stevedanomodolor
Copy link
Contributor Author

stevedanomodolor commented Feb 21, 2024

@stevedanomodolor what's the status here - do you want me to review in detail, have gaps that are TODO, or have some questions to discuss? I don't want to go through and nitpick some small issues if you're really looking for feedback elsewhere right now.

If you consider the general approach to be ok, then you can review it in detail. If the approach is good, what is just left is to modify the test to take into consideration these changes hench the todo in the CMakelists.

@SteveMacenski
Copy link
Member

SteveMacenski commented Feb 21, 2024

I think the analytic expansions might need to be rethought a bit. I think we should be taking all N of the goals and computing the analytic path, if valid. If any are valid, take the shortest one. There shouldn't be a loop surrounding the preamble which tells us if we want to do analytic expansions in this iteration:

      closest_distance = goal_distance_pair.second;
      NodePtr goal_node = goal_distance_pair.first;
      // We want to expand at a rate of d/expansion_ratio,
      // but check to see if we are so close that we would be expanding every iteration
      // If so, limit it to the expansion ratio (rounded up)
      int desired_iterations = std::max(
        static_cast<int>(closest_distance / _search_info.analytic_expansion_ratio),
        static_cast<int>(std::ceil(_search_info.analytic_expansion_ratio)));
      // If we are closer now, we should update the target number of iterations to go
      analytic_iterations =
        std::min(analytic_iterations, desired_iterations);

      // Always run the expansion on the first run in case there is a
      // trivial path to be found
      if (analytic_iterations <= 0) {

I think your logic is that if we sort by heuristic, then the first that comes back as a valid expansion will be the shortest. I think that would generally be true if the heuristic was a very purist implementation of a distance heuristic. But instead, we have the maximum of a few heuristics including cost information so the "closest" and the one with the "lowest travel cost" aren't necessarily the same thing. So I think largely these changes should be taken back to square one unfortunately and loop to find each of the N goals orientation's analytic expansion length (if valid) and then select the lowest cost one. Interestingly, you can use the new scoringFn to measure that for the final one to store. Luckily, there wasn't a huge number of changes you made to the analytic expansions, so its not a big setback at all and largely its just moving code around and measuring different things

So after

          while (min_turn_rad < max_min_turn_rad) {
            min_turn_rad += 0.5;  // In Grid Coords, 1/2 cell steps
            ompl::base::StateSpacePtr state_space;
            if (node->motion_table.motion_model == MotionModel::DUBIN) {
              state_space = std::make_shared<ompl::base::DubinsStateSpace>(min_turn_rad);
            } else {
              state_space = std::make_shared<ompl::base::ReedsSheppStateSpace>(min_turn_rad);
            }
            refined_analytic_nodes = getAnalyticPath(node, goal_node, getter, state_space);
            score = scoringFn(refined_analytic_nodes);
            if (score <= best_score) {
              analytic_nodes = refined_analytic_nodes;
              best_score = score;
            }
          }

You can use that best_score, store it for that particular angle to decide which to use.

Copy link
Member

@SteveMacenski SteveMacenski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ran out of time this evening to review, but this is a few things -- also you have a number of linting issues I can see. Check CI for the full list of formatting problems

nav2_smac_planner/include/nav2_smac_planner/a_star.hpp Outdated Show resolved Hide resolved
nav2_smac_planner/CMakeLists.txt Outdated Show resolved Hide resolved
nav2_smac_planner/src/smac_planner_hybrid.cpp Outdated Show resolved Hide resolved
@SteveMacenski
Copy link
Member

Its also ready enough to update docs for the new variable for the mode to describe the mode, and the migration guide update to show this feature. An image/gif of this in action with the different modes would be great!

I looked through it and all looks good except the analytic expansions I didn't get to right now

Copy link
Contributor

@jwallace42 jwallace42 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

I think you are missing some work for the distance heuristic.

The distance heuristic is pre computed based on free space. We current only calculate it for the the first goal. This means that we could artificially inflate the cost to go making the heuristic inadmissible.

My suggestion would be to remove the distance heuristic when we are in ALL_DIRECTION mode. For the BIDIRECTIONAL mode I would pre compute the distance for both angles and take the min of those two.

From what I have seen the distance heuristic is rarely greater than the obstacle heuristic so you probably haven't seen any issues.

nav2_smac_planner/src/a_star.cpp Outdated Show resolved Hide resolved
@SteveMacenski
Copy link
Member

Any questions or anything I can unblock on? 😄

Copy link
Contributor

mergify bot commented Mar 9, 2024

@stevedanomodolor, your PR has failed to build. Please check CI outputs and resolve issues.
You may need to rebase or pull in main due to API changes (or your contribution genuinely fails).

2 similar comments
Copy link
Contributor

mergify bot commented Mar 9, 2024

@stevedanomodolor, your PR has failed to build. Please check CI outputs and resolve issues.
You may need to rebase or pull in main due to API changes (or your contribution genuinely fails).

Copy link
Contributor

mergify bot commented Mar 10, 2024

@stevedanomodolor, your PR has failed to build. Please check CI outputs and resolve issues.
You may need to rebase or pull in main due to API changes (or your contribution genuinely fails).

@stevedanomodolor
Copy link
Contributor Author

stevedanomodolor commented Mar 10, 2024

Any questions or anything I can unblock on? 😄

No blocking points, just making changes based on @jwallace42 feedback and testing them but after merging to the main and pulling the latest dockers, pr is not building.

Copy link
Contributor

mergify bot commented Mar 10, 2024

@stevedanomodolor, your PR has failed to build. Please check CI outputs and resolve issues.
You may need to rebase or pull in main due to API changes (or your contribution genuinely fails).

1 similar comment
Copy link
Contributor

mergify bot commented Mar 10, 2024

@stevedanomodolor, your PR has failed to build. Please check CI outputs and resolve issues.
You may need to rebase or pull in main due to API changes (or your contribution genuinely fails).

@SteveMacenski
Copy link
Member

SteveMacenski commented Mar 11, 2024

Yeah there's a transient issue due to Rolling moving to 24.04 so a bunch of tooling and package indices are being messed with. Don't worry about it, its not your fault as long as it works locally. Just make sure to keep up on unit testing.

Want me to take a look again?

nav2_smac_planner/src/a_star.cpp Outdated Show resolved Hide resolved
nav2_smac_planner/src/a_star.cpp Show resolved Hide resolved
nav2_smac_planner/src/analytic_expansion.cpp Outdated Show resolved Hide resolved
@stevedanomodolor
Copy link
Contributor Author

Yeah there's a transient issue due to Rolling moving to 24.04 so a bunch of tooling and package indices are being messed with. Don't worry about it, its not your fault as long as it works locally. Just make sure to keep up on unit testing.

Want me to take a look again?

I will take advantage of the time to add more unit testing after making the modification you suggested. After the added unit tests, you can look into it.

Copy link
Contributor

mergify bot commented Mar 23, 2024

@stevedanomodolor, your PR has failed to build. Please check CI outputs and resolve issues.
You may need to rebase or pull in main due to API changes (or your contribution genuinely fails).

9 similar comments
Copy link
Contributor

mergify bot commented Mar 24, 2024

@stevedanomodolor, your PR has failed to build. Please check CI outputs and resolve issues.
You may need to rebase or pull in main due to API changes (or your contribution genuinely fails).

Copy link
Contributor

mergify bot commented Mar 24, 2024

@stevedanomodolor, your PR has failed to build. Please check CI outputs and resolve issues.
You may need to rebase or pull in main due to API changes (or your contribution genuinely fails).

Copy link
Contributor

mergify bot commented Mar 24, 2024

@stevedanomodolor, your PR has failed to build. Please check CI outputs and resolve issues.
You may need to rebase or pull in main due to API changes (or your contribution genuinely fails).

Copy link
Contributor

mergify bot commented Mar 24, 2024

@stevedanomodolor, your PR has failed to build. Please check CI outputs and resolve issues.
You may need to rebase or pull in main due to API changes (or your contribution genuinely fails).

Copy link
Contributor

mergify bot commented Mar 25, 2024

@stevedanomodolor, your PR has failed to build. Please check CI outputs and resolve issues.
You may need to rebase or pull in main due to API changes (or your contribution genuinely fails).

Copy link
Contributor

mergify bot commented Mar 25, 2024

@stevedanomodolor, your PR has failed to build. Please check CI outputs and resolve issues.
You may need to rebase or pull in main due to API changes (or your contribution genuinely fails).

Copy link
Contributor

mergify bot commented Mar 25, 2024

@stevedanomodolor, your PR has failed to build. Please check CI outputs and resolve issues.
You may need to rebase or pull in main due to API changes (or your contribution genuinely fails).

Copy link
Contributor

mergify bot commented Mar 25, 2024

@stevedanomodolor, your PR has failed to build. Please check CI outputs and resolve issues.
You may need to rebase or pull in main due to API changes (or your contribution genuinely fails).

Copy link
Contributor

mergify bot commented Mar 25, 2024

@stevedanomodolor, your PR has failed to build. Please check CI outputs and resolve issues.
You may need to rebase or pull in main due to API changes (or your contribution genuinely fails).

stevedanomodolor and others added 20 commits November 18, 2024 19:36
Signed-off-by: stevedan <stevedan.o.omodolor@gmail.com>
Signed-off-by: stevedan <stevedan.o.omodolor@gmail.com>
Signed-off-by: stevedan <stevedan.o.omodolor@gmail.com>
Signed-off-by: stevedan <stevedan.o.omodolor@gmail.com>
Signed-off-by: stevedan <stevedan.o.omodolor@gmail.com>
Signed-off-by: stevedan <stevedan.o.omodolor@gmail.com>
)

Add header data to goal for short paths.

Commit d8ae3c1 added the possibility to
the rotation shim controller to rotate towards the goal when the goal
was closer that the `forward_sampling_distance`. This feature was not
fully working as the goal was missing proper header data, causing the
rotation shim to give back control to the main controller.

Co-authored-by: agennart <antoine.gennart@quimesis.be>
* Added load and save panel

Signed-off-by: Alberto Tudela <ajtudela@gmail.com>

* Improved dock_panel state machine

Signed-off-by: Alberto Tudela <ajtudela@gmail.com>

* Added loading dock plugins log

Signed-off-by: Alberto Tudela <ajtudela@gmail.com>

* Redo UI

Signed-off-by: Alberto Tudela <ajtudela@gmail.com>

* Update tooltips

Signed-off-by: Alberto Tudela <ajtudela@gmail.com>

* Fix null-dereference

Signed-off-by: Alberto Tudela <ajtudela@gmail.com>

---------

Signed-off-by: Alberto Tudela <ajtudela@gmail.com>
Signed-off-by: Daniil Khaninaev <khaninaev@yahoo.com>
…4724)

Add frame_id to goal when rotating towards goal heading, otherwise the
transform would fail. This bug was introduced in 30e2cde by not setting
the frame_id.

Signed-off-by: agennart <antoine.gennart@quimesis.be>
Co-authored-by: agennart <antoine.gennart@quimesis.be>
Signed-off-by: stevedan <stevedan.o.omodolor@gmail.com>
Signed-off-by: stevedan <stevedan.o.omodolor@gmail.com>
Signed-off-by: stevedan <stevedan.o.omodolor@gmail.com>
Signed-off-by: stevedan <stevedan.o.omodolor@gmail.com>
Signed-off-by: stevedan <stevedan.o.omodolor@gmail.com>
Signed-off-by: stevedan <stevedan.o.omodolor@gmail.com>
Signed-off-by: stevedan <stevedan.o.omodolor@gmail.com>
…ithub.com:stevedanomodolor/navigation2 into feat/smac_planner_include_orientation_flexibility
Signed-off-by: stevedan <stevedan.o.omodolor@gmail.com>
@SteveMacenski
Copy link
Member

SteveMacenski commented Nov 19, 2024

I just wanted to use the same goals to benchmark the current state of the stack and the changes I made.

But if you use a single goal, its not necessarily representative of randomness. If you have the same random seed at the start, then it should be deterministic.

The issue with this is that we assume that all the possible angles do not collide with the goal which is not the case because during the isinput valid stage, we remove goals in collision.

I guess this is where I'd handwave that the heuristic is an estimate, not an exact science - but this is a good point and a reason that if we don't see performance degradation we could do the for loop over each of the goal orientations for the distance heuristic, we can/should do that (which also simplifies code changes, which makes me happy 😄 ).

Why is that one ALL_DIRECTION_SmacHybrid so much higher than the others (20x)? This is also where maybe the goal non-randomness is working against you (the goal is at a really inconvenient location) rather than an actual problem in the software? I don't know though.

There was no significant difference between the computational time which makes me believe that the bottleneck in all directions is not in the distance heuristic computation stage but most probably is in the expansion stage in the planning loop.

It would be good to understand this to know that's the reason with some confidence. I don't disagree that could be a future improvement, but I'd like for us to at least understand if this is a correct assumption (and if not, maybe the issue is somewhere we can fix easily)

@stevedanomodolor
Copy link
Contributor Author

stevedanomodolor commented Nov 20, 2024

I just wanted to use the same goals to benchmark the current state of the stack and the changes I made.

But if you use a single goal, its not necessarily representative of randomness. If you have the same random seed at the start, then it should be deterministic.

The issue with this is that we assume that all the possible angles do not collide with the goal which is not the case because during the isinput valid stage, we remove goals in collision.

I guess this is where I'd handwave that the heuristic is an estimate, not an exact science - but this is a good point and a reason that if we don't see performance degradation we could do the for loop over each of the goal orientations for the distance heuristic, we can/should do that (which also simplifies code changes, which makes me happy 😄 ).

Why is that one ALL_DIRECTION_SmacHybrid so much higher than the others (20x)? This is also where maybe the goal non-randomness is working against you (the goal is at a really inconvenient location) rather than an actual problem in the software? I don't know though.

I dont think it is though because i did two tests.

  • generated lots of random start and goal position using the map that is currently used for benchmarking the planners and still got similar results where the all directions is high. This was the initial result i sent.
  • the second one that i did was a known start and end goal with no obstacle. The reason i chose this to do the optimization is because in the previous case, there was a chance that the goalsset might be reduced because it might be in collision. This way I know that i am working in the worse case where there is no obstacle and i expand to all the bins. I did this just to have a reference. This is just for this test specifically.

I think the problem is we are trying to expand to multiple goals, we are jumping from 1 goals to the worst case 72 different goals(if we have 72 bins).
In both cases the all directions was significantly higher, the second is higher because no goal in collision and we are using all the goalset. This is what i suspect.

There was no significant difference between the computational time which makes me believe that the bottleneck in all directions is not in the distance heuristic computation stage but most probably is in the expansion stage in the planning loop.

It would be good to understand this to know that's the reason with some confidence. I don't disagree that could be a future improvement, but I'd like for us to at least understand if this is a correct assumption (and if not, maybe the issue is somewhere we can fix easily)

I think i can do just that, i will time the functions in the planning loop to see where rhe bottleneck is.

@SteveMacenski
Copy link
Member

SteveMacenski commented Nov 20, 2024

Yeah that sounds good to me. I generally agree that this is probably the issue, I just want to know for sure before we assume too much :-)

I'm trying to think of some strategies to speed this up (if this is the case): Check every-Nth bin rather than all 72? Full resolution granularity when you don't care about your orientation at all seems over kill. Then we could do a refinement step to check in the sliver that has the 2 lowest bounding costs. So for example, we check every 5th bin (drops the cost for checking during search when unsuccessful by 4/5ths). If any are valid, we check the bounding range only between the 2 shortest ones.

That way, normal searches that have no expanions possible completes N-1/Nx faster and we only do the dense checking for a smaller sliver once we know there is any valid solution. I'd aruge the probability that we have some single-orientation solution to the planning problem that its 2 neighbors on either side are not valid at all for is virtually non-existent in practice -- which in exchange we speed up our planning time again

@stevedanomodolor
Copy link
Contributor Author

Yeah that sounds good to me. I generally agree that this is probably the issue, I just want to know for sure before we assume too much :-)

You are right on this. I assumed wrong. I did the following test for all the cases: default, bidirectional, and all_direction for the two planners. The start and end are on the left.
image

I measured the total time it took to call both the get_expansion and get_heuristic functions. The increase in execution time for both functions is more or less the same, but the get_heuristic function showed a significantly increase in comparison. This occurs in the all_direction mode, as the increase is not as pronounced in the bidirectional mode. By the way, I am using the default parameters provided on the Nav2 website. What I find strange is that the SMAC Hybrid planner performed much worse in all_direction mode compared to the SMAC Lattice planner.

<title></title>
<meta name="generator" content="LibreOffice 24.2.6.2 (Linux)"/>
<style type="text/css">
	body,div,table,thead,tbody,tfoot,tr,th,td,p { font-family:"Liberation Sans"; font-size:x-small }
	a.comment-indicator:hover + comment { background:#ffd; position:absolute; display:block; border:1px solid black; padding:0.5em;  } 
	a.comment-indicator { background:red; display:inline-block; border:1px solid black; width:0.5em; height:0.5em;  } 
	comment { display:none;  } 
</style>
  get heuristic time(ms) get expansion time(ms) ?x heuristic ?x expansion
Default hybrid 0.841365 1.427716    
Bidirectional hybrid 0.95309 1.517734 1.13279016835737 1.06305035455231
All direction hybrid 7.583123 12.685215 9.01288144859841 8.88497082052733
Default lattice 0.600979 1.27284    
Bidirectional lattice 1.057823 1.427675 1.76016632860716 1.12164529713083
All direction lattice 2.145226 2.166438 3.569552347087 1.70205053266711

I'm trying to think of some strategies to speed this up (if this is the case): Check every-Nth bin rather than all 72? Full resolution granularity when you don't care about your orientation at all seems over kill. Then we could do a refinement step to check in the sliver that has the 2 lowest bounding costs. So for example, we check every 5th bin (drops the cost for checking during search when unsuccessful by 4/5ths). If any are valid, we check the bounding range only between the 2 shortest ones.

That way, normal searches that have no expanions possible completes N-1/Nx faster and we only do the dense checking for a smaller sliver once we know there is any valid solution. I'd aruge the probability that we have some single-orientation solution to the planning problem that its 2 neighbors on either side are not valid at all for is virtually non-existent in practice -- which in exchange we speed up our planning time again

Would try this, it should improve the overall I believe.

@SteveMacenski
Copy link
Member

SteveMacenski commented Nov 26, 2024

What I find strange is that the SMAC Hybrid planner performed much worse in all_direction mode compared to the SMAC Lattice planner.

The Hybrid-A* can have 64, 72, or other total bins it needs to check. The state lattice planner typically has ~16 since the primitives have to create a regularized lattice structure. You could do more, but typically 16 is sufficient. If you reduced Hybrid-A* to 16, do you see a similar result as the state lattice planner?

@SteveMacenski
Copy link
Member

To summarize our call: We should do a course-to-fine search rather than going for all N (72) bins. We could introduce a new parameter for the analytic expansion that is the coarse search resolution (default: 4). If we find any valid path in that coarse search, then we do the full resolution. If we make it default to 4, it should have similar characteristics to the state lattice performance.

This should be relatively easy to implement using a queue and a while loop to replace the for loop, where it is initialized with every Nth goal orientation to start with. When the queue is empty at the end of the while loop, we can check if any expansion is valid. If so, then queue up the remaining non-Nth goal.

:-)

@stevedanomodolor
Copy link
Contributor Author

What I find strange is that the SMAC Hybrid planner performed much worse in all_direction mode compared to the SMAC Lattice planner.

The Hybrid-A* can have 64, 72, or other total bins it needs to check. The state lattice planner typically has ~16 since the primitives have to create a regularized lattice structure. You could do more, but typically 16 is sufficient. If you reduced Hybrid-A* to 16, do you see a similar result as the state lattice planner?

yes, get the same result

@SteveMacenski
Copy link
Member

Oh great - that means what we discussed will almost definitely improve performance to that level!

@stevedanomodolor
Copy link
Contributor Author

I tried the improvement, and it did reduce the overall time. 🎉

Now, I am testing another idea to further reduce the time for the distance heuristic. What do you think:

The main issue with the current method of storing a loopup table that contains the minimum values for all directions is that the chosen minimum goal might still end up in collision. In addition during the isInputValid check, we discard goals that are in collision. As a result, the "minimum" value stored may not be valid.

I propose the following, the first lookup table stores the distance as is now. In addition to this, i create another lookup table that for each position (x, y, θ) to (x,y,theta) i store the index of the position of the loop up table but sorted from minimum to maximum distance.

During the isInputValid step, I create a boolean list that marks which goals are invalid (i.e., in collision) and gives this information to the distance heuristic.

Using the Second Table, when evaluating the getDistance heuristic, we iterate through the indices in the second lookup table for the given (x, y, θ). We pick the first index corresponding to a goal that is not marked as invalid in the boolean list.

I tried before to create another lookup table during the is input valid, but its takes a long time to do that loop.

@SteveMacenski
Copy link
Member

SteveMacenski commented Dec 19, 2024

I tried the improvement, and it did reduce the overall time. 🎉

Yay! What's it look now?

What do you think

I think I understand: You want to keep the current lookup table so that you can access any point, orientation to query (HLUT1). Then, create a second lookup table that contains for each X,Y cell a vector of indexes of HLUT1, sorted by distance (HLUT2). So the size would be the same as HLUT, but store a vector rather than a float.

This is where you lose me.

During the isInputValid step, I create a boolean list that marks which goals are invalid (i.e., in collision) and gives this information to the distance heuristic.

Using the Second Table, when evaluating the getDistance heuristic, we iterate through the indices in the second lookup table for the given (x, y, θ). We pick the first index corresponding to a goal that is not marked as invalid in the boolean list.

Even if you had this, HLUT2 is sorted by distance. How do you know which distance belongs to which orientation? They're no longer ordered by orientation.

You would probably need to store a struct that contains the distance and the bin/orientation information. If you had that, I don't think you'd need the bool list, since you could just match any input node information to the struct's information. You'd march in order until you find the first bool list that's valid, likely just a few. However, you're now storing more information.

Or, don't sort it at all and go through the vector and find the min that meets the condition that has its corresponding bool list value is true. Then the bool list is needed and would require a full iteration of the vector.

I'd consider the memory impact of such a lookup table. If we have a HLUT dimension of 200x200 (10m at 5cm resolution) of floats, that's 0.32Mb. If we have each orientation stored as HLUT2 would have, say 72 as default, thats now 23Mb. For a HLUT of 20m x 20m (our default), that's 1.28Mb and 92Mb respectively. Double all these numbers if you store a float or int for the distance and some cell index information in a struct.

Assuming that's an OK amount of memory to store, accessing a memory block of that size, then iterating through the vector may actually turn out to be slower than just iterating through HLUT1 72 times.

Or not, we can't know without trying! Its a good idea and alot of these kind of things in Smac were done by 'just trying it out' and seeing what the results were


Separately, depending on the metrics from the change you made that worked, we may not need to pull out additional performance improvements by pushing more into lookup tables. But, we certainly could.

I think if we did something like that, it should be in a follow up PR as to not muddle up the great work done here and decouple the complexity a bit. The for each goal orientation -> find minimum distance heuristic loop seems performant enough for a first stab.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants