百度apollo自动驾驶planning代码学习-Apollo\modules\planning\common\util\util.cc & util.h代码解析_common/command util.h-程序员宅基地

技术标签: 自动驾驶  c++  Apollo学习笔记  人工智能  

概述

util.cc/.h是planning模块下的common/util路径下
根据路径和命名也可以看出
util.cc其实就是实现了一些planning中会用到的一些辅助工具,util这个文件夹在很多工程中都可以看到,都是存放一些辅助功能的实现代码。

从代码来看util.cc主要是实现:
1.判断当前反馈的车辆状态是否有效;
2.判断两次routing(全局路径规划)的结果是否相同;
3.根据还剩下的刹车距离计算自车刹停需要的减速度;
4.检查道路参考线信息上是否有stopsign停车标志;
5.检查道路参考线信息上是否有交通灯;
6.检查自车是否处于路口;
7.读取指定路径下的文件的名称。

util.h

#pragma once

#include <string>
#include <vector>

#include <boost/filesystem.hpp>
#include <boost/range/iterator_range.hpp>

#include "modules/common/vehicle_state/proto/vehicle_state.pb.h"
#include "modules/common/vehicle_state/vehicle_state_provider.h"
#include "modules/planning/common/reference_line_info.h"
#include "modules/routing/proto/routing.pb.h"

namespace apollo {
    
namespace planning {
    
namespace util {
    

//判断VehicleState车辆状态是否有效,输入参数是一个VehicleState类对象
bool IsVehicleStateValid(const apollo::common::VehicleState& vehicle_state);

//判断是否是不同的routing
//输入参数就是之前的RoutingResponse和之后的RoutingResponse
bool IsDifferentRouting(const apollo::routing::RoutingResponse& first,
                        const apollo::routing::RoutingResponse& second);

//获取ADC(Automative Driving Car)的刹停减速度
//参数VehicleStateProvider类对象vehicle_state
//参数自车前端对应的Frenet纵坐标adc_front_edge_s
//参数停止线对应的Frenet纵坐标stop_line_s
double GetADCStopDeceleration(
    apollo::common::VehicleStateProvider* vehicle_state,
    const double adc_front_edge_s, const double stop_line_s);

/*
 * 检查一个stop_sign_overlap是否在参考线上?就是检查参考线上是否有停车标志
 * Apollo中的overlap表示空间中两个元素的重叠关系
 */
 //参数:reference_line_info 参考线上的信息
 //参数:stop_sign_overlap_id停车标志的id
bool CheckStopSignOnReferenceLine(const ReferenceLineInfo& reference_line_info,
                                  const std::string& stop_sign_overlap_id);

/*
 *  检查一个traffic_light_overlap 是否在参考线上?就是检查参考线上是否有交通灯
 *  Apollo中的overlap表示空间中两个元素的重叠关系
 */
 //参数:reference_line_info 参考线上的信息
 //参数:traffic_light_overlap_id 交通灯overlap的id
bool CheckTrafficLightOnReferenceLine(
    const ReferenceLineInfo& reference_line_info,
    const std::string& traffic_light_overlap_id);

/*
 * 检查ADC(Automative Driving Car)是否在路口pnc-junction
 */
//参数 reference_line_info参考线信息
bool CheckInsidePnCJunction(const ReferenceLineInfo& reference_line_info);

/*
 * 获取一个路径下的文件名
 */
 //参数 路径path
 //参数 文件名,还是个string的vector,存放指定路径下读取到的多个文件名
 //涉及到boost库的用法
 //给定一个路径把指定路径下的文件的名称都读到vector files里
void GetFilesByPath(const boost::filesystem::path& path,
                    std::vector<std::string>* files);

}  // namespace util
}  // namespace planning
}  // namespace apollo

util.cc

#include "modules/planning/common/util/util.h"

#include <limits>
#include <vector>

#include "modules/common/configs/vehicle_config_helper.h"
#include "modules/common/vehicle_state/vehicle_state_provider.h"
#include "modules/map/pnc_map/path.h"
#include "modules/planning/common/planning_gflags.h"

