[Result Github]
Action Summary
Action Class
Donguk Seo Github
 
  (Reference Code)
“action” 이라는 폴더를 생성하고 action 파일을 생성
  # Define the goal
  int32 index
  sensor_msgs/Image img1  # Specify which dishwasher we want to use
  sensor_msgs/Image img2
  ---
  # Define the result
  int32 pano_index
  sensor_msgs/Image panoImg
  ---
  # Define a feedback message
  bool is_make_pano
CMakeList.txt
  find_package(catkin REQUIRED COMPONENTS
    **actionlib
    actionlib_msgs
    genmsg**
  )
                
  ## Generate actions in the 'action' folder
  add_action_files(
    FILES
    **image.action**
  )
                
  ## Generate added messages and services with any dependencies listed here
  generate_messages(
    DEPENDENCIES
    **actionlib_msgs**
  )
                
  catkin_package(
   INCLUDE_DIRS include ${catkin_INCLUDE_DIRS}
  #  LIBRARIES Action_tutorial
   CATKIN_DEPENDS **actionlib** 
  #  DEPENDS system_lib
  )
package.xml
  <build_depend>actionlib</build_depend>
  <build_depend>actionlib_msgs</build_depend>
                
  <build_export_depend>actionlib</build_export_depend>
  <build_export_depend>actionlib_msgs</build_export_depend>
                
  <exec_depend>actionlib</exec_depend>
  <exec_depend>actionlib_msgs</exec_depend>
include header
  // Action Client Related 
  #include <actionlib/client/simple_action_client.h>
  #include <actionlib/client/terminal_state.h>
  #include <Action_tutorial/imageAction.h> 
main.cpp
  // Publisher initialization
  ros::Publisher pub_pano = nh.advertise<sensor_msgs::Image>("PanoramaImage", 100);
            
  // Client initialization  
  actionlib::SimpleActionClient<Action_tutorial::imageAction> client("imgAction", true);
            
  // Will wait for infinite time
  client.waitForServer(); 
            
  // Goal, Result initialization
  Action_tutorial::imageGoal goal;
  Action_tutorial::imageResultConstPtr result;
            
  // Put in goal information
  goal.index = sequence;
  goal.img1 = img1;
  goal.img2 = img2;
            
  // To send Server 
  client.sendGoal(goal);
            
  // Wait for Server output
  bool finished_before_timeout = client.waitForResult(ros::Duration(5));
            
  if(finished_before_timeout)
  {
      result = client.getResult();
      ROS_WARN("Get Pano Img Index: %i", result -> pano_index);
      pub_pano.publish(result -> panoImg);
  }
  else
      ROS_INFO("Action did not finish before the time out.");
include header
  // Action Server Related
  #include <actionlib/server/simple_action_server.h>
  #include <Action_tutorial/imageAction.h>
main.cpp
  // Server initialization 
  actionlib::SimpleActionServer<Action_tutorial::imageAction> server;
            
  // Feedback, Result initialization 
  Action_tutorial::imageFeedback feedback;
  Action_tutorial::imageResult result;
            
  bool success;
            
  // Consturctor including NodeHandle
  ImgServer(ros::NodeHandle &n)
  : nh(n)
  , server(nh, "imgAction", boost::bind(&ImgServer::execute, this, _1), false)
  {
      server.start();
  }
            
  // Get client message and do execute get final goal 
  void execute(const Action_tutorial::imageGoalConstPtr &goal)
  {
      success = false;
            		
  		// Get client information
      int cur_index = goal -> index;
      sensor_msgs::Image image1 = goal -> img1;
      sensor_msgs::Image image2 = goal -> img2;
            
      cv_img1 = sensorMsg2cvMat(image1);
      cv_img2 = sensorMsg2cvMat(image2);
            
      makePanoImg(cv_img1, cv_img2, cv_pano_img, cur_index);
                
      if(success)
      {
          sensor_msgs::Image pano = cvMat2sensorMsg(cv_pano_img, image1.header);
                    
  				// Put result of final goal
  				result.pano_index = cur_index;
          result.panoImg = pano;
          ROS_WARN("Success Panorama Image !!");
            
  				// To send client using result 
          server.setSucceeded(result);
      }
  }