35 #include "dwb_plugins/standard_traj_generator.hpp"
40 #include "dwb_plugins/xy_theta_iterator.hpp"
41 #include "pluginlib/class_list_macros.hpp"
42 #include "dwb_core/exceptions.hpp"
43 #include "nav2_ros_common/node_utils.hpp"
44 #include "tf2/utils.hpp"
45 #include "tf2_geometry_msgs/tf2_geometry_msgs.hpp"
51 const nav2::LifecycleNode::SharedPtr & nh,
52 const std::string & plugin_name)
55 kinematics_handler_ = std::make_shared<KinematicsHandler>();
59 nav2::declare_parameter_if_not_declared(
61 plugin_name +
".sim_time", rclcpp::ParameterValue(1.7));
62 nav2::declare_parameter_if_not_declared(
64 plugin_name +
".discretize_by_time", rclcpp::ParameterValue(
false));
66 nav2::declare_parameter_if_not_declared(
68 plugin_name +
".time_granularity", rclcpp::ParameterValue(0.5));
69 nav2::declare_parameter_if_not_declared(
71 plugin_name +
".linear_granularity", rclcpp::ParameterValue(0.5));
72 nav2::declare_parameter_if_not_declared(
74 plugin_name +
".angular_granularity", rclcpp::ParameterValue(0.025));
75 nav2::declare_parameter_if_not_declared(
77 plugin_name +
".include_last_point", rclcpp::ParameterValue(
true));
79 nav2::declare_parameter_if_not_declared(
81 plugin_name +
".limit_vel_cmd_in_traj", rclcpp::ParameterValue(
false));
91 nh->get_parameter(plugin_name +
".sim_time", sim_time_);
92 nh->get_parameter(plugin_name +
".discretize_by_time", discretize_by_time_);
96 nh->get_parameter(plugin_name +
".include_last_point", include_last_point_);
102 kinematics_handler_->activate();
107 kinematics_handler_->deactivate();
111 const nav2::LifecycleNode::SharedPtr & nh)
113 velocity_iterator_ = std::make_shared<XYThetaIterator>();
114 velocity_iterator_->initialize(nh, kinematics_handler_,
plugin_name_);
118 const nav_2d_msgs::msg::Twist2D & current_velocity)
120 velocity_iterator_->startNewIteration(current_velocity, sim_time_);
125 return velocity_iterator_->hasMoreTwists();
130 return velocity_iterator_->nextTwist();
134 const nav_2d_msgs::msg::Twist2D & cmd_vel)
136 std::vector<double> steps;
137 if (discretize_by_time_) {
140 double vmag = hypot(cmd_vel.x, cmd_vel.y);
143 double projected_linear_distance = vmag * sim_time_;
146 double projected_angular_distance = fabs(cmd_vel.theta) * sim_time_;
149 int num_steps = ceil(
153 steps.resize(num_steps);
155 if (steps.size() == 0) {
158 std::fill(steps.begin(), steps.end(), sim_time_ / steps.size());
163 const geometry_msgs::msg::Pose & start_pose,
164 const nav_2d_msgs::msg::Twist2D & start_vel,
165 const nav_2d_msgs::msg::Twist2D & cmd_vel)
167 dwb_msgs::msg::Trajectory2D traj;
168 traj.velocity = cmd_vel;
170 geometry_msgs::msg::Pose pose = start_pose;
171 nav_2d_msgs::msg::Twist2D vel = start_vel;
172 double running_time = 0.0;
174 traj.poses.push_back(start_pose);
175 bool first_vel =
false;
176 for (
double dt : steps) {
187 traj.poses.push_back(pose);
188 traj.time_offsets.push_back(rclcpp::Duration::from_seconds(running_time));
192 if (include_last_point_) {
193 traj.poses.push_back(pose);
194 traj.time_offsets.push_back(rclcpp::Duration::from_seconds(running_time));
204 const nav_2d_msgs::msg::Twist2D & cmd_vel,
205 const nav_2d_msgs::msg::Twist2D & start_vel,
const double dt)
208 nav_2d_msgs::msg::Twist2D new_vel;
209 new_vel.x = projectVelocity(
210 start_vel.x, kinematics.getAccX(),
211 kinematics.getDecelX(), dt, cmd_vel.x);
212 new_vel.y = projectVelocity(
213 start_vel.y, kinematics.getAccY(),
214 kinematics.getDecelY(), dt, cmd_vel.y);
215 new_vel.theta = projectVelocity(
217 kinematics.getAccTheta(), kinematics.getDecelTheta(),
223 const geometry_msgs::msg::Pose start_pose,
224 const nav_2d_msgs::msg::Twist2D & vel,
const double dt)
226 geometry_msgs::msg::Pose new_pose;
228 double theta = tf2::getYaw(start_pose.orientation);
229 new_pose.position.x = start_pose.position.x +
230 (vel.x * cos(theta) + vel.y * cos(M_PI_2 + theta)) * dt;
231 new_pose.position.y = start_pose.position.y +
232 (vel.x * sin(theta) + vel.y * sin(M_PI_2 + theta)) * dt;
234 double new_theta = theta + vel.theta * dt;
236 q.setRPY(0.0, 0.0, new_theta);
237 new_pose.orientation = tf2::toMsg(q);
244 PLUGINLIB_EXPORT_CLASS(
Interface for iterating through possible velocities and creating trajectories.
Standard DWA-like trajectory generator.
void startNewIteration(const nav_2d_msgs::msg::Twist2D ¤t_velocity) override
Start a new iteration based on the current velocity.
double angular_granularity_
If not discretizing by time, the amount of angular space between points.
virtual nav_2d_msgs::msg::Twist2D computeNewVelocity(const nav_2d_msgs::msg::Twist2D &cmd_vel, const nav_2d_msgs::msg::Twist2D &start_vel, const double dt)
Calculate the velocity after a set period of time, given the desired velocity and acceleration limits...
std::string plugin_name_
the name of the overlying plugin ID
void deactivate()
Resets callbacks for dynamic parameter handling.
void activate()
Registers callbacks for dynamic parameter handling.
bool hasMoreTwists() override
Test to see whether there are more twists to test.
virtual std::vector< double > getTimeSteps(const nav_2d_msgs::msg::Twist2D &cmd_vel)
Compute an array of time deltas between the points in the generated trajectory.
bool limit_vel_cmd_in_traj_
Option to limit velocity in the trajectory generator by using current velocity.
double linear_granularity_
If not discretizing by time, the amount of linear space between points.
virtual geometry_msgs::msg::Pose computeNewPosition(const geometry_msgs::msg::Pose start_pose, const nav_2d_msgs::msg::Twist2D &vel, const double dt)
Use the robot's kinematic model to predict new positions for the robot.
double time_granularity_
If discretizing by time, the amount of time between each point in the traj.
void initialize(const nav2::LifecycleNode::SharedPtr &nh, const std::string &plugin_name) override
Initialize parameters as needed.
virtual void initializeIterator(const nav2::LifecycleNode::SharedPtr &nh)
Initialize the VelocityIterator pointer. Put in its own function for easy overriding.
dwb_msgs::msg::Trajectory2D generateTrajectory(const geometry_msgs::msg::Pose &start_pose, const nav_2d_msgs::msg::Twist2D &start_vel, const nav_2d_msgs::msg::Twist2D &cmd_vel) override
Given a cmd_vel in the robot's frame and initial conditions, generate a Trajectory2D.
nav_2d_msgs::msg::Twist2D nextTwist() override
Return the next twist and advance the iteration.
A struct containing one representation of the robot's kinematics.