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

Fixed an issue where canceling a trajectory wouldn't stop the robot.

This commit is contained in:
Thomas Timm Andersen
2015-10-09 10:47:29 +02:00
parent e354ada3ab
commit 80e344d167
2 changed files with 101 additions and 75 deletions

View File

@@ -13,15 +13,17 @@
UrDriver::UrDriver(std::condition_variable& rt_msg_cond, UrDriver::UrDriver(std::condition_variable& rt_msg_cond,
std::condition_variable& msg_cond, std::string host, std::condition_variable& msg_cond, std::string host,
unsigned int reverse_port, double servoj_time, unsigned int safety_count_max, unsigned int reverse_port, double servoj_time,
double max_time_step, double min_payload, double max_payload) : unsigned int safety_count_max, double max_time_step, double min_payload,
double max_payload) :
REVERSE_PORT_(reverse_port), maximum_time_step_(max_time_step), minimum_payload_( REVERSE_PORT_(reverse_port), maximum_time_step_(max_time_step), minimum_payload_(
min_payload), maximum_payload_(max_payload), servoj_time_(servoj_time) { min_payload), maximum_payload_(max_payload), servoj_time_(
servoj_time) {
char buffer[256]; char buffer[256];
struct sockaddr_in serv_addr; struct sockaddr_in serv_addr;
int n, flag; int n, flag;
//char *ip_addr; //char *ip_addr;
executing_traj_ = false;
rt_interface_ = new UrRealtimeCommunication(rt_msg_cond, host, rt_interface_ = new UrRealtimeCommunication(rt_msg_cond, host,
safety_count_max); safety_count_max);
new_sockfd_ = -1; new_sockfd_ = -1;
@@ -63,77 +65,76 @@ std::vector<double> UrDriver::interp_cubic(double t, double T,
} }
return positions; return positions;
} }
/* /*
void UrDriver::addTraj(std::vector<double> inp_timestamps, void UrDriver::addTraj(std::vector<double> inp_timestamps,
std::vector<std::vector<double> > inp_positions, std::vector<std::vector<double> > inp_positions,
std::vector<std::vector<double> > inp_velocities) { std::vector<std::vector<double> > inp_velocities) {
// DEPRECATED // DEPRECATED
printf("!! addTraj is deprecated !!\n"); printf("!! addTraj is deprecated !!\n");
std::vector<double> timestamps; std::vector<double> timestamps;
std::vector<std::vector<double> > positions; std::vector<std::vector<double> > positions;
std::string command_string = "def traj():\n"; std::string command_string = "def traj():\n";
for (unsigned int i = 1; i < inp_timestamps.size(); i++) { for (unsigned int i = 1; i < inp_timestamps.size(); i++) {
timestamps.push_back(inp_timestamps[i - 1]); timestamps.push_back(inp_timestamps[i - 1]);
double dt = inp_timestamps[i] - inp_timestamps[i - 1]; double dt = inp_timestamps[i] - inp_timestamps[i - 1];
unsigned int steps = (unsigned int) ceil(dt / maximum_time_step_); unsigned int steps = (unsigned int) ceil(dt / maximum_time_step_);
double step_size = dt / steps; double step_size = dt / steps;
for (unsigned int j = 1; j < steps; j++) { for (unsigned int j = 1; j < steps; j++) {
timestamps.push_back(inp_timestamps[i - 1] + step_size * j); timestamps.push_back(inp_timestamps[i - 1] + step_size * j);
} }
} }
// //make sure we come to a smooth stop // //make sure we come to a smooth stop
// while (timestamps.back() < inp_timestamps.back()) { // while (timestamps.back() < inp_timestamps.back()) {
// timestamps.push_back(timestamps.back() + 0.008); // timestamps.push_back(timestamps.back() + 0.008);
// } // }
// timestamps.pop_back(); // timestamps.pop_back();
unsigned int j = 0; unsigned int j = 0;
for (unsigned int i = 0; i < timestamps.size(); i++) { for (unsigned int i = 0; i < timestamps.size(); i++) {
while (inp_timestamps[j] <= timestamps[i]) { while (inp_timestamps[j] <= timestamps[i]) {
j += 1; j += 1;
} }
positions.push_back( positions.push_back(
UrDriver::interp_cubic(timestamps[i] - inp_timestamps[j - 1], UrDriver::interp_cubic(timestamps[i] - inp_timestamps[j - 1],
inp_timestamps[j] - inp_timestamps[j - 1], inp_timestamps[j] - inp_timestamps[j - 1],
inp_positions[j - 1], inp_positions[j], inp_positions[j - 1], inp_positions[j],
inp_velocities[j - 1], inp_velocities[j])); inp_velocities[j - 1], inp_velocities[j]));
} }
timestamps.push_back(inp_timestamps[inp_timestamps.size() - 1]); timestamps.push_back(inp_timestamps[inp_timestamps.size() - 1]);
positions.push_back(inp_positions[inp_positions.size() - 1]); positions.push_back(inp_positions[inp_positions.size() - 1]);
/// This is actually faster than using a stringstream :-o /// This is actually faster than using a stringstream :-o
for (unsigned int i = 1; i < timestamps.size(); i++) { for (unsigned int i = 1; i < timestamps.size(); i++) {
char buf[128]; char buf[128];
sprintf(buf, sprintf(buf,
"\tservoj([%1.5f, %1.5f, %1.5f, %1.5f, %1.5f, %1.5f], t=%1.5f)\n", "\tservoj([%1.5f, %1.5f, %1.5f, %1.5f, %1.5f, %1.5f], t=%1.5f)\n",
positions[i][0], positions[i][1], positions[i][2], positions[i][0], positions[i][1], positions[i][2],
positions[i][3], positions[i][4], positions[i][5], positions[i][3], positions[i][4], positions[i][5],
timestamps[i] - timestamps[i - 1]); timestamps[i] - timestamps[i - 1]);
command_string += buf; command_string += buf;
} }
command_string += "end\n"; command_string += "end\n";
//printf("%s", command_string.c_str()); //printf("%s", command_string.c_str());
rt_interface_->addCommandToQueue(command_string); rt_interface_->addCommandToQueue(command_string);
} }
*/ */
void UrDriver::doTraj(std::vector<double> inp_timestamps, void UrDriver::doTraj(std::vector<double> inp_timestamps,
std::vector<std::vector<double> > inp_positions, std::vector<std::vector<double> > inp_positions,
std::vector<std::vector<double> > inp_velocities) { std::vector<std::vector<double> > inp_velocities) {
std::chrono::high_resolution_clock::time_point t0, t; std::chrono::high_resolution_clock::time_point t0, t;
std::vector<double> positions; std::vector<double> positions;
unsigned int j; unsigned int j;
executing_traj_ = true; executing_traj_ = true;
UrDriver::uploadProg(); UrDriver::uploadProg();
t0 = std::chrono::high_resolution_clock::now(); t0 = std::chrono::high_resolution_clock::now();
t = t0; t = t0;
j = 0; j = 0;
while ((inp_timestamps[inp_timestamps.size() - 1] while ((inp_timestamps[inp_timestamps.size() - 1]
>= std::chrono::duration_cast<std::chrono::duration<double>>(t - t0).count()) and executing_traj_) { >= std::chrono::duration_cast<std::chrono::duration<double>>(t - t0).count())
and executing_traj_) {
while (inp_timestamps[j] while (inp_timestamps[j]
<= std::chrono::duration_cast<std::chrono::duration<double>>( <= std::chrono::duration_cast<std::chrono::duration<double>>(
t - t0).count() && j < inp_timestamps.size() - 1) { t - t0).count() && j < inp_timestamps.size() - 1) {
@@ -144,19 +145,19 @@ void UrDriver::doTraj(std::vector<double> inp_timestamps,
t - t0).count() - inp_timestamps[j - 1], t - t0).count() - inp_timestamps[j - 1],
inp_timestamps[j] - inp_timestamps[j - 1], inp_positions[j - 1], inp_timestamps[j] - inp_timestamps[j - 1], inp_positions[j - 1],
inp_positions[j], inp_velocities[j - 1], inp_velocities[j]); inp_positions[j], inp_velocities[j - 1], inp_velocities[j]);
UrDriver::servoj(positions); UrDriver::servoj(positions);
// oversample with 4 * sample_time // oversample with 4 * sample_time
std::this_thread::sleep_for(std::chrono::milliseconds((int) ((servoj_time_*1000)/4.))); std::this_thread::sleep_for(
std::chrono::milliseconds((int) ((servoj_time_ * 1000) / 4.)));
t = std::chrono::high_resolution_clock::now(); t = std::chrono::high_resolution_clock::now();
} }
//Signal robot to stop driverProg() //Signal robot to stop driverProg()
UrDriver::closeServo(positions); UrDriver::closeServo(positions);
} }
void UrDriver::servoj(std::vector<double> positions, void UrDriver::servoj(std::vector<double> positions, int keepalive,
int keepalive, double time) { double time) {
unsigned int bytes_written; unsigned int bytes_written;
int tmp; int tmp;
unsigned char buf[32]; unsigned char buf[32];

View File

@@ -148,6 +148,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;
as_.start(); as_.start();
//subscribe to the data topic of interest //subscribe to the data topic of interest
@@ -180,8 +181,13 @@ private:
actionlib::ServerGoalHandle< actionlib::ServerGoalHandle<
control_msgs::FollowJointTrajectoryAction> gh) { control_msgs::FollowJointTrajectoryAction> gh) {
print_info("on_goal"); print_info("on_goal");
actionlib::ActionServer<control_msgs::FollowJointTrajectoryAction>::Goal goal =
*gh.getGoal(); //make a copy that we can modify
if (goal_handle_ != NULL) {
RosWrapper::cancelCB(*goal_handle_);
}
goal_handle_ = &gh; goal_handle_ = &gh;
actionlib::ActionServer<control_msgs::FollowJointTrajectoryAction>::Goal goal = *goal_handle_->getGoal(); //make a copy that we can modify
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();
@@ -195,7 +201,6 @@ private:
gh.setRejected(result_, result_.error_string); gh.setRejected(result_, result_.error_string);
print_error(result_.error_string); print_error(result_.error_string);
} }
if (!has_positions()) { if (!has_positions()) {
result_.error_code = result_.INVALID_GOAL; result_.error_code = result_.INVALID_GOAL;
result_.error_string = "Received a goal without positions"; result_.error_string = "Received a goal without positions";
@@ -226,8 +231,15 @@ private:
} }
reorder_traj_joints(goal.trajectory); reorder_traj_joints(goal.trajectory);
std::vector<double> timestamps; std::vector<double> timestamps;
std::vector<std::vector<double> > positions, velocities; std::vector<std::vector<double> > positions, velocities;
if (goal.trajectory.points[0].time_from_start.toSec() != 0.) {
print_warning("Trajectory's first point should be the current position, with time_from_start set to 0.0 - Inserting point in malformed trajectory");
timestamps.push_back(0.0);
positions.push_back(robot_.rt_interface_->robot_state_->getQActual());
velocities.push_back(robot_.rt_interface_->robot_state_->getQdActual());
}
for (unsigned int i = 0; i < goal.trajectory.points.size(); i++) { for (unsigned int i = 0; i < goal.trajectory.points.size(); i++) {
timestamps.push_back( timestamps.push_back(
goal.trajectory.points[i].time_from_start.toSec()); goal.trajectory.points[i].time_from_start.toSec());
@@ -235,10 +247,14 @@ private:
velocities.push_back(goal.trajectory.points[i].velocities); velocities.push_back(goal.trajectory.points[i].velocities);
} }
gh.setAccepted();
goal_handle_->setAccepted();
robot_.doTraj(timestamps, positions, velocities); robot_.doTraj(timestamps, positions, velocities);
result_.error_code = result_.SUCCESSFUL; if (goal_handle_ != NULL) {
gh.setSucceeded(result_); result_.error_code = result_.SUCCESSFUL;
goal_handle_->setSucceeded(result_);
goal_handle_ = NULL;
}
} }
void cancelCB( void cancelCB(
@@ -246,9 +262,13 @@ private:
control_msgs::FollowJointTrajectoryAction> gh) { control_msgs::FollowJointTrajectoryAction> gh) {
print_info("on_cancel"); print_info("on_cancel");
// set the action state to preempted // set the action state to preempted
robot_.stopTraj(); if (goal_handle_ != NULL) {
result_.error_code = result_.SUCCESSFUL; print_info("Stopping previous traj");
result_.error_string = "Goal cancelled by client"; robot_.stopTraj();
result_.error_code = result_.SUCCESSFUL;
result_.error_string = "Goal cancelled by client";
goal_handle_ = NULL;
}
gh.setCanceled(result_); gh.setCanceled(result_);
} }
@@ -285,7 +305,8 @@ 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 = *goal_handle_->getGoal(); actionlib::ActionServer<control_msgs::FollowJointTrajectoryAction>::Goal goal =
*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;
@@ -336,7 +357,8 @@ private:
} }
bool has_velocities() { bool has_velocities() {
actionlib::ActionServer<control_msgs::FollowJointTrajectoryAction>::Goal goal = *goal_handle_->getGoal(); actionlib::ActionServer<control_msgs::FollowJointTrajectoryAction>::Goal goal =
*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())
@@ -346,7 +368,8 @@ private:
} }
bool has_positions() { bool has_positions() {
actionlib::ActionServer<control_msgs::FollowJointTrajectoryAction>::Goal goal = *goal_handle_->getGoal(); actionlib::ActionServer<control_msgs::FollowJointTrajectoryAction>::Goal goal =
*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++) {
@@ -358,7 +381,8 @@ private:
} }
bool has_limited_velocities() { bool has_limited_velocities() {
actionlib::ActionServer<control_msgs::FollowJointTrajectoryAction>::Goal goal = *goal_handle_->getGoal(); actionlib::ActionServer<control_msgs::FollowJointTrajectoryAction>::Goal goal =
*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++) {
@@ -371,7 +395,8 @@ private:
} }
bool traj_is_finite() { bool traj_is_finite() {
actionlib::ActionServer<control_msgs::FollowJointTrajectoryAction>::Goal goal = *goal_handle_->getGoal(); actionlib::ActionServer<control_msgs::FollowJointTrajectoryAction>::Goal goal =
*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++) {