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

Implement Goto Node, Extract Leaf Node from Action Node, CheckPoint Node is a Leaf #622

Open
wants to merge 10 commits into
base: develop
Choose a base branch
from

Conversation

calvertdw
Copy link
Member

No description provided.

@calvertdw calvertdw force-pushed the feature/goto-node branch 2 times, most recently from d65f7d1 to 25c8bc9 Compare January 31, 2025 21:22
@calvertdw calvertdw changed the title Implement behavior goto node Implement Goto Node, Extract Leaf Node from Action Node, CheckPoint Node is a Leaf Jan 31, 2025
import us.ihmc.tools.io.WorkspaceResourceDirectory;

public class RDXCheckPointNode extends RDXActionNode<CheckPointNodeState, CheckPointNodeDefinition>
public class RDXCheckPointNode extends RDXLeafNode<CheckPointNodeState, CheckPointNodeDefinition>
Copy link
Member Author

Choose a reason for hiding this comment

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

Checkpoint extends leaf (I wish checkpoint was spelled as one word, but whatever)

@@ -159,7 +159,7 @@ public void render3DPanelImGuiOverlays()
{
if (isMouseHovering)
{
tooltip.render("%s Action\nIndex: %d\nName: %s".formatted(getActionTypeTitle(), state.getActionIndex(), definition.getName()));
tooltip.render("%s Action\nIndex: %d\nName: %s".formatted(getLeafTypeTitle(), state.getLeafIndex(), definition.getName()));
Copy link
Member Author

Choose a reason for hiding this comment

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

Action -> Leaf almost everywhere

@calvertdw calvertdw marked this pull request as ready for review January 31, 2025 22:29
import us.ihmc.tools.io.WorkspaceResourceDirectory;

public class RDXGotoNode extends RDXBehaviorTreeNode<GotoNodeState, GotoNodeDefinition>
public class RDXGotoNode extends RDXLeafNode<GotoNodeState, GotoNodeDefinition>
Copy link
Member Author

Choose a reason for hiding this comment

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

Goto node is a leaf


/**
* The UI representation of a robot behavior action. It provides a base
* template for implementing an interactable action.
*/
public abstract class RDXActionNode<S extends ActionNodeState<D>,
D extends ActionNodeDefinition>
extends RDXBehaviorTreeNode<S, D>
extends RDXLeafNode<S, D>
Copy link
Member Author

Choose a reason for hiding this comment

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

Actions are leaves

@@ -17,7 +17,7 @@ public class RDXActionProgressWidgetsManager
{
private final ImGuiUniqueLabelMap labels = new ImGuiUniqueLabelMap(getClass());
private final ImGuiLabelledWidgetAligner widgetAligner = new ImGuiLabelledWidgetAligner();
private final SortedSet<RDXActionNode<?, ?>> sortedActionNodesToRender = new TreeSet<>(Comparator.comparingInt(node -> node.getState().getActionIndex()));
private final SortedSet<RDXActionNode<?, ?>> sortedActionNodesToRender = new TreeSet<>(Comparator.comparingInt(node -> node.getState().getLeafIndex()));
Copy link
Member Author

Choose a reason for hiding this comment

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

Progress widgets still only render actions, because leaves don't take time

Copy link
Member Author

Choose a reason for hiding this comment

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

Root node (sequence) deals primarily with leaves, not actions

Copy link
Member Author

Choose a reason for hiding this comment

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

AI2R needs to be tested. I don't know how to do it. @LuigiPenco93?

Copy link
Contributor

@LuigiPenco93 LuigiPenco93 Feb 3, 2025

Choose a reason for hiding this comment

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

we'd need a python example similar to what Dex has done for the scene graph

{
LogTools.warn("Actions failed, fallback actions are next for execution.");
LogTools.warn("Leaves failed, fallback leaves are next for execution.");
Copy link
Member Author

Choose a reason for hiding this comment

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

Leaves

subscriptionNode.setBehaviorTreeNodeStateMessage(gotoNodeStateMessage.getState());
subscriptionNode.setBehaviorTreeNodeDefinitionMessage(gotoNodeStateMessage.getDefinition().getDefinition());
subscriptionNode.setBehaviorTreeNodeStateMessage(gotoNodeStateMessage.getState().getState());
subscriptionNode.setBehaviorTreeNodeDefinitionMessage(gotoNodeStateMessage.getDefinition().getDefinition().getDefinition());
Copy link
Member Author

Choose a reason for hiding this comment

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

I actually don't know why these lines are here

private final CRDTBidirectionalBoolean gotoNext;
private final CRDTBidirectionalLong gotoNodeID;
/** We use this to save the goto node name to file instead of the number for human readability. */
private String gotoNodeName = GOTO_NEXT;
Copy link
Member Author

Choose a reason for hiding this comment

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

Very similar implementation to executeAfter

@Override
public void validateFields(List<LeafNodeState<?>> leafNodes)
{
super.validateFields(leafNodes);
Copy link
Member Author

Choose a reason for hiding this comment

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

This validation step also validates the executeAfter fields

bool goto_next

# The ID of the node to goto
uint32 goto_node_id
Copy link
Member Author

Choose a reason for hiding this comment

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

Goto node message fields

Copy link
Contributor

@TomaszTB TomaszTB 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. Left a couple of thoughts

Comment on lines +27 to +28
private final S state;
private final D definition;
Copy link
Contributor

Choose a reason for hiding this comment

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

A whole bunch of classes that extend the RDXBehaviorTreeNode and BehaviorTreeNodeExecutor also store the state and definition, which they get from the super class... What about making the state and definition fields protected? Not in this PR though. Just a thought.

Copy link
Member Author

Choose a reason for hiding this comment

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

That's actually a great idea, I'll add a JIRA ticket

Comment on lines 67 to 69
// int j = i + 1;
// for (; j < state.getActionChildren().size()
// && state.getActionChildren().get(j).calculateExecuteAfterActionIndex(state.getActionChildren()) < i; j++);
// for (; j < state.getLeafChildren().size()
// && state.getLeafChildren().get(j).calculateExecuteAfterLeafIndex(state.getLeafChildren()) < i; j++);
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a reason to keep this commented code?

Copy link
Member Author

Choose a reason for hiding this comment

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

Done!

this.leafIndex = leafIndex;
}

public int getLeafIndex()
Copy link
Contributor

Choose a reason for hiding this comment

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

Needs javadoc, I wouldn't have any clue what a leaf index is from this

Copy link
Member Author

Choose a reason for hiding this comment

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

Added doc

return isExecuting.getValue();
}

public int calculateExecuteAfterLeafIndex()
Copy link
Contributor

Choose a reason for hiding this comment

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

Needs javadoc, what does this mean and when do you call it?

Copy link
Member Author

Choose a reason for hiding this comment

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

Added doc and changed to getExecuteAfterLeafIndex. I named it calculate to warn that it's not a basic getter, but I don't want to cache the calculation

return leafIndex - 1; // previous
}

public LeafNodeState<?> findExecuteAfterLeaf()
Copy link
Contributor

Choose a reason for hiding this comment

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

Needs javadoc, what does this mean and when do you call it?

Copy link
Member Author

Choose a reason for hiding this comment

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

Added doc and changed to getExecuteAfterLeaf. I named it find to warn that it's not a basic getter, but I don't want to cache the calculation

this.state = state;
}

public String getCantExecuteMessage()
Copy link
Contributor

Choose a reason for hiding this comment

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

getCantExecuteMessage() -> getExecuteFailureMessage() or something

Copy link
Member Author

Choose a reason for hiding this comment

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

This is a message to print when the canExecute pre-condition is false (i.e. the action is not valid to even attempt execution) I've added doc.

private final ImGuiFlashingColors isExecutingFlashingColor = new ImGuiFlashingColors(0.1, ImGuiTools.PURPLE, ImGuiTools.DARK_PURPLE);
private final ImGuiHollowArrowRenderer hollowArrowRenderer = new ImGuiHollowArrowRenderer();
private final ImGuiFlashingText flashingDescriptionColor = new ImGuiFlashingText(ImGuiTools.RED);
private boolean wasFailed = false;
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you add a comment about what wasFailed represents? e.g. Used in update() for sending notifications

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

@@ -92,24 +97,24 @@ public void fromMessage(BehaviorTreeRootNodeStateMessage message)
}

@Nullable
public <T extends ActionNodeState<?>> T findNextPreviousAction(Class<T> actionClass, int queryIndex, @Nullable RobotSide side)
public <T extends LeafNodeState<?>> T findNextPreviousLeaf(Class<T> leafClass, int queryIndex, @Nullable RobotSide side)
Copy link
Contributor

Choose a reason for hiding this comment

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

Out of scope for this PR but I still really do not like the name findNextPreviousLeaf

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.

4 participants