-
Notifications
You must be signed in to change notification settings - Fork 173
Test cases for Fallbacks container #280
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
Conversation
v4hn
left a comment
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.
@j-kuehn Thank you for the discussed tests! I would appreciate if you could provide a fix for ActiveChildReset as well. 🐈
@rhaschke I would appreciate your opinion on the second issue. I strictly prefer the behavior in the test (don't run alternatives if a solution succeeds) but if you prefer we can add an option to toggle behaviors instead.
core/test/test_container.cpp
Outdated
| t.add(std::move(fallbacks)); | ||
|
|
||
| EXPECT_TRUE(t.plan()); | ||
| EXPECT_EQ(t.numSolutions(), 4u); |
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.
Depending on the preferred semantics (whether fallback alternatives should be computed at all), the test is still not correct: If no alternatives should be considered you would have to check for two solutions where both should come from the first ForwardMockup.
Let's wait for Robert's response before modifying 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.
I don't yet fully understand the purpose of this test. I would expect two solutions here, contributed by the first child. However, this was not yet tested here. I pushed a corresponding fixup.
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.
There should be another test case, where the external generator is failing first before succeeding.
Currently, I would expect this test to fail (with a solution of the wrong, second child).
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 test suggested that after computing solutions for the second spawned solution from the generator, the active_child_ would not be reset to the first child for computing the third solution. Before your two commits, this led to the first child being ignored for the third spawned generator solution.
As @v4hn pointed out, this test was not consistent with the proposed functionality in ComputeFirstSuccessfulStageOnly, but rather tried to test the status quo. But even after your fix for the ActiveChildReset test, I would have expected the test to fail, because as I understand it, the active_child_ is pointing to the second child after the second spawned generator solution. So for the third solution, I expected the container to use the second child for computation. However, the test passes, so it is actually using the first child. I'm not sure how your commit fixed this.
I just tried adding another test as you suggested, where the external generator is failing first before succeeding:
std::make_unique<GeneratorMockup>(PredefinedCosts{ { INF, 0.0 } }));However, this yields 0 solutions and I'm not sure why.
rhaschke
left a comment
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.
Thanks for providing these tests. See detailed comments below.
I suggest to disable/skip ConnectStageInsideFallbacks for now as it won't easily fix.
@v4hn: Do you already have concrete plans, how to implement a topological processing order?
core/test/test_container.cpp
Outdated
| t.add(std::move(fallbacks)); | ||
|
|
||
| EXPECT_TRUE(t.plan()); | ||
| EXPECT_EQ(t.numSolutions(), 4u); |
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 yet fully understand the purpose of this test. I would expect two solutions here, contributed by the first child. However, this was not yet tested here. I pushed a corresponding fixup.
core/test/test_container.cpp
Outdated
| EXPECT_EQ(t.solutions().size(), 0u); | ||
| } | ||
|
|
||
| TEST(Fallback, ConnectStageInsideFallbacks) { |
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 fails for the following reason:
- The
Generatorspawns a solution, which is correctly forwarded to the start pull interface ofConnect. - However, because there was no state pushed into the end pull interface of
Connect,canCompute()returns false
and theFallbackscontainer forwards to the next child (which doesn't exist).
This can only be solved, if we drop the simple linear execution order and switch to topological execution order.
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.
Sounds reasonable to disable this test for now.
This should work, but will require more changes.
v4hn
left a comment
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.
Thanks for the feedback. I wanted to leave it to @j-kuehn to implement a fix for at least the simple test, but it looks like we disagree on what exactly should happen? Please give your reasoning to my comment below.
|
|
||
| if (!Stage::solutions().empty()) | ||
| return false; // we are done as soon as a child has found solutions | ||
|
|
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 patch does not make any sense to me.
If the generator in ComputeFirstSuccessfulStageOnly would spawn multiple solutions, I would still expect a solution from the first child for each of the inputs! Otherwise you prune too many computation branches and loose solutions.
| EXPECT_TRUE(t.plan()); | ||
| EXPECT_EQ(t.numSolutions(), 4u); | ||
| EXPECT_EQ(t.numSolutions(), 2u); | ||
| EXPECT_EQ(first->solutions().size(), 2u); |
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 seems we agree on how this test should behave. That's good. :)
However, this only succeeds because of https://github.com/ros-planning/moveit_task_constructor/pull/280/files#diff-5b0930974b77eab73f48b74214a60ac0562cd2a110285279bb5ad1094b40a842R822 now (Robert fixes the active child as soon as it produced any solution, even if it can't compute in between). As I do not agree with this patch we are not done here yet.
Codecov Report
@@ Coverage Diff @@
## master #280 +/- ##
==========================================
+ Coverage 51.61% 51.64% +0.04%
==========================================
Files 101 101
Lines 6587 6588 +1
==========================================
+ Hits 3399 3402 +3
+ Misses 3188 3186 -2
Continue to review full report at Codecov.
|
|
superseded by #287 |
I added three test cases for the
Fallbackscontainer:ConnectStageInsideFallbacksshows that adding aConnectstage to theFallbackscontainer seems to be broken, as no solution can be computed for the task currently.ComputeFirstSuccessfulStageOnlysuggests that solutions inside theFallbackscontainer should not be computed after one solution has been found. I'm not sure how the container was originally intended to work, so this might not be a bug.ActiveChildResetreveals the failure of the container to reset theactive_child_for every spawned solution from a generator. In this test case, the firstForwardMockupdoes not become theactive_child_for the third spawned solution from theGeneratorMockup.