467 const geometry_msgs::msg::PoseStamped & pose,
const geometry_msgs::msg::Twist & velocity,
468 nav2_core::GoalChecker * goal_checker)
472 "[BackwardLocalPlanner] ------------------- LOCAL PLANNER LOOP -----------------");
479 nh_->get_logger(),
"[BackwardLocalPlanner] Current pose frame id: "
481 <<
", path pose frame id: " << pose.header.frame_id);
485 RCLCPP_ERROR_STREAM(
nh_->get_logger(),
"[BackwardLocalPlanner] Inconsistent frames");
493 geometry_msgs::msg::Pose posetol;
494 geometry_msgs::msg::Twist twistol;
495 if (goal_checker->getTolerances(posetol, twistol))
501 nh_->get_logger(),
"[BackwardLocalPlanner] xy_goal_tolerance_: "
508 nh_->get_logger(),
"[BackwardLocalPlanner] could not get tolerances from goal checker");
514 "[BackwardLocalPlanner] ------------------- LOCAL PLANNER LOOP -----------------");
516 geometry_msgs::msg::TwistStamped cmd_vel;
517 RCLCPP_INFO(
nh_->get_logger(),
"[BackwardLocalPlanner] LOCAL PLANNER LOOP");
518 geometry_msgs::msg::PoseStamped paux;
519 geometry_msgs::msg::PoseStamped tfpose;
525 "[BackwardLocalPlanner] missing robot pose, canceling compute Velocity Command");
527 bool divergenceDetected =
false;
529 bool emergency_stop =
false;
530 if (divergenceDetected)
533 nh_->get_logger(),
"[BackwardLocalPlanner] Divergence detected. Sending emergency stop.");
534 emergency_stop =
true;
538 RCLCPP_INFO_STREAM(
nh_->get_logger(),
"[BackwardLocalPlanner] carrot goal created");
542 cmd_vel.twist.linear.x = 0;
543 cmd_vel.twist.angular.z = 0;
545 nh_->get_logger(),
"[BackwardLocalPlanner] emergency stop, exit compute commands");
550 double rho_error, betta_error, alpha_error;
554 tf2::convert(tfpose.pose.orientation, q);
559 const geometry_msgs::msg::PoseStamped & carrotgoalpose =
562 nh_->get_logger(),
"[BackwardLocalPlanner] carrot goal pose current index: "
565 const geometry_msgs::msg::Point & carrotGoalPosition = carrotgoalpose.pose.position;
567 tf2::Quaternion goalQ;
568 tf2::fromMsg(carrotgoalpose.pose.orientation, goalQ);
569 RCLCPP_INFO_STREAM(
nh_->get_logger(),
"[BackwardLocalPlanner] -- Control Policy --");
571 double betta = tf2::getYaw(goalQ);
572 RCLCPP_INFO_STREAM(
nh_->get_logger(),
"[BackwardLocalPlanner] goal orientation: " << betta);
575 double dx = carrotGoalPosition.x - tfpose.pose.position.x;
576 double dy = carrotGoalPosition.y - tfpose.pose.position.y;
579 rho_error = sqrt(dx * dx + dy * dy);
582 double theta = tf2::getYaw(q);
583 double alpha = atan2(dy, dx);
586 alpha_error = angles::shortest_angular_distance(alpha, theta);
587 betta_error = angles::shortest_angular_distance(betta, theta);
590 bool linearGoalReached;
591 bool currentPoseInGoal =
598 if (currentPoseInGoal && carrotInFinalGoalIndex)
603 "[BackwardLocalPlanner] GOAL REACHED. Send stop command and skipping trajectory collision: "
605 cmd_vel.twist.linear.x = 0;
606 cmd_vel.twist.angular.z = 0;
610 carrotInLinearGoalRange &&
625 tfpose, vetta, gamma, alpha_error, betta_error, rho_error);
630 vetta =
k_rho_ * rho_error;
639 "[BackwardLocalPlanner] we entered in a pure spinning state even in not pure-spining "
641 "carrotDistanceGoalReached: %d",
642 carrotInLinearGoalRange);
651 cmd_vel.twist.linear.x = vetta;
652 cmd_vel.twist.angular.z = gamma;
675 nh_->get_logger(),
"[BackwardLocalPlanner] local planner,"
677 <<
" current pose in goal: " << currentPoseInGoal << std::endl
678 <<
" carrot in final goal index: " << carrotInFinalGoalIndex << std::endl
679 <<
" carrot in linear goal range: " << carrotInLinearGoalRange << std::endl
683 <<
" theta: " << theta << std::endl
684 <<
" betta: " << theta << std::endl
685 <<
" err_x: " << dx << std::endl
686 <<
" err_y:" << dy << std::endl
687 <<
" rho_error:" << rho_error << std::endl
688 <<
" alpha_error:" << alpha_error << std::endl
689 <<
" betta_error:" << betta_error << std::endl
690 <<
" vetta:" << vetta << std::endl
691 <<
" gamma:" << gamma << std::endl
692 <<
" cmd_vel.lin.x:" << cmd_vel.twist.linear.x << std::endl
693 <<
" cmd_vel.ang.z:" << cmd_vel.twist.angular.z);
699 if (carrotHalfPlaneConstraintFailure)
703 "[BackwardLocalPlanner] CarrotHalfPlaneConstraintFailure detected. Sending "
704 "emergency stop and success to the planner.");
705 cmd_vel.twist.linear.x = 0;
710 geometry_msgs::msg::PoseStamped global_pose;
714 auto yaw = tf2::getYaw(global_pose.pose.orientation);
716 auto & pos = global_pose.pose.position;
718 Eigen::Vector3f currentpose(pos.x, pos.y, yaw);
719 Eigen::Vector3f currentvel(
720 cmd_vel.twist.linear.x, cmd_vel.twist.linear.y, cmd_vel.twist.angular.z);
721 std::vector<Eigen::Vector3f> trajectory;
723 currentpose, currentvel, 0.8 , M_PI / 8 , 3.0 , 0.05 ,
727 bool acceptedLocalTrajectoryFreeOfObstacles =
true;
739 geometry_msgs::msg::Twist mockzerospeed;
741 for (
auto & p : trajectory)
743 float dx = p[0] - finalgoalpose.pose.position.x;
744 float dy = p[1] - finalgoalpose.pose.position.y;
746 float dst = sqrt(dx * dx + dy * dy);
751 "[BackwardLocalPlanner] trajectory simulation for collision checking: goal "
752 "reached with no collision");
756 costmap2d->worldToMap(p[0], p[1], mx, my);
758 if (costmap2d->getCost(mx, my) >= nav2_costmap_2d::INSCRIBED_INFLATED_OBSTACLE)
760 acceptedLocalTrajectoryFreeOfObstacles =
false;
763 "[BackwardLocalPlanner] ABORTED LOCAL PLAN BECAUSE OBSTACLE DETEDTED at point "
764 << i <<
"/" << trajectory.size() << std::endl
765 << p[0] <<
", " << p[1]);
774 nh_->get_logger(),
"[BackwardLocalPlanner] Abort local - Backwards global plan size: %ld",
776 cmd_vel.twist.angular.z = 0;
777 cmd_vel.twist.linear.x = 0;
781 if (acceptedLocalTrajectoryFreeOfObstacles)
786 "[BackwardLocalPlanner] accepted local trajectory free of obstacle. Local planner "
793 cmd_vel.twist.linear.x = 0;
794 cmd_vel.twist.angular.z = 0;
801 nh_->get_logger(),
"[BackwardLocalPlanner][Not accepted local plan] starting countdown");
810 nh_->get_logger(),
"[BackwardLocalPlanner][Abort local] timeout! duration %lf/%f",
812 cmd_vel.twist.linear.x = 0;
813 cmd_vel.twist.angular.z = 0;
901 RCLCPP_INFO(
nh_->get_logger(),
"[BackwardLocalPlanner] resample precise");
906 "[BackwardLocalPlanner] resample precise skipping, size: " <<
backwardsPlanPath_.size());
916 RCLCPP_INFO_STREAM(
nh_->get_logger(),
"[BackwardLocalPlanner] resample precise, check: " << i);
920 tf2::Quaternion qCurrent, qNext;
921 tf2::convert(currpose.pose.orientation, qCurrent);
922 tf2::convert(nextpose.pose.orientation, qNext);
924 double dx = nextpose.pose.position.x - currpose.pose.position.x;
925 double dy = nextpose.pose.position.y - currpose.pose.position.y;
926 double dist = sqrt(dx * dx + dy * dy);
928 bool resample =
false;
929 if (dist > maxallowedLinearError)
932 nh_->get_logger(),
"[BackwardLocalPlanner] resampling point, linear distance:"
933 << dist <<
"(" << maxallowedLinearError <<
")" << i);
938 double currentAngle = tf2::getYaw(qCurrent);
939 double nextAngle = tf2::getYaw(qNext);
941 double angularError = fabs(angles::shortest_angular_distance(currentAngle, nextAngle));
942 if (angularError > maxallowedAngularError)
946 nh_->get_logger(),
"[BackwardLocalPlanner] resampling point, angular distance:"
947 << angularError <<
"(" << maxallowedAngularError <<
")" << i);
953 geometry_msgs::msg::PoseStamped pintermediate;
954 auto duration = rclcpp::Time(nextpose.header.stamp) - rclcpp::Time(currpose.header.stamp);
956 pintermediate.header.frame_id = currpose.header.frame_id;
957 pintermediate.header.stamp = rclcpp::Time(currpose.header.stamp) + duration * 0.5;
959 pintermediate.pose.position.x = 0.5 * (currpose.pose.position.x + nextpose.pose.position.x);
960 pintermediate.pose.position.y = 0.5 * (currpose.pose.position.y + nextpose.pose.position.y);
961 pintermediate.pose.position.z = 0.5 * (currpose.pose.position.z + nextpose.pose.position.z);
962 tf2::Quaternion intermediateQuat = tf2::slerp(qCurrent, qNext, 0.5);
963 pintermediate.pose.orientation = tf2::toMsg(intermediateQuat);
974 nh_->get_logger(),
"[BackwardLocalPlanner] End resampling. resampled:" << counter
975 <<
" new inserted poses "