Expand description
Mecha10 Behavior Runtime
This crate provides a unified behavior composition system for robotics and AI.
All behaviors implement the BehaviorNode trait with a simple tick-based interface.
§Philosophy
- Behavior Logic = Rust code (complex logic, high performance)
- Behavior Composition = JSON config (simple orchestration, hot-reloadable)
- Configuration = JSON with validation (parameters only)
§Example
use mecha10_behavior_runtime::{BehaviorNode, NodeStatus, Context};
use async_trait::async_trait;
#[derive(Debug)]
struct MyBehavior;
#[async_trait]
impl BehaviorNode for MyBehavior {
async fn tick(&mut self, ctx: &Context) -> anyhow::Result<NodeStatus> {
// Your behavior logic here
Ok(NodeStatus::Success)
}
}Re-exports§
pub use actions::register_builtin_actions;pub use actions::LandNode;pub use actions::MoveNode;pub use actions::RlTaskNode;pub use actions::SensorCheckNode;pub use actions::SetRlTargetNode;pub use actions::TakeoffNode;pub use actions::TimerNode;pub use actions::WanderNode;pub use config::detect_project_root;pub use config::get_current_environment;pub use config::list_available_behaviors;pub use config::load_behavior_config;pub use config::resolve_behavior_config_path;pub use config::validate_behavior_composition_json;pub use config::validate_behavior_config;pub use config::BehaviorConfig;pub use config::CompositionConfig;pub use config::NodeConfig;pub use config::NodeReference;pub use config::ParallelPolicyConfig;pub use config::SubsumptionLayerConfig;pub use config::ValidationResult;pub use control::PidController;pub use control::PidGains;
Modules§
- actions
- Built-in action nodes for behavior trees
- config
- Configuration management for behavior trees
- control
- Reusable control-loop primitives shared by behaviour action nodes.
- hot_
reload - Hot-reload functionality for behavior trees during development
- prelude
Macros§
Structs§
- Behavior
Executor - Behavior
Loader - Context
- Execution
Context - Execution
Stats - Force
Failure Node - Always reports
Failureonce its child resolves, regardless of whether the child actually succeeded or failed;Runningpasses through unchanged. The mirror ofForceSuccessNode- useful inside aSelectorto force a fallback to try the next option even after this one “succeeded” in some advisory sense. - Force
Success Node - Always reports
Successonce its child resolves, regardless of whether the child actually succeeded or failed;Runningpasses through unchanged. Useful for an optional step in aSequencewhose failure shouldn’t abort the rest of the sequence (e.g. a best-effort log/ notify action). - Inverter
Node - Negates a
Success/Failureresult from its single child;Runningpasses through unchanged. The canonical decorator for turning a “condition” leaf/subtree into its opposite (e.g. “target NOT in range”) without duplicating the underlying check. - Node
Registry - Parallel
Node - Repeat
Node - Re-runs its child every time it succeeds, up to an optional fixed count; a
Failurefrom the child always ends the loop immediately withFailure.count: Nonerepeats indefinitely (the node only ever stops via the child failing) - e.g. a patrol leg re-run forever until something fails it. - Retry
Node - Re-runs its child up to
max_attemptstimes whenever it fails, succeeding as soon as one attempt succeeds; only reportsFailureonce every attempt has been exhausted. The complement ofRepeatNode(which loops on success) - for flaky/best-effort actions like a detection scan that may need a few tries (e.g.capture-target’s “take a picture of a uniquely-found target”). - Select
OrNode - Sequence
Node - Subsumption
Layer - A single priority layer in a
SubsumptionNode: a priority (higher wins) plus the behavior that implements it. - Subsumption
Node - Priority-based preemption (subsumption architecture): on each tick, tries each layer
highest-priority first. The first layer whose
tick()returnsRunning/Success“wins” and its status is returned for that tick - lower-priority layers aren’t ticked at all that cycle, so their own internal progress (e.g. aSequenceNode’s current child index) is naturally preserved rather than reset, which is what gives a preempted lower layer “resume where it left off” semantics for free. - Timeout
Node - Bounds how long its child may stay
Running: starts a clock on the first tick after construction/reset, and oncedurationhas elapsed without the child resolving, immediately reportsFailurewithout ticking the child again that call (and resets the child’s own state, since it was abandoned mid-flight). A child that resolves (Success/Failure) before the deadline passes its status straight through. Needed for any “give up after N seconds” bound, e.g.track-object’s “follows it until out of range”. - Watch
Node - Like
ParallelNode, but with no memory of a prior resolution: every child is ticked, every call, unconditionally.ParallelNodefreezes a child once it resolves to non-Running(viachild_statuses) until an externalreset()- correct for “run these concurrent subtasks to completion”, wrong for an interrupt-condition layer that must be re-evaluated indefinitely (the operator may click, clear, click again, many times over a session).
Enums§
Traits§
Functions§
- boxed_
children_ mut - Maps an iterator of boxed child behaviors to
BehaviorNode::children_mut’s trait-object return type.