namespace apollo {
    
namespace planning {
    
namespace util {
    
//引用modules\common\vehicle_state\proto\vehicle_state.proto定义的message生成的
//VehicleState类  google protobuf生成.cc和.h文件,将.proto定义的message数据结构生成
//c++类
using apollo::common::VehicleState;
//引用modules\map\pnc_map\path.h里定义的PathOverlap结构体数据类型
using apollo::hdmap::PathOverlap;
//引用modules\routing\proto\routing.proto里定义的message RoutingResponse生成的类
using apollo::routing::RoutingResponse;

//判断VehicleState车辆状态是否有效,输入参数是一个VehicleState类对象
bool IsVehicleStateValid(const VehicleState& vehicle_state) {
    
  //判断vehicle_state的x,y,z,heading,曲率kappa,v,acc是否为nan(not a number)
  //只要有一个量是nan就直接返回false,否则返回true
  if (std::isnan(vehicle_state.x()) || std::isnan(vehicle_state.y()) ||
      std::isnan(vehicle_state.z()) || std::isnan(vehicle_state.heading()) ||
      std::isnan(vehicle_state.kappa()) ||
      std::isnan(vehicle_state.linear_velocity()) ||
      std::isnan(vehicle_state.linear_acceleration())) {
    
    return false;
  }
  return true;
}

//判断是否是不同的routing
//输入参数就是之前的RoutingResponse和之后的RoutingResponse
bool IsDifferentRouting(const RoutingResponse& first,
                        const RoutingResponse& second) {
    
  if (first.has_header() && second.has_header()) {
    
    //若前后RoutingResponse里的header里的sequence_num,推测是车道段数是否不相同
    //是不相同则返回true,否则返回false
    return first.header().sequence_num() != second.header().sequence_num();
  }
  //如果有一个没有header那都说明是不同的routing
  return true;
}

//获取ADC(Automative Driving Car)的刹停减速度
//参数VehicleStateProvider类对象vehicle_state
//参数自车前端对应的Frenet纵坐标adc_front_edge_s
//参数停止线对应的Frenet纵坐标stop_line_s
double GetADCStopDeceleration(
    apollo::common::VehicleStateProvider* vehicle_state,
    const double adc_front_edge_s, const double stop_line_s) {
    
  //先获取车辆的实际车速放入adc_speed 
  double adc_speed = vehicle_state->linear_velocity();
  //从车辆参数配置文件modules\common\data\vehicle_param.pb.txt读取
  //读取判定停车时的最大速度绝对值(默认是0.2m/s),当车速小于此阈值时,认为车辆已经停住
  //了
  const double max_adc_stop_speed = common::VehicleConfigHelper::Instance()
                                        ->GetConfig()
                                        .vehicle_param()
                                        .max_abs_speed_when_stopped();
  //如果车辆实际速度已经小于阈值max_adc_stop_speed,则认为车辆已经停下
  //则需要刹停的减速度为0.0
  if (adc_speed < max_adc_stop_speed) {
    
    return 0.0;
  }

  //初始化stop_distance,目前还剩下可以用来减速的距离
  double stop_distance = 0;

  //如果停止线对应Frenet的纵坐标stop_line_s 比车辆前端对应的Frenet的纵坐标
  //adc_front_edge_s要大的话
  //剩下的可用来刹停的距离stop_distance  = 停止线s坐标-车前端s坐标
  if (stop_line_s > adc_front_edge_s) {
    
    stop_distance = stop_line_s - adc_front_edge_s;
  }
  //如果剩下可以用来刹停的距离小于1e-5,减速度直接拉满
  //让减速度为double可以表示的最大数值,返回这个最大数值
  if (stop_distance < 1e-5) {
    
    return std::numeric_limits<double>::max();
  }

  //如果剩下刹停的距离并不小,就根据高中物理 a = v^2/(2*x),那么这里计算到的是
  //减速度的绝对值
  return (adc_speed * adc_speed) / (2 * stop_distance);
}

/*
 * 检查一个stop_sign_overlap是否在参考线上?就是检查参考线上是否有停车标志
 * Apollo中的overlap表示空间中两个元素的重叠关系
 */
 //参数:reference_line_info 参考线上的信息
 //参数:stop_sign_overlap_id停车标志的id
bool CheckStopSignOnReferenceLine(const ReferenceLineInfo& reference_line_info,
                                  const std::string& stop_sign_overlap_id) {
    
  //先从reference_line_info参考线信息上获取所有的stop_sign的overlap
  const std::vector<PathOverlap>& stop_sign_overlaps =
      reference_line_info.reference_line().map_path().stop_sign_overlaps();
  //遍历参考线线信息里的所有stopsign的overlap,看有没有id和给定Id相同的
  //令这个id相同的overlap对象赋给stop_sign_overlap_it,若没找到
  //stop_sign_overlap_it就会等于overlap里的最后一个
  auto stop_sign_overlap_it =
      std::find_if(stop_sign_overlaps.begin(), stop_sign_overlaps.end(),
                   [&stop_sign_overlap_id](const PathOverlap& overlap) {
    
                     return overlap.object_id == stop_sign_overlap_id;
                   });
  //所以只要stop_sign_overlap_it不是参考线上overlap里的最后一个,说明找到了相同id
  //只要下面!=成立,说明参数id可以在参考线信息的overlap里找到,说明这个stopsign的
  //overlap是在参考线信息上的,下面表达式成立就在参考线上,返回true,否则false
  return (stop_sign_overlap_it != stop_sign_overlaps.end());
}

/*
 *  检查一个traffic_light_overlap 是否在参考线上?就是检查参考线上是否有交通灯
 *  Apollo中的overlap表示空间中两个元素的重叠关系
 */
 //参数:reference_line_info 参考线上的信息
 //参数:traffic_light_overlap_id 交通灯overlap的id
bool CheckTrafficLightOnReferenceLine(
    const ReferenceLineInfo& reference_line_info,
    const std::string& traffic_light_overlap_id) {
    
  //先从reference_line_info参考线信息上获取所有的traffic_light的overlap
  const std::vector<PathOverlap>& traffic_light_overlaps =
      reference_line_info.reference_line().map_path().signal_overlaps();
  //遍历参考线线信息里的所有traffic_light的overlap,看有没有id和给定Id相同的
  //令这个id相同的overlap对象赋给traffic_light_overlap_it ,若没找到
  //traffic_light_overlap_it 就会等于交通灯overlap里的最后一个
  auto traffic_light_overlap_it =
      std::find_if(traffic_light_overlaps.begin(), traffic_light_overlaps.end(),
                   [&traffic_light_overlap_id](const PathOverlap& overlap) {
    
                     return overlap.object_id == traffic_light_overlap_id;
                   });
  //所以只要traffic_light_overlap_it不是参考线上overlap里最后一个,说明找到了相同id
  //只要下面!=成立,说明参数id可以在参考线信息的overlap里找到,说明该traffic_light的
  //overlap是在参考线信息上的,下面表达式成立就在参考线上,返回true,否则false
  return (traffic_light_overlap_it != traffic_light_overlaps.end());
}

/*
 * 检查ADC(Automative Driving Car)是否在路口pnc-junction
 */
//参数 reference_line_info参考线信息
bool CheckInsidePnCJunction(const ReferenceLineInfo& reference_line_info) {
    
  //首先从参考线信息上获取自车前端frenet系s坐标,就是自车sl边界的末尾s
  const double adc_front_edge_s = reference_line_info.AdcSlBoundary().end_s();
  //首先从参考线信息上获取自车尾部frenet系s坐标,就是自车sl边界的起始s
  const double adc_back_edge_s = reference_line_info.AdcSlBoundary().start_s();

  //先定义一个PathOverlap类型的pnc_junction_overlap路口overlap对象
  hdmap::PathOverlap pnc_junction_overlap;
  //用自车前端frenet系s坐标去参考先信息上查询是否处于路口内,若是,将所在的路口对象赋给
  //pnc_junction_overlap
  reference_line_info.GetPnCJunction(adc_front_edge_s, &pnc_junction_overlap);
  //若pnc_junction_overlap是空的,说明上一步并不在路口内,找不到,就返回false
  //说明自车不在pnc路口
  if (pnc_junction_overlap.object_id.empty()) {
    
    return false;
  }

  //这里定义了一个常数kIntersectionPassDist 阈值2.0m
  static constexpr double kIntersectionPassDist = 2.0;  // unit: m
  //这里是判断自车在路口里有没有出来,看自车后端对应的frenet系s坐标减去
  //减去pnc路口末尾点在frenet系s坐标,两者之差distance_adc_pass_intersection 
  //若自车后端已经离开路口末尾2.0m以上,则判定自车已经不在路口。否则就在路口。
  const double distance_adc_pass_intersection =
      adc_back_edge_s - pnc_junction_overlap.end_s;
  ADEBUG << "distance_adc_pass_intersection[" << distance_adc_pass_intersection
         << "] pnc_junction_overlap[" << pnc_junction_overlap.object_id
         << "] start_s[" << pnc_junction_overlap.start_s << "]";

  return distance_adc_pass_intersection < kIntersectionPassDist;
}

/*
 * 获取一个路径下的文件名
 */
 //参数 路径path
 //参数 文件名,还是个string的vector,存放指定路径下读取到的多个文件名
 //涉及到boost库的用法
 //给定一个路径把指定路径下的文件的名称都读到vector files里
void GetFilesByPath(const boost::filesystem::path& path,
                    std::vector<std::string>* files) {
    
  ACHECK(files);
  //判断路径是否存在,不存在的话直接返回
  if (!boost::filesystem::exists(path)) {
    
    return;
  }
  //boost::filesystem::is_regular_file 检查文件是否存在
  if (boost::filesystem::is_regular_file(path)) {
    
    AINFO << "Found record file: " << path.c_str();
    //存在的话往files指针里塞path的sting字符串
    files->push_back(path.c_str());
    return;
  }
  //判断path是否为一个文件夹,这是遍历path下的每一个文件/文件夹,
  //都读到vector files里?
  if (boost::filesystem::is_directory(path)) {
    
    for (auto& entry : boost::make_iterator_range(
             boost::filesystem::directory_iterator(path), {
    })) {
    
      GetFilesByPath(entry.path(), files);
    }
  }
}

}  // namespace util
}  // namespace planning
}  // namespace apollo
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_39199083/article/details/124562843

