☰
机械臂控制入门:Ubuntu 22.04 + ROS 2 Humble 下 MoveIt2 从零部署与避坑指南
2026/9/28 7:47:28 网站建设 项目流程

很多人做机械臂控制,第一个想跑的demo就是MoveIt2自带的Panda机械臂。热度最高的问题永远是那几个:Ubuntu 22.04上到底怎么装MoveIt2?装完为什么RViz里动不了?Plan出来了为什么执行没反应?我这次把从零部署的完整流程拆开讲,顺便把最容易踩的版本坑、环境变量坑、launch文件坑都标记出来。这篇指南适合已经装好Ubuntu、想在本地把MoveIt2完整跑起来的人,不管是后面接真实机械臂,还是先做仿真和算法验证,这套流程都能兜住底。

1. 版本选型先行:MoveIt2与Ubuntu、ROS 2之间的对应关系

1.1 为什么首选Ubuntu 22.04 + Humble + MoveIt2的组合

很多朋友一上来就踩坑,原因不在于命令敲错,而在于版本混用。MoveIt2不是独立运行的软件,它寄生在ROS 2之上,而ROS 2又绑定具体的Ubuntu版本。这三者的关系就像一个地基、楼体和装修:Ubuntu是地基,ROS 2是楼体骨架,MoveIt2是里面的机械臂控制装修。地基不匹配,后面全白干。

截至我写这篇指南,Ubuntu 22.04 + ROS 2 Humble + MoveIt2是生态最成熟、社区资料最多、预编译二进制最完整的组合。MoveIt2官方持续集成主要跑的就是Humble分支,遇到问题在GitHub Issues和ROS Answers里搜,基本都能找到答案。相比之下,Ubuntu 24.04 + Jazzy虽然也算新组合,但很多第三方驱动、仿真插件还没有完全跟上来,如果只是为了学部署和跑demo,没必要当小白鼠。

需要提醒的是,MoveIt2和经典的MoveIt 1代是两个世界。MoveIt 1基于ROS 1,跑在Ubuntu 20.04和Noetic上;MoveIt2从底层改成ROS 2风格,节点、话题、参数系统、launch机制全部重写了。如果你以前只玩过MoveIt 1,看这篇时要先清空旧经验,别用roslaunch和rosparam的思维方式去套MoveIt2。

1.2 版本对应关系速查

我整理了一张表,建议保存下来:

Ubuntu版本ROS 2发行版MoveIt2支持状态适合场景
22.04Humble官方主推,二进制齐全新手学部署、跑demo、接真实机械臂
20.04Foxy支持但偏旧,部分包停更老项目维护,不推荐新开坑
24.04Jazzy支持,资料较少想尝鲜,能接受自己翻源码解决问题
22.04Iron/Iron Irwini中期版本,已停止维护不推荐

Humble是LTS版本,维护周期长,这是它成为默认选择的核心原因。MoveIt2的二进制包、教程包、docker镜像全部围绕Humble做同步验证。Linux发行版每两年一个大版本,ROS 2的LTS节奏也差不多,选Humble基本意味着未来几年内不会因为系统升级而被迫重装环境。

1.3 部署前快速自查版本兼容性

装好ROS 2之后,在动手装MoveIt2之前,先跑两个命令确认基础环境:

# 检查ROS 2发行版信息 printenv ROS_DISTRO # 检查ROS 2核心命令是否可用 ros2 --help

如果printenv ROS_DISTRO输出的不是humble,说明你的环境变量来源有问题。常见情况是之前装过其他版本ROS,.bashrc里叠加了多个source语句,导致系统不知道你当前要用哪个发行版。这种事我在帮人排查时见过太多次,后面在环境变量小节我会单独展开。

还有个小技巧:装完MoveIt2后可以用ros2 pkg list | grep moveit快速确认哪些包已经就位。如果输出了一长串moveit_*开头的包名,说明安装成功;如果只有零星几个,一定是源没配对或者安装过程被中断了。

2. 装好ROS 2 Humble:键盘上最不能省的几步配置

2.1 locale 与 apt 源配置

ROS 2对locale有要求,官方文档建议使用UTF-8。这一步很多人忽略,结果后续编译时频繁报奇怪的字符编码错误。执行以下命令:

