Skip to main content

Crate behaviortree

Crate behaviortree 

Source
Expand description

§behaviortree

‘behaviortree’ implements a behavior tree library similar to BehaviorTree.CPP but in Rust.

Examples implementing the BehaviorTree.CPP tutorials can be found here. For embedded devices similar examples are available here

⚠️ INFO ⚠️ This crate is still in development.

§Usage

Below is a very simple example using functions as Actions. For more examples see:

use behaviortree::prelude::*;

const XML: &str = r#"
<root BTCPP_format="4">
    <BehaviorTree ID="MyBehavior">
        <Sequence>
			<MyAction1/>
			<MyAction2/>
        </Sequence>
    </BehaviorTree>
</root>
"#;

fn action_1() -> BehaviorResult {
    // your activity
    // ...

    // In case of Failure    
    //return Ok(BehaviorState::Failure);

    // In case of Success    
    Ok(BehaviorState::Success)
}

fn action_2() -> BehaviorResult {
    // your activity
    // ...
    Ok(BehaviorState::Success)
}

#[tokio::main]
async fn main() {
    // create a behavior factory
    let mut factory = BehaviorTreeFactory::new().unwrap();

    // register your behaviors
    register_simple_behavior!(factory, action_1, "MyAction1", BehaviorKind::Action).unwrap();
    register_simple_behavior!(factory, action_2, "MyAction2", BehaviorKind::Action).unwrap();

    // create the tree
    let mut tree = factory.create_from_text(XML).unwrap();
    
    // run the tree until Success or Failure
    tree.tick_while_running().await.unwrap();
}

For implementation of your own behaviors, there is a set of derive macros: Action, Condition, Control and Decorator.

use behaviortree::prelude::*;

const XML: &str = r#"
<root BTCPP_format="4">
    <BehaviorTree ID="MyBehavior">
        <MyAction message = "hello world!"/>
    </BehaviorTree>
</root>
"#;

#[derive(Action, Debug)]
pub struct SaySomething {
	/// The ports
	#[behavior(portlist)]
	portlist: PortArray<1>,
}

#[async_trait::async_trait]
impl Behavior for SaySomething {
	async fn tick(
		&mut self,
		_behavior: &mut BehaviorData,
		_children: &mut BehaviorTreeElementList,
		_runtime: &SharedRuntime,
	) -> BehaviorResult {
		let msg = self.portlist.get::<String>("message")?;
		println!("Robot says: {msg}");
		Ok(BehaviorState::Success)
	}
}

impl SaySomething {
	port_array_init! {1,
		create_inbound_entry_parseable!("message", String)
	}
}

#[tokio::main]
async fn main() {
    // create a behavior factory
    let mut factory = BehaviorTreeFactory::new().unwrap();

    // register the behavior
    SaySomething::register(&mut factory, "MyAction").unwrap();

    // create the tree
    let mut tree = factory.create_from_text(XML).unwrap();
    
    // run the tree until Success or Failure
    tree.tick_while_running().await.unwrap();
}

§Capabilities

✅: Supported
☑️: Supported with some caveats
🚦: Needs testing but basically works
🔴: Not yet supported
??: Unclear if it can be supported
❌: Will not be supported

§General capabilities

Capabilitystd OSEmbeddedCaveats
XML
- parsing☑️embedded tree depth limited
- generation
Ports
- remapping
- access by ref
Subtrees
- structure
- remapping
- ‘include’ from file
Blackboard
- hierarchy
- remapping
- access by ref
- backup🔴??
Pre-/post-conditions
Scripting
Loggers/Observersembedded basically works, no time info
Substitution rules🚦🚦no delay in embedded, currently no functions possible
Using Groot2 for:
- XML Create/Edit☑️☑️different type systems
- Live Monitoring☑️☑️different type systems, Ethernet over USB
- Pro Features🔴??

§Built-in behaviors

Names as in BehaviorTree.CPPstd OSEmbedded
Actions
AlwaysFailure, AlwaysSuccess
Script
SetBlackboard, UnsetBlackboard
PopFromQueue<T>
Sleep🔴
Conditions
ScriptCondition
WasEntryUpdated
Controls
Fallback
AsyncFallback, ReactiveFallback
Sequence, SequenceWithMemory
AsyncSequence, ReactiveSequence
Parallel, ParallelAll
IfThenElse, WhileDoElse
Switch<u8>
ManualSelector🔴??
Decorators
ForceFailure, ForceSuccess
Inverter
KeepRunningUntilFailure
Repeat
RetryUntilSuccessful
EntryUpdated
LoopQueue<T>
RunOnce
Precondition
Delay🔴
Timeout🔴

§License

Licensed with the fair use “NGMC” license, see license file

§Contribution

Any contribution intentionally submitted for inclusion in the work by you, shall be licensed with the same “NGMC” license, without any additional terms or conditions.

Re-exports§

pub use error::Error;

Modules§

error
behaviortree errors.
prelude
Most commonly used interfaces of behaviortree.

Macros§

create_inbound_entry
Creates a name/inbound_port pair.
create_inbound_entry_parseable
Creates a name/inbound_port pair with a parseable data type.
create_inoutbound_entry
Creates a name/inoutbound_port pair.
create_inoutbound_entry_parseable
Creates a name/inoutbound_port pair with a parseable data type.
create_outbound_entry
Creates a name/outbound_port pair.
create_outbound_entry_parseable
Creates a name/outbound_port pair with a parseable data type.
create_port_array
Creates an array of ports.
create_port_map
Creates a map of ports.
create_port_vec
Creates a list of ports.

Structs§

Databoard
A hierarchical, thread safe name/value store. The name is something that can be converted into an Arc<str>. The value can be anything that implements the traits Any and Debug.
PortArray
A fixed unsorted array of PortVariants.
PortMap
An extendable sorted map of PortVariants.
PortVec
An extendable unsorted list of PortVariants.
RemappingList
A mutable remapping list.

Enums§

BehaviorKind
All types of behaviors usable in a behavior tree.
BehaviorState
Behavior state.

Traits§

Behavior
Defines the methods common to all behaviors. These methods are available when traversing a behavior tree.
BehaviorExecution
Supertrait for execution of a Behavior. The contained functions are generated by the derive macros.
PortCollection
Methods for something that is a collection of ports. Each port is identified by its name, so the name has to be unique within a certain port collection.
PortCollectionAccessors
Access methods for port collections. Each port is identified by its name, so the name has to be unique within a certain port collection.
PortCollectionAccessorsCommon
Common access methods for port collections. Each port is identified by its name, so the name has to be unique within a certain port collection.
PortCollectionProvider
Trait for something that provides a collection of Ports.

Type Aliases§

Arc
BehaviorCreationFn
Type alias for a behavior creation function
BehaviorResult
Result type definition for behaviors.
Mutex
RwLock
RwLockReadGuard
RwLockWriteGuard

Derive Macros§

Action
Derive macro for an Action type Behavior, usage.
Condition
Derive macro for an Condition type Behavior, usage.
Control
Derive macro for an Control type Behavior, usage.
Decorator
Derive macro for an Decorator type Behavior, usage.