智能推荐

稀疏编码的数学基础与理论分析-程序员宅基地

文章浏览阅读290次,点赞8次,收藏10次。1.背景介绍稀疏编码是一种用于处理稀疏数据的编码技术,其主要应用于信息传输、存储和处理等领域。稀疏数据是指数据中大部分元素为零或近似于零的数据,例如文本、图像、音频、视频等。稀疏编码的核心思想是将稀疏数据表示为非零元素和它们对应的位置信息,从而减少存储空间和计算复杂度。稀疏编码的研究起源于1990年代,随着大数据时代的到来,稀疏编码技术的应用范围和影响力不断扩大。目前,稀疏编码已经成为计算...

EasyGBS国标流媒体服务器GB28181国标方案安装使用文档-程序员宅基地

文章浏览阅读217次。EasyGBS - GB28181 国标方案安装使用文档下载安装包下载,正式使用需商业授权, 功能一致在线演示在线API架构图EasySIPCMSSIP 中心信令服务, 单节点, 自带一个 Redis Server, 随 EasySIPCMS 自启动, 不需要手动运行EasySIPSMSSIP 流媒体服务, 根..._easygbs-windows-2.6.0-23042316使用文档

【Web】记录巅峰极客2023 BabyURL题目复现——Jackson原生链_原生jackson 反序列化链子-程序员宅基地

