Crates.io | behaviortree |
lib.rs | behaviortree |
version | 0.3.1 |
created_at | 2025-07-27 05:20:04.993582+00 |
updated_at | 2025-08-27 11:35:55.045631+00 |
description | A BehaviorTree library similar to [BehaviorTree.CPP](https://www.behaviortree.dev/), which can be used in embedded environments. |
homepage | http://github.com/stepkun/behaviortree.git |
repository | https://github.com/stepkun/behaviortree.git |
max_upload_size | |
id | 1769724 |
size | 315,767 |
'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
⚠️ WARNING ⚠️ This crate is still in development.
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::default();
// register your behaviors
register_behavior!(factory, action_1, "MyAction1", BehaviorKind::Action).unwrap();
register_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 complex behaviors, there is a set of derive macros: Action
, Condition
, Control
and Decorator
.
use behaviortree::prelude::*;
/// Derive an `Action`
#[derive(Action, Debug, Default)]
pub struct SaySomething {}
/// Implement the `Action`s functionality
#[async_trait::async_trait]
impl Behavior for SaySomething {
/// Minimum implement the tick function
async fn tick(
&mut self,
behavior: &mut BehaviorData,
_children: &mut ConstBehaviorTreeElementList,
_runtime: &SharedRuntime,
) -> BehaviorResult {
// getting the port
let msg = behavior.get::<String>("message")?;
// doing something
println!("Robot says: {msg}");
// signaling success
Ok(BehaviorState::Success)
}
/// Define the available ports.
/// This is optional, the default implementation is for no ports.
fn provided_ports() -> PortList {
port_list! {input_port!(String, "message")}
}
}
✅: Supported (✅): Supported, not fully tested, should work 🔴: Not supported
Capability | With OS | Embedded |
---|---|---|
XML parsing | ✅ | ✅ |
Ports | ✅ | ✅ |
- access by ref | 🔴 | 🔴 |
Port remapping | ✅ | ✅ |
SubTrees | ✅ | ✅ |
SubTree remapping | ✅ | ✅ |
Blackboard | ✅ | ✅ |
- access by ref | 🔴 | 🔴 |
- backup | 🔴 | 🔴 |
XML generation | ✅ | ✅ |
Scripting | ✅ | ✅ |
Pre-/post-conditions | ✅ | ✅ |
Loggers/Observers | ✅ | 🔴 |
Substitution rules | 🔴 | 🔴 |
Using Groot2 for: | ||
- XML Create/Edit | ✅ | ✅ |
- Live Monitoring | ✅ | 🔴 |
- Pro Features | 🔴 | 🔴 |
BehaviorTree.CPP nodes | With OS | Embedded |
---|---|---|
Action | ||
Script | ✅ | ✅ |
SetBlackboard | (✅) | (✅) |
Sleep | (✅) | 🔴 |
UnsetBlackboard | (✅) | (✅) |
Condition | ||
ScriptCondition | (✅) | (✅) |
WasEntryUpdated | ✅ | (✅) |
Control | ||
Fallback | ✅ | ✅ |
ReactiveFallback | ✅ | (✅) |
Sequence | ✅ | ✅ |
ReactiveSequence | ✅ | ✅ |
SequenceWithMemory | ✅ | (✅) |
Parallel | ✅ | (✅) |
ParallelAll | ✅ | (✅) |
IfThenElse | ✅ | (✅) |
WhileDoElse | ✅ | (✅) |
Switch | ✅ | (✅) |
Decorator | ||
ForceFailure | ✅ | (✅) |
ForceSuccess | ✅ | (✅) |
Inverter | ✅ | ✅ |
KeepRunningUntilFailure | ✅ | (✅) |
Repeat | ✅ | (✅) |
Retry (deprecated) | 🔴 | 🔴 |
RetryUntilSuccessful | ✅ | (✅) |
Delay | (✅) | 🔴 |
EntryUpdated | ✅ | (✅) |
LoopeQueue | ✅ | ✅ |
RunOnce | ✅ | (✅) |
ScriptPrecondition | (✅) | (✅) |
Timeout | (✅) | 🔴 |
Licensed with the fair use "NGMC" license, see license file
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.