ROS::ros机器人路径远离障碍物的方法

ros机器人路径远离障碍物的方法

A星或dijkstra规划的路径会贴着障碍物,如果膨胀半径设置过小机器人在跟踪路径运动时会碰到障碍物,特别是在转弯的时候。
这里提供一种路径优化的方法让路径与膨胀层保持一定距离。
步骤:
1、遍历所有的路径点,记录下路径点周围一定范围length(可设置)的障碍物。
2、若所有的障碍物都在路径的同一测则找到距离该路径点A最近的障碍物点B,设最近的距离为d。
3、将路径点A平移,平移的方向为A指向B的方向,平移的距离为length - d,即让A与B的保持距离为length。
效果图如下:

红色的路径为未优化的全局路径,绿色的为优化后的局部路径
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述
代码如下:

void filtePath(std::vector<geometry_msgs::PoseStamped> &plan,double safe_distance)
  {
    if(plan.empty())
    {
      ROS_INFO("PurePlannerROS::filtePath: plan is empty.");
      return;
    }
    int safe_cell = (int)( safe_distance / this->costmap_->getResolution() );
    if(safe_cell < 1)
    {
      ROS_INFO("The safety distance is too small.");
      return;
    }
    size_t point_size = plan.size();
    geometry_msgs::PoseStamped tem_point;
    geometry_msgs::PoseStamped before_point;
    geometry_msgs::PoseStamped next_point;
    geometry_msgs::PoseStamped nearest_obstacle;
    unsigned int mx_min,mx_max,my_min,my_max,mx,my;
    for(size_t i=0;i<point_size;i++)
    {
      tem_point = plan[i];
      before_point = i>0?plan[i-1]:plan[i];
      next_point   = i<point_size-1?plan[i+1]:plan[i];

      this->costmap_->worldToMap(tem_point.pose.position.x,tem_point.pose.position.y,mx,my);
      mx_min = mx>safe_cell?mx-safe_cell:mx;
      mx_max = mx+safe_cell<this->costmap_->getSizeInCellsX()?mx+safe_cell:mx;
      my_min = my>safe_cell?my-safe_cell:my;
      my_max = my+safe_cell<this->costmap_->getSizeInCellsY()?my+safe_cell:my;
      std::vector<geometry_msgs::Point> obstacle_vec;
      geometry_msgs::Point obstacle;
      obstacle_vec.clear();
      for(unsigned int j=mx_min;j<mx_max;j++) //Find all obstacles within a safe distance.
      {
        for(unsigned int k=my_min;k<my_max;k++)
        {
          if(this->costmap_->getCost(j,k) != costmap_2d::FREE_SPACE)
          {
            this->costmap_->mapToWorld(j,k,obstacle.x,obstacle.y);
            obstacle_vec.push_back(obstacle);
          }
        }
      }

      if(obstacle_vec.empty() != true)
      {
         //Check if the points are on the same side.
        bool same_side_flag = false;
        if(next_point.pose.position.x != before_point.pose.position.x)
        {
          double lk = 0,lb = 0,ly = 0,num = 0;
          lk = (next_point.pose.position.y-before_point.pose.position.y) / (next_point.pose.position.x-before_point.pose.position.x);
          lb = next_point.pose.position.y - lk * next_point.pose.position.x;

          for(size_t m=0;m<obstacle_vec.size();m++)
          {
            ly = lk * obstacle_vec[m].x + lb;
            if(ly != 0)
              break;
          }

          for(size_t m=0;m<obstacle_vec.size();m++)
          {
            num = ly*(lk * obstacle_vec[m].x + lb);
            if(num < 0)
            {
              same_side_flag = true;
              break;
            }
          }
        }
        else
        {
          double const_x = next_point.pose.position.x;
          double err = 0,num = 0;
          for(size_t m=0;m<obstacle_vec.size();m++)
          {
            err = const_x - obstacle_vec[m].x;
            if(err != 0)
              break;
          }
          for(size_t m=0;m<obstacle_vec.size();m++)
          {
            num = err*(const_x - obstacle_vec[m].x);
            if(num < 0)
            {
              same_side_flag = true;
              break;
            }
          }
        }

        if(same_side_flag == true)
        {
          ROS_INFO("These points are not on the same side.");
          continue;
        }

        double distance=0,min_distance_obst = 1000.0;
        size_t min_obst_index = 0;
        double diff_x,diff_y;
        for(size_t l=0;l<obstacle_vec.size();l++) //find nearest obstacle
        {
          diff_x = obstacle_vec[l].x - tem_point.pose.position.x;
          diff_y = obstacle_vec[l].y - tem_point.pose.position.y;
          distance = sqrt(diff_x*diff_x+diff_y*diff_y);
          if(min_distance_obst > distance)
          {
            min_distance_obst = distance;
            min_obst_index = l;
          }
        }

        if(safe_distance - min_distance_obst < 0.0)
        {
          continue;
        }

        nearest_obstacle.pose.position.x = obstacle_vec[min_obst_index].x;
        nearest_obstacle.pose.position.y = obstacle_vec[min_obst_index].y;

        distance =  safe_distance - min_distance_obst;
        double err_x,err_y,theta,finally_x,finally_y;
        theta = atan2(tem_point.pose.position.y-nearest_obstacle.pose.position.y,tem_point.pose.position.x-nearest_obstacle.pose.position.x);
        err_x = distance*cos(theta);
        err_y = distance*sin(theta);
        finally_x = tem_point.pose.position.x + err_x;
        finally_y = tem_point.pose.position.y + err_y;
        this->costmap_->worldToMap(finally_x,finally_y,mx,my);
        if(this->costmap_->getCost(mx,my) == costmap_2d::FREE_SPACE)
        {
          plan[i].pose.position.x = finally_x;
          plan[i].pose.position.y = finally_y;
        }
      }
    }
  }
  • 16
    点赞
  • 151
    收藏
    觉得还不错? 一键收藏
  • 28
    评论
