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

Subtree parameters #45

Closed
Masadow opened this issue Jan 7, 2019 · 7 comments
Closed

Subtree parameters #45

Masadow opened this issue Jan 7, 2019 · 7 comments
Assignees
Labels
duplicate This issue or pull request already exists

Comments

@Masadow
Copy link
Contributor

Masadow commented Jan 7, 2019

If there is, then I'm unaware (and it's not possible to add some in Groot) but that would be pretty neat to add the possibility to give parameters to subtree.

For instance, I have a subtree called Walk that is a sequence of nodes FaceTo and MoveTo.

Actually, I have to specify the target in both FaceTo and MoveTo while I would like to specify it at Walk level. Then FaceTo and MoveTo would just have to read Walk target value.

(In fact, I have to make a new subtree each time I want to face a different target).

I know I can use a blackboard value called target but it's not the desired result as in a more complex graph, I want to keep track of multiple targets (For example, in strategy game where the player orders a unit to harvest a resource, I will have two targets, the resource and the nearest storage to make the trip between the two)

@facontidavide
Copy link
Collaborator

This addition is already in the pipeline for version 3 ;)
This is actually duplicated, because it is related to the change I am discussing in #44

@facontidavide
Copy link
Collaborator

I agree that adding parameters (ports in version 3) to Subtree avoid name collision and allow reusability, but I am puzzled by this sentence:

In fact, I have to make a new subtree each time I want to face a different target.

That's not the way it works:

Suppose that you have

<BehaviorTree ID="Walk">
<SequenceStar>
   <MoveTo target="{my_target}" />
   <FaceTo target="{my_target}" />
</SequenceStar>
</BehaviorTree>

You just have to visit multiple targets (let's say 10 targets), instead of creating "10 subtrees with different targets" I would do something like:

<BehaviorTree ID="VisitManyLocations">
   <RepeatUntilEmptyFIFO queue={targets_list}>
       <SequenceStar>
           <PullFromFIFO queue={targets_list} output_target="{my_target}" />
           <Walk/>
       </SequenceStar>
   </RepeatUntilEmptyFIFO>
</BehaviorTree>

Note:

  • RepeatUntilEmptyFIFO is a custom DecoratorNode.
  • PullFromFIFO a custom SyncActionNode.
  • Walk is the subtree we specified earlier.

Nevertheless, this will not solve completely the issue I am discussin in #44

@Masadow
Copy link
Contributor Author

Masadow commented Jan 17, 2019

Problem is not really visiting multiple locations, but using the move subtree in different contexts

Here is an example:

<root main_tree_to_execute="BehaviorTree">
    <!--------------------------------------->
    <BehaviorTree ID="BehaviorTree">
        <Root>
            <Fallback name="job_fallback">
                <Sequence>
                    <Condition ID="checkJob" job="walking"/>
                    <Fallback>
                        <SubTree ID="WalkToTarget"/>
                        <Action ID="idle"/>
                    </Fallback>
                </Sequence>
                <Sequence>
                    <Condition ID="checkJob" job="harvesting"/>
                    <Fallback>
                        <Sequence>
                            <Condition ID="hasInventorySpace" value="false"/>
                            <Fallback>
                                <Sequence>
                                    <Condition ID="StorageFound"/>
                                    <Condition ID="isCloseTo" target_key="storage"/>
                                    <Action ID="unloadInventory"/>
                                </Sequence>
                                <Sequence>
                                    <Action ID="FindNearestStorage"/>
                                    <Action ID="faceTo" target_key="storage"/>
                                    <Action ID="walkTo" target_key="storage"/>
                                </Sequence>
                            </Fallback>
                        </Sequence>
                        <Sequence>
                            <Condition ID="isCloseTo" target_key="target"/>
                            <Condition ID="hasInventorySpace" value="true"/>
                            <Action ID="harvest"/>
                        </Sequence>
                        <SubTree ID="WalkToTarget"/>
                    </Fallback>
                </Sequence>
            </Fallback>
        </Root>
    </BehaviorTree>
    <!--------------------------------------->
    <BehaviorTree ID="WalkToTarget">
        <Root>
            <Sequence>
                <Action ID="faceTo" target_key="target"/>
                <Action ID="walkTo" target_key="target"/>
            </Sequence>
        </Root>
    </BehaviorTree>
    <!--------------------------------------->
    <TreeNodesModel>
        <Action ID="FindNearestStorage"/>
        <Condition ID="StorageFound"/>
        <SubTree ID="WalkToTarget"/>
        <Condition ID="checkJob">
            <Parameter label="job" default="walking"/>
        </Condition>
        <Action ID="faceTo">
            <Parameter label="target_key" default="target"/>
        </Action>
        <Action ID="harvest"/>
        <Condition ID="hasInventorySpace">
            <Parameter label="value" default="true"/>
        </Condition>
        <Action ID="idle"/>
        <Condition ID="isCloseTo">
            <Parameter label="target_key" default="target"/>
        </Condition>
        <Action ID="unloadInventory"/>
        <Action ID="walkTo">
            <Parameter label="target_key" default="target"/>
        </Action>
    </TreeNodesModel>
    <!--------------------------------------->
</root>

As you can see in this example, I can't reuse WalkToTarget subtree to move to the nearest storage, I would have been able to if I could write <SubTree ID="WalkToTarget" target="storage"/>

I could have played with the blackboard like you did but I felt like it was less natural and less readdable in a way bigger graph

@facontidavide
Copy link
Collaborator

I am currently working on this very feature... stay tuned :)

@facontidavide
Copy link
Collaborator

check branch ver_3. The new port remapping for SubTrees should do what you need

@facontidavide
Copy link
Collaborator

facontidavide commented Jan 25, 2019

I created a tutorial to introduce this new feature.
Let me know if it is sufficiently clear. https://github.com/BehaviorTree/BehaviorTree.CPP/blob/ver_3/examples/t07_subtree_port_remapping.cpp

@facontidavide
Copy link
Collaborator

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
duplicate This issue or pull request already exists
Projects
None yet
Development

No branches or pull requests

2 participants