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

Bad Expected Access Error #199

Closed
buddha314 opened this issue May 29, 2020 · 11 comments
Closed

Bad Expected Access Error #199

buddha314 opened this issue May 29, 2020 · 11 comments
Assignees
Labels
bug Something isn't working

Comments

@buddha314
Copy link

This is likely to be user error, but I would appreciate your opinion.

BT::NodeStatus FlipCoin::tick() {
    /* initialize random seed */
    auto pb = getInput<std::string>("bias");
    std::cout << "bias: " << stod(pb.value()) << std::endl;
    double bias = 0.7;

    BT::NodeStatus status;
    this->f = this->getFlip();
    if (this->f < bias) {
        status = BT::NodeStatus::SUCCESS;
        std::cout << "We won! " << this->f <<  std::endl;
    } else {
        status = BT::NodeStatus::FAILURE;
        std::cout << "We lost! " << this-> f << std::endl;
    }
    return status;
}

double FlipCoin::getFlip() {
    srand(time(NULL));
    double f = rand() / double (RAND_MAX);
    return f;
}

BT::PortsList FlipCoin::providedPorts() {
    return {BT::InputPort<std::string>("bias")};
}

Main

int main() {
    std::cout << "Hello, World!" << std::endl;

    // We use the BehaviorTreeFactory to register our custom nodes
    BehaviorTreeFactory factory;

    // The recommended way to create a Node is through inheritance.
    factory.registerNodeType<FlipCoin>("FlipCoin");

    factory.registerNodeType<ApproachObject>("ApproachObject");

    auto tree = factory.createTreeFromFile("../my_tree.xml");
    tree.tickRoot();

    return 0;
}

The XML

<root main_tree_to_execute = "MainTree">
    <BehaviorTree ID = "MainTree">
        <Sequence>
            <Action ID="FlipCoin" name="flip_coin" bias="0.7" />
            <Action ID="ApproachObject" name="approach_object" />
        </Sequence>
    </BehaviorTree>
</root>

And I get the error

/mnt/c/Users/b/CLionProjects/beetree/cmake-build-debug/beetree
Hello, World!
terminate called after throwing an instance of 'nonstd::expected_lite::bad_expected_access<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >'
  what():  bad_expected_access

Process finished with exit code 134

Thank you!

@facontidavide
Copy link
Collaborator

I tried a minimal example and everything looks fine...

static const char* xml_text = R"(
<root main_tree_to_execute = "MainTree">
    <BehaviorTree ID = "MainTree">
        <Action ID="FlipCoin" name="flip_coin" bias="0.7" />
    </BehaviorTree>
</root>
 )";

class FlipCoin : public BT::SyncActionNode
{
public:

  FlipCoin(const std::string& name, const NodeConfiguration& config):
    SyncActionNode(name, config) {}

  BT::NodeStatus tick()
  {
    auto pb = getInput<std::string>("bias");
    std::cout << "bias: " << stod(pb.value()) << std::endl;
    return BT::NodeStatus::SUCCESS;
  }

  static BT::PortsList providedPorts()
  {
    return { BT::InputPort<std::string>("bias") };
  }
};

int main()
{
  BehaviorTreeFactory factory;
  factory.registerNodeType<FlipCoin>("FlipCoin");
  auto tree = factory.createTreeFromText( xml_text );
  tree.tickRoot();
  return 0;
}

@vinnnyr
Copy link

vinnnyr commented Jun 6, 2020

@buddha314 I have seen this issue when attempting to call getInput on a string that was not provided as a port by mistake. I don't see that error in your example code however, but I am just throwing that idea out there.

@buddha314
Copy link
Author

Thanks! I'll see if that opens up some ideas.

@facontidavide
Copy link
Collaborator

