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_);
101 const nav2::LifecycleNode::SharedPtr & nh)
103 velocity_iterator_ = std::make_shared<XYThetaIterator>();
104 velocity_iterator_->initialize(nh, kinematics_handler_,
plugin_name_);
108 const nav_2d_msgs::msg::Twist2D & current_velocity)
110 velocity_iterator_->startNewIteration(current_velocity, sim_time_);
115 return velocity_iterator_->hasMoreTwists();
120 return velocity_iterator_->nextTwist();
124 const nav_2d_msgs::msg::Twist2D & cmd_vel)
126 std::vector<double> steps;
127 if (discretize_by_time_) {
130 double vmag = hypot(cmd_vel.x, cmd_vel.y);
133 double projected_linear_distance = vmag * sim_time_;
136 double projected_angular_distance = fabs(cmd_vel.theta) * sim_time_;
139 int num_steps = ceil(
143 steps.resize(num_steps);
145 if (steps.size() == 0) {
148 std::fill(steps.begin(), steps.end(), sim_time_ / steps.size());
153 const geometry_msgs::msg::Pose & start_pose,
154 const nav_2d_msgs::msg::Twist2D & start_vel,
155 const nav_2d_msgs::msg::Twist2D & cmd_vel)
157 dwb_msgs::msg::Trajectory2D traj;
158 traj.velocity = cmd_vel;
160 geometry_msgs::msg::Pose pose = start_pose;
161 nav_2d_msgs::msg::Twist2D vel = start_vel;
162 double running_time = 0.0;
164 traj.poses.push_back(start_pose);
165 bool first_vel =
false;
166 for (
double dt : steps) {
177 traj.poses.push_back(pose);
178 traj.time_offsets.push_back(rclcpp::Duration::from_seconds(running_time));
182 if (include_last_point_) {
183 traj.poses.push_back(pose);
184 traj.time_offsets.push_back(rclcpp::Duration::from_seconds(running_time));
194 const nav_2d_msgs::msg::Twist2D & cmd_vel,
195 const nav_2d_msgs::msg::Twist2D & start_vel,
const double dt)
198 nav_2d_msgs::msg::Twist2D new_vel;
199 new_vel.x = projectVelocity(
200 start_vel.x, kinematics.getAccX(),
201 kinematics.getDecelX(), dt, cmd_vel.x);
202 new_vel.y = projectVelocity(
203 start_vel.y, kinematics.getAccY(),
204 kinematics.getDecelY(), dt, cmd_vel.y);
205 new_vel.theta = projectVelocity(
207 kinematics.getAccTheta(), kinematics.getDecelTheta(),
213 const geometry_msgs::msg::Pose start_pose,
214 const nav_2d_msgs::msg::Twist2D & vel,
const double dt)
216 geometry_msgs::msg::Pose new_pose;
218 double theta = tf2::getYaw(start_pose.orientation);
219 new_pose.position.x = start_pose.position.x +
220 (vel.x * cos(theta) + vel.y * cos(M_PI_2 + theta)) * dt;
221 new_pose.position.y = start_pose.position.y +
222 (vel.x * sin(theta) + vel.y * sin(M_PI_2 + theta)) * dt;
224 double new_theta = theta + vel.theta * dt;
226 q.setRPY(0.0, 0.0, new_theta);
227 new_pose.orientation = tf2::toMsg(q);
234 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
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.