sudo apt update && sudo apt install locales sudo locale-gen en_US en_US.UTF-8 sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 export LANG=en_US.UTF-8

装完建议重启终端或者重新登录,让locale全局生效。对于中文用户来说,这一步尤其重要,否则某些ROS 2工具链在打印日志时会出现编码问题,报错信息也会变得不可读。

接下来是ROS 2软件源。官方源在国内访问速度不稳定,我推荐直接换成清华或者阿里云的镜像源。以清华源为例,配置方式是在/etc/apt/sources.list.d/ros2.list里写入:

deb [arch=amd64 signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] https://mirrors.tuna.tsinghua.edu.cn/ros2/ubuntu jammy main

然后把ROS 2的GPG key加到系统信任列表:

sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg sudo apt update

注意URL里的路径,GitHub的raw地址在某些网络环境下可能抽风。如果你在sudo apt update时一直报错,可以尝试用代理或者稍后再试,我遇到过好几次是临时网络问题,换个时段就正常了。

2.2 安装桌面版而不是基础版

ROS 2 Humble的安装包分为几个档次,核心命令是:

sudo apt install ros-humble-desktop

有些教程图省事,只装ros-humble-ros-base,这个包只包含最小通信核心,不带RViz、不带常用可视化工具。做MoveIt2机械臂控制demo,RViz是核心交互界面,你总不能在命令行里盯着关节角度数字去想象机械臂姿态。所以务必装desktop版本。

如果想用MoveIt2的图形化配置工具,还需要单独装:

sudo apt install ros-humble-moveit sudo apt install ros-humble-moveit-setup-assistant

moveit-setup-assistant是后面做自定义机械臂配置的入口,现在一起装好省得后面再找。另外建议顺手装下colcon和ROS 2开发工具:

sudo apt install python3-colcon-common-extensions ros-dev-tools

colcon相当于ROS 1时代catkin_make的进化版,后面源码编译MoveIt2时要用到。ros-dev-tools提供rosdep、vcs等辅助命令,这些涉及源码依赖解析,属于绕不开的工具。

2.3 source环境变量的坑:不要重复叠加

安装完成后,需要把ROS 2环境加载到当前终端:

source /opt/ros/humble/setup.bash

每次开新终端都要source一遍很烦,所以大家习惯把它写进.bashrc。但问题来了:如果你以前装过其他版本,或者自己工作区编译过包,.bashrc里可能有多行source,顺序一旦乱掉,环境变量互相覆盖,就会出现明明装了Humble、printenv ROS_DISTRO却输出别的发行版的诡异情况。

我建议的.bashrc写法,放在文件的最后:

source /opt/ros/humble/setup.bash # 如果编译了自己的工作区,在下面加一行 # source ~/ws_moveit2/install/setup.bash

这里有个优先级问题:自己的工作区要放在ROS 2基础环境之后source,这样工作区里的包会覆盖系统同名包,后续修改源码调试时才会生效。放反了会导致系统包把你自定义的包版本遮蔽掉,改了代码半天不起作用。

3. MoveIt2安装的两种姿势:apt二进制与源码编译怎么选

3.1 apt二进制安装:五分钟跑起来的实测体验

在ROS 2基础环境装好之后,安装MoveIt2二进制版只需要一条命令:

sudo apt install ros-humble-moveit

这条命令会拉取一组预编译的moveit核心包,包括moveit_ros_planning、moveit_ros_planning_interface、moveit_ros_perception、moveit_kinematics等,覆盖规划、运动学、碰撞检测等核心模块。二进制包的好处是省去了编译时间,依赖关系由apt自动处理,装完基本就能用。

但要注意一点:apt二进制版本默认不带机械臂的demo配置包。也就是说,你装好之后并不能直接ros2 launch一个Panda出来,因为二进制包只有引擎,没有车型。这就涉及到我下面要讲的第二种姿势,以及配套的教程仓库。

3.2 源码编译:工作区结构与依赖处理

源码编译MoveIt2其实没想象中可怕,但需要一点耐心。我推荐的方式是建一个独立的ws_moveit2工作区,避免和系统环境混在一起:

mkdir -p ~/ws_moveit2/src cd ~/ws_moveit2/src git clone https://github.com/ros-planning/moveit2.git -b humble git clone https://github.com/ros-planning/moveit2_tutorials.git -b humble

