state_machine_elevator.cpp
Go to the documentation of this file.
00001 
00009 #include <ros/ros.h>
00010 #include <tf/transform_listener.h>
00011 #include <std_msgs/String.h>
00012 #include <std_msgs/Bool.h>
00013 #include <std_srvs/Empty.h>
00014 #include <geometry_msgs/PoseStamped.h>
00015 #include <actionlib/client/simple_action_client.h>
00016 #include <actionlib_msgs/GoalStatus.h>
00017 #include <move_base_msgs/MoveBaseAction.h>
00018 #include <stdio.h>
00019 #include <string>
00020 #include <sstream>
00021 #include <open_door_detector/detect_open_door.h>
00022 
00023 // global variables
00024 ros::Time last_button_msg_time; // last time a button has been pressed
00025 int current_goal = 0; // currently active goal
00026 
00027 // function declarations
00028 void createPoseFromParams(std::string param_name, geometry_msgs::PoseStamped* pose);
00029 void buttonCb(std_msgs::Bool msg);
00030 bool last_button_state = false;
00031 void createOffsetPose(geometry_msgs::PoseStamped* goal, float posX_off, float posY_off, float rotW_off);
00032 
00033 // position parameter
00034 float posX_off;
00035 float posY_off;
00036 float rotW_off;
00037 float angle;
00038 float dist;
00039 float width;
00040 
00041 
00042 
00043 
00044 
00045 // define state names
00046 enum state {
00047         START, START_POS, WAIT_BUTTON, WAIT_ELEVATOR, DRIVE_DOOR, DRIVE_IN, ROTATION 
00048 };
00049 
00050 int main(int argc, char** argv) {
00051         
00052         // init ROS
00053         ros::init(argc, argv, "state_machine_elevator");
00054         ros::NodeHandle nh;
00055         ros::Rate loop_rate(10);
00056         
00057         // set up publishers
00058         ros::Publisher speech_pub = nh.advertise<std_msgs::String>("/speech", 1);
00059         
00060         // set up subscribers
00061         ros::Subscriber button_sub = nh.subscribe<std_msgs::Bool>("/pushed", 1, buttonCb);
00062         
00063         // client for navigation goals
00064         actionlib::SimpleActionClient<move_base_msgs::MoveBaseAction> client("move_base", true);
00065         
00066         // init time
00067         ros::Time ask_time;
00068         last_button_msg_time = ros::Time(0);
00069         
00070         move_base_msgs::MoveBaseGoal goal;
00071         goal.target_pose.header.frame_id = "map";
00072         
00073         // init state machine
00074         state st = START;
00075         
00076         // wait for other nodes to start up
00077         ros::Duration(10).sleep();
00078         
00079         // tf listener
00080         tf::TransformListener listener;
00081         tf::StampedTransform transform;
00082         
00083         geometry_msgs::PoseStamped door_pos;
00084         
00085         
00086       
00087         
00088         while(ros::ok()) {
00089                 
00090 
00091 
00092                 switch(st) {
00093                         case START: {
00094                                 ROS_INFO("START");
00095                                 createPoseFromParams("start", &(goal.target_pose));
00096                                 client.sendGoal(goal);
00097                                 
00098                                 st=START_POS;
00099                                 ROS_INFO("Switching to state %d", st);
00100                                 break;
00101                                 
00102                         }
00103                         
00104                         case START_POS: {
00105                                 //ROS_INFO("START_POS");
00106 
00107                                 
00108                                 if (client.getState() == actionlib::SimpleClientGoalState::SUCCEEDED) {
00109                                         st = WAIT_BUTTON;
00110                                         ROS_INFO("Reached start position");
00111                                         ROS_INFO("Switching to state %d", st);
00112                                 }
00113                                 
00114                                 break;
00115                         }
00116                         case WAIT_BUTTON: {
00117                                 
00118                                 
00119                                 std_msgs::String say_callelevator;
00120                                 say_callelevator.data = "Please call Elevator";
00121                                 speech_pub.publish(say_callelevator);
00122                                 
00123                                 //ROS_INFO("Waiting for button");
00124                                 if(last_button_state) { // person called elevator
00125                                         st = WAIT_ELEVATOR;
00126                                         ROS_INFO("Waiting for elevator");
00127                                         ROS_INFO("Switching to state %d", st);
00128 
00129                                 }
00130                                 break;
00131                         }
00132                         
00133                         case WAIT_ELEVATOR: {
00134                                 //check which door is open and get posX, posY, rotW and choose next state
00135                                 
00136                                 //initialze service
00137                                 ros::ServiceClient client = nh.serviceClient<open_door_detector::detect_open_door>("detect_open_door");
00138                                 ros::ServiceClient mapclient = nh.serviceClient<std_srvs::Empty>("move_base/clear_costmaps");
00139                                 open_door_detector::detect_open_door srv;
00140                                 std_srvs::Empty mapSrv;
00141                                 
00142                                 
00143                                 ros::param::get("/goals/doorparams/apertureangle", angle);
00144                                 ros::param::get("/goals/doorparams/walldistance", dist);
00145                                 ros::param::get("/goals/doorparams/mindoorwidth", width);
00146                                 //angle =0;
00147                                 //dist = 2;
00148                                 //width = 0.5;
00149                                 
00150                                 srv.request.aperture_angle = angle;
00151                                 srv.request.wall_distance = dist;
00152                                 srv.request.min_door_width = width;
00153                                 
00154                                 
00155                                 if (client.call(srv)){
00156                                   
00157                                   door_pos = srv.response.door_pos;
00158                                   
00159                                 } else {
00160                                   ROS_ERROR("Failed to call service detect_open_door");
00161                                   return 1;
00162                                   
00163                                 }       
00164                                 posX_off = door_pos.pose.position.x;
00165                                 posY_off = door_pos.pose.position.y;
00166                                 
00167                                 if(posX_off != 0 || posY_off != 0) {
00168                                    ros::Duration(2).sleep();
00169                                    if (client.call(srv)){
00170                                   
00171                                     door_pos = srv.response.door_pos;
00172                                     
00173                                     } else {
00174                                       ROS_ERROR("Failed to call service detect_open_door");
00175                                       return 1;
00176                                     
00177                                     }   
00178                                     posX_off = door_pos.pose.position.x;
00179                                     posY_off = door_pos.pose.position.y;
00180                                     if(posX_off != 0 || posY_off != 0) {
00181                                         st = DRIVE_DOOR; 
00182                                         ROS_INFO("posX is: %f", posX_off);
00183                                         ROS_INFO("posY is: %f", posY_off);
00184                                         mapclient.call(mapSrv);
00185                                         ros::Duration(0.5).sleep();
00186                                     }
00187                                 }
00188                                 
00189                                 
00190                                 ROS_INFO("Driving to Door");
00191                                 ROS_INFO("Switching to state %d", st);
00192                                 
00193                                 
00194                                 
00195                                 break;
00196                         }
00197                         
00198                         case DRIVE_DOOR: {
00199                                 //calculate the left point from inertial point + kinect data
00200                                 createOffsetPose(&(goal.target_pose), posX_off, posY_off, rotW_off);
00201                                 
00202                                 /*
00203                                 ros::Time now = ros::Time::now();
00204                                 listener.waitForTransform("map", "base_footprint", now, 2.0);
00205                                 listener.lookupTransform("map", "base_footprint", now, transform);
00206                                 
00207                                 tf::Transform toGoal;
00208                                 toGoal.setOrigin(tf::Vector3(x, y, 0));
00209                                 toGoal.setRotation(tf::Quaternion(tf::Vector3(0,0,1), phi));
00210                                 
00211                                 tf::Transform final = transform * toGoal;
00212                                 
00213                                 pose->pose.position.x
00214                                 goal.x = final.getOrigin().y();
00215                                 goal.x = final.getOrigin().phi();
00216                                 */
00217 
00218                                 //createPoseFromParams("goal_1", &(goal.target_pose));
00219                                 client.sendGoal(goal);
00220                                 st=DRIVE_IN;
00221                                 
00222                                 break;
00223                         }
00224                         
00225                         case DRIVE_IN: {
00226                                 if (client.getState() == actionlib::SimpleClientGoalState::SUCCEEDED) {
00227                                         
00228                                         ROS_INFO("Im at the door");
00229                                         
00230                                         ros::param::get("/goals/endPose/x", posX_off);
00231                                         ros::param::get("/goals/endPose/y", posY_off);
00232                                         ros::param::get("/goals/endPose/w", rotW_off);
00233                                                                         
00234                                         createOffsetPose(&(goal.target_pose), posX_off, posY_off, rotW_off);
00235                                         client.sendGoal(goal);
00236                                         st = ROTATION;
00237                                         ROS_INFO("Driving into the elevator");
00238                                         ROS_INFO("Switching to state %d", st);
00239                                 }
00240                                 
00241                                 break;
00242                                 
00243                         }
00244                         
00245                         case ROTATION: {
00246                                 if (client.getState() == actionlib::SimpleClientGoalState::SUCCEEDED) {
00247                                   //ROS_INFO("Im in the elevator!");
00248                                   
00249                                   
00250                                 }
00251                                 break;
00252                         }       
00253                 }
00254         ros::spinOnce();
00255                 
00256         }
00257         
00258         
00259         
00260         
00261 
00262         
00263         return 0;
00264 }
00265 
00266 void buttonCb(std_msgs::Bool msg) {
00267         last_button_msg_time = ros::Time::now();
00268         last_button_state = msg.data;
00269 }
00270 
00281 void createPoseFromParams(std::string param_name, geometry_msgs::PoseStamped* pose) {
00282         pose->header.stamp = ros::Time::now();
00283         ros::param::get("/goals/"+param_name+"/x", pose->pose.position.x);
00284         ros::param::get("/goals/"+param_name+"/y", pose->pose.position.y);
00285         ros::param::get("/goals/"+param_name+"/z", pose->pose.position.z);
00286         ros::param::get("/goals/"+param_name+"/q1", pose->pose.orientation.x);
00287         ros::param::get("/goals/"+param_name+"/q2", pose->pose.orientation.y);
00288         ros::param::get("/goals/"+param_name+"/q3", pose->pose.orientation.z);
00289         ros::param::get("/goals/"+param_name+"/q4", pose->pose.orientation.w);
00290 }
00291 
00292 void createOffsetPose(geometry_msgs::PoseStamped* goal, float posX_off, float posY_off, float rotW_off) {
00293         goal->header.stamp = ros::Time::now();
00294         goal->pose.position.x = goal->pose.position.x + posX_off;
00295         goal->pose.position.y= goal->pose.position.y + posY_off;
00296         
00297         tf::Quaternion quat(tf::Vector3(0,0,1), rotW_off);
00298         goal->pose.orientation.x = quat.x();
00299         goal->pose.orientation.y = quat.y();
00300         goal->pose.orientation.z = quat.z();
00301         goal->pose.orientation.w = quat.w();
00302         
00303 }
00304 
00305 
00306 
00307 


elevator
Author(s): Alexander Reiter , Armin Steinhauser
autogenerated on Fri Aug 28 2015 13:41:19