1
0
mirror of https://gitlab.com/obbart/universal_robots_ros_driver.git synced 2026-04-10 18:10:47 +02:00

Improved goal handling.

If the robot receives a new goal before the previous is succeeded, the previous will be aborted
This commit is contained in:
Thomas Timm Andersen
2015-10-09 14:39:24 +02:00
parent d8602c2246
commit 6b6ded461b

View File

@@ -19,6 +19,7 @@
#include <thread> #include <thread>
#include <algorithm> #include <algorithm>
#include <cmath> #include <cmath>
#include <chrono>
#include <time.h> #include <time.h>
#include "ros/ros.h" #include "ros/ros.h"
@@ -48,7 +49,8 @@ protected:
std::condition_variable msg_cond_; std::condition_variable msg_cond_;
ros::NodeHandle nh_; ros::NodeHandle nh_;
actionlib::ActionServer<control_msgs::FollowJointTrajectoryAction> as_; actionlib::ActionServer<control_msgs::FollowJointTrajectoryAction> as_;
actionlib::ServerGoalHandle<control_msgs::FollowJointTrajectoryAction>* goal_handle_; actionlib::ServerGoalHandle<control_msgs::FollowJointTrajectoryAction> goal_handle_;
bool has_goal_;
control_msgs::FollowJointTrajectoryFeedback feedback_; control_msgs::FollowJointTrajectoryFeedback feedback_;
control_msgs::FollowJointTrajectoryResult result_; control_msgs::FollowJointTrajectoryResult result_;
ros::Subscriber speed_sub_; ros::Subscriber speed_sub_;
@@ -148,7 +150,7 @@ public:
"The control thread for this driver has been started"); "The control thread for this driver has been started");
} else { } else {
//start actionserver //start actionserver
goal_handle_ = NULL; has_goal_ = false;
as_.start(); as_.start();
//subscribe to the data topic of interest //subscribe to the data topic of interest
@@ -177,12 +179,23 @@ public:
} }
private: private:
void trajThread(std::vector<double> timestamps,
std::vector<std::vector<double> > positions,
std::vector<std::vector<double> > velocities) {
robot_.doTraj(timestamps, positions, velocities);
if (has_goal_) {
result_.error_code = result_.SUCCESSFUL;
goal_handle_.setSucceeded(result_);
has_goal_ = false;
}
}
void goalCB( void goalCB(
actionlib::ServerGoalHandle< actionlib::ServerGoalHandle<
control_msgs::FollowJointTrajectoryAction> gh) { control_msgs::FollowJointTrajectoryAction> gh) {
print_info("on_goal"); print_info("on_goal");
if (!robot_.sec_interface_->robot_state_->isPowerOnRobot()) { if (!robot_.sec_interface_->robot_state_->isPowerOnRobot()) {
result_.error_code = -100; result_.error_code = -100; //nothing is defined for this...?
result_.error_string = result_.error_string =
"Cannot accept new trajectories: Robot arm is not powered on"; "Cannot accept new trajectories: Robot arm is not powered on";
gh.setRejected(result_, result_.error_string); gh.setRejected(result_, result_.error_string);
@@ -190,7 +203,7 @@ private:
return; return;
} }
if (!robot_.sec_interface_->robot_state_->isRealRobotEnabled()) { if (!robot_.sec_interface_->robot_state_->isRealRobotEnabled()) {
result_.error_code = -100; result_.error_code = -100; //nothing is defined for this...?
result_.error_string = result_.error_string =
"Cannot accept new trajectories: Robot is not enabled"; "Cannot accept new trajectories: Robot is not enabled";
gh.setRejected(result_, result_.error_string); gh.setRejected(result_, result_.error_string);
@@ -198,7 +211,7 @@ private:
return; return;
} }
if (robot_.sec_interface_->robot_state_->isEmergencyStopped()) { if (robot_.sec_interface_->robot_state_->isEmergencyStopped()) {
result_.error_code = -100; result_.error_code = -100; //nothing is defined for this...?
result_.error_string = result_.error_string =
"Cannot accept new trajectories: Robot is emergency stopped"; "Cannot accept new trajectories: Robot is emergency stopped";
gh.setRejected(result_, result_.error_string); gh.setRejected(result_, result_.error_string);
@@ -206,7 +219,7 @@ private:
return; return;
} }
if (robot_.sec_interface_->robot_state_->isProtectiveStopped()) { if (robot_.sec_interface_->robot_state_->isProtectiveStopped()) {
result_.error_code = -100; result_.error_code = -100; //nothing is defined for this...?
result_.error_string = result_.error_string =
"Cannot accept new trajectories: Robot is protective stopped"; "Cannot accept new trajectories: Robot is protective stopped";
gh.setRejected(result_, result_.error_string); gh.setRejected(result_, result_.error_string);
@@ -215,11 +228,17 @@ private:
} }
actionlib::ActionServer<control_msgs::FollowJointTrajectoryAction>::Goal goal = actionlib::ActionServer<control_msgs::FollowJointTrajectoryAction>::Goal goal =
*gh.getGoal(); //make a copy that we can modify *gh.getGoal(); //make a copy that we can modify
if (goal_handle_ != NULL) { if (has_goal_) {
RosWrapper::cancelCB(*goal_handle_); print_warning(
"Received new goal while still executing previous trajectory. Canceling previous trajectory");
has_goal_ = false;
robot_.stopTraj();
result_.error_code = -100; //nothing is defined for this...?
result_.error_string = "Received another trajectory";
goal_handle_.setAborted(result_, result_.error_string);
std::this_thread::sleep_for(std::chrono::milliseconds(250));
} }
goal_handle_ = &gh; goal_handle_ = gh;
if (!validateJointNames()) { if (!validateJointNames()) {
std::string outp_joint_names = ""; std::string outp_joint_names = "";
for (unsigned int i = 0; i < goal.trajectory.joint_names.size(); for (unsigned int i = 0; i < goal.trajectory.joint_names.size();
@@ -288,26 +307,25 @@ private:
} }
goal_handle_->setAccepted(); goal_handle_.setAccepted();
robot_.doTraj(timestamps, positions, velocities); has_goal_ = true;
if (goal_handle_ != NULL) { std::thread(&RosWrapper::trajThread, this, timestamps, positions,
result_.error_code = result_.SUCCESSFUL; velocities).detach();
goal_handle_->setSucceeded(result_);
goal_handle_ = NULL;
}
} }
void cancelCB( void cancelCB(
actionlib::ServerGoalHandle< actionlib::ServerGoalHandle<
control_msgs::FollowJointTrajectoryAction> gh) { control_msgs::FollowJointTrajectoryAction> gh) {
// set the action state to preempted // set the action state to preempted
print_info("on_cancel"); print_info("on_cancel");
if (goal_handle_ != NULL) { if (has_goal_) {
robot_.stopTraj(); if (gh == goal_handle_) {
result_.error_code = result_.SUCCESSFUL; robot_.stopTraj();
result_.error_string = "Goal cancelled by client"; has_goal_ = false;
goal_handle_ = NULL; }
} }
result_.error_code = -100; //nothing is defined for this...?
result_.error_string = "Goal cancelled by client";
gh.setCanceled(result_); gh.setCanceled(result_);
} }
@@ -345,7 +363,7 @@ private:
bool validateJointNames() { bool validateJointNames() {
std::vector<std::string> actual_joint_names = robot_.getJointNames(); std::vector<std::string> actual_joint_names = robot_.getJointNames();
actionlib::ActionServer<control_msgs::FollowJointTrajectoryAction>::Goal goal = actionlib::ActionServer<control_msgs::FollowJointTrajectoryAction>::Goal goal =
*goal_handle_->getGoal(); *goal_handle_.getGoal();
if (goal.trajectory.joint_names.size() != actual_joint_names.size()) if (goal.trajectory.joint_names.size() != actual_joint_names.size())
return false; return false;
@@ -397,7 +415,7 @@ private:
bool has_velocities() { bool has_velocities() {
actionlib::ActionServer<control_msgs::FollowJointTrajectoryAction>::Goal goal = actionlib::ActionServer<control_msgs::FollowJointTrajectoryAction>::Goal goal =
*goal_handle_->getGoal(); *goal_handle_.getGoal();
for (unsigned int i = 0; i < goal.trajectory.points.size(); i++) { for (unsigned int i = 0; i < goal.trajectory.points.size(); i++) {
if (goal.trajectory.points[i].positions.size() if (goal.trajectory.points[i].positions.size()
!= goal.trajectory.points[i].velocities.size()) != goal.trajectory.points[i].velocities.size())
@@ -408,7 +426,7 @@ private:
bool has_positions() { bool has_positions() {
actionlib::ActionServer<control_msgs::FollowJointTrajectoryAction>::Goal goal = actionlib::ActionServer<control_msgs::FollowJointTrajectoryAction>::Goal goal =
*goal_handle_->getGoal(); *goal_handle_.getGoal();
if (goal.trajectory.points.size() == 0) if (goal.trajectory.points.size() == 0)
return false; return false;
for (unsigned int i = 0; i < goal.trajectory.points.size(); i++) { for (unsigned int i = 0; i < goal.trajectory.points.size(); i++) {
@@ -421,7 +439,7 @@ private:
bool has_limited_velocities() { bool has_limited_velocities() {
actionlib::ActionServer<control_msgs::FollowJointTrajectoryAction>::Goal goal = actionlib::ActionServer<control_msgs::FollowJointTrajectoryAction>::Goal goal =
*goal_handle_->getGoal(); *goal_handle_.getGoal();
for (unsigned int i = 0; i < goal.trajectory.points.size(); i++) { for (unsigned int i = 0; i < goal.trajectory.points.size(); i++) {
for (unsigned int j = 0; for (unsigned int j = 0;
j < goal.trajectory.points[i].velocities.size(); j++) { j < goal.trajectory.points[i].velocities.size(); j++) {
@@ -435,7 +453,7 @@ private:
bool traj_is_finite() { bool traj_is_finite() {
actionlib::ActionServer<control_msgs::FollowJointTrajectoryAction>::Goal goal = actionlib::ActionServer<control_msgs::FollowJointTrajectoryAction>::Goal goal =
*goal_handle_->getGoal(); *goal_handle_.getGoal();
for (unsigned int i = 0; i < goal.trajectory.points.size(); i++) { for (unsigned int i = 0; i < goal.trajectory.points.size(); i++) {
for (unsigned int j = 0; for (unsigned int j = 0;
j < goal.trajectory.points[i].velocities.size(); j++) { j < goal.trajectory.points[i].velocities.size(); j++) {
@@ -590,13 +608,13 @@ private:
and !warned) { and !warned) {
print_error("Robot is protective stopped!"); print_error("Robot is protective stopped!");
} }
if (goal_handle_ != NULL) { if (has_goal_) {
print_error("Aborting trajectory"); print_error("Aborting trajectory");
robot_.stopTraj(); robot_.stopTraj();
result_.error_code = result_.SUCCESSFUL; result_.error_code = result_.SUCCESSFUL;
result_.error_string = "Robot was halted"; result_.error_string = "Robot was halted";
goal_handle_->setAborted(result_, result_.error_string); goal_handle_.setAborted(result_, result_.error_string);
goal_handle_ = NULL; has_goal_ = false;
} }
warned = true; warned = true;
} else } else