### 回答1: ROS机器人操作系统)是一个开源的机器人软件框架,可以帮助实现机器人的全局路径规划和局部路径避开障碍物的功能。 全局路径规划主要是决定机器人从起点到终点的最优路径。在ROS中,我们可以使用一些已经实现的算法,例如Dijkstra算法、A*算法或RRT算法来进行全局路径规划。这些算法可以根据机器人和环境的具体情况,计算出一个安全、高效的路径,并将其表示为一个路径点序列。 局部路径避开障碍物主要是为了应对动态环境或避免碰撞。在ROS中,通常会使用障碍物检测和避障算法来实现。通过使用传感器(如激光雷达或摄像头)获取环境信息,可以检测到机器人周围的障碍物。接着,使用局部路径规划算法(如Dynamic Window Approach、随机采样一致性或强化学习算法)来生成可行的、避开障碍物路径,以确保机器人能够安全地绕过障碍物。 在ROS中,全局路径规划和局部路径避开障碍物通常是结合使用的。全局路径规划算法会计算出整个行驶路线,并将其分解为小段的局部路径,然后局部路径避开障碍物算法会在局部路径上进行优化,以适应动态环境。机器人可以根据局部路径的指令,进行实时调整和控制,从而避开障碍物并到达目标位置。 综上所述,ROS全局路径规划和局部路径避开障碍物是一套完整的路径规划解决方案,能够帮助机器人实现安全、高效地导航和避障。 ### 回答2: ROS机器人操作系统)是一种广泛应用于机器人领域的开源软件平台。在ROS中,全局路径规划是指通过构建地图并使用路径规划算法来确定机器人从起点到目标点的最优路径。而局部路径规划则是在机器人运动过程中实时避开障碍物,以保证机器人的安全移动。 全局路径规划首先需要对机器人所处的环境进行建图。通过使用传感器(如激光雷达或摄像头)获取环境中的数据,并进行处理和分析,构建出机器人所在区域的地图。在构建好地图之后,可以应用路径规划算法(如A*算法、Dijkstra算法或RRT算法),从机器人的起点到目标点计算出最优的路径。 局部路径规划是在机器人运动过程中实时进行的,主要用于避开障碍物并保证机器人的安全。使用传感器获取机器人周围的障碍物信息,并将其与机器人的运动状态相结合,根据障碍物位置和机器人的移动方向进行路径调整。常用的局部路径规划算法有VFH算法、DWA算法或基于感知场的方法。 在ROS中,可以使用已有的全局路径规划和局部路径规划算法来完成相应的功能。比如,可以使用ROS中的导航栈(Navigation Stack)来实现全局路径规划和局部路径规划。导航栈是ROS中用于实现机器人导航功能的软件包,提供了全局路径规划和局部路径规划的实现方法。 总结而言,ROS中的全局路径规划和局部路径规划是机器人导航中非常重要的两个步骤。全局路径规划通过构建地图和路径规划算法确定机器人的最优路径,而局部路径规划则是在机器人运动中实时避开障碍物,确保机器人的安全移动。使用ROS中的导航栈可以很方便地实现这些功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 28
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值