# Behavior Executor Node
Loads and executes behavior trees for autonomous robot control.
## Overview
The behavior executor node runs behavior trees at a configurable tick rate, providing autonomous control for robots. It supports enable/disable control from the dashboard and advanced interrupt/resume functionality for seamless integration with manual control.
## Features
- **Behavior Tree Execution**: Loads and runs behavior trees from JSON files
- **Built-in Actions**: Wander, move, timer, sensor_check nodes
- **Configurable Tick Rate**: Control execution frequency
- **Dashboard Control**: Enable/disable via dashboard UI
- **Smart Interruption**: Pause for manual commands, auto-resume when done
- **Status Publishing**: Real-time execution status and statistics
- **Health Monitoring**: Reports behavior tree health and tick counts
## Configuration
```toml
# Behavior Executor Configuration
behavior_name = "patrol" # Name of behavior to load (from behaviors/)
behaviors_dir = "behaviors" # Directory containing behavior JSON files
tick_rate_hz = 10.0 # Execution frequency in Hz
max_ticks = 10000 # Optional maximum tick count
log_stats = true # Log periodic statistics
[topics]
control = "/behavior/control" # Control topic for enable/disable/interrupt/resume
status = "/behavior/status" # Status publishing topic
```
## Control Messages
The behavior executor listens to `/behavior/control` for control commands:
### Basic Control (Dashboard)
**Enable Behavior Tree**
```json
{
"action": "enable",
"timestamp": 1234567890
}
```
**Disable Behavior Tree**
```json
{
"action": "disable",
"timestamp": 1234567890
}
```
### Advanced Control (Node Interruption)
**Interrupt with Auto-Resume**
```json
{
"action": "interrupt",
"source": "llm-command",
"duration_secs": 30,
"timestamp": 1234567890
}
```
When `duration_secs` is provided, the behavior tree will automatically resume after the timeout.
**Manual Resume**
```json
{
"action": "resume",
"source": "llm-command",
"timestamp": 1234567890
}
```
Resumes the behavior tree immediately, cancelling any pending auto-resume.
## Status Messages
Published to `/behavior/status` every second:
```json
{
"behavior_name": "patrol",
"is_running": true,
"tick_count": 12345,
"timestamp": 1234567890
}
```
## Control Flow
### Startup
1. Node starts with behavior execution **disabled**
2. Waits for `enable` command from dashboard
3. When enabled, resets behavior tree and starts ticking
### Interruption Flow
```
1. Behavior tree is running (enabled)
2. Receives "interrupt" command from node (e.g., llm-command)
→ Behavior execution pauses
→ If duration_secs provided, schedules auto-resume
3. Manual command executes
4. After timeout OR manual resume:
→ Behavior tree resets and resumes execution
```
### Manual Control
```
Dashboard:
- "Enable" button → Starts behavior tree
- "Disable" button → Stops behavior tree
Nodes:
- Send "interrupt" → Pauses for user command
- Send "resume" → Resumes autonomous behavior
```
## Behavior Tree Files
Behavior trees are loaded from JSON files in the `behaviors/` directory:
**Example: `behaviors/patrol.json`**
```json
{
"type": "Sequence",
"children": [
{
"type": "wander",
"params": {
"linear_speed": 0.3,
"angular_speed": 0.5,
"duration_secs": 5.0
}
},
{
"type": "timer",
"params": {
"duration_secs": 2.0
}
}
]
}
```
## Built-in Action Nodes
### Wander
Moves the robot with random velocity:
```json
{
"type": "wander",
"params": {
"linear_speed": 0.3,
"angular_speed": 0.5,
"duration_secs": 5.0
}
}
```
### Move
Moves with fixed velocity:
```json
{
"type": "move",
"params": {
"linear": 0.5,
"angular": 0.0,
"duration_secs": 3.0
}
}
```
### Timer
Waits for a duration:
```json
{
"type": "timer",
"params": {
"duration_secs": 2.0
}
}
```
### Sensor Check
Checks sensor values:
```json
{
"type": "sensor_check",
"params": {
"sensor_topic": "/sensors/proximity",
"condition": "greater_than",
"threshold": 0.5
}
}
```
## Integration with LLM Command
The behavior executor works seamlessly with the llm-command node:
1. **Robot is patrolling** (behavior tree enabled)
2. **User says "stop"** via LLM
3. **llm-command sends interrupt** with 30s timeout
4. **Behavior tree pauses**, robot stops
5. **After 30 seconds**, behavior tree auto-resumes
6. **Robot continues patrolling**
This provides a natural "take control, then hand back" UX.
## Running
The node is launched automatically by `mecha10 dev` when included in `mecha10.json`.
To run manually:
```bash
cargo run -p mecha10-nodes-behavior-executor
```
## Health Check
The health check monitors:
- Behavior execution status (Success/Failure)
- Tick count
- Last status
If the behavior status is `Failure`, the health check reports unhealthy.
## Dependencies
- **mecha10-core**: Framework core (Context, Topic, Message)
- **mecha10-behavior-runtime**: Behavior tree runtime
- **tokio**: Async runtime
- **serde/serde_json**: Serialization
- **anyhow**: Error handling
## See Also
- [mecha10-behavior-runtime](../../behavior-runtime/README.md) - Behavior tree implementation
- [llm-command](../llm-command/README.md) - Natural language commands with interruption
- [Behavior Interrupt System](../../core/src/behavior_interrupt/README.md) - Reusable interrupt trigger