Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include <iostream>
00030
00031 #include <boost/bind.hpp>
00032 #include <boost/thread.hpp>
00033 #include <boost/foreach.hpp>
00034
00035 #include <ros/ros.h>
00036 #include <random_numbers/random_numbers.h>
00037 #include <sensor_msgs/LaserScan.h>
00038 #include <geometry_msgs/Twist.h>
00039
00040 #include <decision_making/FSM.h>
00041 #include <decision_making/ROSTask.h>
00042 #include <decision_making/DecisionMaking.h>
00043
00044 using namespace std;
00045 using namespace decision_making;
00046
00047 #define foreach BOOST_FOREACH
00048
00049
00050
00051
00052
00053 random_numbers::RandomNumberGenerator _randomizer;
00054 ros::Publisher _velocityPublisher;
00055
00056
00057
00058
00059
00060 FSM(Wandering)
00061 {
00062 FSM_STATES
00063 {
00064 Drive,
00065 Turn,
00066 Pause
00067 }
00068 FSM_START(Turn)
00069 FSM_BGN
00070 {
00071 FSM_STATE(Turn)
00072 {
00073 FSM_CALL_TASK(Turn)
00074
00075 FSM_TRANSITIONS
00076 {
00077 FSM_ON_EVENT(/TURN_TIMEOUT, FSM_NEXT(Drive))
00078 FSM_ON_EVENT(/PAUSE, FSM_NEXT(Pause))
00079 }
00080 }
00081 FSM_STATE(Drive)
00082 {
00083 FSM_CALL_TASK(Drive)
00084
00085 FSM_TRANSITIONS
00086 {
00087 FSM_ON_EVENT(/DRIVE_TIMEOUT, FSM_NEXT(Turn))
00088 FSM_ON_EVENT(/OBSTACLE, FSM_NEXT(Turn))
00089 FSM_ON_EVENT(/PAUSE, FSM_NEXT(Pause))
00090 }
00091 }
00092 FSM_STATE(Pause)
00093 {
00094 FSM_CALL_TASK(Pause)
00095
00096 FSM_TRANSITIONS
00097 {
00098 FSM_ON_EVENT(/RESUME, FSM_NEXT(Turn))
00099 }
00100 }
00101 }
00102 FSM_END
00103 }
00104
00105
00106
00107
00108
00109 void onLaserScanMessage(const sensor_msgs::LaserScan::Ptr laserScanMessage, RosEventQueue* eventQueue) {
00110 double frontRange = laserScanMessage->ranges[laserScanMessage->ranges.size() / 2];
00111
00112 if (frontRange < 0.5) {
00113 eventQueue->riseEvent("/OBSTACLE");
00114 }
00115 }
00116
00117
00118
00119
00120
00121
00122 decision_making::TaskResult driveTask(string name, const FSMCallContext& context, EventQueue& eventQueue) {
00123 ROS_INFO("Driving...");
00124
00125 double timeToDriveMs = _randomizer.uniformInteger(4000, 8000);
00126
00127 geometry_msgs::Twist forwardMessage;
00128 forwardMessage.linear.x = 2;
00129 _velocityPublisher.publish(forwardMessage);
00130
00134 for (int i = 0; i < 100; ++i) {
00135 if (eventQueue.isTerminated()) {
00136 ROS_INFO("Obstacle!");
00137 return TaskResult::TERMINATED();
00138 }
00139
00140 boost::this_thread::sleep(boost::posix_time::milliseconds(timeToDriveMs / 100.0));
00141 }
00142
00143 eventQueue.riseEvent("/DRIVE_TIMEOUT");
00144 return TaskResult::SUCCESS();
00145 }
00146
00147 decision_making::TaskResult turnTask(string name, const FSMCallContext& context, EventQueue& eventQueue) {
00148 ROS_INFO("Turning...");
00149
00150 bool turnRight = _randomizer.uniformInteger(0, 1);
00151 int timeToTurnMs = _randomizer.uniformInteger(2000, 4000);
00152
00153 geometry_msgs::Twist turnMessage;
00154 turnMessage.angular.z = 2 * (turnRight ? 1 : -1);
00155 _velocityPublisher.publish(turnMessage);
00156
00157 boost::this_thread::sleep(boost::posix_time::milliseconds(timeToTurnMs));
00158
00159 eventQueue.riseEvent("/TURN_TIMEOUT");
00160 return decision_making::TaskResult::SUCCESS();
00161 }
00162
00163 decision_making::TaskResult pauseTask(string name, const FSMCallContext& context, EventQueue& eventQueue) {
00164 ROS_INFO("Pausing...");
00165
00166 geometry_msgs::Twist stopMessage;
00167 _velocityPublisher.publish(stopMessage);
00168
00169 return decision_making::TaskResult::SUCCESS();
00170 }
00171
00172
00173
00174
00175
00176 int main(int argc, char **argv) {
00180 ros::init(argc, argv, "wandering");
00181 ros_decision_making_init(argc, argv);
00182 ros::NodeHandle nodeHandle;
00183 RosEventQueue eventQueue;
00184
00188 LocalTasks::registrate("Drive", driveTask);
00189 LocalTasks::registrate("Turn", turnTask);
00190 LocalTasks::registrate("Pause", pauseTask);
00191
00196 ros::Subscriber laserSubscriber = nodeHandle.subscribe<void>("/pioneer_1/scan_raw", 1,
00197 boost::function<void(const sensor_msgs::LaserScan::Ptr)>(boost::bind(onLaserScanMessage, _1, &eventQueue)));
00198
00199 _velocityPublisher = nodeHandle.advertise<geometry_msgs::Twist>("/pioneer_1/cmd_vel", 100, false);
00200
00204 ros::AsyncSpinner spinner(1);
00205 spinner.start();
00206
00210 ROS_INFO("Starting wandering machine...");
00211 FsmWandering(NULL, &eventQueue);
00212
00216 return 0;
00217 }