Chapter 7: Autonomous Behaviors

State Machines

from enum import Enum

class RobotState(Enum):
    IDLE = 0
    EXPLORING = 1
    AVOIDING_OBSTACLE = 2
    CHARGING = 3

class BehaviorController(Node):
    def __init__(self):
        super().__init__('behavior_controller')
        self.state = RobotState.IDLE
        self.timer = self.create_timer(0.1, self.state_machine)
    
    def state_machine(self):
        if self.state == RobotState.IDLE:
            if self.battery_low():
                self.state = RobotState.CHARGING
            else:
                self.state = RobotState.EXPLORING
        
        elif self.state == RobotState.EXPLORING:
            if self.obstacle_detected():
                self.state = RobotState.AVOIDING_OBSTACLE
            elif self.battery_low():
                self.state = RobotState.CHARGING
        
        elif self.state == RobotState.AVOIDING_OBSTACLE:
            if not self.obstacle_detected():
                self.state = RobotState.EXPLORING

Behavior Trees

class BehaviorTree:
    def __init__(self):
        self.root = Sequence([
            CheckBattery(),
            Selector([
                AvoidObstacle(),
                Navigate()
            ])
        ])
    
    def tick(self):
        return self.root.execute()

Obstacle Avoidance

def avoid_obstacle(self, scan_data):
    min_distance = min(scan_data.ranges)
    
    if min_distance < 0.5:
        # Turn away from obstacle
        twist = Twist()
        twist.angular.z = 1.0
        self.cmd_vel_pub.publish(twist)
    else:
        # Move forward
        twist = Twist()
        twist.linear.x = 0.3
        self.cmd_vel_pub.publish(twist)

Next: Chapter 8 - Real Robot Deployment!