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 "tf2/utils.hpp"
44 #include "tf2_geometry_msgs/tf2_geometry_msgs.hpp"
50 const nav2::LifecycleNode::SharedPtr & nh,
51 const std::string & plugin_name)
54 kinematics_handler_ = std::make_shared<KinematicsHandler>();
66 sim_time_ = nh->declare_or_get_parameter(
67 plugin_name +
".sim_time", 1.7);
68 discretize_by_time_ = nh->declare_or_get_parameter(
69 plugin_name +
".discretize_by_time",
false);
71 plugin_name +
".time_granularity", 0.5);
73 plugin_name +
".linear_granularity", 0.5);
75 plugin_name +
".angular_granularity", 0.025);
77 plugin_name +
".limit_vel_cmd_in_traj",
false);
82 kinematics_handler_->activate();
87 kinematics_handler_->deactivate();
91 const nav2::LifecycleNode::SharedPtr & nh)
93 velocity_iterator_ = std::make_shared<XYThetaIterator>();
94 velocity_iterator_->initialize(nh, kinematics_handler_,
plugin_name_);
98 const nav_2d_msgs::msg::Twist2D & current_velocity)
100 velocity_iterator_->startNewIteration(current_velocity, sim_time_);
105 return velocity_iterator_->hasMoreTwists();
110 return velocity_iterator_->nextTwist();
114 const nav_2d_msgs::msg::Twist2D & cmd_vel)
116 std::vector<double> steps;
117 if (discretize_by_time_) {
120 double vmag = hypot(cmd_vel.x, cmd_vel.y);
123 double projected_linear_distance = vmag * sim_time_;
126 double projected_angular_distance = fabs(cmd_vel.theta) * sim_time_;
129 int num_steps = ceil(
133 steps.resize(num_steps);
135 if (steps.size() == 0) {
138 std::fill(steps.begin(), steps.end(), sim_time_ / steps.size());
143 const geometry_msgs::msg::Pose & start_pose,
144 const nav_2d_msgs::msg::Twist2D & start_vel,
145 const nav_2d_msgs::msg::Twist2D & cmd_vel)
147 dwb_msgs::msg::Trajectory2D traj;
148 traj.velocity = cmd_vel;
150 geometry_msgs::msg::Pose pose = start_pose;
151 nav_2d_msgs::msg::Twist2D vel = start_vel;
152 double running_time = 0.0;
154 bool first_vel =
false;
155 for (
double dt : steps) {
156 traj.poses.push_back(pose);
157 traj.time_offsets.push_back(rclcpp::Duration::from_seconds(running_time));
171 traj.poses.push_back(pose);
172 traj.time_offsets.push_back(rclcpp::Duration::from_seconds(running_time));
181 const nav_2d_msgs::msg::Twist2D & cmd_vel,
182 const nav_2d_msgs::msg::Twist2D & start_vel,
const double dt)
185 nav_2d_msgs::msg::Twist2D new_vel;
186 new_vel.x = projectVelocity(
187 start_vel.x, kinematics.getAccX(),
188 kinematics.getDecelX(), dt, cmd_vel.x);
189 new_vel.y = projectVelocity(
190 start_vel.y, kinematics.getAccY(),
191 kinematics.getDecelY(), dt, cmd_vel.y);
192 new_vel.theta = projectVelocity(
194 kinematics.getAccTheta(), kinematics.getDecelTheta(),
200 const geometry_msgs::msg::Pose start_pose,
201 const nav_2d_msgs::msg::Twist2D & vel,
const double dt)
203 geometry_msgs::msg::Pose new_pose;
205 double theta = tf2::getYaw(start_pose.orientation);
206 new_pose.position.x = start_pose.position.x +
207 (vel.x * cos(theta) + vel.y * cos(M_PI_2 + theta)) * dt;
208 new_pose.position.y = start_pose.position.y +
209 (vel.x * sin(theta) + vel.y * sin(M_PI_2 + theta)) * dt;
211 double new_theta = theta + vel.theta * dt;
213 q.setRPY(0.0, 0.0, new_theta);
214 new_pose.orientation = tf2::toMsg(q);
221 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.
void activate() override
Registers callbacks for dynamic parameter handling.
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.
void deactivate() override
Resets callbacks for dynamic parameter handling.
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.