注意分支一定指定humble,默认分支可能对应较新的ROS 2版本,直接拉下来编译会有一堆API不兼容问题。clone完成后,MoveIt2官方提供了一个.repos文件,里面声明了所有依赖仓库的地址和版本:

cd ~/ws_moveit2 vcs import src < src/moveit2/moveit2.repos

然后解析依赖并安装:

rosdep update rosdep install --from-paths src --ignore-src -r -y

--from-paths src指从src目录读取所有包,--ignore-src表示在apt源里找依赖而不是从本地源编译,-r是跳过解析失败的包继续往下走,-y自动确认。这几步做下来基本能补齐所有系统级软件依赖。

最后编译:

cd ~/ws_moveit2 colcon build --event-handlers desktop_notification- status- --cmake-args -DCMAKE_BUILD_TYPE=Release

--event-handlers desktop_notification- status-是为了减少编译终端输出,不让日志刷屏;-DCMAKE_BUILD_TYPE=Release开启编译优化,否则运行速度会明显偏慢。

3.3 编译过程中常见的卡点和内存经验

源码编译MoveIt2最常见的几个问题,我一个个遇到过的都列出来:

第一,内存不够。MoveIt2里moveit_task_constructor、moveit_ros_visualization这几个包编译时特别吃内存,4G内存的虚拟机很容易直接OOM卡死。建议至少8G内存,如果条件不允许,可以单独编译某个包:

colcon build --packages-select moveit_task_constructor --cmake-args -DCMAKE_BUILD_TYPE=Release

第二,rosdep解析失败。某些包在rosdep规则里引用了不在默认源里的依赖,-r参数会跳过它们,但后续编译可能报缺少头文件。解决方式是根据报错信息手动apt install对应开发包,然后在rosdep数据库里补一下规则。

第三,网络问题导致vcs import失败。vcs import拉取的是GitHub仓库,偶发超时是正常的。断点续拉的方式是重新执行一遍同样的命令,vcs会跳过已经存在的目录。所以不用担心拉一半坏了,多试几次就行。

3.4 我的建议:先二进制后源码

如果是第一次部署,目标只是跑通demo、了解MoveIt2玩法,我强烈建议先走apt二进制路线,配合moveit2_tutorials源码仓库使用。具体的组合是:

sudo apt install ros-humble-moveit mkdir -p ~/ws_moveit2/src cd ~/ws_moveit2/src git clone https://github.com/ros-planning/moveit2_tutorials.git -b humble cd ~/ws_moveit2 colcon build --cmake-args -DCMAKE_BUILD_TYPE=Release

这样编译的只有tutorials包,不涉及MoveIt2主体,五分钟就能编完,同时能拿到Panda机械臂的demo配置。如果需要改MoveIt2源码再做全量编译,再把moveit2.git仓库clone进src目录重编。

我的亲身体会是,全量编译一次MoveIt2在性能好的机器上要30到45分钟,加上排错时间一个下午就没了。对新手来说,这个时间投入不值得,不如先跑通再说。等你真正需要修改规划器插件、调试底层算法时,再回头编译源码,那时你已经熟悉整体结构,遇到问题也知道去哪查,效率高得多。

4. 跑通Panda机械臂demo:从ros2 launch到RViz里Plan & Execute

4.1 用moveit2_tutorials自带demo启动

按照3.4的组合装好之后,source环境变量,然后执行:

source /opt/ros/humble/setup.bash source ~/ws_moveit2/install/setup.bash ros2 launch moveit2_tutorials demo.launch.py

这条命令会启动一个完整的仿真环境:加载Panda机械臂的URDF模型、启动机器人状态发布节点、加载MoveIt2规划管线、打开RViz可视化界面。整个过程如果没有任何报错,你会看到屏幕上出现一个Panda机械臂,旁边有一个MotionPlanning面板。

这里有个容易混淆的点:demo.launch.py并不是MoveIt2主体包提供的,而是教程仓库里的启动脚本。它的作用是帮你组装一个最小可运行系统,把URDF、SRDF、规划配置、RViz配置全部串联起来。如果你以后有了自己的机械臂包,也需要做类似的事情。

4.2 RViz里MotionPlanning面板的正确打开方式

