Comments (4)
I solved this by extending the LoopDecorator to return early on RUNNING results in addition to FAILURE as well as by only having it wrap a single Task rather than the Sequence that I used above.
import BehaviorTree, {
FAILURE,
Introspector,
RunCallback,
RUNNING,
Sequence,
StatusWithState,
SUCCESS,
Task,
} from "behaviortree"
import { LoopDecorator } from "behaviortree/lib/decorators"
import { RunResult } from "behaviortree/lib/types"
class InterruptableLoopDecorator extends LoopDecorator {
nodeType = "InterruptableLoopDecorator"
decorate(run: RunCallback) {
let i = 0
let result: RunResult = FAILURE
while (i++ < this.config.loop) {
result = run()
if (result === FAILURE) return FAILURE
if (result === RUNNING) return RUNNING
}
return result
}
}
const actionQueue = [() => 1, () => 2, () => 3, () => 4, () => 5]
const testActionsTree = new BehaviorTree({
tree: new Sequence({
nodes: [
new Task({
name: "populateQueue",
run: (b) => {
b.queuedActions = [...actionQueue]
console.log("Queued items:" + b.queuedActions.length)
return SUCCESS
},
}),
new InterruptableLoopDecorator({
node: new Task({
name: "executeItem",
run: (b) => {
b.currentAction = b.queuedActions.shift()
if (b.currentAction) {
const actionResult = b.currentAction()
console.log("Executed item:", actionResult)
if (actionResult === 3) {
return RUNNING
}
return SUCCESS
}
return FAILURE
},
}),
}),
],
}),
blackboard: {
queuedActions: [],
currentAction: undefined,
},
})
const introspector = new Introspector()
testActionsTree.step({ introspector })
console.log("lastresult 1: ", JSON.stringify(introspector.lastResult, null, 2))
if ((testActionsTree.lastResult as StatusWithState)?.total === RUNNING) {
testActionsTree.step({ introspector })
console.log("lastresult 2: ", JSON.stringify(introspector.lastResult, null, 2))
}
which now outputs:
npx ts-node --project tsconfig.test.json test-tree.ts
Queued items:5
Executed item: 1
Executed item: 2
Executed item: 3
lastresult 1: {
"children": [
{
"name": "populateQueue",
"result": true
},
{
"children": [
{
"name": "executeItem",
"result": true
},
{
"name": "executeItem",
"result": true
},
{
"name": "executeItem"
}
]
}
]
}
Executed item: 4
Executed item: 5
lastresult 2: {
"result": false,
"children": [
{
"result": false,
"children": [
{
"name": "executeItem",
"result": true
},
{
"name": "executeItem",
"result": true
},
{
"name": "executeItem",
"result": false
}
]
}
]
}
Thanks again!
from behaviortree.js.
Hello @markpol.
Glad you like it. And also good to here that someone is trying out the typescript version. I think I should put it down as official release soon, since I haven't heared any typescript related problems yet. And it is pretty old by now :-D
But to your question/use case: That is an interesting one. It definitely sounds that you are misusing the sequence node for something it ain’t meant to do since it does not have a sequence of nodes to care for – since it is only dynamically done in the blackboards –, right?.
As far as I understand your problem, you need a new kind of node, that runs through the list in the blackboard, and can therefore remember where it left off.
Does your sequence have any real children?
from behaviortree.js.
Hi @Calamari,
Thanks for the quick reply. Here is some simplified code that perhaps better describes what I'm trying to do:
import BehaviorTree, { FAILURE, Introspector, RUNNING, Sequence, SUCCESS, Task } from "behaviortree"
import { LoopDecorator } from "behaviortree/lib/decorators"
const actionQueue = [() => 1, () => 2, () => 3, () => 4, () => 5]
const testActionsTree = new BehaviorTree({
tree: new Sequence({
nodes: [
new Task({
name: "populateQueue",
run: (b) => {
b.queuedActions = [...actionQueue]
console.log("Queued items:" + b.queuedActions.length)
return SUCCESS
},
}),
new LoopDecorator({
node: new Sequence({
nodes: [
new Task({
name: "shiftItem",
run: (b) => {
b.currentAction = b.queuedActions.shift()
if (b.currentAction) {
console.log("Picked item:", actionQueue.length - b.queuedActions.length)
return SUCCESS
}
return FAILURE
},
}),
new Task({
name: "processItem",
run: (b) => {
const actionResult = b.currentAction()
console.log("Executed item:", actionResult)
return actionResult === 3 ? RUNNING : SUCCESS
},
}),
],
}),
}),
],
}),
blackboard: {
queuedActions: [],
currentAction: undefined,
},
})
const introspector = new Introspector()
testActionsTree.step({ introspector })
console.log("lastresult: ", JSON.stringify(introspector.lastResult, null, 2))
testActionsTree.step({ introspector })
and the output:
npx ts-node --project tsconfig.test.json test-tree.ts ─╯
Queued items: 5
Picked item: 1
Executed item: 1
Picked item: 2
Executed item: 2
Picked item: 3
Executed item: 3
Picked item: 4
Executed item: 4
Picked item: 5
Executed item: 5
lastresult: {
"result": false,
"children": [
{
"name": "populateQueue",
"result": true
},
{
"result": false,
"children": [
{
"result": true,
"children": [
{
"name": "shiftItem",
"result": true
},
{
"name": "processItem",
"result": true
}
]
},
{
"result": true,
"children": [
{
"name": "shiftItem",
"result": true
},
{
"name": "processItem",
"result": true
}
]
},
{
"children": [
{
"name": "shiftItem",
"result": true
},
{
"name": "processItem"
}
]
},
{
"result": true,
"children": [
{
"name": "shiftItem",
"result": true
},
{
"name": "processItem",
"result": true
}
]
},
{
"result": true,
"children": [
{
"name": "shiftItem",
"result": true
},
{
"name": "processItem",
"result": true
}
]
},
{
"result": false,
"children": [
{
"name": "shiftItem",
"result": false
}
]
}
]
}
]
}
Queued items: 5
Picked item: 1
Executed item: 1
Picked item: 2
Executed item: 2
Picked item: 3
Executed item: 3
Picked item: 4
Executed item: 4
Picked item: 5
Executed item: 5
So ideally, i would want the tree to stop at action 3 where RUNNING is returned in the processItem task. Then be able to continue afterwards with actions 4 and 5 by calling step() on the tree again. I hope this makes more sense.
I might be able to get the desired result by introducing more state in the blackboard but wasn't sure if there's a better approach.
from behaviortree.js.
Nice, thanks for sharing. It is an interesting use case. Maybe useful for people to know about.
from behaviortree.js.
Related Issues (20)
- it doesn't work in browser HOT 3
- Need node break function HOT 3
- Task with no immediate return SUCCESS/FAILURE instantly returns SUCCESS HOT 6
- The first task of a nested sequence does not seem to inoke start HOT 14
- debug: true not working HOT 8
- Help understanding JSON trees HOT 2
- What is the correct way to import behaviortree in a webpack app? (You may need an appropriate loader to handle this file type) HOT 3
- Export tree to JSON HOT 2
- Programmatically pushing nodes to branchnodes requires update of numNodes property HOT 2
- Node.js constructor: use original user parameter instead of destructuring HOT 3
- Unneeded dependencies HOT 2
- Add TypeScript support HOT 2
- How to make parallel behavior? HOT 7
- QA: alternative names for node HOT 2
- Bad usage examples HOT 3
- Decorators in a tree stored in the register exhibit global state HOT 4
- Missing `start` call ? HOT 5
- Question: Is there a non-remember Selector? HOT 4
- CooldownDecorator example
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from behaviortree.js.