文章浏览阅读1.2k次,点赞27次,收藏7次。2023巅峰极客 BabyURL之前AliyunCTF Bypassit I这题考查了这样一条链子:其实就是Jackson的原生反序列化利用今天复现的这题也是大同小异,一起来整一下。_原生jackson 反序列化链子

一文搞懂SpringCloud,详解干货,做好笔记_spring cloud-程序员宅基地

文章浏览阅读734次,点赞9次,收藏7次。微服务架构简单的说就是将单体应用进一步拆分,拆分成更小的服务,每个服务都是一个可以独立运行的项目。这么多小服务,如何管理他们?(服务治理 注册中心[服务注册 发现 剔除])这么多小服务,他们之间如何通讯?这么多小服务,客户端怎么访问他们?(网关)这么多小服务,一旦出现问题了,应该如何自处理?(容错)这么多小服务,一旦出现问题了,应该如何排错?(链路追踪)对于上面的问题,是任何一个微服务设计者都不能绕过去的,因此大部分的微服务产品都针对每一个问题提供了相应的组件来解决它们。_spring cloud

Js实现图片点击切换与轮播-程序员宅基地

文章浏览阅读5.9k次,点赞6次,收藏20次。Js实现图片点击切换与轮播图片点击切换<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title></title> <script type="text/ja..._点击图片进行轮播图切换

