DWA算法(四) dwaComputeVelocityCommands

接上一篇,分析如果还没到x y误差范围内,进行DWA规划的情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
else
{
// 是否规划成功
bool isOk = dwaComputeVelocityCommands(current_pose_, cmd_vel);

if (isOk)
publishGlobalPlan(transformed_plan);
else
ROS_WARN_NAMED("dwa_local_planner", "DWA planner failed to produce path.");

std::vector<geometry_msgs::PoseStamped> empty_plan;
publishGlobalPlan(empty_plan);
}
return isOk;

关键就是dwaComputeVelocityCommands

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
bool DWAPlannerROS::dwaComputeVelocityCommands(
tf::Stamped<tf::Pose> &global_pose,
geometry_msgs::Twist& cmd_vel )
{
// dynamic window sampling approach to get useful velocity commands
if(! isInitialized() )
{
ROS_ERROR("This planner has not been initialized, please call initialize() before using this planner");
return false;
}

tf::Stamped<tf::Pose> robot_vel;
odom_helper_.getRobotVel(robot_vel);

/* For timing uncomment
struct timeval start, end;
double start_t, end_t, t_diff;
gettimeofday(&start, NULL);
*/

//compute what trajectory to drive along
tf::Stamped<tf::Pose> drive_cmds;
drive_cmds.frame_id_ = costmap_ros_->getBaseFrameID();

// call with updated footprint
base_local_planner::Trajectory path = dp_->findBestPath(global_pose, robot_vel, drive_cmds, costmap_ros_->getRobotFootprint());
//ROS_ERROR("Best: %.2f, %.2f, %.2f, %.2f", path.xv_, path.yv_, path.thetav_, path.cost_);

/* For timing uncomment
gettimeofday(&end, NULL);
start_t = start.tv_sec + double(start.tv_usec) / 1e6;
end_t = end.tv_sec + double(end.tv_usec) / 1e6;
t_diff = end_t - start_t;
ROS_INFO("Cycle time: %.9f", t_diff);
*/

//pass along drive commands
cmd_vel.linear.x = drive_cmds.getOrigin().getX();
cmd_vel.linear.y = drive_cmds.getOrigin().getY();
cmd_vel.angular.z = tf::getYaw(drive_cmds.getRotation());

//if we cannot move... tell someone
std::vector<geometry_msgs::PoseStamped> local_plan;
if(path.cost_ < 0)
{
ROS_DEBUG_NAMED("dwa_local_planner",
"The dwa local planner failed to find a valid plan, cost functions discarded all candidates. This can mean there is an obstacle too close to the robot.");
local_plan.clear();
publishLocalPlan(local_plan);
return false;
}
ROS_DEBUG_NAMED("dwa_local_planner", "A valid velocity command of (%.2f, %.2f, %.2f) was found for this cycle.",
cmd_vel.linear.x, cmd_vel.linear.y, cmd_vel.angular.z);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    // Fill out the local plan
for(unsigned int i = 0; i < path.getPointsSize(); ++i)
{
double p_x, p_y, p_th;
path.getPoint(i, p_x, p_y, p_th);

tf::Stamped<tf::Pose> p =
tf::Stamped<tf::Pose>(tf::Pose(
tf::createQuaternionFromYaw(p_th),
tf::Point(p_x, p_y, 0.0)),
ros::Time::now(),
costmap_ros_->getGlobalFrameID());
geometry_msgs::PoseStamped pose;
tf::poseStampedTFToMsg(p, pose);
local_plan.push_back(pose);
}

//publish information to the visualizer
publishLocalPlan(local_plan);
return true;
}