Skip to content

Conversation

@j-kuehn
Copy link
Contributor

@j-kuehn j-kuehn commented Jul 12, 2021

I added three test cases for the Fallbacks container:

  • ConnectStageInsideFallbacks shows that adding a Connect stage to the Fallbacks container seems to be broken, as no solution can be computed for the task currently.
  • ComputeFirstSuccessfulStageOnly suggests that solutions inside the Fallbacks container 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.
  • ActiveChildReset reveals the failure of the container to reset the active_child_ for every spawned solution from a generator. In this test case, the first ForwardMockup does not become the active_child_ for the third spawned solution from the GeneratorMockup.

@j-kuehn j-kuehn changed the title Fallback tests Test cases for Fallbacks container Jul 12, 2021
Copy link
Contributor

@v4hn v4hn left a 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.

t.add(std::move(fallbacks));

EXPECT_TRUE(t.plan());
EXPECT_EQ(t.numSolutions(), 4u);
Copy link
Contributor

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.

Copy link
Contributor

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.

Copy link
Contributor

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).

Copy link
Contributor Author

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.

Copy link
Contributor

@rhaschke rhaschke left a 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?

t.add(std::move(fallbacks));

EXPECT_TRUE(t.plan());
EXPECT_EQ(t.numSolutions(), 4u);
Copy link
Contributor

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.

EXPECT_EQ(t.solutions().size(), 0u);
}

TEST(Fallback, ConnectStageInsideFallbacks) {
Copy link
Contributor

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:

  1. The Generator spawns a solution, which is correctly forwarded to the start pull interface of Connect.
  2. However, because there was no state pushed into the end pull interface of Connect, canCompute() returns false
    and the Fallbacks container 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.

Copy link
Contributor Author

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.

@rhaschke
Copy link
Contributor

Ping @v4hn, @j-kuehn. Any thoughts on my feedback?

This should work, but will require more changes.
Copy link
Contributor

@v4hn v4hn left a 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

Copy link
Contributor

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);
Copy link
Contributor

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
Copy link

codecov bot commented Jul 26, 2021

Codecov Report

Merging #280 (414964a) into master (74d33c4) will increase coverage by 0.04%.
The diff coverage is 100.00%.

Impacted file tree graph

@@            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     
Impacted Files Coverage Δ
core/src/container.cpp 70.82% <100.00%> (+0.43%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 74d33c4...414964a. Read the comment docs.

@v4hn
Copy link
Contributor

v4hn commented Sep 3, 2021

superseded by #287

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.

3 participants