demo启动后RViz默认布局一般已经加载好MoveIt2的MotionPlanning插件。但如果你手动添加面板,要在RViz顶部菜单点 Panels -> Add New Panel,选择moveit_ros_visualization下的MotionPlanning。

这个面板是整个demo的中枢,核心区域分几块:

  • Planning Group:选择机械臂的规划组,Panda默认有panda_arm和panda_arm_hand等,demo里选panda_arm即可。
  • Start State:规划起始状态,一般保持current,表示从当前关节位置开始。
  • Goal State:目标状态,这里可以输入关节角度,也可以点击RViz中的运动学标志拖拽末端姿态。
  • Plan & Execute:先规划再执行,也可以分开点,先Plan预演,确认无误再Execute。

你可以在RViz里用鼠标拖动机械臂末端的交互标记,直接把末端拖到一个目标位置,然后点 Plan & Execute。如果一切正常,机械臂会在仿真环境里划出一条规划好的轨迹,然后跟随轨迹运动。

这个交互反馈非常直观,也是大多数人对MoveIt2的第一印象来源。但我要提醒一点,拖拽末端时不要拖太猛,尤其不要拖到机械臂自碰撞或者超出关节极限的位置,否则规划器会因为找不到合法路径而报错,新手就以为是环境坏了,其实只是目标不可达。

4.3 高频报错与排查表

demo跑不起来时,错误五花八门,但归纳下来最核心的就这几类:

现象根因解决办法
RViz里看不到机械臂模型robot_description参数没加载成功检查demo.launch.py里URDF路径是否正确,确认launch日志无报错
点Plan没反应Planning Group选错或机器人状态没发布确认面板里选了panda_arm,用ros2 topic list查看是否有/joint_states发布
报错 Failed to find planning pluginOMPL插件库没加载检查是否有ompl_planning.yaml配置,确认moveit_ros_planning的插件XML路径
执行时机械臂不动仿真控制器没启动或轨迹执行接口没连接确认demo.launch.py是否包含了模拟控制器节点,换用ros2 node list检查节点状态
launch时报找不到包环境变量没source工作区重新执行source ~/ws_moveit2/install/setup.bash

4.4 如何确认规划与执行真的成功

很多人看到机械臂动了就以为万事大吉,其实MoveIt2 demo运行是否正常,要从三个层面验证:

第一,topic层面。打开新终端,运行:

ros2 topic echo /display_planned_path

规划成功后,这个topic会发布moveit_msgs/msg/DisplayTrajectory消息。如果你能看到消息内容,说明MoveIt2的规划结果已经正常发布。再运行:

ros2 topic echo /joint_states

这个topic来自机器人状态发布器,会以固定频率发布当前关节角度。如果这个topic一直在刷,说明机械臂状态链路完整。

第二,控制台日志层面。demo终端会输出类似Planning request received、planning succeeded、Execution started的日志。注意观察有没有Waiting for execute callback之类的提示,这往往意味着轨迹发了但无人接收,是控制接口的问题。

第三,交互反馈层面。规划成功后,RViz里会显示一段绿色的轨迹线,执行过程中可以看到机械臂跟随这条线运动。如果你发现轨迹线规划出来了但执行时机械臂纹丝不动,优先检查模拟控制器的状态参数:

ros2 param get /move_group execute_trajectory

参数返回true才是正常。这个参数在真实机械臂对接时也有参考价值,别忽略。

5. 把demo换成自己的机械臂:URDF与MoveIt Setup Assistant的关键处理

5.1 用MoveIt Setup Assistant生成自定义配置包

官方demo跑通只算热身,大部分人的实际需求是把MoveIt2部署到自己的机械臂上。这是从demo到产品化最关键的一步,也是MoveIt2最核心的能力:只要提供一个合格的URDF,MoveIt Setup Assistant就能自动生成一套完整的配置包。

启动配置工具:

ros2 launch moveit_setup_assistant setup_assistant.launch.py

界面启动后选Create New MoveIt2 Config,加载你的URDF文件。这里要求的是xacro文件也可以,但建议在加载前先用xacro预处理成纯URDF,减少变量解析带来的问题。预处理命令:

xacro robot.xacro > robot.urdf

强烈建议先做这步,因为Setup Assistant对xacro的include路径处理比较脆弱,经常出现找不到宏定义的情况。转成纯URDF你就能专心检查模型本身。

