要说速腾16线雷达配FAST-LIO2这件事,我前前后后折腾了两个礼拜,中间踩过的坑比吃的盐还多。网上也不是没有教程,但要么只讲驱动,要么只讲算法,能直接把“速腾16线雷达 + FAST-LIO2 + ROS Melodic”串起来跑通的保姆级文章,我是真没找到。所以这篇我决定把自己从零开始的完整过程写下来,包括驱动怎么配、源码怎么编译、launch和yaml怎么改、外参怎么设、建图效果漂移了怎么排查,全部一次讲透。
这篇文章适合什么读者?就是你手里有一台速腾RS-LiDAR-16或者类似的多线机械雷达,电脑上装好了Ubuntu 18.04和ROS Melodic,想跑FAST-LIO2做实时定位建图,但对着GitHub仓库不知道从哪下手的人。如果你已经能正常看到雷达点云,但不清楚怎么把数据喂给FAST-LIO2,这篇同样适合你。我默认你懂最基本的ROS命令,比如roscore、roslaunch、rostopic,不需要你是大佬,但别完全没见过终端。
先说结论:速腾16线完全能跑FAST-LIO2,但前提是搞清楚三个关键点。第一,雷达驱动必须输出标准的sensor_msgs/PointCloud2话题,并且话题格式要符合FAST-LIO2对机械雷达点云的预期;第二,除了雷达,你还必须有一个IMU,因为FAST-LIO2是激光惯性紧耦合里程计,没有IMU它启动都起不来;第三,launch和yaml文件里的参数必须改对,尤其是lidar_type、scan_line、topic名称和外参,任何一个不对,效果都会非常拉胯。下面我开始一步步说。
1. 项目全貌与准备
1.1 速腾16线雷达和FAST-LIO2是什么
先捋一下这两个主角。速腾RS-LiDAR-16是RoboSense家非常经典的一款16线机械式激光雷达,水平360度扫描,垂直视角大概30度(上下各15度),测距范围在20厘米到150米左右,点频约30万点每秒,默认通过以太网UDP协议输出点云。它在户外机器人和低速无人车上用得很多,因为性价比高、装车简单。
FAST-LIO2是香港大学MaRS Lab开源的激光惯性里程计,全称是Fast LiDAR-Inertial Odometry,核心思路是用迭代扩展卡尔曼滤波器把激光雷达点云和IMU数据紧耦合在一起,一边算状态估计一边更新ikd-Tree维护的地图。相比LOAM这类纯激光里程计,它的优势是运动畸变处理更好、初始化快、地图局部精度高,而且对计算资源要求比较友好。
这两者搭配起来很自然:速腾16线提供三维点云,IMU提供角速度和加速度,FAST-LIO2把两者融合,输出雷达位姿和增量地图。实际测试下来,在室内和园区场景,只要参数调对、运动不过分剧烈,效果能做到比较稳定的厘米到分米级精度。当然你要指望它像多线高精雷达那样做超大场景的全局地图,那不太现实,但做实时定位建图是完全够用的。
1.2 软硬件环境清单
我这次使用的环境是:
- 笔记本电脑一台,CPU是i7-8750H,内存16GB,核显就够,不需要独显
- Ubuntu 18.04.5,ROS Melodic完整版(ros-melodic-desktop-full)
- 速腾RS-LiDAR-16一台,用的是在线网络连接模式,不是离线pcap包
- IMU用的是自制的MPU6050模块,通过Arduino转串口发ROS消息,话题名/imu/data,消息类型sensor_msgs/Imu,频率200Hz
- 雷达和电脑用网线直连,雷达默认IP 192.168.1.200,电脑手动设置IP为192.168.1.102
需要注意,FAST-LIO2的代码对ROS版本要求其实不高,Melodic和Noetic都能编译。但是驱动部分如果你用RoboSense官方新版rslidar_sdk,它对ROS版本有一些严格要求,Melodic没问题。如果你的系统是Ubuntu 20.04 + ROS Noetic,驱动部分可能要换用更新的SDK版本,这个后面细说。
1.3 动手前必须搞懂的四个概念
动手之前,我先讲几个绕不开的概念,搞懂它们能帮你少走很多弯路。
第一是点云话题消息类型。驱动输出的点云话题,消息类型通常是sensor_msgs/PointCloud2。FAST-LIO2接收的话题类型在官方代码里也兼容PointCloud2,所以关键在于设置正确的topic名称,比如/rslidar_points或者/velodyne_points,只要两边对上就行。
第二是lidar_type参数。FAST-LIO2预处理代码里用整数区分不同雷达的点云结构:0代表Livox系列,1代表Velodyne这类机械旋转雷达,2代表Ouster。速腾16线本质上也是机械旋转雷达,点云排列方式和Velodyne类似,所以一般设置lidar_type为1。如果你的点云时间戳格式特殊,可能还需要改preprocess代码,但大多数情况下用1就行。
第三是点云的时间戳类型。FAST-LIO2做运动畸变补偿时,需要知道每个点是在扫描周期内的哪个时刻采到的。机械雷达消息里,每个点的相对时间通常存在PointCloud2的time字段(PointXYZIRT格式有time),如果你的驱动输出的是不带每点时间的PointXYZI,那FAST-LIO2只能用默认方式近似,也就是把一次扫描里的点都安排到0到0.1秒的时间跨度里,这个需要和驱动配置配合好。
第四是外参。雷达和IMU之间的安装位置关系,用旋转矩阵和平移向量表示,定义在FAST-LIO2的yaml文件里。如果外参不准,里程计会漂移,严重时甚至崩掉。稍后我会仔细讲怎么设。
2. 驱动安装:把速腾16线点云跑起来
2.1 驱动版本怎么选
RoboSense官方的雷达驱动有好几个版本,最常用的是rslidar_sdk和老的rslidar_pointcloud dDriver。我自己推荐用rslidar_sdk,它是官方新出的统一SDK,支持RS16、RS32、RS80、RS128这些型号,同时支持在线和pcap离线模式,编译方式简单,ROS集成度也好。
老版的rslidar_pointcloud是围绕rslidar_msgs和rslidar_driver拆分的,比较旧,在新系统上编译经常遇到protobuf或者Boost版本问题。所以如果你没有历史包袱,直接用rslidar_sdk。到我现在写的时候,rslidar_sdk的稳定版本是1.5.x,GitHub地址是RoboSense-LiDAR/rslidar_sdk。
2.2 编译rslidar_sdk
先把驱动代码克隆到工作空间。我习惯建一个catkin_ws,然后在src目录下放代码。
cd ~/catkin_ws/src git clone https://github.com/RoboSense-LiDAR/rslidar_sdk.git cd rslidar_sdk git submodule update --init --recursiverslidar_sdk依赖YAML库。如果你不是用catkin直接编译,而是单独cmake,需要先装libyaml-cpp-dev。但我们用ROS catkin方式编译时,也有可能会遇到找不到yaml-cpp的情况,所以先装依赖:
sudo apt-get install libyaml-cpp-dev cd ~/catkin_ws catkin_make source devel/setup.bash编译过程中如果报找不到ROS头文件,确认你已经source过/opt/ros/melodic/setup.bash。如果报找不到yaml-cpp,确认libyaml-cpp-dev装好了,并且在CMakeLists.txt里能看到对yaml-cpp的find_package。
2.3 修改雷达驱动配置
rslidar_sdk的配置文件在rslidar_sdk/config/rslidar_config.yaml。我的配置大概长这样:
common: frame_id: rslidar lidar_type: RS16 time_sync_en: false pcap_file: "" driver: lidar_type: RS16 msop_port: 6699 difop_port: 7788 lidar_ip: 192.168.1.200 host_ip: 192.168.1.102 pcap: false ros: ros_recv_port: 6699 pointcloud_topic: /rslidar_points pointcloud_type: 0 frame_id: rslidar需要解释几个关键项:
- lidar_type:填写RS16,SDK会根据这个值选择对应的解析协议。
- msop_port和difop_port:保持默认6699和7788,不要随便改。重点是把lidar_ip改成雷达本机IP,host_ip改成你电脑的IP。如果找不到雷达,多半就是这两个IP没配对。
- pointcloud_topic:输出点云的话题名,后面FAST-LIO2要用同一个名字。
- pointcloud_type:0代表输出的点云包含XYZI字段,1代表包含XYZIRT字段(也就是每个点带时间戳和反射率)。这里要注意,如果你希望FAST-LIO2能利用逐点时间做畸变补偿,建议把pointcloud_type设为1,输出PointXYZIRT格式。但FAST-LIO2的通用机械雷达写法,读取的是point.x,y,z和intensity,以及它内部的time结构。实测中pointcloud_type=0也能跑,但我们后面会聊到时间戳问题。
改好配置后,用launch启动驱动:
roslaunch rslidar_sdk start.launch这里有个坑:rslidar_sdk的launch文件名叫start.launch,不是rslidar_sdk.launch。启动后,用 rostopic hz /rslidar_points 查看,如果正常应该看到10Hz左右的点云频率。再用rviz订阅/rslidar_points,选择Fixed Frame为rslidar,就能看到点云了。
2.4 网络配置和常见启动失败问题
雷达和电脑之间是用网线直连还是经过交换机,配置思路不太一样。我建议直连,简单可靠。
首先要设置电脑的静态IP。Ubuntu 18.04上我用netplan,配置如下:
# /etc/netplan/01-network-manager-all.yaml network: version: 2 renderer: NetworkManager ethernets: eth0: dhcp4: no addresses: - 192.168.1.102/24然后 sudo netplan apply 让配置生效。接着查看网卡状态,确保IP地址已经变成192.168.1.102。这时候再ping雷达的IP:
ping 192.168.1.200能ping通就说明链路没问题。如果ping不通,可以先检查网线、网口,再检查防火墙:
sudo ufw disable还有个小细节:雷达的默认IP有时不是192.168.1.200,而是192.168.1.201或者别的。如果你不确定,可以用RoboSense官方的上位机软件查看,或者在启动驱动后看终端日志,它会打印雷达的IP地址。
启动驱动后如果rviz里看不到点云,先用rostopic info /rslidar_points确认话题有没有发出消息。如果话题存在但频率是0,说明驱动没收到UDP数据,大概率是IP或者端口没对。如果话题频率正常但rviz不显示,多半是Frame ID设置问题,在rviz里把Fixed Frame改成rslidar。
3. FAST-LIO2源码编译与依赖安装
3.1 依赖准备
FAST-LIO2的编译依赖主要有ROS包、PCL、Eigen、Sophus,还有livox_ros_driver。如果你用的是原版FAST-LIO2,CMakeLists里默认会找livox_ros_driver,就算你不用Livox雷达,它也会强制要求这个包存在,否则会报找不到livox_ros_driver。我第一次编译就被这个卡了很久。
我的解决方法是先安装livox_ros_driver,但不一定非要用它。安装方式:
sudo apt install ros-melodic-livox-ros-driver如果你的ROS版本没有这个包,可以从GitHub拉源码编译。
其他基础依赖:
sudo apt install ros-melodic-pcl-ros ros-melodic-cv-bridge libpcl-dev libeigen3-devEigen版本要注意,Ubuntu 18.04系统自带的Eigen是3.3.x,已经够用。别去折腾Eigen 3.4,反而容易出问题。
Sophus是李群李代数库,FAST-LIO2的代码里直接include了sophus/so3.h。你可以从GitHub拉取并编译安装到系统里:
git clone https://github.com/strasdat/Sophus.git cd Sophus mkdir build && cd build cmake .. make -j4 sudo make install如果你是通过git submodule方式拉到了FAST-LIO2自带的Sophus,同样要进到Thirdparty/Sophus里编译一次。
3.2 正式编译FAST-LIO2
假设你已经建好了catkin_ws:
cd ~/catkin_ws/src git clone https://github.com/hku-mars/FAST-LIO2.git cd .. catkin_make如果之前编译过rslidar_sdk,catkin_make会把所有功能包一起编译,需要多等一会儿。如果只想编译FAST-LIO2,可以用:
catkin_make --pkg fast_lio编译完成的标志是生成了devel/lib/fast_lio/fastlio_mapping这个可执行文件。
3.3 编译错误实录
下面几个错误是我实际踩过的,写出来供你对照:
错误1:找不到sophus/Sophus 解决方法:确认Sophus已经sudo make install,或者在CMakeLists里添加Sophus_DIR路径。有时还需要在~/.bashrc里加export Sophus_DIR=/usr/local/lib/cmake/Sophus。
错误2:找不到livox_ros_driver 解决方法:sudo apt install ros-melodic-livox-ros-driver,装完重新catkin_make即可。
错误3:Eigen和PCL头文件冲突 报错信息类似“Eigen/Dense: No such file or directory”。Ubuntu 18.04上我遇到过一次,原因是在include头文件顺序上出了问题。解决方法是确保CMakeLists里把Eigen的include目录放在PCL之前,不过这个属于少数情况,先不用管。
错误4:编译卡在opencv相关 报错找不到opencv2/xfeatures2d等。FAST-LIO2其实不完全依赖opencv的contrib模块,但catkin自动解析会报。我直接sudo apt install libopencv-dev解决。如果你已经装了ROS desktop-full,一般没问题。
4. 配置与运行:把速腾数据喂给FAST-LIO2
4.1 新建rslidar的launch和yaml
FAST-LIO2的launch文件在src/launch目录下,官方给了几个示例,比如mapping_avia.launch、mapping_ouster.launch。我们需要新建一个mapping_rslidar.launch,内容如下:
<launch> <node pkg="fast_lio" type="fastlio_mapping" name="fastlio_mapping" output="screen"> <rosparam file="$(find fast_lio)/config/rslidar.yaml" /> </node> </launch>然后复制一个yaml,比如从config/velodyne.yaml复制改为rslidar.yaml。我的核心配置如下:
common: lid_topic: "/rslidar_points" imu_topic: "/imu/data" time_sync_en: false preprocess: lidar_type: 1 scan_line: 16 blind: 0.5 time_scale: 1e-3 mapping: acc_cov: 0.1 gyr_cov: 0.1 b_acc_cov: 0.0001 b_gyr_cov: 0.0001 fov_degree: 360 det_range: 100.0 extrinsic_est_en: false extrinsic_T: [0.0, 0.0, 0.0] extrinsic_R: [1, 0, 0, 0, 1, 0, 0, 0, 1]这些参数的含义:
- lid_topic:雷达点云话题,和驱动输出一致。
- imu_topic:IMU数据话题,必须存在且频率不能太低,建议100Hz以上。
- lidar_type为1,对应机械旋转雷达。如果你的驱动输出每点带时间戳,可以用1;部分版本的FAST-LIO2对Livox点云做时间处理,对机械雷达则直接读取点云消息里的header.stamp和每点时间(如果有的话)。
- scan_line设为16,线数必须和雷达一致,否则预处理时按行切分点云会出错。
- blind是盲区距离,设置为0.5米,分辨率内的点被剔除,防止近处杂散点影响配准。
- time_scale用于把点云时间戳的单位换算成秒,一般机械雷达是1e-3(毫秒),Livox是1e-6(微秒)。如果你发现建图时间轴错乱,多半是这个参数不对。
- extrinsic_T和extrinsic_R分别是IMU在雷达坐标系下的平移和旋转。如果你把IMU放在雷达正上方且朝向一致,平移项可能要改,旋转为单位阵。
4.2 话题映射和IMU准备
启动FAST-LIO2前,先确认驱动和IMU节点都已经运行,并且三个话题都能正常收到数据:
- /rslidar_points,sensor_msgs/PointCloud2
- /imu/data,sensor_msgs/Imu
用rostopic echo /imu/data/header.stamp看一眼时间戳是否正确。IMU时间戳乱跳会直接导致滤波器发散,这是我们实际踩坑最重的一款。
FAST-LIO2要求IMU数据频率足够高。官方README建议至少100Hz,我的200Hz效果很好。如果你的IMU只有50Hz,也能跑,但抖动会明显一些。
如果暂时没有IMU,只靠雷达也能跑纯激光版本吗?不行,因为FAST-LIO2的传播方程依赖IMU激励。你可以用cv2_ros之类的仿真器生成虚拟IMU,但那不是真实场景。所以请务必准备一个IMU。
4.3 外参标定与配置心得
外参是FAST-LIO2最容易翻车的点。官方参数中extrinsic_T表示IMU在雷达坐标系下的平移向量,extrinsic_R是旋转矩阵,表达的是从雷达到IMU的旋转?或者说,代码里定义了:I_T_L = [extrinsic_R, extrinsic_T],表示雷达在IMU坐标系下的位姿?不同版本含义不完全一样,这里我们不纠结数学,只说怎么设。
如果你的IMU和雷达安装在一个刚性支架上,且两者大概平行,可以先用近似值。比如IMU放在雷达正上方10cm,则extrinsic_T大概就是[0, 0, 0.1]。旋转部分先设单位阵,跑起来之后如果发现方向明显不对,再翻转旋转矩阵的对应行。
注意:外参不准确会导致建图在起步阶段就迅速漂移。我第一次用外参[0, 0, 0],但我的IMU实际在y方向偏了5cm,结果地图拐弯时出现了严重的s形漂移。后来用卷尺量了一下,改成[0, 0.05, 0]之后,效果立刻正常了。
所以最省事的做法,是先用尺子量一个大概的平移量,旋转矩阵用单位阵,先让系统能跑通,再用标定工具优化。如果对旋转敏感,可以试试把外参当作可优化量,设置extrinsic_est_en为true,让FAST-LIO2在后端自动估计。但我个人经验是,外参初始误差过大时,自动估计很难收敛,甚至会让系统崩溃。建议先把大致外参估准,再考虑开自动估计。
4.4 完整运行流程
一切准备就绪后,按下面顺序启动:
终端1:
roslaunch rslidar_sdk start.launch终端2:
rosrun imu_node my_imu_node终端3:
roslaunch fast_lio mapping_rslidar.launchFAST-LIO2启动后,在终端会不断打印update及其耗时。初始几秒内,如果没有运动,它不会输出位姿;你需要拿着雷达(或者把雷达装在机器人上)小幅晃动几次,让它完成初始化。如果一切正常,会在控制台看到类似下面的输出:
[ INFO] [1700000000.123456789]: LiDAR motion start! [ INFO] [1700000000.456789012]: Update: 2.123 ms如果你是用rosbag离线测试,那就直接播放bag:
rosbag play your_data.bag注意bag里的雷达话题和IMU话题必须和yaml里一致。如果不一致,可以用rosbag play的remap功能,比如:
rosbag play your_data.bag /rslidar_points:=/lidar_points /imu_data:=/imu/data不过我还是建议直接改yaml里的lid_topic和imu_topic,一劳永逸。
运行过程中,FAST-LIO2会发布几个重要话题,包括:
- /Odometry:里程计位姿,类型nav_msgs/Odometry
- /path:轨迹,类型nav_msgs/Path
- /cloud_registered:配准后的当前帧点云
- /cloud_registered_raw:原始点云
- /map:局部地图点云
在rviz里添加/cloud_registered和/map,就能看到动态建图过程。
4.5 用rviz实时查看建图效果
启动rviz,固定坐标系选为:camera_init或body?FAST-LIO2的全局坐标系叫camera_init,虽然是激光雷达里程计,但它沿用了LOAM的命名。把Fixed Frame设为camera_init,然后添加PointCloud2显示,选择/cloud_registered,保持模式为Map,这样能看到点云一张一张拼接起来。接着添加Path或Odometry,查看轨迹是否平滑。
如果初始瞬间地图就糊成一团,先不要慌,可能是运动太快导致点云畸变,或者外参没设对。可以试着把雷达固定不动几秒后再以缓慢速度绕一圈,让初始化更稳定。实际测试中,启动时用手拿着设备在原地小幅度晃动几次,往往最有效。
5. 建图效果优化与避坑实录
5.1 建图漂移的排查方向
我做了几组实验,发现建图漂移大多源于这几类问题,按出现频率排序如下:
最常见的是IMU外参不准,通常表现为转弯时地图错位,起步阶段轨迹漂移。解决方法是用尺子量准平移量,旋转矩阵尽量用水平仪校准,或者拿标定工具做一次标定。
第二常见的是点云时间戳混乱。如果你的驱动输出的点云不带逐点时间戳,FAST-LIO2会把一帧的所有点当作同时刻采集来处理,这就会导致运动畸变补偿失效,在快速旋转时地图出现撕裂。解决方法是把rslidar_sdk的pointcloud_type设为1,输出PointXYZIRT格式,然后在驱动配置里把time_sync_en设为true,确保每点时间戳以毫秒为单位,并把FAST-LIO2的preprocess/time_scale设为1e-3。如果驱动输出的是系统时间而非雷达扫描相对时间,效果依然不好,建议参考官方FAST-LIO2对Velodyne的处理方式。
第三是扫描线数配置错误。scan_line必须与雷达线数完全一致,有次我手滑设成32,FAST-LIO2在预处理阶段把16线数据按32行切分,点云索引直接越界,程序崩溃。
第四是盲区设置过小。如果blind设置成0,近距离的尘埃和杂点会大量进入配准,导致位姿抖动。
5.2 点云类型与时间戳
这里展开讲一下点云类型。fast_lio2的源码里,预处理模块会判断lidar_type:如果是1(机械雷达),它会把收到的PointCloud2转换成PCL的PointCloud ,其中PointType定义通常包含x,y,z,intensity和time。如果你用PointXYZI的消息,time字段是0,但FAST-LIO2里对机械雷达的处理不是完全依赖time字段,而是根据点的线号和时间戳的插值来补,具体看代码里InputFeature函数。如果你不想深究代码,最简单的办法是让驱动输出点云时带上每点的时间信息。
rslidar_sdk的pointcloud_type参数:0表示输出PointXYZI,1表示输出PointXYZIRT。我们建议设1,并在启动驱动后看看topic里的字段:
rostopic echo /rslidar_points -n1输出里应该有time字段才对。如果没有,检查驱动配置。若用的是老驱动,可能这个参数不生效,需要自己改一下发布逻辑。
5.3 关键参数调优心得
我调试过程中尝试过很多组参数,下面几个改动收益最大:
- point_filter_num:这个参数在FAST-LIO2的yaml里叫point_filter_num,表示每隔多少点取一个点,默认4,我改成6之后建图速度明显加快,精度几乎没有损失。如果你的CPU较弱,可以改成10甚至16,但太大会损失细节。
- fov_degree:默认360,如果你的雷达实际水平视场不是360度(比如某些车载雷达),需要按实际设置;速腾16是360度,保持默认即可。
- det_range:默认100米,但速腾16的有效距离也差不多这样。如果你在室内小场景,可以减小到30米,减少远点噪声影响。
- extrinsic_est_en:我先设false,等外参差不多准后再设true。在室外试过开自动估计,大多数时候能收敛,但室内特征少的时候偶尔会飘。
- acc_cov和gyr_cov:这两个是IMU噪声方差。默认0.1对多数IMU都适用。如果你用的IMU噪声很大,可以稍微加大到0.2,但不要过大,否则滤波更信任雷达,容易初始化困难。
5.4 实测避坑清单
我把实际操作中最容易踩的坑整理成表格,方便你对照:
| 现象 | 大概率原因 | 解决方法 |
|---|---|---|
| 启动后无位姿输出 | IMU话题没匹配,或运动不充分 | 检查imu_topic,正常发布/imu/data,手持设备晃几下 |
| 地图快速发散 | 外参错误 | 量准平移量,旋转矩阵先设单位阵,再微调 |
| 转向时地图撕裂 | 点云时间戳异常 | 驱动输出PointXYZIRT,time_scale设为1e-3 |
| 建图卡顿严重 | CPU过载,点云太密 | 调大point_filter_num,减小det_range |
| 地图出现层叠错位 | IMU频率过低 | 提高IMU发布频率到100Hz以上 |
| 启动即崩溃,报错out of range | scan_line与实际线数不符 | 改为16,并检查预处理代码中线数读取方式 |
还有两个小技巧。第一个,录制bag时尽量让机器人先静止3秒,再缓慢启动,这能给FAST-LIO2一个稳定的IMU初始化窗口。第二个,在室外建图时,地面点会影响配准,可以在yaml里把blind调大一点,比如1.0,把近距离地面噪声剔除;或者在预处理里加一个高度过滤,但这个需要改代码,新手可以先忽略。
最后分享一个我的个人操作习惯:每次改完参数后,我会把原来的bag用同一个bag测试,并分别保存生成的点云pcd文件,用pcl_compare或者可视化工具对比效果。这样调参不会变成“玄学”,每一次改动都有数据支撑。尤其是外参,从[0,0,0]改成[0,0.05,0]这种微调整,用同一份bag测试对比轨迹误差,很快就能找到最佳值。
这个项目后续我还在继续扩展,比如用IMU预积分配合轮式里程计做室内定位,以及把FAST-LIO2输出的地图导入到navigation栈里做路径规划。如果你也在折腾同样的方案,希望这篇记录能帮你省下几天时间。有什么问题欢迎在评论区交流,我看到都会回。