If you send me the entire code, I can try to reproduce the issue (my minimal code doesn't reproduce it)

@facontidavide
Copy link
Collaborator

any update on this? as I said, I am not able to reproduce this. I will close this for the time being. Feeel free to open it again

@simchanu29
Copy link

simchanu29 commented Nov 18, 2020

I got a similar issue with a tree containing a subtree containing an action. I had a blackboard value initialized in the tree, given to the action in the subtree by port remapping.

I got the exact same error

terminate called after throwing an instance of 'nonstd::expected_lite::bad_expected_access<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >'
  what():  bad_expected_access

With some debugging I found that in utils/expected.hpp the error is getInput() failed because it was unable to find the key [server_name] remapped to [server_name]. Maybe this error should be printed on a bad_expected_access ?

If anyone get the same error this was my issue and how i fixed it :

    <BehaviorTree ID="BehaviorTree">
        <SubTree ID="SubTreeMove" delay_msec="5000" num_attempts="3" server_name="/move_goal" target="{pos}"/>
    </BehaviorTree>
    <!-- ////////// -->
    <BehaviorTree ID="SubTreeMove">
        <Fallback>
            <Action ID="MoveBaseAction" server_name="{server_name}" target="{target}"/>
            <Delay delay_msec="{delay_msec}">
                <RetryUntilSuccesful num_attempts="{num_attempts}">
                    <Action ID="MoveBaseAction" server_name="{server_name}" target="{target}"/>
                </RetryUntilSuccesful>
            </Delay>
        </Fallback>
    </BehaviorTree>

The tree above doesn't work. I had misunderstood how remapping between a tree and a subtree works.

If I understood correctly, the arguments inside the SubTree xml tag must be keys and not values. Therefore I can't give a value server_name="/move_goal" because it will look for the key /move_goal and won't find it. It's the same for the other parameter, for example {pos} is a mistake as well and must be pos.

I think this imply that all the keys listed in the remapping must be initialized before by a SetBlackboard action (or something similar).

So since I don't want to have 3 SetBlackboard actions before my SubTree I have to do the following :

    <BehaviorTree ID="BehaviorTree">
        <SubTree ID="SubTreeMove" target="pos"/>
    </BehaviorTree>
    <!-- ////////// -->
    <BehaviorTree ID="SubTreeMove">
        <Fallback>
            <Action ID="MoveBaseAction" server_name="/move_goal" target="{target}"/>
            <Delay delay_msec="5000">
                <RetryUntilSuccesful num_attempts="3">
                    <Action ID="MoveBaseAction" server_name="/move_goal" target="{target}"/>
                </RetryUntilSuccesful>
            </Delay>
        </Fallback>
    </BehaviorTree>

The documentation helped a bit but maybe it would benefit to be a bit clearer on this topic.

On a side remark, I'm not sure this is in the scope of the issue, but I think it would be better if a SubTree act like a function with value arguments (with the brackets you can still give a key) instead of working like a function with pointer arguments. It would be easier to be able to set values in a SubTree xml tag (like in a function) instead of having to pass the values by key (reference) and thus having to set them before.

@cameronschloer
Copy link

cameronschloer commented Mar 15, 2022

It definitely seems like there is something buggy going on. I'm getting the same issue with a very simple tree that breaks in only one specific scenario.

Here is my failing tree:

  <root main_tree_to_execute = "MainTree" >
    <BehaviorTree ID="MainTree">
      <SendActionMsg commanded_action="START_OF_PATH" lights="false" />
    </BehaviorTree>
  </root>

Here are two trees that will run with no error that are almost identical:

  <root main_tree_to_execute = "MainTree" >
    <BehaviorTree ID="MainTree">
      <SendActionMsg commanded_action="START_OF_PATH" lights="false" blades_active="false" />
    </BehaviorTree>
  </root>
  <root main_tree_to_execute = "MainTree" >
    <BehaviorTree ID="MainTree">
      <SendActionMsg commanded_action="START_OF_PATH" blades_active="false" />
    </BehaviorTree>
  </root>

The order of the ports doesn't matter (same results). The tree will not run with "lights" when it doesn't have "blades_active" with it, but "blades_active" can be by itself. Both are declared the same way as bools. It seems like something is fragile and breaking here in the code. I would assume it's my code, but it seems like others have had this issue too.

It's inconsistent enough that adding or removing certain ports seems to mask the issue, so that's probably why those that have commented have been able to find workarounds. I have been able to find workarounds too, but this seems to be a problem with the BT code itself.

As simchanu29 mentioned, it would at least be good to expand the error message to be more clear on what is failing exactly.

@facontidavide
Copy link
Collaborator

facontidavide commented Mar 15, 2022

Please provide the entire code in a ZIP file to allow me to reproduce the problem

@facontidavide facontidavide self-assigned this Oct 24, 2022
@facontidavide facontidavide added the bug Something isn't working label Oct 24, 2022
@Ztubben
Copy link

Ztubben commented Dec 27, 2022

Hello

I have the same issue. Any progress in this matter?

@facontidavide
Copy link
Collaborator

@Ztubben , please provide a way to reproduce the error. A self contained example, that I can compile and run, and I will be happy to address this this week.

It would be very helpful id @cameronschloer and @simchanu29 do the same.

As I said, I was never able to reproduce the issue mentioned by @buddha314

@facontidavide
Copy link
Collaborator

closing for inactivity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

6 participants