32 template <
class HWInterface>
36 if (!ControlPolicy::init(hw, nh, controller_nh))
43 if (!speed_scaling_interface)
46 "without this feature.");
47 speed_scaling_ =
nullptr;
51 speed_scaling_ = std::make_unique<scaled_controllers::SpeedScalingHandle>(speed_scaling_interface->getHandle(
"speed" 60 controller_nh,
"follow_cartesian_trajectory",
65 action_server_->start();
70 template <
class HWInterface>
74 ControlPolicy::updateCommand(ControlPolicy::getState());
77 template <
class HWInterface>
80 if (action_server_->isActive())
83 action_server_->setPreempted();
87 template <
class HWInterface>
90 if (action_server_->isActive() && !done_.load())
93 const double factor = (speed_scaling_) ? *speed_scaling_->getScalingFactor() : 1.0;
94 trajectory_duration_.now += period * factor;
98 if (trajectory_duration_.now < trajectory_duration_.end)
100 std::lock_guard<std::mutex> lock_trajectory(lock_);
103 trajectory_.sample(trajectory_duration_.now.toSec(), desired);
105 ControlPolicy::updateCommand(desired);
108 auto actual = ControlPolicy::getState();
109 auto error = desired - actual;
111 cartesian_control_msgs::FollowCartesianTrajectoryFeedback
f;
112 auto now = trajectory_duration_.now.toSec();
113 f.desired = desired.
toMsg(now);
114 f.actual = actual.toMsg(now);
115 f.error = error.toMsg(now);
117 action_server_->publishFeedback(f);
121 monitorExecution(error);
130 template <
class HWInterface>
132 const cartesian_control_msgs::FollowCartesianTrajectoryGoalConstPtr& goal)
137 if (!this->isRunning())
139 ROS_ERROR(
"Can't accept new action goals. Controller is not running.");
140 cartesian_control_msgs::FollowCartesianTrajectoryResult result;
141 result.error_code = cartesian_control_msgs::FollowCartesianTrajectoryResult::INVALID_GOAL;
142 action_server_->setAborted(result);
146 path_tolerances_ = goal->path_tolerance;
147 goal_tolerances_ = goal->goal_tolerance;
151 auto state = ControlPolicy::getState();
153 std::lock_guard<std::mutex> lock_trajectory(lock_);
155 cartesian_control_msgs::CartesianTrajectory traj = goal->trajectory;
156 traj.points.insert(traj.points.begin(), state.toMsg(0));
158 if (!trajectory_.init(traj))
160 ROS_ERROR(
"Action goal has invalid trajectory.");
161 cartesian_control_msgs::FollowCartesianTrajectoryResult result;
162 result.error_code = cartesian_control_msgs::FollowCartesianTrajectoryResult::INVALID_GOAL;
163 action_server_->setAborted(result);
170 trajectory_duration_.end = goal->trajectory.points.back().time_from_start + goal->goal_time_tolerance;
174 while (!done_.load())
180 template <
class HWInterface>
183 cartesian_control_msgs::FollowCartesianTrajectoryResult result;
184 result.error_string =
"preempted";
185 action_server_->setPreempted(result);
190 template <
class HWInterface>
193 using Result = cartesian_control_msgs::FollowCartesianTrajectoryResult;
199 std::lock_guard<std::mutex> lock_trajectory(lock_);
200 trajectory_.sample(trajectory_duration_.now.toSec(), goal);
209 auto error = goal - ControlPolicy::getState();
211 if (!withinTolerances(error, goal_tolerances_))
213 result.error_code = Result::GOAL_TOLERANCE_VIOLATED;
214 action_server_->setAborted(result);
218 result.error_code = Result::SUCCESSFUL;
219 action_server_->setSucceeded(result);
225 template <
class HWInterface>
229 if (!withinTolerances(error, path_tolerances_))
231 using Result = cartesian_control_msgs::FollowCartesianTrajectoryResult;
233 result.error_code = Result::PATH_TOLERANCE_VIOLATED;
234 action_server_->setAborted(result);
239 template <
class HWInterface>
244 cartesian_control_msgs::CartesianTolerance uninitialized;
245 std::stringstream str_1;
246 std::stringstream str_2;
248 str_2 << uninitialized;
250 if (str_1.str() == str_2.str())
255 auto not_within_limits = [](
const auto& a,
const auto& b) {
return a.x() > b.x || a.y() > b.y || a.z() > b.z; };
258 if (not_within_limits(error.
p, tolerance.position_error) ||
259 not_within_limits(error.
rot(), tolerance.orientation_error) ||
260 not_within_limits(error.
v, tolerance.twist_error.linear) ||
261 not_within_limits(error.
w, tolerance.twist_error.angular) ||
262 not_within_limits(error.
v_dot, tolerance.acceleration_error.linear) ||
263 not_within_limits(error.
w_dot, tolerance.acceleration_error.angular))
void update(const ros::Time &time, const ros::Duration &period) override
void monitorExecution(const ros_controllers_cartesian::CartesianState &error)
cartesian_control_msgs::CartesianTrajectoryPoint toMsg(int time_from_start=0) const
void starting(const ros::Time &time) override
bool withinTolerances(const ros_controllers_cartesian::CartesianState &error, const cartesian_control_msgs::CartesianTolerance &tolerance)
void executeCB(const cartesian_control_msgs::FollowCartesianTrajectoryGoalConstPtr &goal)
bool init(hardware_interface::RobotHW *hw, ros::NodeHandle &root_nh, ros::NodeHandle &controller_nh) override
void stopping(const ros::Time &time) override
#define ROS_INFO_STREAM(args)
const std::string & getNamespace() const
Eigen::Vector3d rot() const