5.2 URDF坐标系与关节类型检查清单

在导入URDF前,先自查几个关键点,否则后面配置规划组时会遇到各种莫名奇妙的问题:

  • 关节类型:MoveIt2的规划组只认revolute、prismatic、continuous这三种可动关节。如果用到fixed关节,它把两个link刚性连接,这本身没问题,但如果你想对它做运动规划就会报错。
  • 关节axis方向:每个旋转关节必须设置正确的axis,比如0 0 1表示绕Z轴旋转。这个值错了,Kinematics求解出来的姿态会完全不对。
  • link碰撞属性:每个link最好都有collision标签,即使简化为几何体也行。完全没有碰撞信息的link,碰撞检测时会默认认为它永远不与其他物体碰撞。
  • 单位:URDF默认使用米和弧度,不要用毫米和角度,否则导出的配置没法用。

我第一次导入自己画的机械臂时,单独每个环节看着都对,但Setup Assistant里选完规划组后,RViz里的模型直接崩溃。排查下来发现是一个旋转关节的axis写成了0 1 0,实际应该绕Z轴,导致运动学树结构错乱。这种问题通常只能靠肉眼检查URDF或逐个关节做正运动学验证来定位。

5.3 规划组、预定义位姿、控制器配置

在Setup Assistant里需要重点配置三块内容:

Planning Groups:设置规划组时,把机械臂的所有可动关节选进一个组,命名要直观,比如arm_group。同时设置运动学求解器插件,一般默认选kdl_kinematics_plugin/KDLLinearSolver即可。如果你的机械臂自由度较高,比如七轴、九轴,后面可以再装TRAC-IK插件来提高求解成功率。

Pre-defined Positions:这里可以预设一些常用位姿,比如home、vertical、carry等。设置好后可以在RViz里通过下拉菜单快速切换目标状态,调试时非常方便。记住初始位置home最好和URDF建模时的零位一致,否则每次启动demo机械臂会先跳到奇怪的姿态。

ROS 2 Controllers:这里配置的是轨迹控制器。仿真阶段选JointTrajectoryController,并填写对应的关节名称。生成的配置文件里会包含一个ros2_controllers.yaml,描述控制器的类型、命名空间和关节列表。如果是直接生成模拟控制器,Setup Assistant还会顺便生成一个模拟硬件节点的launch片段。

配置完成后点击Generate Package,生成的MoveIt2配置包会放在你指定的目录。这个包包含了config、launch、srdf等关键目录,相当于一套为你的机械臂量身定制的控制配置。

5.4 编译并跑起自己的机械臂demo

把生成的配置包放到工作区src目录,编译:

cd ~/ws_moveit2 colcon build --packages-select 你的机械臂包的名称 source install/setup.bash

一般配置包里会自带demo.launch.py启动脚本,直接运行:

ros2 launch 你的机械臂包的名称 demo.launch.py

如果配置正确,你会看到自己的机械臂出现在RViz里,MotionPlanning面板也能正常显示规划组和位姿。注意,像Panda自带的MoveIt2教程包一样,配置包本身只做规划和可视化,不包含真实硬件的驱动。要想连真实机械臂,必须另写硬件接口节点,把关节命令发给伺服驱动器。

6. demo到真实硬件之间,还差着这套机制认知

6.1 规划器插件与运动学解算器

MoveIt2能跑通demo,全靠背后一串插件机制。理解这层机制,才能从"照着教程按按钮"变成"出了问题知道去哪里排查"。

规划器插件:demo默认使用OMPL(Open Motion Planning Library)里的RRTConnect算法。OMPL不是一个算法,而是一个算法库,MoveIt2通过插件机制加载它。配置文件里可以看到:

planning_plugin: ompl_interface/OMPLPlanner

如果后面遇到复杂约束规划,可以给规划组配置多个算法,比如RRTStar、PRM、LBKPIECE等,根据场景选择。在ompl_planning.yaml里,每个规划组下面都可以配置一组planner_configs,指定不同算法的参数。初学者不用急着调参,默认配置对大多数六轴机械臂的demo场景已经够用。

