Probabilistic Selector and probabilistic on python Behavior Trees

58 views
Skip to first unread message

Paulo Silva dos Santos

unread,
Jul 7, 2021, 4:15:26 AM7/7/21
to Atoms Crowd
Hi people, i am trying to make a probabilistic module or extension, but i am not sure where to start.

Probabilistic Selector:

I did try to use the Probabilistic Selector, but it didn't work as i expected, so, how it work?
i see the "Fail Chance" but even if i set it to 0 it keep falling (according to the debug) and didn't select any child node.

i am using houdini and this is a example of the behavior tree

behaviortree.jpg

Python Probability and Behavior Trees:

So, i am thinking about to use python too, and have more control over a chain of probabilistic actions, given a condition.

1. Do i have any way of getting metadata inside the python modules in a global manner?
something that can make me control on a top level, something like top level of the agentGroup, like pythonModule-> [agentGroup[agent], agentGroup[agent]] instead of agentGroup[behaviorTree->python]

2. Some examples in how the python and the probabilistic modules work will really be appreciate, because, some of the documentation about how the nodes work is a plain text with little information, like:

failChance - Failure chance used as probability to return a failure status
in my intuition, if i set it to 0 its not supposed to return fail, but on my basic setup (image attached) its not true.

3. just repeating myself, any advice in how to implement that (even using c++, not preferred) and make a probabilistic module is welcome. because i am starting to implement that.

Thx

Paulo Satan
R&D Casablanca


Alan Stanzione

unread,
Jul 7, 2021, 1:52:58 PM7/7/21
to Paulo Silva dos Santos, Atoms Crowd
Hello Paulo,
please use atoms 4.1.1 that we just released. There was a problem with the UI, it didn't display the weights attribute. You should see now the weights attributes like these:
image.png

You need to add weight for each of the children. These weights are used to compute the probability of each child. I've attached an example scene.
If you want check I've attached also the source c++ code of the probability selector in case you want change it.
I've also updated the docs with some example of custom Task/Decorator and Composite nodes.

For python you have access to the agent, agent group and behaviour tree context. If you need to access the blackboard instance you can use the context.blackboardInstance. For example to get the first entry of the blackboard you just need to call context.blackboardInstance.entry(0).value().

Not sure what you mean with Do i have any way of getting metadata inside the python modules in a global manner?
Inside the tree, you have full access to the agent metadata and the blackboard/tree instance of an agent. If you need to access other agents you can do with a couple of specific nodes. Like the getclosestagent or the get/setagentmetadata. Where you can pass a global id of an agent to read/write the metadata you want. Only please take in mind that each agent has an instance of the tree and blackboard and each instance is evaluated in parallel. So if the tree of agent 1 is reading a "foo" metadata of agent 3 and agent 3 is writing the "foo" metadata at the same time, you have problems there. To fix those problems you need to use the lock decorator and the lock attributes on the nodes.

Let me know if you have more questions.
Thanks
Alan


--
You received this message because you are subscribed to the Google Groups "Atoms Crowd" group.
To unsubscribe from this group and stop receiving emails from it, send an email to atoms-crowd...@toolchefs.com.
To view this discussion on the web visit https://groups.google.com/a/toolchefs.com/d/msgid/atoms-crowd/b0ba7cf2-a3f6-4bf9-8f5f-5ba96daa1513n%40toolchefs.com.


--
Alan Stanzione | CTO - Co-Founder

Toolchefs LTD
86-90, Paul Street,
London, EC2A 4NE


LTD Company registered in England & Wales # 09345032

ProbabilitySelector.h
porbability_selector.ma
ProbabilitySelector.cpp

Paulo Silva dos Santos

unread,
Jul 23, 2021, 11:48:37 AM7/23/21
to Alan Stanzione, Atoms Crowd
Hi Alan, i am back.

You need to add weight for each of the children. These weights are used to compute the probability of each child. I've attached an example scene.
so, i was using the probability node, but i am not sure if it is computing as i wanted, i had put 4 outputs to the prob node, and i was expecting to see a 1/4 prob chance of enabling any of this output
if i set as 0.25 chance, but, they just selected the first and the second (using the same scene that you attached to the email).

