493 const geometry_msgs::msg::PoseStamped & pose,
const geometry_msgs::msg::Twist & velocity,
494 nav2_core::GoalChecker * goal_checker)
498 "[BackwardLocalPlanner] ------------------- LOCAL PLANNER LOOP -----------------");
505 nh_->get_logger(),
"[BackwardLocalPlanner] Current pose frame id: "
507 <<
", path pose frame id: " << pose.header.frame_id);
511 RCLCPP_ERROR_STREAM(
nh_->get_logger(),
"[BackwardLocalPlanner] Inconsistent frames");
519 geometry_msgs::msg::Pose posetol;
520 geometry_msgs::msg::Twist twistol;
521 if (goal_checker->getTolerances(posetol, twistol))
527 nh_->get_logger(),
"[BackwardLocalPlanner] xy_goal_tolerance_: "
534 nh_->get_logger(),
"[BackwardLocalPlanner] could not get tolerances from goal checker");
540 "[BackwardLocalPlanner] ------------------- LOCAL PLANNER LOOP -----------------");
542 geometry_msgs::msg::TwistStamped cmd_vel;
543 RCLCPP_INFO(
nh_->get_logger(),
"[BackwardLocalPlanner] LOCAL PLANNER LOOP");
544 geometry_msgs::msg::PoseStamped paux;
545 geometry_msgs::msg::PoseStamped tfpose;
551 "[BackwardLocalPlanner] missing robot pose, canceling compute Velocity Command");
553 bool divergenceDetected =
false;
555 bool emergency_stop =
false;
556 if (divergenceDetected)
559 nh_->get_logger(),
"[BackwardLocalPlanner] Divergence detected. Sending emergency stop.");
560 emergency_stop =
true;
564 RCLCPP_INFO_STREAM(
nh_->get_logger(),
"[BackwardLocalPlanner] carrot goal created");
568 cmd_vel.twist.linear.x = 0;
569 cmd_vel.twist.angular.z = 0;
571 nh_->get_logger(),
"[BackwardLocalPlanner] emergency stop, exit compute commands");
576 double rho_error, betta_error, alpha_error;
580 tf2::convert(tfpose.pose.orientation, q);
585 const geometry_msgs::msg::PoseStamped & carrotgoalpose =
588 nh_->get_logger(),
"[BackwardLocalPlanner] carrot goal pose current index: "
591 const geometry_msgs::msg::Point & carrotGoalPosition = carrotgoalpose.pose.position;
593 tf2::Quaternion goalQ;
594 tf2::fromMsg(carrotgoalpose.pose.orientation, goalQ);
595 RCLCPP_INFO_STREAM(
nh_->get_logger(),
"[BackwardLocalPlanner] -- Control Policy --");
597 double betta = tf2::getYaw(goalQ);
598 RCLCPP_INFO_STREAM(
nh_->get_logger(),
"[BackwardLocalPlanner] goal orientation: " << betta);
601 double dx = carrotGoalPosition.x - tfpose.pose.position.x;
602 double dy = carrotGoalPosition.y - tfpose.pose.position.y;
605 rho_error = sqrt(dx * dx + dy * dy);
608 double theta = tf2::getYaw(q);
609 double alpha = atan2(dy, dx);
612 alpha_error = angles::shortest_angular_distance(alpha, theta);
613 betta_error = angles::shortest_angular_distance(betta, theta);
616 bool linearGoalReached;
617 bool currentPoseInGoal =
624 if (currentPoseInGoal && carrotInFinalGoalIndex)
629 "[BackwardLocalPlanner] GOAL REACHED. Send stop command and skipping trajectory collision: "
631 cmd_vel.twist.linear.x = 0;
632 cmd_vel.twist.angular.z = 0;
636 carrotInLinearGoalRange &&
654 tfpose, vetta, gamma, alpha_error, betta_error, rho_error);
659 vetta =
k_rho_ * rho_error;
668 "[BackwardLocalPlanner] we entered in a pure spinning state even in not pure-spining "
670 "carrotDistanceGoalReached: %d",
671 carrotInLinearGoalRange);
680 cmd_vel.twist.linear.x = vetta;
681 cmd_vel.twist.angular.z = gamma;
704 nh_->get_logger(),
"[BackwardLocalPlanner] local planner,"
706 <<
" current pose in goal: " << currentPoseInGoal << std::endl
707 <<
" carrot in final goal index: " << carrotInFinalGoalIndex << std::endl
708 <<
" carrot in linear goal range: " << carrotInLinearGoalRange << std::endl
712 <<
" theta: " << theta << std::endl
713 <<
" betta: " << theta << std::endl
714 <<
" err_x: " << dx << std::endl
715 <<
" err_y:" << dy << std::endl
716 <<
" rho_error:" << rho_error << std::endl
717 <<
" alpha_error:" << alpha_error << std::endl
718 <<
" betta_error:" << betta_error << std::endl
719 <<
" vetta:" << vetta << std::endl
720 <<
" gamma:" << gamma << std::endl
721 <<
" cmd_vel.lin.x:" << cmd_vel.twist.linear.x << std::endl
722 <<
" cmd_vel.ang.z:" << cmd_vel.twist.angular.z);
728 if (carrotHalfPlaneConstraintFailure)
732 "[BackwardLocalPlanner] CarrotHalfPlaneConstraintFailure detected. Sending "
733 "emergency stop and success to the planner.");
734 cmd_vel.twist.linear.x = 0;
739 geometry_msgs::msg::PoseStamped global_pose;
743 auto yaw = tf2::getYaw(global_pose.pose.orientation);
745 auto & pos = global_pose.pose.position;
747 Eigen::Vector3f currentpose(pos.x, pos.y, yaw);
748 Eigen::Vector3f currentvel(
749 cmd_vel.twist.linear.x, cmd_vel.twist.linear.y, cmd_vel.twist.angular.z);
750 std::vector<Eigen::Vector3f> trajectory;
752 currentpose, currentvel, 0.8 , M_PI / 8 , 3.0 , 0.05 ,
756 bool acceptedLocalTrajectoryFreeOfObstacles =
true;
768 geometry_msgs::msg::Twist mockzerospeed;
770 for (
auto & p : trajectory)
772 float dx = p[0] - finalgoalpose.pose.position.x;
773 float dy = p[1] - finalgoalpose.pose.position.y;
775 float dst = sqrt(dx * dx + dy * dy);
780 "[BackwardLocalPlanner] trajectory simulation for collision checking: goal "
781 "reached with no collision");
785 costmap2d->worldToMap(p[0], p[1], mx, my);
787 if (costmap2d->getCost(mx, my) >= nav2_costmap_2d::INSCRIBED_INFLATED_OBSTACLE)
789 acceptedLocalTrajectoryFreeOfObstacles =
false;
792 "[BackwardLocalPlanner] ABORTED LOCAL PLAN BECAUSE OBSTACLE DETEDTED at point "
793 << i <<
"/" << trajectory.size() << std::endl
794 << p[0] <<
", " << p[1]);
803 nh_->get_logger(),
"[BackwardLocalPlanner] Abort local - Backwards global plan size: %ld",
805 cmd_vel.twist.angular.z = 0;
806 cmd_vel.twist.linear.x = 0;
810 if (acceptedLocalTrajectoryFreeOfObstacles)
815 "[BackwardLocalPlanner] accepted local trajectory free of obstacle. Local planner "
822 cmd_vel.twist.linear.x = 0;
823 cmd_vel.twist.angular.z = 0;
830 nh_->get_logger(),
"[BackwardLocalPlanner][Not accepted local plan] starting countdown");
839 nh_->get_logger(),
"[BackwardLocalPlanner][Abort local] timeout! duration %lf/%f",
841 cmd_vel.twist.linear.x = 0;
842 cmd_vel.twist.angular.z = 0;
934 RCLCPP_INFO(
nh_->get_logger(),
"[BackwardLocalPlanner] resample precise");
939 "[BackwardLocalPlanner] resample precise skipping, size: " <<
backwardsPlanPath_.size());
949 RCLCPP_INFO_STREAM(
nh_->get_logger(),
"[BackwardLocalPlanner] resample precise, check: " << i);
953 tf2::Quaternion qCurrent, qNext;
954 tf2::convert(currpose.pose.orientation, qCurrent);
955 tf2::convert(nextpose.pose.orientation, qNext);
957 double dx = nextpose.pose.position.x - currpose.pose.position.x;
958 double dy = nextpose.pose.position.y - currpose.pose.position.y;
959 double dist = sqrt(dx * dx + dy * dy);
961 bool resample =
false;
962 if (dist > maxallowedLinearError)
965 nh_->get_logger(),
"[BackwardLocalPlanner] resampling point, linear distance:"
966 << dist <<
"(" << maxallowedLinearError <<
")" << i);
971 double currentAngle = tf2::getYaw(qCurrent);
972 double nextAngle = tf2::getYaw(qNext);
974 double angularError = fabs(angles::shortest_angular_distance(currentAngle, nextAngle));
975 if (angularError > maxallowedAngularError)
979 nh_->get_logger(),
"[BackwardLocalPlanner] resampling point, angular distance:"
980 << angularError <<
"(" << maxallowedAngularError <<
")" << i);
986 geometry_msgs::msg::PoseStamped pintermediate;
987 auto duration = rclcpp::Time(nextpose.header.stamp) - rclcpp::Time(currpose.header.stamp);
989 pintermediate.header.frame_id = currpose.header.frame_id;
990 pintermediate.header.stamp = rclcpp::Time(currpose.header.stamp) + duration * 0.5;
992 pintermediate.pose.position.x = 0.5 * (currpose.pose.position.x + nextpose.pose.position.x);
993 pintermediate.pose.position.y = 0.5 * (currpose.pose.position.y + nextpose.pose.position.y);
994 pintermediate.pose.position.z = 0.5 * (currpose.pose.position.z + nextpose.pose.position.z);
995 tf2::Quaternion intermediateQuat = tf2::slerp(qCurrent, qNext, 0.5);
996 pintermediate.pose.orientation = tf2::toMsg(intermediateQuat);
1007 nh_->get_logger(),
"[BackwardLocalPlanner] End resampling. resampled:" << counter
1008 <<
" new inserted poses "