从零构建具身智能体OpenClaw:分层架构与仿真到部署实践
1. 项目概述为什么我们要从零开始造一个“爪子”最近“具身智能”这个词火得不行感觉不提它就跟不上时代了。但说实话很多讨论都飘在天上讲大模型、讲通用人工智能却很少告诉我们一个能真正在物理世界里“动手”的智能体到底该怎么一步步搭起来。这就是我启动“OpenClaw”这个项目的初衷——我想亲手从最基础的代码行开始构建一个能感知、能决策、最终能操控机械臂完成抓取任务的智能体框架。它不只是一个玩具更是一个探索具身智能核心工程路径的沙盒。OpenClaw顾名思义是一个开源的“爪子”。它的目标很明确为机械臂赋予一个通用、可学习的抓取能力。这听起来简单背后却串联起机器人学、计算机视觉、强化学习、运动规划等一系列硬核技术。市面上成熟的机器人操作系统如ROS功能强大但略显笨重而许多AI研究代码又过于实验化难以直接部署。OpenClaw想走一条中间路线保持架构的清晰与轻量让开发者能快速理解每一环并方便地替换其中的模块进行实验。在具身智能的时代我们面临多种路径选择。是依赖精密的三维重建与物理仿真还是拥抱端到端的大模型直接输出动作OpenClaw的架构设计本身就是对这些问题的回答。它不会采用单一、极端的方案而是尝试一种分层、松耦合的架构让感知、决策、控制各司其职又协同工作。通过这个系列我希望不仅能分享代码更能梳理清楚在资源有限的情况下如何权衡与选择技术栈如何将前沿的AI算法落地到真实的物理交互中。无论你是机器人方向的学生还是对AI落地感兴趣的工程师相信这个“从零开始”的过程都能带来一些实实在在的启发。2. 核心架构设计构建一个分层、可演进的智能体OpenClaw的整体架构设计遵循了“高内聚、低耦合”的软件工程原则同时深度融合了机器人领域的“感知-规划-执行”范式。我们将系统自上而下分为四层应用层、决策层、控制层和硬件抽象层。这样的设计确保了系统的清晰性、可维护性和可扩展性。2.1 应用层定义任务与交互接口应用层是系统与用户或其他高级系统交互的窗口。它不关心具体的算法实现只关注“要做什么”。这一层主要包括任务编排器和对外接口。任务编排器负责解析高级指令例如“抓取桌子上的红色杯子”并将其分解为一系列可执行的子目标序列。在初期我们可以实现一个简单的基于状态机的任务解析器。例如指令会被分解为1. 识别并定位红色杯子2. 规划接近杯子的路径3. 执行抓取动作4. 将杯子移动到目标位置。对外接口则提供了系统集成的可能性。我们计划支持多种接口方式命令行接口CLI用于快速测试和调试单个功能模块。这也是为什么在相关热词中会出现openclaw gateway [openclaw] could not start the cli这样的错误搜索一个健壮、友好的CLI是开发效率的保障。Web API提供RESTful或WebSocket接口允许远程客户端如前端界面、移动应用向OpenClaw发送任务指令并接收状态反馈。这为构建可视化监控平台或与其他服务集成奠定了基础。消息总线接口兼容ROS等机器人中间件的消息格式使OpenClaw能够无缝接入现有的机器人生态系统订阅传感器话题发布控制指令。注意应用层设计应保持极简。它的核心价值是协议转换和任务描述不应包含复杂的业务逻辑。所有具体的识别、规划、控制算法都应下沉到下层。初期可以先用一个Python字典来定义任务描述协议例如{“action”: “pick”, “object”: {“color”: “red”, “type”: “cup”}, “location”: “table”}。2.2 决策层智能体的“大脑”与“小脑”决策层是OpenClaw智能性的核心体现我将其类比为生物的“大脑”高级认知和“小脑”反射与协调。这一层接收来自感知层的结构化环境信息并输出高层级的运动意图或轨迹点。“大脑”——高级策略模块这部分负责需要推理和决策的任务。我们初期将重点实现两种范式基于模型的规划Model-Based Planning当环境模型如物体的精确三维位姿、机器人运动学已知或可估计时这是最可靠的方法。我们会集成运动规划库如OMPL的Python接口根据当前机械臂状态和目标物体位姿计算出一条无碰撞的运动轨迹。这相当于一个深思熟虑的“计划”。基于学习的策略Learning-Based Policy对于难以精确建模的任务如柔性物体抓取、动态环境交互我们将引入强化学习RL或模仿学习IL。决策层此时作为一个“策略网络”输入是观测如图像、关节角输出是原始动作如关节力矩或末端位移。我们将设计一个标准的Gymnasium兼容环境方便接入各种RL算法库如Stable-Baselines3。“小脑”——反应式控制器与状态机这部分处理更底层的、快速的反应逻辑。例如抓取姿态生成器根据感知层提供的物体包围盒或点云计算出一组可行的机械臂末端执行器夹爪的预抓取位姿Approach Pose和抓取位姿Grasp Pose。这可以是一个基于规则的算法如对点云进行主成分分析PCA来估算物体朝向也可以是一个训练好的神经网络。任务状态机管理一个抓取任务的微观流程。例如状态可能包括APPROACHING接近、GRASPING闭合夹爪、LIFTING提升、RETREATING退回。决策层根据当前状态和传感器反馈如“夹爪是否已闭合到位”、“是否感受到阻力”来触发状态转移。实操心得决策层是系统中最易变、最需要实验的部分。务必通过良好的接口设计将策略模块“插件化”。例如定义一个抽象的Policy基类包含reset(observation)和step(observation)方法。这样无论是传统的规划器、PyTorch/TensorFlow模型还是未来可能接入的大语言模型LLM作为规划器都可以通过实现这个接口来接入系统极大提升了架构的灵活性。2.3 控制层将意图转化为精确动作决策层输出的是“去哪里”或“做什么”的意图控制层的职责则是精确地“执行”。它负责生成实时的、低层级的控制指令并确保执行的稳定性和安全性。运动学与动力学求解这是控制层的数学核心。我们需要实现或封装正向运动学FK根据关节角度计算机械臂末端执行器的位置和姿态。逆向运动学IK根据期望的末端位姿反解出可行的关节角度组合。这是轨迹跟踪的关键。对于常见的机械臂模型如UR、Franka我们可以使用pybullet或ikpy这样的库来求解IK。对于复杂构型或需要避障的情况可能需要采用数值优化方法。轨迹插值决策层可能只给出了几个关键路径点。控制层需要在这些点之间进行平滑插值如使用五次多项式曲线生成一串高频率的、连续的关节角度设定点以保证运动平滑。实时控制器这是与硬件周期紧密交互的部分。控制器以固定的频率如100Hz或500Hz运行在每个控制周期内读取当前关节编码器反馈实际位置。接收来自决策层的当前期望轨迹点目标位置。根据误差目标位置 - 实际位置计算控制量。最简单的可以是比例-微分PD控制更复杂的可能包含模型前馈、重力补偿等。将计算出的控制量通常是关节力矩或速度下发给硬件抽象层。安全监控控制层必须集成安全逻辑例如关节限位检查防止指令超出机械臂物理范围。奇异点规避当机械臂处于奇异构型时IK解算会失败或关节速度趋于无穷大需要检测并处理。碰撞检测通过与感知层交互或基于已知的环境模型预测并避免碰撞。紧急情况下能触发急停。2.4 硬件抽象层打通虚拟与现实的桥梁硬件抽象层HAL是隔离软件算法与具体硬件设备的关键。它的存在使得我们可以在仿真环境中开发和测试绝大部分代码然后通过更换HAL的实现就能将同样的代码部署到真实的机械臂上。仿真接口实现我们将首选 PyBullet 作为仿真环境。在HAL中我们会实现一个SimulationArm类。这个类在PyBullet中加载URDF机器人模型。实现get_joint_states()、set_joint_torques()等方法。提供与真实控制器类似的API。这样控制层以上的所有代码在仿真中运行时完全“感觉”不到自己是在跟一个虚拟环境交互。真实硬件接口实现对于真实机械臂我们需要根据其提供的SDK或通信协议如Modbus TCP、ROS驱动、EtherCAT来实现一个RealArm类。这个类通过Socket、串口或厂商库与控制器建立连接。实现与SimulationArm类完全相同的公共方法这就是抽象接口的意义。处理硬件通信特有的细节如超时重试、数据校验、心跳维护等。传感器抽象同样的原则适用于传感器。定义一个Camera抽象类然后分别实现SimulationCamera从仿真环境渲染图像和RealCamera通过OpenCV调用真实USB或网络摄像头。感知层代码只需调用camera.capture_rgb()即可无需关心数据来源。避坑指南硬件抽象层的接口设计至关重要。一旦确定上层所有模块都将依赖它。设计时要充分考虑扩展性例如未来增加力传感器、触觉传感器时应能方便地添加新的方法而不影响原有接口的稳定性。建议初期就使用Python的abc模块来定义抽象基类强制接口规范。3. 技术栈选型与关键实现细节确定了架构接下来就要选择趁手的工具并深入一些关键模块的实现细节。这里的每一个选择都经过了权衡旨在平衡性能、易用性和学习成本。3.1 编程语言与核心依赖库Python 作为主力语言这是毋庸置疑的选择。Python在AI和机器人研究领域拥有最庞大的生态系统NumPy, SciPy, OpenCV, PyTorch, TensorFlow能极大加速开发。其简洁的语法也利于快速原型验证。虽然实时性不是Python的强项但控制层的关键循环可以通过C扩展或利用numba加速而决策层和感知层对实时性要求相对宽松。核心依赖清单数值计算与数据NumPy、Pandas。所有内部数据如图像、点云、关节状态都用NumPy数组表示高效且统一。计算机视觉OpenCV。用于图像的基本处理裁剪、色彩空间转换、相机标定、轮廓检测等。它是感知层的基石。点云处理Open3D。比PCL的Python绑定更友好。用于加载、可视化、滤波、配准和分割点云数据是三维感知的关键。机器学习与深度学习PyTorch。因其动态图特性在研究和原型阶段调试更加直观。用于训练物体检测、分割以及强化学习策略网络。强化学习环境Gymnasium。提供标准的RL环境接口方便我们封装OpenClaw的仿真环境并接入主流RL算法库。物理仿真PyBullet。轻量、易用、功能强大支持刚体和软体动力学完美满足我们对机械臂运动、抓取和碰撞检测的仿真需求。运动规划OMPL(通过pybullet_planning或ompl的Python绑定访问)。用于在已知地图中进行高效的路径规划。Web与通信FastAPI。用于快速构建RESTful API。websockets库用于实现实时双向通信。如果需要兼容ROS则使用rospy。3.2 感知模块从像素到理解感知模块的目标是将原始的传感器数据RGB图像、深度图、点云转化为对场景的结构化理解主要为决策层提供“目标物体的6D位姿3D位置3D旋转”。方案选择基于深度学习的位姿估计传统方法如ICP迭代最近点匹配需要模板模型且对遮挡和初始值敏感。我们采用基于深度学习的方法它更鲁棒且能端到端地处理RGB-D数据。实现步骤数据获取与标注在PyBullet仿真环境中自动生成大量随机摆放物体的场景。通过渲染获取RGB图像、深度图和物体实例分割掩码。由于仿真环境已知物体的精确位姿和模型我们可以自动生成6D位姿标签一个3D平移向量和一个3D旋转四元数。这解决了真实数据标注成本极高的难题。网络模型选型我们将采用一种经典的两阶段架构。第一阶段使用一个CNN骨干网络如ResNet从RGB图像中提取特征并接一个检测头如类似YOLO的结构预测物体2D边界框和粗略的类别。第二阶段对于每个检测框内的区域结合对应的深度图或裁剪出的点云通过一个PointNet之类的网络回归出物体相对于相机坐标系的精确6D位姿。训练与仿真到真实迁移在仿真数据上训练模型。为了提升模型在真实世界的泛化能力需要在训练时加入大量的数据增强如随机颜色抖动、高斯噪声、模拟不同光照等。更高级的做法是使用域随机化技术在仿真中随机改变纹理、光照、背景迫使模型学习更本质的几何特征而非表面的纹理特征。注意事项位姿估计的精度直接决定抓取成功率。在评估时不仅要看旋转和平移的平均误差更要用“ADD-S”这类度量标准它计算模型点云在预测位姿和真实位姿下的平均最近点距离更能反映抓取任务中的实际影响。如果误差过大需要检查训练数据是否覆盖了足够的视角和遮挡情况。3.3 抓取规划模块如何生成一个可靠的抓取点知道了物体在哪、是什么姿态下一步就是决定“怎么抓”。抓取规划模块输入物体的点云和估计位姿输出一组候选的夹爪抓取位姿。基于采样的抓取生成这是一种简单有效的方法尤其适用于二指平行夹爪。抗动坐标系建立在物体的点云上利用PCA计算其三个主方向建立一个物体坐标系。抓取姿态采样围绕物体表面在多个预定义的接近方向通常沿物体坐标系的各轴正负方向上在合适的距离上采样夹爪的预抓取位姿。抓取质量评估对每个采样位姿进行评估。评估准则可以包括力闭合分析从夹爪与物体的接触点计算判断该抓取是否能在任意扰动下通过施加力来保持平衡这是一个理论上的充分条件。抗扰动性通过轻微扰动抓取位姿模拟抓取的稳定性。可达性结合当前机械臂的状态通过逆运动学IK判断该抓取位姿是否可达并考虑与环境的碰撞。排序与选择根据评估分数对所有候选抓取进行排序选择分数最高的作为最终输出。集成学习-based抓取评估网络为了更高效地评估抓取质量我们可以训练一个神经网络Grasp Evaluation Network。该网络以物体点云和抓取位姿表示为夹爪两个指尖在物体坐标系中的位置为输入输出一个0到1的分数表示抓取成功的概率。这个网络可以在仿真环境中通过大量“试抓”自动生成训练数据成功或失败的抓取样本来进行训练。实操心得在实际部署中不要只依赖一个“最优”抓取。应该生成一个抓取候选列表例如Top-5。当首选抓取由于运动规划失败或实时感知发现障碍物时可以快速回退到次优抓取提高系统的鲁棒性。这个候选列表可以缓存在决策层作为局部重规划的依据。4. 仿真环境搭建与系统集成测试在接触真实硬件之前一个高保真的仿真环境是我们的主战场。它能让我们安全、快速、低成本地进行算法迭代和系统集成测试。4.1 基于PyBullet的高保真仿真环境搭建我们选择PyBullet是因为它开源、易用并且提供了丰富的机器人模型和物理特性支持。环境构建步骤场景建模使用URDF或SDF格式文件定义我们的工作台场景。这包括桌面、待抓取的物体如YCB数据集中的物体模型、机械臂本身以及可能存在的障碍物。可以在Blender中建模并导出或直接使用PyBullet内置的几何体拼接。机械臂导入加载机械臂的URDF文件。URDF文件描述了机器人的连杆、关节、质量、惯性、碰撞几何体等。对于常见机械臂如UR5, Panda可以直接从开源项目获取。务必确认URDF中的关节类型旋转关节、平移关节、运动学链和坐标系定义正确。传感器模拟在仿真中创建“虚拟相机”。通过在场景中特定位置放置一个“渲染相机”设置其内参焦距、主点和外参相对于世界坐标系的位置和朝向每步仿真中可以调用pybullet.getCameraImage函数来获取RGB、深度、分割掩码图像。这完美模拟了真实RGB-D相机如Intel RealSense的输出。物理参数调校仿真的真实性很大程度上取决于物理参数如摩擦系数、 restitution弹性系数、关节阻尼和电机力/力矩极限。需要参考真实硬件数据或通过反复试验调整这些参数使机械臂的运动、物体的滑动和碰撞行为尽可能真实。代码示例初始化仿真环境与机械臂import pybullet as p import pybullet_data import time # 连接物理引擎 physicsClient p.connect(p.GUI) # 使用GUI可视化p.DIRECT用于无头模式 p.setAdditionalSearchPath(pybullet_data.getDataPath()) p.setGravity(0, 0, -9.8) # 加载地面和场景 planeId p.loadURDF(plane.urdf) tableId p.loadURDF(table/table.urdf, basePosition[0.5, 0, 0]) objectId p.loadURDF(ycb_objects/lego.urdf, basePosition[0.5, 0, 0.62]) # 加载机械臂 robotId p.loadURDF(franka_panda/panda.urdf, basePosition[0, 0, 0], useFixedBaseTrue) # 获取关节信息 numJoints p.getNumJoints(robotId) jointIndices [i for i in range(numJoints) if p.getJointInfo(robotId, i)[2] ! p.JOINT_FIXED] # 设置控制器参数位置控制模式 p.setJointMotorControlArray(robotId, jointIndices, p.POSITION_CONTROL, targetPositions[0]*len(jointIndices)) # 主仿真循环 for _ in range(10000): p.stepSimulation() time.sleep(1./240.) # 模拟实时240Hz # 在此处可以插入感知、决策、控制逻辑4.2 端到端集成测试流程当各个模块开发到一定阶段后需要在仿真中进行端到端的集成测试验证整个流水线是否通畅。测试用例设计静态抓取测试场景中只有一个静止物体。测试流程感知模块成功检测并估计位姿 - 抓取规划模块生成抓取位姿 - 运动规划模块规划出一条无碰撞轨迹 - 控制层执行轨迹 - 夹爪闭合 - 判断是否成功抓取并提起物体。多物体选择测试场景中有多个不同类别的物体。通过任务指令如“抓取红色的方块”测试应用层的指令解析和决策层的目标选择逻辑。动态避障测试在机械臂运动路径上临时加入一个移动的障碍物。测试感知模块的实时更新能力以及决策层/规划层的重规划Replanning反应速度。抓取失败恢复测试模拟一次抓取失败如夹爪滑脱。测试系统是否能检测到失败例如通过末端力传感器读数或视觉反馈并触发恢复行为如重新尝试抓取或更换抓取点。自动化测试脚本编写Python脚本来自动化运行上述测试用例。脚本应能自动设置不同的测试场景物体种类、位置、数量。运行完整的OpenClaw pipeline。记录关键数据感知误差、规划时间、执行时间、任务成功率。生成测试报告包括成功率统计和失败案例分析如哪些物体容易失败是感知错误还是规划错误。避坑指南仿真与现实的差距Sim2Real Gap是最大的挑战之一。在仿真中运行完美的算法在真实世界可能一塌糊涂。为了缩小差距除了之前提到的域随机化在仿真测试时就要有意识地引入“不完美”给相机图像添加噪声给关节控制添加延迟和抖动使用简化的碰撞几何体等。这样训练和测试出的系统才更具鲁棒性。5. 部署实践与性能调优当仿真中的成功率令人满意后就可以着手向真实硬件部署了。这一步是工程上的关键一跃会遇到许多在纯软件仿真中不曾出现的问题。5.1 从仿真到真实的平滑过渡部署的核心是更换硬件抽象层的实现。我们之前设计的抽象接口此时将发挥巨大作用。部署清单硬件准备确保真实机械臂如UR5、Franka Emika Panda、RGB-D相机如Intel RealSense D435、工控机或高性能嵌入式设备如NVIDIA Jetson已就位并完成基本的硬件连接和厂商驱动安装。实现真实硬件接口创建RealArm和RealCamera类。以UR机械臂为例通常通过TCP/IP接口UR的Primary/Secondary Client Interface进行通信。我们需要实现一个客户端按照UR的通信协议周期性地发送关节目标位置或速度并接收状态反馈。对于RealSense相机使用pyrealsense2库来获取对齐的RGB和深度图像流。校准校准再校准这是部署成功最关键的一步。手眼校准确定相机坐标系与机械臂基座坐标系或末端坐标系之间的变换关系。使用经典的Tsai-Lenz或Park-Martin方法通过让机械臂末端携带一个标定板移动到多个位姿同时拍摄标定板图像来完成。不准确的校准会导致感知到的物体位置和机械臂实际运动位置完全对不上。相机内参标定虽然相机出厂有内参但最好重新标定尤其是使用过程中可能发生的轻微镜头畸变。使用OpenCV的棋盘格标定法即可。安全第一在真实环境中首次运行前务必采取安全措施将机械臂速度/力限制调至很低操作员手持急停开关先在远离障碍物、路径空旷的情况下进行简单的点动测试验证坐标变换和运动方向是否正确。5.2 实时性与性能瓶颈分析真实系统对实时性有严格要求。我们需要分析并优化整个流水线的延迟。性能剖析步骤测量各模块耗时使用Python的time模块或更专业的cProfile在真实硬件上运行系统测量感知、决策、控制各阶段的处理时间。一个典型的抓取周期可能包括图像采集33ms 30Hz、感知推理100-200ms、运动规划50-500ms不等、轨迹执行可变。识别瓶颈通常基于深度学习的感知模块是最耗时的。运动规划在复杂环境中也可能很慢。优化策略感知优化考虑使用更轻量的神经网络模型如MobileNet作为骨干使用TensorRT或OpenVINO对PyTorch模型进行推理优化和量化如果帧率要求不高可以不必每帧都进行全流程感知而是当机械臂在移动时以更高频率运行一个轻量的目标跟踪算法只在需要时触发完整的检测和位姿估计。规划优化缓存常见的规划结果在非紧急情况下使用较长的规划时间限制以找到更优解在需要快速反应时如避障切换到快速但可能次优的规划器。异步流水线设计不要让系统串行等待。可以让感知、决策、控制运行在不同的线程或进程中。例如当控制层在执行当前轨迹时决策层已经在为下一个目标进行规划感知层也在持续采集和处理最新数据。使用线程安全的队列如queue.Queue进行模块间通信。控制频率确保控制层的运行频率如500Hz远高于机械臂的动力学响应频率以保证控制的平滑和稳定。这可能需要用C重写控制循环的核心部分或使用numba加速Python代码。实操心得在部署初期不要追求全自动运行。实现一个“单步调试”模式非常有用。在这个模式下系统每执行一个关键步骤如完成感知、生成抓取点、规划好路径后都暂停等待操作员确认。这能帮助你在出现问题时精准定位是哪个环节出了错是校准不准、感知错误还是规划失败极大提高了调试效率。6. 常见问题排查与调试心法在开发和部署OpenClaw的过程中你会遇到无数个“为什么不行”的时刻。下面是我总结的一些典型问题及其排查思路希望能帮你少走弯路。6.1 感知相关物体为什么检测不到或位姿不准问题现象仿真中完美真实场景中检测框乱飞或根本检测不到物体。排查首先检查图像输入是否正常。用OpenCV显示相机原始图像看是否有畸变、过曝或失焦。然后检查数据预处理归一化、缩放是否与训练时一致。最大的可能是域差异。仿真训练的模型无法适应真实场景的纹理、光照。解决进行域适应训练。收集少量真实数据哪怕只有几十张对模型进行微调。或者在仿真训练时使用更激进的域随机化。问题现象检测框准确但估计出的物体位姿跳动严重或明显错误。排查首先确认手眼校准绝对准确。这是位姿问题的首要怀疑对象。可以用一个固定位置的物体反复测量其估计位姿看是否稳定。如果不稳定可能是深度图质量差透明、反光物体会导致深度缺失或噪声。解决优化深度图质量调整相机参数或对深度图进行滤波如双边滤波。对于位姿网络在训练数据中增加更多遮挡和噪声增强。6.2 规划与控制相关机械臂为什么不动或运动诡异问题现象发送了目标位姿但机械臂不运动或控制器报错。排查检查逆运动学IK是否求解成功。IK求解器可能因为目标位姿超出工作空间或处于奇异点附近而失败。打印IK求解的状态和结果。检查控制指令是否成功发送到了硬件接口以及硬件接口返回的状态信息。解决为IK求解设置超时和重试机制。如果失败尝试对目标位姿进行微调或从抓取规划模块请求另一个候选抓取位姿。确保硬件接口的通信链路正常指令格式正确。问题现象机械臂能运动但轨迹不平滑有抖动或“画圈”现象。排查这通常是控制问题。检查控制频率是否足够高且稳定。检查PD控制器的增益参数P和D值是否合适P值太大会导致振荡D值太大会抑制运动。在仿真中仔细调试这些参数。解决确保控制循环在一个稳定的实时线程中运行避免被其他耗时任务阻塞。仔细调整控制器增益可以从很小的值开始慢慢增加直到响应快速且平稳。6.3 系统集成相关模块间通信为什么丢数据或不同步问题现象决策层拿到的感知数据是过时的导致规划基于错误的环境信息。排查检查各模块间数据传递的时间戳。每个数据包如图像、关节状态都应附带一个高精度的时间戳。在决策层使用数据时检查时间戳的新鲜度。解决实现一个简单的数据缓存与查询机制。例如感知模块以固定频率发布带时间戳的数据到共享内存或消息队列。决策层在需要时总是获取最新时间戳的数据或根据自己当前的时间请求最近时刻的数据。对于严格时序要求的可以考虑使用ROS的message_filters进行近似时间同步。调试心法永远采用“分而治之”的策略。将系统分解单独测试每个模块。用录制好的数据“bag文件”的概念喂给感知模块看输出是否正确。在仿真中用脚本给决策层预设一个完美的感知结果看规划和执行是否正常。最后再连接所有模块。日志记录至关重要为每个关键步骤、关键变量输出详细的日志并区分不同的日志等级INFO, DEBUG, ERROR。当问题发生时这些日志是唯一的“黑匣子”数据。