Go to the documentation of this file.00001 #include <iostream>
00002
00003 #include <decision_making/SynchCout.h>
00004 #include <decision_making/BT.h>
00005 #include <decision_making/FSM.h>
00006 #include <decision_making/ROSTask.h>
00007 #include <decision_making/DecisionMaking.h>
00008
00009 #include <ros/ros.h>
00010 #include <std_msgs/Bool.h>
00011 #include <sensor_msgs/Range.h>
00012
00013 using namespace std;
00014 using namespace decision_making;
00015
00016 volatile bool leftBumper, rightBumper, wallSensor;
00017
00018 ros::Subscriber leftBumperSub;
00019 ros::Subscriber rightBumperSub;
00020 ros::Subscriber wallSensorSub;
00021
00022 EventQueue* mainEventQueue;
00023 struct MainEventQueue{
00024 MainEventQueue(){ mainEventQueue = new RosEventQueue(); }
00025 ~MainEventQueue(){ delete mainEventQueue; }
00026 };
00027
00028 FSM(Roomba)
00029 {
00030 enum STATES
00031 {
00032 findWall,
00033 turnSx,
00034 correctSx,
00035 correctDx
00036 }
00037 FSM_START(findWall);
00038 FSM_BGN
00039 {
00040 FSM_STATE(findWall)
00041 {
00042 FSM_TRANSITIONS
00043 {
00044 FSM_ON_CONDITION( leftBumper==1||rightBumper==1 , FSM_NEXT(turnSx));
00045 }
00046 }
00047 FSM_STATE(turnSx)
00048 {
00049 FSM_TRANSITIONS
00050 {
00051 FSM_ON_CONDITION( leftBumper==0&&rightBumper==0 , FSM_NEXT(correctDx));
00052 }
00053 }
00054 FSM_STATE(correctSx)
00055 {
00056 FSM_TRANSITIONS
00057 {
00058 FSM_ON_CONDITION( leftBumper==1||rightBumper==1 , FSM_NEXT(turnSx));
00059 FSM_ON_CONDITION( wallSensor==0 , FSM_NEXT(correctDx));
00060 }
00061 }
00062 FSM_STATE(correctDx)
00063 {
00064 FSM_TRANSITIONS
00065 {
00066 FSM_ON_CONDITION( leftBumper==1||rightBumper==1 , FSM_NEXT(turnSx));
00067 FSM_ON_CONDITION( wallSensor==1 , FSM_NEXT(correctSx));
00068 }
00069 }
00070 }
00071 FSM_END
00072 }
00073
00074 void onLeftBumperMessage(const std_msgs::Bool::Ptr& bumperState) {
00075 ROS_INFO("Left bumper state = %s", bumperState->data ? "Active" : "Not active");
00076 leftBumper = bumperState->data;
00077 }
00078
00079 void onRightBumperMessage(const std_msgs::Bool::Ptr& bumperState) {
00080 ROS_INFO("Right bumper state = %s", bumperState->data ? "Active" : "Not active");
00081 rightBumper = bumperState->data;
00082 }
00083
00084 void onWallSensorMessage(const sensor_msgs::Range::Ptr& sensor) {
00085 wallSensor = sensor->range < 0.3;
00086 ROS_INFO("Wall sensor range = %f, state = %s", sensor->range, wallSensor ? "Active" : "Not active");
00087 }
00088
00089 int main(int argc, char** argv){
00090
00091 ros::init(argc, argv, "fsm_roomba");
00092 MainEventQueue meq;
00093 ros_decision_making_init(argc, argv);
00094
00095 ros::NodeHandle node;
00096 leftBumperSub = node.subscribe("/roomba/left_bumper", 1, onLeftBumperMessage);
00097 rightBumperSub = node.subscribe("/roomba/left_bumper", 1, onRightBumperMessage);
00098 wallSensorSub = node.subscribe("/roomba/wall_sensor", 1, onWallSensorMessage);
00099
00100 ros::AsyncSpinner spinner(2);
00101 spinner.start();
00102
00103 ROS_INFO("Starting roobma...");
00104
00108 mainEventQueue->async_spin();
00109 FsmRoomba(NULL, mainEventQueue);
00110 mainEventQueue->close();
00111
00112 spinner.stop();
00113 ROS_INFO("Roomba done");
00114
00115 return 0;
00116 }
00117
00118