Now, I just figured out another way to do it using python. I get some ids from the agentGroup, and process only that selection of ids, that was the result of my prob chance.
And I use a filter to process only the agent 0 (not sure how to process the entire group and select some of them in any other way) , but now, I want to expand it to, every N frames, run this selection again and do x.

But i can find a way to get which frame my play head are at, i tried:
x = hou.frame()
print(x)

inside the python behavior/decorator and always it crash my houdini (i am using 18.5.499)

any of the functions that get some kind of simulation, time and etc didn't return where i am at the simulation, so no luck, some examples:

p.s. I am using the c++ as a reference to build my python script.


For python you have access to the agent, agent group and behaviour tree context. If you need to access the blackboard instance you can use the context.blackboardInstance. For example to get the first entry of the blackboard you just need to call context.blackboardInstance.entry(0).value().

Have any way to get the name of ctx.blackboardInst.entry(0)? it's really very dangerous to get it by index alone, i want to double check if the returning type of my blackboard is of name x.
i tried this http://atoms.toolchefs.com/docs/sdk/struct_atoms_1_1_blackboard_entry.html, but the name didn't exist on my entry object, the value function worked as expected.

so, to resume what i need help for:

01. I sent another email, asking how I can make 2 agents walk side by side, and I didn't have success on it, so, again, i ask for some help, maybe a scene as example?

02. the problem of using a hou.frame() function inside atoms, crash it everytime (houdini version 18.5.499), i need some way to get wich frame I am at, using hou.frame or any other way, so i can compute a chance of enabling a condition every N frames.

03. ctx.blackboardInst.entry(0), some way to get what is the name of the entry(0)

04. have any way to execute some scripts only on the agent 0 in frames 0,10,20(like the question 02)? because the way i did it, using the following code is a bit of a workaround, and, i think, it can hit performance, so, if is possible to get out in some way from the entire evaluation of every agent, i think, that is a good way to not hit any kind of performance slow down.

## this code is inside a python module decorator/behaviour on the initialize section

currentID = agent.metadata().getEntry("id").value()


if (currentID == 0):

doThings()


Thx

Paulo Satan
Casablanca R&D

Alan Stanzione

unread,
Jul 23, 2021, 11:49:38 AM7/23/21
to Paulo Silva dos Santos, Atoms Crowd
Hello Paulo,
the probability selector works correctly here, Please make sure to add the correct number of weights entries. Also remember to activate the "use agent id as seed" if you want a different random value per agent. I've attached an example scene with 4 connections.

1) I've attached an example file. Please use atoms 4.3.0  that we will release next week since I added a couple of behaviour node to help with this setup.


2) You're right but seems a problem with the hou module, it doesn't seem Houdini let use this module outside the main thread. I've fix this on atoms 4.3.0 that we will release next week, forcing the computation of the module to a single thread if there are some python nodes. 
By the way with the previous version you have a couple of ways to access the simulation time.

One getting the simulation time from agentGroup.simulationTime().time()

Another one is exposing a property from the blackboard.
- Create a new double entry and expose it
image.png
Then press the refresh button on the behaviour tree module to expose the entry you just created and set an expression on it
image.png

Now you can access directly as a blackboard entry on all the nodes inside your tree.

3) From atoms 4.3.0 you can use directly context.getBlackboardValueFromName("foo").value(). Otherwise the blackboardIsntance contains only the data for that instance. The static data like the name is stored on the blackboard that you can access from context.blackboardInstance().blackboard().entry(0).name()

4) Please don't use the "id" metadata but the "groupId" metadata. The id is the global simulation id of the agent, it is not deterministic and it can change between different scene rewind. Instead, the "groupId" is a unique local id of an agent inside an agent group. It is deterministic and doesn't change on scene rewind.
By the way, you have some different ways to do it. For example, if the time is constant you can use a repeat node with a wait node

image.png

If you need to specify some intervals that are not constant you can use the iterator decorator with array metadata like this:

image.png
image.png
image.png
The iterator iterate over an array and at every iteration it fills the "blackboard out" entry with the current item value. So you can use a conditional and a wait node to wait some condition before pass to the next value. In this case, it is waiting for the simulation frame stored inside the simFrame blackboard entry become >= of the current item to execute the python node.

Thanks
Alan

probabilitySelector.hip
sidebysidewalk_2.hip
Reply all
Reply to author
Forward
0 new messages