00001 /* Copyright (C) 2015-2017 Michele Colledanchise - All Rights Reserved 00002 * 00003 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), 00004 * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 00005 * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 00006 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 00007 * 00008 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00009 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 00010 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00011 */ 00012 00013 00014 #include <actions/ros_action.h> 00015 #include <string> 00016 00017 00018 BT::ROSAction::ROSAction(std::string name) : 00019 ActionNode::ActionNode(name), 00020 action_client_(name, true) 00021 { 00022 actionlib::SimpleActionClient<behavior_tree_core::BTAction> action_client_(get_name(), true); 00023 ROS_INFO("Waiting For the Acutator named %s to start", get_name().c_str()); 00024 action_client_.waitForServer(); // will wait for infinite time until the server starts 00025 ROS_INFO("The Acutator %s has started", get_name().c_str()); 00026 // thread_ start 00027 thread_ = std::thread(&ROSAction::WaitForTick, this); 00028 } 00029 00030 BT::ROSAction::~ROSAction() {} 00031 00032 void BT::ROSAction::WaitForTick() 00033 { 00034 while (true) 00035 { 00036 // Waiting for a tick to come 00037 tick_engine.Wait(); 00038 00039 // Running state 00040 node_result.status = BT::RUNNING; 00041 set_status(BT::RUNNING); 00042 // Perform action... 00043 ROS_INFO("I am running the request to %s", get_name().c_str()); 00044 action_client_.sendGoal(goal); 00045 do 00046 { 00047 node_result = *(action_client_.getResult()); // checking the result 00048 } 00049 while (node_result.status == BT::RUNNING && get_status() != BT::HALTED); 00050 00051 if (get_status() == BT::HALTED) 00052 { 00053 ROS_INFO("The Node is Halted"); 00054 ROS_INFO("I am Halting the client"); 00055 action_client_.cancelGoal(); 00056 } 00057 else 00058 { 00059 ROS_INFO("The Server Has Replied"); 00060 // Set this node status according to what the external node replied 00061 set_status((ReturnStatus)node_result.status); 00062 } 00063 } 00064 } 00065 00066 00067 void BT::ROSAction::Halt() 00068 { 00069 set_status(BT::HALTED); 00070 }