运动学解算器:规划时要判断某个末端位姿是否可达,需要运动学求逆解。MoveIt2的默认插件是KDL,它的特点是通用、稳定,但对某些特殊构型可能存在奇异点附近求解失败的问题。如果你发现MoveIt2频繁报IK failed,可以考虑安装TRAC-IK:

sudo apt install ros-humble-trac-ik-kinematics-plugin

然后在配置包里把运动学插件类型改成trac_ik_kinematics_plugin/TRAC_IKKinematicsPlugin。TRAC-IK在某些场景能把求解成功率从百分之六七十提升到百分之九十以上。

6.2 碰撞检测的两种模式

MoveIt2的碰撞检测底层是FCL(Flexible Collision Library)。碰撞检测分为两种典型模式:自碰撞检测和环境碰撞检测。

自碰撞检测检查机械臂本身各link之间是否互相穿透,比如前臂和后臂是否打架。默认情况下MoveIt2允许相邻link之间不做碰撞检测,因为相邻关节的link在物理上本来就连接在一起。配置在SRDF文件的disable_collisions标签里。如果这个标签配置不当,要么机械臂会规划出看起来没问题实际会自撞的轨迹,要么相反地,因为某些link被错误标记为碰撞,导致没有任何可行路径。

环境碰撞检测则检查机械臂与外部物体(比如桌子、工件)是否碰撞。demo里没有外部环境,所以这块感知不出来。在真实场景中,可以通过加载一张环境点云或物体模型,让MoveIt2把环境也纳入碰撞空间计算。常见做法是使用Octomap更新occupied_cells_map,把传感器点云转成八叉树地图,放到PlanningScene里参与碰撞检测。

6.3 ros2_control与FollowJointTrajectory对接

这是从demo走向真机最关键的一步。你在RViz里点的Execute,最终不是直接驱动硬件,而是把规划好的轨迹打包成FollowJointTrajectory的Action Goal,发送给一个轨迹执行控制器。

MoveIt2侧的相关话题是:

/joint_trajectory_controller/follow_joint_trajectory/_action/action_goal

真实硬件接法通常是通过ros2_control,它负责管理硬件抽象层和控制器。迁移到真实机械臂时,你需要做的是:

  • 写一个ros2_control硬件插件,封装你机械臂的串口或EtherCAT通信。
  • 把MoveIt2配置包里的控制器命名改成你实际起的控制器名字。
  • 确认MoveIt2和ros2_control之间的话题名匹配。

我见过很多项目卡在这一步:RViz里仿真一切正常,一接真机就发现话题对不上,或者Action接口的命名空间不一致。排查方法很简单,用ros2 action list看看当前有哪些Action Server,再用ros2 action info查看它们的类型,确保MoveIt2期待看到的接口和实际运行的接口一致。这是一个非常实用的诊断命令,值得记下来。

6.4 从仿真到真机的信号链路

最后再从头到尾梳理一遍信号链路,这对理解整套系统非常有帮助。

在demo中,从一个目标姿态到机械臂真正运动,经过的节点是:运动规划请求进入move_group节点,加载OMPL规划器在配置好的规划组里搜索路径,生成joint轨迹,然后通过FollowJointTrajectory的Action发送给模拟控制器,模拟控制器更新关节状态,再由robot_state_publisher发布tf和joint_states,让RViz渲染显示。

真实硬件只是把链路最后一段换掉:模拟控制器换成真实控制器节点,它接收同一个Action Goal,把关节角度转换成伺服指令发给电机,然后从编码器读回实际关节角,继续发布joint_states。这条链路上任何一环断裂,都会出现"RViz轨迹正常、真实机械臂不动"或者反过来的问题。

我还想提醒一个细节,就是MoveIt2的move_group节点有一个参数叫move_group/allow_trajectory_execution,如果这个参数是false,即使规划成功也不会执行。官方demo里经常会打开演示模式,真实部署时容易踩到。检查一下这个参数,能少排查半小时。

跑完全流程之后,我个人最大的感受是:MoveIt2部署看似命令复杂,但只要理解了"版本组合、环境编译、launch组装、机制对接"这四层逻辑,整条链路其实非常清晰。建议你在跑通Panda demo之后,一定要花点时间自己导出一次自定义机械臂配置包,哪怕只是拿简化的两轴模型练手。那次完整走完Setup Assistant的经验,能帮你省掉后续真机联调时90%的基础提问时间。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询