25 #include <blackboard/remote.h> 26 #include <interfaces/SkillerInterface.h> 27 #include <utils/time/time.h> 30 #include <fawkes_msgs/ExecSkillAction.h> 31 #include <fawkes_msgs/ExecSkillGoal.h> 32 #include <fawkes_msgs/ExecSkillActionGoal.h> 33 #include <fawkes_msgs/SkillStatus.h> 39 #define GET_PRIV_PARAM(P) \ 41 if (! ros::param::get("~" #P, cfg_ ## P ## _)) { \ 42 ROS_ERROR("%s: Failed to retrieve parameter " #P ", aborting", ros::this_node::getName().c_str()); \ 56 : rosnode(rn), blackboard(bb) {}
58 fawkes_msgs::ExecSkillResult
61 fawkes_msgs::ExecSkillResult result;
62 result.errmsg = errmsg;
67 fawkes_msgs::ExecSkillFeedback
70 return fawkes_msgs::ExecSkillFeedback();
77 goal.
getGoal()->skillstring.c_str());
78 std::lock_guard<std::mutex> lock(loop_mutex);
79 if (exec_running_ && exec_as_) {
80 std::string error_msg =
"Replaced by new goal";
81 as_goal_.setAborted(create_result(error_msg), error_msg);
83 if (! blackboard || !blackboard->is_alive()) {
84 std::string error_msg =
"Blackboard not connected";
85 goal.
setAborted(create_result(error_msg), error_msg);
89 goal_ = goal.
getGoal()->skillstring;
100 std::lock_guard<std::mutex> lock(loop_mutex);
102 std::string error_msg =
"Abort on request";
103 goal.
setCanceled(create_result(error_msg), error_msg);
108 exec_request_ =
false;
109 exec_running_ =
false;
114 skiller_if_ = blackboard->open_for_reading<SkillerInterface>(
"Skiller");
115 }
catch (
const Exception &e) {
125 pub_status_ = rosnode->advertise<fawkes_msgs::SkillStatus>(
"skiller_status",
true);
133 blackboard->close(skiller_if_);
134 }
catch (Exception& e) {
137 pub_status_.shutdown();
144 if (skiller_if_->exclusive_controller() != skiller_if_->serial()) {
149 if (skiller_if_->has_writer())
150 skiller_if_->msgq_enqueue(
new SkillerInterface::StopExecMessage());
152 std::string error_msg =
"Abort on request";
153 as_goal_.setAborted(create_result(error_msg), error_msg);
155 skiller_if_->msgq_enqueue(
new SkillerInterface::ReleaseControlMessage());
156 exec_running_ =
false;
162 std::lock_guard<std::mutex> lock(loop_mutex);
166 if (!exec_running_ && !exec_request_ && wait_release_ == 0 &&
167 skiller_if_->exclusive_controller() == skiller_if_->serial())
169 ROS_INFO(
"%s: No skill running and no skill requested, releasing control",
171 skiller_if_->msgq_enqueue(
new SkillerInterface::ReleaseControlMessage());
176 if (wait_release_ > 0 &&
177 skiller_if_->exclusive_controller() == skiller_if_->serial())
179 if (++wait_release_ % 50 == 0) {
180 ROS_WARN(
"%s: waiting for exclusive control release",
184 if (wait_release_ > 30) {
192 if (!skiller_if_->has_writer()) {
193 std::string error_msg(
"no writer for skiller, cannot execute");
196 as_goal_.setAborted(create_result(error_msg), error_msg);
200 if (skiller_if_->exclusive_controller() != skiller_if_->serial()) {
203 skiller_if_->msgq_enqueue(
new SkillerInterface::AcquireControlMessage());
206 exec_request_ =
false;
208 SkillerInterface::ExecSkillMessage *msg =
209 new SkillerInterface::ExecSkillMessage(goal_.c_str());
215 skiller_if_->msgq_enqueue(msg);
216 exec_running_ =
true;
217 exec_msgid_ = msg->id();
218 exec_skill_string_ = msg->skill_string();
220 }
catch (Exception &e) {
225 }
else if (exec_running_) {
226 if (exec_as_) as_goal_.publishFeedback(create_feedback());
228 if (skiller_if_->status() == SkillerInterface::S_INACTIVE ||
229 skiller_if_->msgid() != exec_msgid_)
234 if (loops_waited_ >= 5) {
237 std::string error_msg =
"Skiller doesn't start";
238 if (exec_as_) as_goal_.setAborted(create_result(error_msg), error_msg);
239 exec_running_ =
false;
242 else if (skiller_if_->status() != SkillerInterface::S_RUNNING) {
243 exec_running_ =
false;
244 if (exec_as_ && exec_skill_string_ == skiller_if_->skill_string()) {
245 if (skiller_if_->status() == SkillerInterface::S_FINAL) {
246 std::string error_msg =
"Skill executed";
247 as_goal_.setSucceeded(create_result(error_msg), error_msg);
249 else if (skiller_if_->status() == SkillerInterface::S_FAILED){
250 std::string error_msg =
"Failed to execute skill";
252 if (asprintf(&tmp,
"Failed to execute skill, error: %s", skiller_if_->error()) != -1) {
256 as_goal_.setAborted(create_result(error_msg), error_msg);
265 if (skiller_if_->changed()) {
266 fawkes_msgs::SkillStatus msg;
267 const Time *time = skiller_if_->timestamp();
268 msg.stamp =
ros::Time(time->get_sec(), time->get_nsec());
269 msg.skill_string = skiller_if_->skill_string();
270 msg.error = skiller_if_->error();
271 msg.status = skiller_if_->status();
272 pub_status_.publish(msg);
304 ros::init(argc, argv,
"fawkes_skiller_forward");
308 std::shared_ptr<RosSkillerNode> ros_skiller_node;
309 std::string cfg_fawkes_host_;
310 int cfg_fawkes_port_;
311 std::shared_ptr<fawkes::BlackBoard> blackboard_;
321 std::make_shared<fawkes::RemoteBlackBoard>(cfg_fawkes_host_.c_str(), cfg_fawkes_port_);
322 ros_skiller_node = std::make_shared<RosSkillerNode>(&n, blackboard_);
323 ros_skiller_node->init();
325 }
catch (fawkes::Exception &e) {
327 if (ros_skiller_node) {
328 ros_skiller_node->finalize();
330 ros_skiller_node.reset();
333 }
else if (! blackboard_->is_alive()) {
335 if (blackboard_->try_aliveness_restore()) {
339 ros_skiller_node->loop();
345 if (ros_skiller_node) ros_skiller_node->finalize();
fawkes_msgs::ExecSkillFeedback create_feedback()
void action_cancel_cb(SkillerServer::GoalHandle goal)
#define ROS_WARN_THROTTLE(rate,...)
int main(int argc, char **argv)
fawkes::SkillerInterface * skiller_if_
std::shared_ptr< fawkes::BlackBoard > blackboard
void action_goal_cb(SkillerServer::GoalHandle goal)
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
std::string exec_skill_string_
boost::shared_ptr< const Goal > getGoal() const
ROSCPP_DECL const std::string & getName()
SkillerServer::GoalHandle as_goal_
void setCanceled(const Result &result=Result(), const std::string &text=std::string(""))
ROSCPP_DECL CallbackQueue * getGlobalCallbackQueue()
void setAccepted(const std::string &text=std::string(""))
unsigned int wait_release_
ros::NodeHandle * rosnode
RosSkillerNode(ros::NodeHandle *rn, std::shared_ptr< fawkes::BlackBoard > bb)
fawkes_msgs::ExecSkillResult create_result(std::string errmsg)
void setAborted(const Result &result=Result(), const std::string &text=std::string(""))
#define GET_PRIV_PARAM(P)
actionlib::ActionServer< fawkes_msgs::ExecSkillAction > SkillerServer
ros::Publisher pub_status_
unsigned int loops_waited_