智能车
Chapter 1
Definition of the Smart Vehicle
- Perception
- Autonomous Decision : brain of the vehicle (autonomously analyze, learn and decide)
- Automatic Control
Different Levels of Smart Vehicles
- L1 - driving assistance
- L2 - partially-automated
- L3 - conditional-automated
- L4 - highly-automated
- L5 - fully-automated
Perception
Sensor
- Radar(超声波雷达)
- LiDAR(激光雷达)
- RGB Camera
- GPS, IMU
Dataset Preparation
- image labeling tools
- road analysis tool
Control
-
Interactive Gaming(博弈) Algorithms
-
Protection Algorithms of In-Vehicle Network
- ECU(electronic control unit 电子控制单元) Authentication
- Encryption communication(数据加密)
-
Human Machine Interaction(人机交互)
-
Automatic Control(自动控制)
V2X Communication
- V2I (infrastructure)
- V2V (vehicle)
- V2P (pedestrian)
Energy Efficient Computing
-
Asynchronous Circuits (异步电路)
Combi Block1 -> Handshaking -> Combi Block2 -> ...
通过
Handshaking
电路实现异步数据传输 -
Synchronous Circuits (同步电路)
时序逻辑电路,通过
Clock
时钟信号实现同步数据计算
Power Consumption
-
Dynamic power dissipation
-
Leakage Power Mechanism
Compute Circuit
Simplified FPGA Architecture
- Functional Block (逻辑门)
- I/O Block (输入输出信号)
- Routing Network (导线)
Digital Systems Implement Computations on Platforms
-
Graph
- Data flow graph (DFG)
- Control data flow graph (CDFG)
-
Clock cycles
Hardware Acceleration Design Flow
-
Fixed-Point Data Type Refinement (float-point -> fixed-point)
Matlab has a useful tool.
-
Logic Optimization
-
Datapath and Controller Generation
-
FPGA Technology mapping
Chapter 2
Sensor Performance
- Range
- Resolution
- Bandwidth of Frequency
- Sensitivity
Types of error
- Systematic error
- Random error
Range Sensor
Stereo Camera
Drawback : short range
- Intrinsic calibration
- Extrinsic calibration
Time of flight
GPS (Global Positioning System)
- GPS coordinate errors
- Wrong survey (人为测量温差)
- Continental drift (大陆漂移)
IMU
-
Gray Encoder (格雷编码,用于测量旋转角度)
-
Magnetic compass (磁力计,测量磁场方向)
-
Gyroscope (陀螺仪)
- Mechanical gyroscope
- Optical gyroscope
-
Accelerator (加速度计)
-
IMU (Inertial Measurement Unit)
- IMU Error and Drift
Synchronization & Calibration
Camera Calibration
-
ROS Image Processing
-
Right Hand Coordinate System
-
Tools & Tutorials
- Camera to Camera (Stereo Camera)
- Camera to LiDAR
- Camera to IMU
- Multi-Sensor Calibration
HD Maps
- Path Planning
- Traffic Rules and Constraints
PCL (Point Cloud Library)
-
K-d tree
对于 维的数据,利用分割轴对数据进行划分,每次将分割轴上值的中位数作为新的分割轴来分割数据
-
NDT (Normal Distributions Transform)
-
Quad-tree (四叉树)
-
Oct-tree (八叉树)
Vector Maps
- OSM (Open-source-map)
Map
-
Sematic Map
-
Topologic Map
vertices and edges with coordinates
-
Voronoi Diagram
-
Geographic Information System (GIS)
NDS (Navigation Data Standard)
The worldwide standard for map data in automotive eco-systems
- Road Network Layer
Odometry (里程计)
- Non-Gaussian Error
- odometry drift
Aligning 3D Data (三维点云配准)
-
ICP (Iterative Closest Point, 迭代最近点法)
对两个长度相同的三维点集进行配准
-
Horn's Method
Semantic SLAM
Chapter 3
3D Representations
- Point Cloud
- Mesh
- Volumetric (类比图像的表示,使用三维坐标表示三维的点云,利用Conv3D进行计算)
- Implicit representation (NeRF, 使用神经网络的参数来表示点云)
- 3D gaussian
Point Clouds Feature Extraction
Challenge
- unordered point set as input (与点的顺序无关)
- invariance under geometric transformations (与位移变换无关)
PointNet
- T-Net
- MLP
- Global Max Pooling
- Local Features + Global Features
BEV (Bird's eye view,鸟瞰图)
PointP后illar
Voxel-base (体素特征)
将无序三维点云数据转换为规则体素网格,每个点包含特征:空间中点的位置坐标、局部密度信息、局部结构信息等
PolarNet (基于极坐标BEV进行卷积)
- Ring CNN (环卷积)
- Cylinder 3D
Detection
Task
- pedestrian detection
- traffic sign
Metric
-
预测是否正确 标签为真 标签为假 预测正确 TP TN 预测错误 FP FN - (在标签为真的所有样本中预测正确的比率)
- (所有预测为真的样本中预测正确的比率)
2D Detection
-
DPM: Deformable Part Model
-
R-CNN: Region CNN
最后的分类器使用的SVM
-
SPPNet: Spatial Pyramid Pooling
最后的分类器使用的SVM
-
Faster RCNN
-
FPN: Feature Pyramid Network(特征金字塔)
-
Mask R-CNN
-
YOLO (anchor-based)
-
RetinaNet
FPN + Focal loss
-
CenterNet (anchor-free)
3D Detection
- 3D-CNN
- PolarPillar
- 3D-SSD
- VoteNet
Evaluation
TSNE: t-Distributed Stochastic Neighbor Embedding (t-SNE)是一种降维技术,用于在二维或三维的低维空间中表示高维数据集,从而使其可视化
将高维数据进行降维可视化
Fusion-based methods
2D、3D特征融合(多模态融合)
- Transformer
- CLIP (Contrastive Language-Image Pre-Training,多模态预训练神经网络)
Voxel-based View Transformation
-
LSS
-
BEVDet(MLP)
-
IPM
通过数学几何运算进行图像矫正(逆透视)
Transformer-based Methods
End-to-End Model
Chapter 4
The Path Planning Problem
-
RRT (Rapidly exploring Random Tree,快速随机树搜索算法)
-
Graph Search
-
DFS (Depth first search,深度优先搜索)
-
BFS (Breadth first search,广度优先搜索)
维护一个队列,将临近的所有点都加入到队列中,然后逐个对出队的点找临近点并入队,重复上述操作
从终点回溯,i的父节点为f,f的父节点为e,e的父节点为a,这样就可以得到a到i的最短路径为:a->e->f->i
相较于DFS,BFS中使用了大量的入队、出队操作,耗时增加,但是能保证找到最优路径,DFS算法找到的并不一定是最优路径
-
Dijkstra
-
GBFS (Greedy best first search,贪婪最佳优先算法)
-
(启发式搜索算法)
评估函数:
: 从起始点到任何节点n的实际路径成本 ()
: 从起始点到目标节点n的预估成本,是一个启发式估计(与启发函数的选择有关)
的定义:
- 欧几里得距离:
- 曼哈顿距离:
-
Trajectory Planning
Kinematics(运动学) vs Kinetics(动力学)
Tire Models
- Differential gear (差速器)
Chapter 5
Simulation-Based Testing
- Scenario
- Domain Specific Language
Compiler
-
Lexeme
-
BNF
-
AST Tree
-
EBNF
-
Propositional Logic (命题逻辑)
It has a set of symbols, a syntax and a semantics
- Well-formed formula (wff)
-
Predicate Logic (谓词逻辑)
ROS2
Preparation
create workspace and package
mkdir -p ~/ros2_ws/src cd ~/ros2_ws/src ros2 pkg create --build-type ament_python <pkg_name> # 创建一个空的package cd ~/ros2_ws colcon build [--packages-select <pkg_name>] # 编译
ros2 pkg create
# ros2 pkg create ros2 pkg create --build-type ament_python <pkg_name> \ # 创建一个空的package --dependencies rclpy ... # 指定依赖
<!-- 在package.xml文件中指定需要引入的依赖 --> <exec_depend>rclpy</exec_depend> <exec_depend>std_msgs</exec_depend>
colcon build
colcon build # 编译所有packages colcon build [--packages-select <pkg_name1> ...] # 编译指定packages
CLI Tools
Topic
ros2 topic list [-t] # list all active topics # -t : with the message type of the topic
ros2 topic echo <topic_name> # show the data being published on the topic
ros2 topic info <topic_name> # show the detail information of the topic <topic_name>
ros2 topic pub [--once] [-w 1] <topic_name> <msg_type> '<args>' # publish the message '<args>' of <msg_type> to <topic_name> # --once : publish once # -w N : 表示匹配多个subscription节点
ros2 topic hz <topic_name> # show the detail information of the topic <topic_name>
ros2 interface show <msg_type> # see the details of the message <msg_type> # ex: <var_type> <var_name>
Service
ros2 service list [-t] # show all active services # -t: with the type of all services
ros2 service type <srv_name> # show the type of the serive <srv_name>
ros2 service list # show all active services
ros2 service find <srv_type> # find the services which are the type of <srv_type>
ros2 interface show <srv_type> # show the details of the service <srv_type> # ex: # <request_srv_detials> # --- # <response_srv_details>
ros2 service call <srv_name> <srv_type> <arguments> # call the service <srv_name> with arguments
Parameters
A parameter is a configuration value of a node. You can think of parameters as node settings. A node can store parameters as integers, floats, booleans, strings, and lists. In ROS 2, each node maintains its own parameters.
ros2 param list # show all parameters of all nodes(packages)
ros2 param get <node_name> <parameter_name>
ros2 param set <node_name> <parameter_name> <value>
ros2 param dump <node_name> <output_yaml_file_path>
ros2 param load <node_name> <input_yaml_file_path>
Bag
Convert ROS1 bag
to ROS2 bag
pip install rosbags rosbags-convert --src <ros1-bag> --dst <ros2-bag> # or rosbags-convert --src <ros2-bag> --dst <ros1-bag>
evo
用于评估SLAM输出的轨迹的精度,可以自动生成均值、方差、轨迹等信息的图或者表
evo_traj
evo_traj tum ... [-p] evo_traj kitti ... # -p|--plot: 输出轨迹的可视化图形
Python
publisher and subscriber
-
创建Publisher节点文件
import rclpy from rclpy.node import Node from std_msgs.msg import String, Int32 # from tutorial_interfaces.msg import Num # custom interface import time class MyPuberNode(Node): def __init__(self): super().__init__('my_puber_node') self.pub = self.create_publisher(Int32, 'topic', 10) self.timer = self.create_timer(1, self.timer_callback) self.i = 0 def timer_callback(self): msg = Int32() msg.num = self.i self.pub.publish(msg) # self.get_logger().info(f'Publishing: timestamp={time.time()})') # 发布时间戳 self.get_logger().info(f'Publishing: Int32({msg.data})') # 发布Int32类型数据 self.i += 1 def main(args=None): rclpy.init(args=args) puber = MyPuberNode() rclpy.spin(puber) puber.destroy_node() rclpy.shutdown() -
创建Subscriber节点文件
import rclpy from rclpy.node import Node from std_msgs.msg import String, Int32 # from tutorial_interfaces.msg import Num import time class MySuberNode(Node): def __init__(self): super().__init__('my_suber_node') self.sub = self.create_subscription(Int32, 'topic', self.listener_callback, 10) self.sub def listener_callback(self, msg): self.get_logger().info(f'Subscribing: {msg.data}') def main(args=None): rclpy.init(args=args) suber = MySuberNode() rclpy.spin(suber) suber.destroy_node() rclpy.shutdown() -
修改
setup.py
中的入口点entry_points={ 'console_scripts': [ 'puber = py_pubsub.test_puber:main', 'suber = py_pubsub.test_suber:main' ], }, -
编译
cd ~/ros2_ws colcon build [--packages-select py_pub_sub] -
运行
# 终端1 source install/setup.bash ros2 run py_pubsub puber # 终端2 source install/setup.bash ros2 run py_pubsub suber
函数详解:
self.create_publisher( # 创建发布节点 <msg_type>, # std_msgs.msg, 结点发布消息的类型 <topic_name>, # str,topic的名称 [<callback_function>], # function, callback函数 <queue_size> # int, 消息存储队列大小(防止subscriber节点未接收到消息) ) self.create_subscriber( # 创建订阅节点 <msg_type>, # std_msgs.msg, 结点发布消息的类型 'topic', # <listener_callback_function>, # [required] function, callback函数 <queue_size> # int, 消息存储队列大小 ) self.create_timer( # 创建计时器 <time_period>, # float, 时间间隔 <callback_function> # function, 回调函数 )
# main function def main(args=None): rclpy.init(args=args) suber = MySuberNode() # 创建节点实例 rclpy.spin(suber) # 循环执行节点 suber.destroy_node() # destroy node rclpy.shutdown() # shutdown ros2 server
service and client
-
创建Service节点
import rclpy from rclpy.node import Node from example_interfaces.srv import AddTwoInts class MyServiceNode(Node): def __init__(self): super().__init__('my_service_node') self.srv = self.create_service(AddTwoInts, 'add_two_ints', self.add_two_ints_callback) def add_two_ints_callback(self, req, resp): resp.sum = req.a + req.b self.get_logger().info(f'Request:\na: {req.a}, b: {req.b}') return resp def main(args=None): rclpy.init(args=args) srv = MyServiceNode() rclpy.spin(srv) srv.destroy_node() rclpy.shutdown() -
创建Client节点
import rclpy from rclpy.node import Node from example_interfaces.srv import AddTwoInts class MyClientNode(Node): def __init__(self): super().__init__('my_client_node') self.client = self.create_client(AddTwoInts, 'add_two_ints') self.req = AddTwoInts.Request() def send_request(self, a, b): self.req.a = a self.req.b = b self.future = self.client.call_async(self.req) rclpy.spin_until_future_complete(self, self.future) return self.future.result() def main(args=None): rclpy.init(args=args) client = MyClientNode() resp = client.send_request(40, 20) client.get_logger().info(f'Result of add_two_ints: {client.req.a} + {client.req.b} = {resp.sum}') client.destroy_node() rclpy.shutdown() -
修改
setup.py
中的入口点 -
编译并运行
函数详解:
self.create_service( # 创建service节点(接受client发送的请求,处理请求后返回响应) <srv_type>, # srv, 自定义Service的类型 <srv_name>, # str,自定义Service名称 <callback_function> # function, callback函数 ) self.create_client( # 创建client节点 <srv_type>, # srv, 自定义Service的类型 <srv_name> # str,自定义Service名称 ) self.client.wait_for_service(timeout_sec=1.)
custom msg and srv
It's better to use C++ to custom interface!
-
create new package
ros2 pkg create --build-type ament_cmake custom_interface -
create the directories of
msg
andsrv
-
msg definition
# Num.msg int64 num # Sphere.msg geometry_msgs/Point center # include package geometry_msgs float64 radius -
srv definition
# AddThreeInts.srv int64 a int64 b int64 c --- int64 sum -
CMakeLists.txt
find_package(geometry_msgs REQUIRED) find_package(rosidl_default_generators REQUIRED) rosidl_generate_interfaces(${PROJECT_NAME} "msg/Num.msg" "msg/Sphere.msg" "srv/AddThreeInts.srv" DEPENDENCIES geometry_msgs # Add packages that above messages depend on, in this case geometry_msgs for Sphere.msg ) -
package.xml
<depend>geometry_msgs</depend> <buildtool_depend>rosidl_default_generators</buildtool_depend> <exec_depend>rosidl_default_runtime</exec_depend> <member_of_group>rosidl_interface_packages</member_of_group> -
Build the package
colcon build --packages-select custom_interface -
Test
# source the env first ros2 interface show custom_interface/msg/Sphere ros2 interface show custom_interface/srv/AddThreeInts -
Implementing custom interfaces
<!-- Python package.xml --> <depend>custom_interface</depend> <!-- 导入自定义的包 -->
parameters
C++
publisher and subscriber
-
Publisher
#include <chrono> #include <memory> #include <string> #include "rclcpp/rclcpp.hpp" #include "std_msgs/msg/string.hpp" using namespace std::chrono_literals; class MyPuberCpp : public rclcpp::Node { private: size_t count; rclcpp::TimerBase::SharedPtr timer; rclcpp::Publisher<std_msgs::msg::String>::SharedPtr puber; public: MyPuberCpp() : Node("my_puber_cpp"), count(0) { puber = this->create_publisher<std_msgs::msg::String>("topic", 10); auto timer_callback = [this]() -> void { auto message = std_msgs::msg::String(); message.data = "Hello ROS2: " + std::to_string(this->count++); RCLCPP_INFO(this->get_logger(), "Publishing: %s", message.data.c_str()); this->puber->publish(message); }; timer = this->create_wall_timer(500ms, timer_callback); } }; int main(int argc, char* argv[]) { rclcpp::init(argc, argv); rclcpp::spin(std::make_shared<MyPuberCpp>()); rclcpp::shutdown(); return 0; } -
Subscriber
#include <chrono> #include <memory> #include <string> #include "rclcpp/rclcpp.hpp" #include "std_msgs/msg/string.hpp" using namespace std::chrono_literals; class MySuberCpp : public rclcpp::Node { private: size_t count; rclcpp::Subscription<std_msgs::msg::String>::SharedPtr suber; public: MySuberCpp() : Node("my_suber_cpp"), count(0) { auto topic_callback = [this](std_msgs::msg::String::UniquePtr msg) -> void { RCLCPP_INFO(this->get_logger(), "Subscribing: %s", msg->data.c_str()); }; suber = this->create_subscription<std_msgs::msg::String>("topic", 10, topic_callback); } }; int main(int argc, char* argv[]) { rclcpp::init(argc, argv); rclcpp::spin(std::make_shared<MySuberCpp>()); rclcpp::shutdown(); return 0; }
Homework
HW1
完成表中2020-2023年的数据搜集
数据参考:
https://www.dmv.ca.gov/portal/vehicle-industry-services/autonomous-vehicles/disengagement-reports/
HW2
完成车道线检测的代码
Project
评估
- Relative Translation Error (RTE)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)