4
4
import de .kherud .llama .LlamaModel ;
5
5
import de .kherud .llama .ModelParameters ;
6
6
import de .kherud .llama .args .MiroStat ;
7
+ import us .ihmc .behaviors .behaviorTree .BehaviorTreeRootNodeState ;
7
8
import us .ihmc .commons .time .Stopwatch ;
8
9
import us .ihmc .log .LogTools ;
9
10
import us .ihmc .tools .IHMCCommonPaths ;
@@ -13,79 +14,66 @@ public class BehaviorTreeNextActionReasoning
13
14
private static final String SYSTEM = """
14
15
<|start_header_id|>system<|end_header_id|>
15
16
You are a reasoning system that decides the next action to execute in a tree-based robotic system.
16
- The current tree and state is given by:
17
- {
18
- "nodes": [
19
- {"id": int, "type": string, "children": [ ]}
20
- ],
21
- "state": {
22
- "currently_executing": int
23
- "is_done": bool
24
- }
25
- }
26
- There are two node types: Action and Sequence.
27
- An Action node is the only type of node that can be executed.
28
- A Sequence node can have children. When one child of an action sequence node is done, the next one in the list of children should be executed.
29
- Please consider which node is best to execute next and output only the node ID number of that action.
17
+ The following is a schema for how the tree will be represented for a query.
18
+ There is a tree of nodes, where each node's type can be leaf or sequence.
19
+ A sequence node has 0 or more children nodes.
20
+ A leaf node does not have any children.
21
+ The leaves are depth-first ordered and their position in this ordering is given by the index field.
22
+ Each leaf node also has boolean fields for whether it is currently executing, has failed, and can execute.
23
+ The state portion of the scheme gives the global state of the tree.
24
+ The state has a field called execution next index, which is the index of the next node to execute.
25
+ nodes: [
26
+ { type: sequence, children: [
27
+ { type: leaf, index: int, is_executing: bool, failed: bool, can_execute: bool } }
28
+ ] } ],
29
+ state: { execution_next_index: int }
30
+ A sequence node defines the order of execution of the children as one after the other.
31
+ The next node to execute should be the one after the last one that is executing.
32
+ If no node's are executing, the next node to execute should remain unchanged.
33
+ Your task is to decide the next left to execute by providing its index.
30
34
<|eot_id|>
31
35
<|start_header_id|>user<|end_header_id|>
32
- {
33
- "nodes": [
34
- {"id": 001, "type": "Sequence, "children": [
35
- {"id": 002, "type": "Action"},
36
- {"id": 005, "type": "Action"},
37
- {"id": 020, "type": "Action"},
38
- {"id": 004, "type": "Action"},
39
- {"id": 056, "type": "Action"}
40
- ]}
41
- ],
42
- "state": {
43
- "currently_executing": 002,
44
- "is_done": true
45
- }
46
- }
36
+ nodes: [
37
+ { type: sequence, children: [
38
+ { type: leaf, index: 0, is_executing: false, failed: false, can_execute: true } }
39
+ { type: leaf, index: 1, is_executing: false, failed: false, can_execute: true } }
40
+ { type: leaf, index: 2, is_executing: false, failed: false, can_execute: true } }
41
+ { type: leaf, index: 3, is_executing: false, failed: false, can_execute: true } }
42
+ { type: leaf, index: 4, is_executing: false, failed: false, can_execute: true } }
43
+ ] } ],
44
+ state: { execution_next_index: 0 }
47
45
<|eot_id|>
48
46
<|start_header_id|>assistant<|end_header_id|>
49
- 005
47
+ 0
50
48
<|eot_id|>
51
49
<|start_header_id|>user<|end_header_id|>
52
- {
53
- "nodes": [
54
- {"id": 001, "type": "Sequence, "children": [
55
- {"id": 002, "type": "Action"},
56
- {"id": 005, "type": "Action"},
57
- {"id": 020, "type": "Action"},
58
- {"id": 004, "type": "Action"},
59
- {"id": 056, "type": "Action"}
60
- ]}
61
- ],
62
- "state": {
63
- "currently_executing": 005,
64
- "is_done": true
65
- }
66
- }
50
+ nodes: [
51
+ { type: sequence, children: [
52
+ { type: leaf, index: 0, is_executing: true, failed: false, can_execute: true } }
53
+ { type: leaf, index: 1, is_executing: false, failed: false, can_execute: true } }
54
+ { type: leaf, index: 2, is_executing: false, failed: false, can_execute: true } }
55
+ { type: leaf, index: 3, is_executing: false, failed: false, can_execute: true } }
56
+ { type: leaf, index: 4, is_executing: false, failed: false, can_execute: true } }
57
+ ] } ],
58
+ state: { execution_next_index: 0 }
67
59
<|eot_id|>
68
60
<|start_header_id|>assistant<|end_header_id|>
69
- 020
61
+ 1
70
62
<|eot_id|>
71
63
<|start_header_id|>user<|end_header_id|>
72
- {
73
- "nodes": [
74
- {"id": 001, "type": "Sequence, "children": [
75
- {"id": 002, "type": "Action"},
76
- {"id": 005, "type": "Action"},
77
- {"id": 020, "type": "Action"},
78
- {"id": 004, "type": "Action"},
79
- {"id": 056, "type": "Action"}
80
- ]}
81
- ],
82
- "state": {
83
- "currently_executing": 020,
84
- "is_done": true
85
- }
86
- }
64
+ nodes: [
65
+ { type: sequence, children: [
66
+ { type: leaf, index: 0, is_executing: false, failed: false, can_execute: true } }
67
+ { type: leaf, index: 1, is_executing: false, failed: false, can_execute: true } }
68
+ { type: leaf, index: 2, is_executing: true, failed: false, can_execute: true } }
69
+ { type: leaf, index: 3, is_executing: false, failed: false, can_execute: true } }
70
+ { type: leaf, index: 4, is_executing: false, failed: false, can_execute: true } }
71
+ ] } ],
72
+ state: { execution_next_index: 2 }
87
73
<|eot_id|>
88
74
<|start_header_id|>assistant<|end_header_id|>
75
+ 3
76
+ <|eot_id|>
89
77
""" ;
90
78
91
79
@@ -105,12 +93,21 @@ public BehaviorTreeNextActionReasoning()
105
93
model = new LlamaModel (modelParams );
106
94
}
107
95
108
- public int queryNextLeafToExecuteIndex ()
96
+ public int queryNextLeafToExecuteIndex (BehaviorTreeRootNodeState rootNode )
97
+ {
98
+ String treeEncoding = BehaviorTreeLLMEncoding .encode (rootNode );
99
+ return queryNextLeafToExecuteIndex (treeEncoding );
100
+ }
101
+
102
+ public int queryNextLeafToExecuteIndex (String treeEncoding )
109
103
{
110
104
String prompt = SYSTEM ;
111
- // prompt += """
112
- // Hello!
113
- // """;
105
+ prompt += """
106
+ <|start_header_id|>user<|end_header_id|>
107
+ %s
108
+ <|eot_id|>
109
+ <|start_header_id|>assistant<|end_header_id|>
110
+ """ .formatted (treeEncoding );
114
111
115
112
InferenceParameters inferParams = new InferenceParameters (prompt );
116
113
inferParams .setPenalizeNl (true );
@@ -123,13 +120,12 @@ public int queryNextLeafToExecuteIndex()
123
120
124
121
String reponse = model .complete (inferParams );
125
122
126
- // LogTools.info(prompt + reponse);
127
- //
128
- // LogTools.info("Response: {}", reponse);
123
+ LogTools .info (prompt + reponse );
129
124
130
125
return Integer .parseInt (reponse .trim ());
131
126
}
132
127
128
+ // FIXME: Doesn't work yet
133
129
public void destroy ()
134
130
{
135
131
model .close ();
@@ -142,7 +138,17 @@ public static void main(String[] args)
142
138
for (int i = 0 ; i < 10 ; i ++)
143
139
{
144
140
Stopwatch stopwatch = new Stopwatch ().start ();
145
- int leafIndex = reasoning .queryNextLeafToExecuteIndex ();
141
+ int leafIndex = reasoning .queryNextLeafToExecuteIndex ("""
142
+ nodes: [
143
+ { type: sequence, children: [
144
+ { type: leaf, index: 0, is_executing: false, failed: false, can_execute: true } }
145
+ { type: leaf, index: 1, is_executing: false, failed: false, can_execute: true } }
146
+ { type: leaf, index: 2, is_executing: false, failed: false, can_execute: true } }
147
+ { type: leaf, index: 3, is_executing: true, failed: false, can_execute: true } }
148
+ { type: leaf, index: 4, is_executing: false, failed: false, can_execute: true } }
149
+ ] } ],
150
+ state: { execution_next_index: 2 }
151
+ """ );
146
152
LogTools .info ("Returned {} in {} seconds" , leafIndex , stopwatch .totalElapsed ());
147
153
}
148
154
0 commit comments