What is Behavior-based Programming?
Behavior Robot Programming Basics
The concept of behavior-based robotics is to supply a set of behaviors that independently work to accomplish their goals, but together allow the robot to accomplish larger tasks. I have created a framework for the Mindstorms NXT robotics system in RobotC that allows a programmer to “plug-in” behaviors, rank them, and create complex tasks. There are a few concepts to grasp before diving in.
Traditional robot programming is “plan-based” where a series of tasks are sequentially programmed to solve a larger problem. Behavior-based programming is parallel in nature where behaviors each pesess their own goals, and compete for control of the robot providing an opportunistic platform that ultimately accomplishes the larger task. It also allows for more graceful degradation processes and sensors, handling mistakes and failed input in stride.
In plan-based programming mode, each program is written for a specific overall task. Decisions are built into the program in a specified order, and built to accomplish the larger goal. As the complexity of the robot increases, so does the coding. Not only are there more lines of code, but dealing with new situations requires more code to make decisions to be made inserted inline. This can become cumbersome and error-prone in an autonomous world.
Behavior-based programming employs a hierarchical system of behaviors specifically written to perform an action based on a set of triggers (cruise, bumper escape, avoid, home, etc..). As complexity is added to the overall system, new behaviors can be added without changing existing ones. Behavior-based programming considers each behavior independently to determine control of the robot. It sounds like chaos, but it turns out to be very flexible and robust. As a result of many small, thought out, behaviors achieving mini goals, ultimately accomplishes complex tasks. If built properly, the robot appears to think and make decisions about it environment toward completing the task. That is where the magic is.
An Example – A Room Explorer
Think about an example where a robot is needed to travel around a room and cover as much territory as possible. How would you approach the problem?
Plan Based Approach
Traditionally, my first thoughts go to creating a robot that can methodically travel around the room in a pattern that allows it to cover the entire floor. It might start in a corner, and move back and forth in straight lines from end to end until it hit the opposite corner.
How realistic is this approach? In theory, this solution is possible, but think of all of the things that can go wrong in this scenario.
- What if the room is not rectangular or regular shaped?
- What if the robot can’t drive exactly straight and looses “exact” track of location and plan
- We have all cut the grass before only to see we missed a little strip between two passes. Can a robot accurately create a path that covers lines up each successive pass back and forth? For how long? What is the correction mechanism?
- What if there are obstacles in the room like a chair, or table? Do we go around it and try to get back on course?
- What about physical robot factors like sensors, motors, etc… that are not perfect?
- And many more issues that can quickly derail a “Planned” approach
Thinking about the task in behavior-based terms requires the programmer to think outside the box. Behaviors such as driving and escaping when stuck come to mind. If the robot can drive around randomly, bumping into or turning away from walls and furniture, eventually the robot would cover the floor. Implementing this basic approach might look like this:
Behavior – CRUISE
CRUISE is a simple behavior with no inputs and no feedback mechanism. Its purpose is to always request control of the robot to drive in one pre-defined speed and direction. This behavior produces a low level movement that is usually utilized to move the robot from place to place in the absence of other triggered behaviors.
Behavior – BUMP ESCAPE
BUMP ESCAPE is a more complex behavior to implement, but has a simple purpose. If the robot bumps into something, backup and turn away from the obstacle.
The robot drives around the room bumping into obstacles and changing direction. The CRUISE behavior provides basic locomotion for the robot. When it contacts (bumpers are depressed) an object, BUMP ESCAPE takes control and escapes from the collision. Once the robot is clear BUMP ESCAPE becomes dormant and CRUISE again controls the robot. The arbitrator checks the behaviors that are requesting control and resolves conflict based on hierarchy. In this case, BUMP ESCAPE has a higher priority and receives control when triggered over CRUISE.
This simple robot has a good chance of accomplishing its mission given enough time to randomly bounce around. It does not need to move straight, keep a map of the area, correct course deviations, etc… making it simple and effective. Can it be improved? Yes.
- What if the room has a lot of obstacles in it making navigation tougher?
- What if the room is divided into a couple of segregated areas by obstacles or walls?
Phase II – Adding AVOID
To solve these new problems, the current code does not need to be changed. New behaviors can be added to the robot that makes it more effective.
Behavior – AVOID
The AVIOD behavior employs a proximity sensor to detect an obstacle before hitting it. When the proximity sensor detects an obstacle, it triggers the robot to turn away from the obstacle. If you implement two sensors or a dual infrared proximity detector type of sensor, this behavior can determine if the obstacle is in front, left or right and act accordingly.
The robot drives around the room, finding objects along way to avoid. In the case where the AVOID behavior misses an obstacle, the robot bumps it and escapes by backing up and spinning around.
The robot arbitrator processes requests from each behavior and resolves conflicts based on hierarchy. In this case, the robot CRUISEs around the room until it sees an object. The AVOID behavior takes control and drives toward the object ensuring a bump (if it is set to move toward objects). WALL FOLLOW may or may not assume control based on its parameters when the bump occurs. If it takes control, the robot follows the wall for a time and gives up. CRUISE takes control again. The BUMP ESCAPE behavior requests control when the bumpers are hit too. If WALL FOLLOW declines control, BUMP ESCAPE takes over and escapes from the obstacle.
Other behaviors can be layered on top of this implementation to make the robot more robust. After reading more and more information about this type of application, I found the robot to be even more effective by changing the AVOID behavior to be attracted to obstacles instead of avoiding them, and adding a WALL FOLLOWING behavior on top of everything.
When the robot gets near an obstacle, it turns toward the object and initiates wall following when it makes contact. In order to allow other behaviors to function (and ultimately accomplish navigating the room), the wall following has a random element for triggering and a time limit for following a wall. The goal is not to follow the wall forever, but to use the behavior to cover ground that may be missed by bouncing around a room. Now the robot can skirt around objects and walls and improve chances of advancing into doorways and tight areas.
The reality of designing and programming autonomous robots is that there are an infinite number of solutions that can be implemented. Behavior based programming allows you to build small units of code (behaviors) that can be reused, reprioritized, and built upon to create very robust solutions. This method allows you to break large tasks into smaller units of activity that act independently, but collectively work to complete tasks.