10 #include <nav_msgs/Path.h> 11 #include <geometry_msgs/Pose.h> 12 #include <tf2_geometry_msgs/tf2_geometry_msgs.h> 13 #include <pluginlib/class_list_macros.h> 27 sig_atomic_t
volatile CartControlNodelet::b_sigint_ = 0;
28 ros::Timer CartControlNodelet::main_timer_ = ros::Timer();
33 CartControlNodelet::CartControlNodelet() {}
34 CartControlNodelet::~CartControlNodelet() {}
37 void CartControlNodelet::onInit()
39 nh_ = getNodeHandle();
40 private_nh_ = getPrivateNodeHandle();
43 struct sigaction sigIntHandler;
44 sigIntHandler.sa_handler = CartControlNodelet::sigint_handler;
45 sigemptyset(&sigIntHandler.sa_mask);
46 sigIntHandler.sa_flags = 0;
47 sigaction(SIGINT, &sigIntHandler, NULL);
50 private_nh_.param<
float>(
"main_freq", main_freq_, 10.0);
51 private_nh_.param<
float>(
"speed", robot_speed_, 1.0);
54 path_received_ =
false;
55 path_processed_ =
false;
56 path_executed_ =
true;
59 path_sub_ = nh_.subscribe<nav_msgs::PathConstPtr>(
"path", 1, &CartControlNodelet::path_cb,
this);
62 pose_pub_ = nh_.advertise<geometry_msgs::Pose>(
"pose_output", 0);
66 main_timer_ = private_nh_.createTimer(
67 ros::Duration(1/main_freq_), &CartControlNodelet::main_cb,
this 72 void CartControlNodelet::main_cb(
const ros::TimerEvent &timer_event)
74 if (!ros::ok() || ros::isShuttingDown() || b_sigint_)
78 compute_waypoints(path_, robot_speed_, 1/main_freq_, waypoints_);
80 path_received_ =
false;
83 if (idx_waypoints_ < waypoints_.size()) {
84 pose_pub_.publish(waypoints_[idx_waypoints_]);
90 void CartControlNodelet::sigint_handler(
int s) {
98 void CartControlNodelet::path_cb(
const nav_msgs::PathConstPtr
msg)
101 path_received_ =
true;
105 void CartControlNodelet::compute_waypoints(
const nav_msgs::Path &path,
float speed,
float dt,
106 vector<geometry_msgs::Pose> &waypoints)
const 108 float resolution = speed * dt;
109 int path_size = path.poses.size();
114 waypoints[0] = path.poses[0].pose;
116 while (idx_path < path_size) {
119 int prev_idx_path = idx_path;
122 while (idx_path < path_size && s-prev_s < resolution) {
126 tf2::convert(path.poses[idx_path-1].pose.position, p1);
127 tf2::convert(path.poses[idx_path].pose.position, p2);
128 s += tf2::tf2Distance(p1, p2);
132 if (idx_path < path_size) {
133 if (idx_path - prev_idx_path == 1) {
136 tf2::convert(waypoints[idx_wp].position, p1);
137 tf2::convert(path.poses[idx_path].pose.position, p2);
139 tf2::Quaternion q1, q2;
140 tf2::convert(waypoints[idx_wp].orientation, q1);
141 tf2::convert(path.poses[idx_path].pose.orientation, q2);
143 float d = tf2::tf2Distance(p1, p2);
144 int n = d/resolution;
147 for (
int k = 1; k <=
n; k++) {
148 geometry_msgs::Pose new_pose;
149 tf2::toMsg( p1 + (p2-p1) * (
float(k)/n), new_pose.position);
150 tf2::convert((q1 + (q2-q1) * (
float(k)/n)).normalize(), new_pose.orientation);
152 waypoints.emplace_back(new_pose);
156 waypoints.emplace_back(path.poses[idx_path].pose);
Declaration of a nodelet for cheated cartesian control of a robot.
Nodelet for cheated cartesian control of a robot.