tensorflow-gpu版本安装教程(过程详细)_tensorflow gpu版本安装-程序员宅基地

文章浏览阅读10w+次,点赞245次,收藏1.5k次。在开始安装前,如果你的电脑装过tensorflow,请先把他们卸载干净,包括依赖的包(tensorflow-estimator、tensorboard、tensorflow、keras-applications、keras-preprocessing),不然后续安装了tensorflow-gpu可能会出现找不到cuda的问题。cuda、cudnn。..._tensorflow gpu版本安装

随便推点

物联网时代 权限滥用漏洞的攻击及防御-程序员宅基地

文章浏览阅读243次。0x00 简介权限滥用漏洞一般归类于逻辑问题,是指服务端功能开放过多或权限限制不严格,导致攻击者可以通过直接或间接调用的方式达到攻击效果。随着物联网时代的到来,这种漏洞已经屡见不鲜,各种漏洞组合利用也是千奇百怪、五花八门,这里总结漏洞是为了更好地应对和预防,如有不妥之处还请业内人士多多指教。0x01 背景2014年4月,在比特币飞涨的时代某网站曾经..._使用物联网漏洞的使用者

Visual Odometry and Depth Calculation--Epipolar Geometry--Direct Method--PnP_normalized plane coordinates-程序员宅基地

文章浏览阅读786次。A. Epipolar geometry and triangulationThe epipolar geometry mainly adopts the feature point method, such as SIFT, SURF and ORB, etc. to obtain the feature points corresponding to two frames of images. As shown in Figure 1, let the first image be ​ and th_normalized plane coordinates

开放信息抽取(OIE)系统(三)-- 第二代开放信息抽取系统(人工规则, rule-based, 先抽取关系)_语义角色增强的关系抽取-程序员宅基地

文章浏览阅读708次,点赞2次,收藏3次。开放信息抽取(OIE)系统(三)-- 第二代开放信息抽取系统(人工规则, rule-based, 先关系再实体)一.第二代开放信息抽取系统背景​ 第一代开放信息抽取系统(Open Information Extraction, OIE, learning-based, 自学习, 先抽取实体)通常抽取大量冗余信息,为了消除这些冗余信息,诞生了第二代开放信息抽取系统。二.第二代开放信息抽取系统历史第二代开放信息抽取系统着眼于解决第一代系统的三大问题: 大量非信息性提取(即省略关键信息的提取)、_语义角色增强的关系抽取

10个顶尖响应式HTML5网页_html欢迎页面-程序员宅基地

文章浏览阅读1.1w次,点赞6次,收藏51次。快速完成网页设计,10个顶尖响应式HTML5网页模板助你一臂之力为了寻找一个优质的网页模板,网页设计师和开发者往往可能会花上大半天的时间。不过幸运的是,现在的网页设计师和开发人员已经开始共享HTML5,Bootstrap和CSS3中的免费网页模板资源。鉴于网站模板的灵活性和强大的功能,现在广大设计师和开发者对html5网站的实际需求日益增长。为了造福大众,Mockplus的小伙伴整理了2018年最..._html欢迎页面

计算机二级 考试科目,2018全国计算机等级考试调整,一、二级都增加了考试科目...-程序员宅基地

文章浏览阅读282次。原标题:2018全国计算机等级考试调整,一、二级都增加了考试科目全国计算机等级考试将于9月15-17日举行。在备考的最后冲刺阶段,小编为大家整理了今年新公布的全国计算机等级考试调整方案,希望对备考的小伙伴有所帮助,快随小编往下看吧!从2018年3月开始,全国计算机等级考试实施2018版考试大纲,并按新体系开考各个考试级别。具体调整内容如下:一、考试级别及科目1.一级新增“网络安全素质教育”科目(代..._计算机二级增报科目什么意思

conan简单使用_apt install conan-程序员宅基地

文章浏览阅读240次。conan简单使用。_apt install conan