域描述
该 common 子目录包含节点和库,其功能由 Autoware.Auto 系统中的许多包共享。 中心页面
mpark_variant_vendor
这是 mpark_variant_vendor 包装的设计文件。 这个包是在 mpark::variant 这里找到的一个简单的包装器: https ://github.com/mpark/variant
神经网络设计
目的/用例
该软件包为使用它们进行推理的软件包提供了预编译的神经网络。
设计
神经网络被编译为 Model Zoo CI 管道的一部分,并保存到 S3 存储桶中。 DOWNLOAD_ARTIFACTS 在设置变量 时构建此包时下载并安装它们。
用户可以通过这个包提供自己编译的网络,或者通过创建一个 user 目录并使用相同的目录结构来覆盖预编译的网络。
结构如下:
├── ${ARCH 1}
│ ├── ${型号1}
│ │ ├── ${BACKEND 1}
│ │ │ ├── deploy_graph.json
│ │ │ ├── deploy_lib.so
│ │ │ ├── deploy_param.params
│ │ │ └── 推理)_engine_tvm_config.hpp
│ │ └── ${BACKEND ...}
│ │ └── ...
│ └── ${MODEL ...}
│ └── ...
└── ${ARCH ...}
└── ... |
预编译的网络仅在第一次构建此包时下载。 要重新触发下载步骤,用户可以删除包的构建目录。
假设/已知限制
构建时需要互联网连接。
输入/输出/API
输入:
- DOWNLOAD_ARTIFACTS 需要设置变量以启用下载工件
输出:
- neural_networks_NETWORKS_DIR 包含网络根目录路径的变量
- neural_networks_NAMES 包含可用网络列表的变量
API:无
错误检测和处理
构建包不会失败。 如果没有可用于目标架构的模型,则会显示一条日志消息。
安全注意事项
预编译的网络是从 S3 存储桶下载的,并受到欺骗、篡改和拒绝服务的威胁。 使用 https 连接可以减轻欺骗。 篡改和拒绝服务的缓解措施留给 AWS。
用户提供的网络安装在主机系统上。 用户负责保护他们提供的有关信息披露的文件。
相关问题
- #721:Autoware.auto 中的机器学习推理框架
噪声模型设计
目的/用例
卡尔曼滤波器(请参阅状态过滤(状态估计) )所需的构建块之一 是过程噪声模型。 在本文档中,我们涵盖了有关如何对噪声进行建模以及本项目中使用哪些方法的不同方法的相关文档。
设计
所有噪声模型都遵循定义在 中的奇怪重复模板模式 (CRTP) 接口 autoware::common::state_estimation::NoiseInterface ,该接口本质上允许将以下函数与遵循此接口的任何噪声模型一起使用:
自动 协方差( const std::chrono::nanoseconds & dt) const ; |
由于该接口是按照 CRTP 模式实现的,因此实现该接口的所有类都必须实现一个函数,该函数 crtp_covariance 返回给定状态向量的过程噪声协方差。 在内部,这个函数将从 NoiseInterface 类中调用。
目前实现的具体实现:
以下是有关其实施的详细信息。
均匀噪声模型
该类 autoware::common::state_estimation::UniformNoise 实现了统一噪声的简单模型。 它接收不同变量的方差或完整的协方差矩阵,并在内部存储此协方差,并在查询协方差时返回(并按经过时间缩放)。
维纳噪声模型
该类 autoware::common::state_estimation::WienerNoise 实现了所谓的维纳噪声模型(参见 此处 以供参考)。 它背后的核心思想是用户只指定加速度的噪声,并且这种噪声通过运动模型传播到其他低阶变量。
错误检测和处理
待定
未来的扩展/未实现的部分
如果需要,可以实现更多的运动模型
OSQP 库的接口
这是 osqp_interface 包装的设计文件。
目的/用例
该软件包为 OSQP 库 提供了 C++ 接口。
设计
该类 OSQPInterface 将问题公式化为特征矩阵和向量,将这些对象转换为 C 风格的压缩列稀疏矩阵和动态数组,将数据加载到 OSQP 工作区数据保持器中,并运行优化器。
输入/输出/API
该接口可以通过多种方式使用:
- 初始化没有数据的接口。 在优化调用中加载问题公式。 osqp_interface = OSQPInterface(); osqp_interface.optimize(P, A, q, l, u);
- 用数据初始化接口。 osqp_interface = OSQPInterface(P, A, q, l, u); osqp_interface.optimize();
- 通过修改优化运行之间的问题公式来进行热启动优化。 osqp_interface = OSQPInterface(P, A, q, l, u); osqp_interface.optimize(); osqp.initializeProblem(P_new,A_new,q_new,l_new,u_new); osqp_interface.optimize();
优化函数将优化结果作为向量返回。
std::tuple<std::vector<double>, std::vector<double>> 结果 = osqp_interface.optimize(); std::vector<double> 参数 = std::get<0>(result); 双 x_0 = 参数 [0]; 双 x_1 = 参数 [1];
参考/外部链接
相关问题
参考跟踪控制器设计
目的/用例
这个包旨在提供一个通用 API 和一些简单控制器的通用实现,例如 PID 控制器。 这些控制器的目的是提供一维信号的简单反馈控制。
设计
提供了一个简单的界面。 实现可能是有状态的或无状态的。 如果需要多维输入或输出,则应提供不同的 API,或者应扩展提供的 API。
API 可以在 API 文档 中看到。
假设/已知限制
此 API 当前假定一维输出和一维输入,可能具有单个导数。
如果没有提供导数,则假定它们为零(即零阶保持)。
输入/输出/API
API 可以在 API 文档 中看到。
内部工作/算法
目前,这个包只包含一个没有逻辑的接口定义。
错误检测和处理
目前,这个包只包含一个没有逻辑的接口定义。
安全注意事项
参考/外部链接
未来的扩展/未实现的部分
相关问题
信号滤波器设计
目的/用例
一些算法或组件具有(合理地)平滑变化的输入信号的隐含假设。 另一种看待这一点的方式是,一个组件可能对不同的频域有不良响应。
为了避免这些不良响应,重要的是使用滤波器(在信号处理意义上)来拒绝、去除或衰减信号中的某些频率。
设计
提供了一个简单的界面。 假定此接口的实现是有状态的和离散时间的。
API 可以在 API 文档 中看到。
基类有一些输入清理逻辑,因此实现不需要重新实现这个逻辑。
此外,为了便于使用,使用了标准多态性。 这是合理的,因为这些过滤器旨在与车辆接口一起处理最多达到 100 Hz 的数据。 如果需要这些过滤器以更高的速率处理数据,则应直接使用子类或应实施旨在提高速度的专用过滤器。
过滤器接受一个 Clock 模板参数。 这样做的目的有两个:
- 无需重构即可提供对各种时钟的支持(即稳定与挂钟)
- 确保基于 time_point 的 API 不与基于持续时间的 API 混合
提供了基于持续时间的 API 和基于 time_point 的 API(彼此专有),以支持用户可能拥有的不同用例。
假设/已知限制
此 API 当前假定一维输出和一维输入。
如果需要多维输入或输出,则应提供不同的 API,或者应扩展提供的 API。
假定此接口的实现是有状态的和离散时间的。
输入/输出/API
API 可以在 API 文档 中看到。
内部工作/算法
目前,这个包只包含一个没有逻辑的接口定义。
错误检测和处理
基类确保以下不变量成立:
- 输入数据不是 NAN 或 INF
- 时间步长为正
使用 SFINAE 可防止用户混合 API 调用,可能导致过滤器处于不一致状态。
还要注意确保仅在异常逻辑之后才对程序状态进行修改,以提供强大的异常保证。
安全注意事项
安全专家待定
参考/外部链接
现代过滤器 包括:
未来的扩展/未实现的部分
相关问题
状态和变量
目的/用例
动机
任何形式的状态估计都需要一种表示状态的形式。 一个常见的选择是以某种数组的形式表示状态。 例如,由变量 X 、 Y 、组成的状态将由 Z 大小为 3 的状态向量表示。这是一个有用的视图,但缺乏表达能力,并且在访问变量时会导致代码出现问题。 此外,这种表示过于通用,因为无法区分表示 X 、 Y 、 Z 和例如 roll 、 pitch 的状态向量 yaw - 两者都将实现为大小为 3 的向量。
提议的设计
在这个包中,状态是通过具体类型的变量来表示的。 基本上,任何从简单标签结构继承的东西 autoware::common::state_vector::Variable 都是一个变量。 有一个伴随的特征可以证明这一点。 然后可以将变量类型作为模板参数提供给状态类型。
这允许然后使用 autoware::common::state_vector::CommonState 类型来实例化这个具体类型化的状态。 现在代表不同变量的状态实际上将具有不同的类型。 在幕后,这种状态的一个实例仍将拥有一个适当大小的向量来存储其值。 然后可以通过索引或变量查询这些值。 当前实现还提供了文件中常用的变量 common_variables.hpp 和文件中常用的状态 common_states.hpp 。
示例用法
结构 X : 变量{}; 结构 X_VELOCITY : 变量{}; 结构 Y : 变量{}; 结构 Y_VELOCITY : 变量{}; 结构 偏航:角度变量{}; 使用 状态 = FloatState<X, X_VELOCITY, Y, Y_VELOCITY, YAW>; 状态 状态{}; state.at<X_VELOCITY>() = 1.0F; state.at<Y_VELOCITY>() = 1.0F;
参考
#865 - 重新设计卡尔曼滤波器类层次结构
状态过滤(状态估计) 目的/用例
为了平滑传入的测量,通常使用概率滤波器。 这些有不同的味道。 仅举几个常见的选项,有(扩展)卡尔曼滤波器、无味卡尔曼滤波器或粒子滤波器。 这些中的每一个都有其优点和缺点。 在这个包中,我们实现了一个通用的过滤器接口( autoware::common::state_estimation::StateEstimationInterface )和一些具体的实现。
当前实现的过滤器有:
设计
设计的基石是 autoware::common::state_estimation::StateEstimationInterface ,它定义了这个过滤器的具体实现可以实现的许多功能。 该接口是模板化的,因此遵循奇怪重复模板模式 (CRTP) 模式,以允许使用具体类型并避免需要指针以使过滤器实现具有多态性。
从本质上讲,实现所提议接口的每个过滤器都将具有许多功能:
自动预测(const std::chrono::nanoseconds & dt);
模板<类型名测量T>
自动更正(常量MeasurementT和测量);
模板<类型名StateT >
无效重置(常量StateT 和状态,常量类型名 StateT ::Matrix 和协方差);
自动和状态();
const auto & state() const ;
自动和协方差();
const auto & covariance() const ; |
因为该接口遵循 CRTP 范式,所以实现该接口的类不会直接实现类似 correct 和的函数 predict ,而是实现 crtp_ 由接口调用的内部函数(这里是带前缀的)。
这里期望 MeasurementT 类实现 autoware::common::state_estimation::MeasurementInterface 类,而 StateT 类是 autoware::common::state_estimation::GenericState 类的特化。 (扩展)卡尔曼滤波器设计
autoware::common::state_estimation::KalmanFilter 中声明 的类 kalman_filter.hpp 实现了 autoware::common::state_estimation::StateEstimationInterface .
为了创建卡尔曼滤波器类的实例,用户必须提供 autoware::common::state_estimation::MotionModelInterface 和 autoware::common::state_estimation::NoiseInterface 类的实例。 然后将这些用于实现 crtp_predict 和 crtp_correct 功能。
警告 在 issue #944 关闭之前,角度不会被包裹在状态中。
扩展卡尔曼滤波算法
形式上,此包中的卡尔曼滤波器实现使用以下算法。 让 x 表示某个对象的当前状态。 除此之外,矩阵 S 是测量该状态不确定性的协方差矩阵。 此外,令 f 为非线性转移函数,其雅可比为 F ,不确定性由矩阵 Q 测量。 类似的逻辑适用 于以潜在非线性方式 观察状态 x的测量函数 h 。 换句话说,这个函数给定一个未知状态 \hat{x} 从这个状态产生一个测量值。 这个函数同样有一个雅可比行列式,这里用 H表示 .
卡尔曼滤波器迭代地重复以下步骤:
- 及时预测当前状态及其协方差
- 给定对环境的嘈杂观察,它估计它的预测必须纠正多少
- 计算校正状态和协方差
更正式地说,向量 m 表示真实世界的观察, R 表示其协方差:
\begin{对齐} x_\mathrm{预测} &= f(x) \\ S_\mathrm{预测} &= FSF^\top + Q \\ \\ i &= m - h(x_\mathrm{预测} ) \\ S_i &= H S_\mathrm{预测} H^\top + R \\ K &= S_\mathrm{预测} H^\top S_i^{-1} \\ \\ x_\mathrm{修正} &= x_\mathrm{预测} + K i \\ S_\mathrm{校正} &= (I - KH) S_\mathrm{预测}, \\ \end{对齐}
在这里, I 是单位矩阵, i 是“创新”(直观地说:预测测量与观察到的测量相差多远), S_i 是创新协方差。 帮助“决定”如何校正状态并直观地“加权”当前状态预测的确定性与测量确定性的核心组件是“卡尔曼增益”,在此表示 为 K。
错误检测和处理
该接口是静态的,因此可以在编译时捕获大多数错误。 Sensible static_assert 分散在整个代码中,以便及早捕获编程错误并提供有意义的编译错误。
未来的扩展/未实现的部分
它 autoware::common::state_estimation::StateEstimationInterface 足够通用,可以实现不同 类型 的过滤器。 想到的有:
如果需要,计划在未来进行。
相关问题:
状态估计节点
目的/用例
我们需要一个用于 Autoware Auto 中状态估计的节点。 该节点使用 kalman_filter 包作为主干。
假设
现在我们假设跟踪发生在 2D 中并且使用恒定加速度运动模型。
请注意,传出消息将在与传入消息相同的时间参考帧中加上时间戳,并且我们假设所有为传入消息加上时间戳的时钟都已正确同步。 此外,卡尔曼滤波器预测将发生在由第一个接收状态和预测之间的预期间隔初始化的稳定时间网格上。
输入输出
输入是更新基础滤波器估计预测的测量值。 目前,该节点支持以下输入:
- geometry_msgs/msg/PoseWithCovariance - 提供位置和方向
- autoware_auto_geometry_msgs::msg::RelativePositionWithCovarianceStamped - 提供位置
- geometry_msgs/msg/TwistWithCovariance - 提供速度测量
- nav_msgs/msg/Odometry - 提供位置和速度测量
警告 frame_id 所有传入消息 的s 必须与 frame_id 作为参数提供给该节点的匹配。 发布节点的任务是在正确的帧中提供数据。 假设所有消息都测量同一帧的状态,即 child_frame_id 所有传入消息的 a 都是相同的。 对于没有 child_frame_id 字段的消息,用户有责任强制这些消息与其他消息一样测量同一帧的状态。
该节点可以有多个主题,这些主题必须通过参数进行配置。
状态估计器提供以下输出:
- 过滤的位置、方向和线性和角速度,如 用户可以重新映射 nav_msgs/msg/Odometry 的主题。 filtered_state
笔记 我们在这里只关注带时间戳的消息。
实施细节
该节点的核心功能位于 KalmanFilterWrapper 类中。 要初始化这个类,我们需要以下内容:
- 一个正方形(通常是对角线)矩阵,其中包含我们的状态变量的方差
- 过程噪声的矩形矩阵。 例如,对于一维情况,它可以是 [0, 0, 1],这意味着加速度上只有噪声。
- 过滤器更新之间的预期时间。 如果使用基于计时器的方法,这用于初始化我们期望节点发布预测的时间网格。
- 拒绝异常值测量的马氏距离
- 我们在 EKF 内部使用的运动模型。
这个类提供了一个高级接口来在底层使用可能不同的卡尔曼滤波器实现,通过这个类的模板参数配置它们。 它支持卡尔曼滤波器的所有经典操作,例如预测、更新(在这种情况下来自 ROS 消息)以及将状态及其协方差作为 ROS 消息获取。
笔记 过滤器在看到有状态观察之前不会预测状态。 之后,它按预期工作。
处理无序测量的历史
所有“事件”(例如重置、测量更新、预测)都存储在事件历史中。 它按时间组织为队列。 每当一个新事件到达时,它就会被放入队列中由其时间戳指示的位置,并且现在在队列中较晚的事件在当前事件之上“重播”,从而更新队列中的最后估计状态。 例子
假设我们有最多 5 个事件的历史记录。 事件可以是重置 ( R )、预测 ( P ) 和更新 ( U )。 事件存储在按其时间戳排序的历史记录中,并且为每个事件分配一个状态向量,表示该时间戳 ( S0 - S8 ) 处的状态。
假设历史当前处于以下配置中:
时间戳:0 2 4 6 8
事件:---R----P----U----P----P--->
状态:S0 S2 S4 S6 S8
然后,在时间 5 会有一个新的更新,如下所示:
时间戳:0 2 4 6 8
事件:---R----P----U----P----P---> ^ ü
历史记录只能保存 5 个事件,因此必须删除最旧的事件并插入新的事件。 考虑到时间 5 的新观察,以下所有事件将更新其伴随状态。更新的状态在下图中用 S6' 和 S8' 表示:
时间戳:2 4 5 6 8
事件:---P----U--U--P----P--->
状态:S2 S4 S5 S6' S8'
笔记
严格来说, 基于历史的更新意味着过滤器的输出 不是连续的。 然而,不连续性可能小到可以忽略不计。 如果事实证明并非如此,我们将需要选择更复杂的方法来处理无序测量。
TVM 实用程序
这是 tvm_utility 包装的设计文件。 有关如何为 YOLOv2 Tiny 构建测试的说明,请参阅 YOLOv2 Tiny Example Pipeline 。 有关存储测试工件的位置的信息,请参阅 TVM Utility Artifacts 。
目的/用例
一组 c++ 实用程序,可帮助构建基于 TVM 的机器学习推理管道。 该库包含一个有助于构建管道的管道类和许多机器学习中常见的实用功能。
设计
Pipeline Class 是编写推理管道的标准化方法。 管道类包含 3 个不同的阶段:预处理器、推理引擎和后处理器。 提供了推理引擎阶段的 TVM 实现。
输入/输出/API
前处理器和后处理器需要用户在实例化流水线之前实现。 您可以在此example_pipeline 中查看示例用法 。
管道中的每个阶段都有一个 schedule 函数,该函数将输入数据作为参数并返回输出数据。 一旦管道对象被创建, pipeline.schedule 就会被调用来运行管道。
诠释 主要(){
create_subscription<sensor_msgs::msg::PointCloud2>( "points_raw" ,
rclcpp::QoS{1}, [ this ]( const sensor_msgs::msg::PointCloud2::SharedPtr msg)
{pipeline.schedule(msg);});
} |
输出
- autoware_check_neural_network cmake 宏检查是否存在特定的网络和后端组合
后端
model_zoo.hpp 为了获得目标模型/后端组合的 TVM 配置结构, 预计将包含相关包。 用于进行推理的后端可以通过设置 NETWORKS_BACKEND 为编译定义来指定。 它默认为 llvm .
错误检测和处理
std::runtime_error 每当遇到错误时都应该抛出。 它应该填充适当的文本错误描述。
安全注意事项
输入和输出都由同一个参与者控制,因此以下安全问题超出了范围:
将数据泄露给另一个参与者需要 TVM 或允许读取任意内存的主机操作系统存在缺陷,这本身就是一个重大的安全缺陷。 对于早期操作管道的外部参与者也是如此:只有启动管道的对象才能运行方法来接收其输出。
拒绝服务攻击可能使目标硬件无法用于其他管道,但需要能够在 CPU 上运行代码,这已经允许更严重的拒绝服务攻击。
此软件包不需要提升特权。
未来的扩展/未实现的部分
未来的软件包将使用 tvm_utility 作为感知堆栈的一部分来运行机器学习工作负载。
相关问题
https://gitlab.com/autowarefoundation/autoware.auto/AutowareAuto/-/issues/721
https://gitlab.com/autowarefoundation/autoware.auto/AutowareAuto/-/issues/677
vehicle_constants_manager
这是 vehicle_constants_manager 包装的设计文件。
目的/用例
该库提供了一个用于保存车辆特定常量的结构。 它还提供了一个帮助方法来声明已经传递给节点的车辆特定常量并提供一个 VehicleConstants 对象。
设计
提供 VehicleConstants 的结构包含车辆参数。 它的参数可以分为两类:(变量的详细描述和单位在 vehicle_constants_manager.hpp 文件中。)
- 主要常数
- 轮半径
- 轮宽
- 轮距
- wheel_tread
- 悬垂前端
- 悬垂后部
- overhang_left
- 悬垂右侧
- 车辆高度
- cg_to_rear
- 轮胎转弯刚度
- 轮胎转弯刚度_后n_per_deg
- mass_vehicle
- 惯性偏航公斤米2
- 派生常数
- cg_to_front
- 车辆长度
- 车辆宽度
- offset_longitudinal_min
- offset_longitudinal_max
- offset_lateral_min
- offset_lateral_max
- offset_height_min
- offset_height_max
构造 VehicleConstants 函数使用主要参数进行初始化。
该库还提供了一种 declare_and_get_vehicle_constants 方法。 使用该方法,用户可以声明已经传入节点的车辆参数并获取一个 VehicleConstants 对象。
假设/已知限制
该库假定车辆是使用 Ackermann 转向几何定义的。
declare_and_get_vehicle_constants 方法要求传递的节点覆盖以下参数:
(注意 vehicle 命名空间)
车辆:
轮子半径:
轮宽:
轮距:
轮距:
悬垂前端:
悬垂后部:
悬垂左侧:
悬垂右:
车辆高度:
cg_to_rear:
轮胎转弯刚度_前n_每度:
轮胎转弯刚度_后n_per_deg:
mass_vehicle:
惯性偏航公斤米2: |
输入/输出/API
的构造函数 VehicleConstants 采用主要的车辆常量并生成派生参数。
declare_and_get_vehicle_constants 方法接受一个 rclcpp::Node 对象。 VehicleConstants 如果成功则 返回一个对象。
示例用法:
// 在一个节点的构造函数中,它从一个接收到主要车辆参数的节点
// .yaml 文件或运行 args。
auto vehicle_constants = declare_and_get_vehicle_constants (* this ); |
内部工作/算法
无法使用。
错误检测和处理
该 VehicleConstants 结构在构造时执行一些完整性检查。
std::runtime_error 如果某些参数为负数或 cg_to_rear 大于 wheel_base (以确保重心在前后轴内) ,它将抛出。
安全注意事项
待定。
参考/外部链接
无法使用。
未来的扩展/未实现的部分
无法使用。
相关问题
https://gitlab.com/autowarefoundation/autoware.auto/AutowareAuto/-/issues/1294
二维凸多边形相交
两个凸多边形的交点可以在下图中显示为蓝色区域:
目的/用例
计算两个多边形之间的交集在场景理解的许多应用中很有用。 它可用于估计碰撞检测、形状对齐、形状关联以及处理感知代理周围对象的任何应用程序。
设计
(Livermore, Calif, 1977) 提到以下关于凸多边形相交的观察:
- 两个凸多边形的交点是凸多边形
- 包含在另一个多边形中的多边形的顶点是相交形状的顶点。 (上图中的顶点 A、C、D)
- 包含在另一个多边形中的多边形的边是相交形状的边。 (上图中的边缘CD)
- 两个多边形之间的边相交是相交形状中的顶点。 (上图中的顶点 B、E。)
内部工作/算法
通过上述观察,当前算法以以下方式运行:
- 计算并找到包含在另一个多边形中的每个多边形的顶点(顶点 A、C、D)
- 计算并找到每个多边形之间的交点(Verties B, E)
- 通过逆时针排序来计算由这些顶点形成的凸包。
输入/输出/API
输入:
- 包含按逆时针方向排序的凸多边形顶点的两个可迭代对象。
输出:
未来的工作
相关问题
|