6#include <angles/angles.h>
7#include <pluginlib/class_list_macros.h>
9#include <visualization_msgs/MarkerArray.h>
10#include <boost/intrusive_ptr.hpp>
11#include <angles/angles.h>
13#include <base_local_planner/simple_trajectory_generator.h>
20namespace forward_local_planner
51 ros::NodeHandle private_nh(
"~");
55 ros::NodeHandle nh(
"~/ForwardLocalPlanner");
72 ROS_INFO(
"[ForwardLocalPlanner] initialized");
86 Eigen::Vector3f currentpos = pos;
103 auto dx = newpos[0] - currentpos[0];
104 auto dy = newpos[1] - currentpos[1];
105 float dist, angledist;
108 dist = sqrt(dx * dx + dy * dy);
117 angledist = fabs(angles::shortest_angular_distance(currentpos[2], newpos[2]));
118 if (angledist > maxanglediff)
125 outtraj.push_back(newpos);
145 Eigen::Vector3f new_pos = Eigen::Vector3f::Zero();
146 new_pos[0] = pos[0] + (vel[0] * cos(pos[2]) + vel[1] * cos(M_PI_2 + pos[2])) * dt;
147 new_pos[1] = pos[1] + (vel[0] * sin(pos[2]) + vel[1] * sin(M_PI_2 + pos[2])) * dt;
148 new_pos[2] = pos[2] + vel[2] * dt;
170 visualization_msgs::Marker marker;
172 marker.header.frame_id = this->
costmapRos_->getGlobalFrameID();
173 marker.header.stamp = ros::Time::now();
174 marker.ns =
"my_namespace2";
176 marker.type = visualization_msgs::Marker::ARROW;
177 marker.action = visualization_msgs::Marker::ADD;
178 marker.pose.orientation.w = 1;
180 marker.scale.x = 0.1;
181 marker.scale.y = 0.3;
182 marker.scale.z = 0.1;
183 marker.color.a = 1.0;
186 marker.color.b = 1.0;
188 geometry_msgs::Point start, end;
192 end.x = x + 0.5 * cos(phi);
193 end.y = y + 0.5 * sin(phi);
195 marker.points.push_back(start);
196 marker.points.push_back(end);
198 visualization_msgs::MarkerArray ma;
199 ma.markers.push_back(marker);
205#if ROS_VERSION_MINIMUM(1, 13, 0)
208 geometry_msgs::PoseStamped paux;
209 costmapRos->getRobotPose(paux);
210 tf::Stamped<tf::Pose> tfpose;
211 tf::poseStampedMsgToTF(paux, tfpose);
218 tf::Stamped<tf::Pose> tfpose;
219 costmapRos->getRobotPose(tfpose);
224void clamp(geometry_msgs::Twist &cmd_vel,
double max_linear_x_speed_,
double max_angular_z_speed_)
226 if (max_angular_z_speed_ == 0 || max_linear_x_speed_ == 0)
229 if (cmd_vel.angular.z == 0)
231 cmd_vel.linear.x = max_linear_x_speed_;
235 double kurvature = cmd_vel.linear.x / cmd_vel.angular.z;
237 double linearAuthority = fabs(cmd_vel.linear.x / max_linear_x_speed_);
238 double angularAuthority = fabs(cmd_vel.angular.z / max_angular_z_speed_);
239 if (linearAuthority < angularAuthority)
242 cmd_vel.linear.x = max_linear_x_speed_;
243 cmd_vel.angular.z = kurvature / max_linear_x_speed_;
244 ROS_WARN_STREAM(
"k=" << kurvature <<
"lets go to maximum linear capacity: " << cmd_vel);
249 cmd_vel.angular.x = max_angular_z_speed_;
250 cmd_vel.linear.x = kurvature * max_angular_z_speed_;
251 ROS_WARN_STREAM(
"lets go to maximum angular capacity: " << cmd_vel);
264 ROS_DEBUG(
"[ForwardLocalPlanner] ----- COMPUTE VELOCITY COMMAND LOCAL PLANNER ---");
268 geometry_msgs::PoseStamped currentPose;
269 tf::poseStampedTFToMsg(tfpose,currentPose);
270 ROS_DEBUG_STREAM(
"[ForwardLocalPlanner] current robot pose " << currentPose);
280 const geometry_msgs::Point &p = pose.pose.position;
282 tf::quaternionMsgToTF(pose.pose.orientation, q);
285 double dx = p.x - tfpose.getOrigin().x();
286 double dy = p.y - tfpose.getOrigin().y();
287 double dist = sqrt(dx * dx + dy * dy);
289 double pangle = tf::getYaw(q);
290 double angle = tf::getYaw(tfpose.getRotation());
291 double angular_error = angles::shortest_angular_distance(pangle, angle);
305 ROS_DEBUG_STREAM(
"[ForwardLocalPlanner] selected carrot pose index " <<
currentPoseIndex_ <<
"/" <<
plan_.size());
310 cmd_vel.linear.x = 0;
311 cmd_vel.angular.z = 0;
321 const geometry_msgs::PoseStamped &finalgoalpose =
plan_.back();
323 const geometry_msgs::Point &goalposition = carrot_goalpose.pose.position;
325 tf::Quaternion carrotGoalQ;
326 tf::quaternionMsgToTF(carrot_goalpose.pose.orientation, carrotGoalQ);
330 double betta = tf::getYaw(carrot_goalpose.pose.orientation) +
betta_offset_;
332 double dx = goalposition.x - tfpose.getOrigin().x();
333 double dy = goalposition.y - tfpose.getOrigin().y();
336 double rho_error = sqrt(dx * dx + dy * dy);
339 tf::Quaternion currentOrientation = tfpose.getRotation();
340 double theta = tf::getYaw(currentOrientation);
341 double alpha = atan2(dy, dx);
344 double alpha_error = angles::shortest_angular_distance(alpha, theta);
345 double betta_error = angles::shortest_angular_distance(betta, theta);
352 vetta =
k_rho_ * rho_error;
362 ROS_DEBUG(
"GOAL REACHED");
388 cmd_vel.linear.x = vetta;
389 cmd_vel.angular.z = gamma;
397 ROS_DEBUG_STREAM(
"Forward local planner," << std::endl
398 <<
" theta: " << theta << std::endl
399 <<
" betta: " << betta << std::endl
400 <<
" err_x: " << dx << std::endl
401 <<
" err_y:" << dy << std::endl
402 <<
" rho_error:" << rho_error << std::endl
403 <<
" alpha_error:" << alpha_error << std::endl
404 <<
" betta_error:" << betta_error << std::endl
405 <<
" vetta:" << vetta << std::endl
406 <<
" gamma:" << gamma << std::endl
421 auto yaw = tf::getYaw(global_pose.getRotation());
423 auto &pos = global_pose.getOrigin();
425 Eigen::Vector3f currentpose(pos.x(), pos.y(), yaw);
426 Eigen::Vector3f currentvel(cmd_vel.linear.x, cmd_vel.linear.y, cmd_vel.angular.z);
427 std::vector<Eigen::Vector3f> trajectory;
428 this->
generateTrajectory(currentpose, currentvel, 0.8 , M_PI / 8 , 3.0 , 0.05 , trajectory);
431 bool aceptedplan =
true;
437 for (
auto &p : trajectory)
439 float dx = p[0] - finalgoalpose.pose.position.x;
440 float dy = p[1] - finalgoalpose.pose.position.y;
442 float dst = sqrt(dx * dx + dy * dy);
449 costmap2d->worldToMap(p[0], p[1], mx, my);
450 uint64_t cost = costmap2d->getCost(mx, my);
460 if (costmap2d->getCost(mx, my) >= costmap_2d::INSCRIBED_INFLATED_OBSTACLE)
477 cmd_vel.linear.x = 0;
478 cmd_vel.angular.z = 0;
PLUGINLIB_EXPORT_CLASS(cl_move_base_z::backward_global_planner::BackwardGlobalPlanner, nav_core::BaseGlobalPlanner)
Eigen::Vector3f computeNewPositions(const Eigen::Vector3f &pos, const Eigen::Vector3f &vel, double dt)
ros::Publisher goalMarkerPublisher_
double max_angular_z_speed_
virtual bool computeVelocityCommands(geometry_msgs::Twist &cmd_vel) override
Given the current position, orientation, and velocity of the robot: compute velocity commands to send...
costmap_2d::Costmap2DROS * costmapRos_
const double alpha_offset_
void generateTrajectory(const Eigen::Vector3f &pos, const Eigen::Vector3f &vel, float maxdist, float maxangle, float maxtime, float dt, std::vector< Eigen::Vector3f > &outtraj)
virtual ~ForwardLocalPlanner()
double yaw_goal_tolerance_
std::vector< geometry_msgs::PoseStamped > plan_
const double betta_offset_
ros::Duration waitingTimeout_
virtual bool setPlan(const std::vector< geometry_msgs::PoseStamped > &plan) override
Set the plan that the local planner is following.
virtual bool isGoalReached() override
Check if the goal pose has been achieved by the local planner.
double max_linear_x_speed_
double xy_goal_tolerance_
void publishGoalMarker(double x, double y, double phi)
void clamp(geometry_msgs::Twist &cmd_vel, double max_linear_x_speed_, double max_angular_z_speed_)
tf::Stamped< tf::Pose > optionalRobotPose(costmap_2d::Costmap2DROS *costmapRos)