Files
acRealman_xr/docs/ubuntu22_unity_pico_udp_sender_prompt.md
2026-05-29 12:32:43 +08:00

23 KiB
Raw Blame History

Ubuntu 22.04 Unity Prompt复现 XR_RM_PICO_UDP_Sender

本文档用于在 Ubuntu 22.04 下搭建 Unity + PICO 4 Ultra Android 开发环境,并给出一份可以直接交给 Codex、Claude Code 或其他代码代理的 Unity 项目生成提示词。目标是最终做出与当前仓库中 unity/XR_RM_PICO_UDP_Sender 等价的 APK

PICO 4 Ultra 双手柄 6DoF pose / grip / trigger
  -> Unity Android APK
  -> 60 Hz UDP JSON默认发往 ROS2 主机 15000 端口
  -> xr_rm_input/udp_controller_receiver
  -> /xr/left_controller 与 /xr/right_controller
  -> xr_rm_teleop/single_arm_velocity_teleop

截至 2026-05-29当前项目事实如下

  • 当前 Unity 工程路径:unity/XR_RM_PICO_UDP_Sender
  • 当前工程版本:2022.3.16f1c1
  • 当前 PICO SDKunity/PICO-Unity-Integration-SDK-release_3.4.0
  • 当前 PICO package 引用方式:Packages/manifest.json 中使用本地路径 file:../../PICO-Unity-Integration-SDK-release_3.4.0
  • 当前默认 UDP 目标:192.168.9.89:15000
  • 当前默认发送频率:60 Hz
  • 当前 Android 包名:com.local.xr_rm_udp_sender
  • 当前 APK 名称:Builds/XR-RM-PICO-UDP-Sender.apk

1. Unity 版本选择建议

优先建议使用 Unity 2022.3 LTS而不是直接升级到 Unity 6。

原因:

  • 当前工程已经用 Unity 2022.3 系列创建。
  • PICO 官方 PICO 4 Ultra 资源页说明 PICO Unity Integration SDK 3.0 支持 Unity 2020-23Unity 6 支持仍属于计划项。
  • Unity 6 对 Ubuntu 22.04 的官方 Linux Editor 支持更清晰,但当前 PICO SDK 主线更适合 Unity 2022.3。
  • Unity 2022.3 官方系统要求页列出的 Linux Editor 发行版是 Ubuntu 20.04 和 18.04,不是 22.04;因此在 Ubuntu 22.04 上使用 2022.3 时,建议保持 GNOME + X11、使用官方显卡驱动并避免 Wayland 相关变量干扰。

推荐策略:

  1. 如果要最大程度复现当前工程:使用 Unity 2022.3.16f1 或最接近的 2022.3 LTS 国际版补丁。当前工程的 2022.3.16f1c1 是中国版编辑器标识,在 Ubuntu 国际版 Hub 中通常选择不带 c1 的对应版本或相近补丁。
  2. 如果是新建工程并希望减少 Linux/Android 构建问题:使用 Unity 2022.3.31f1 或 Unity Hub 中较新的 2022.3.x LTS 补丁,但不要升到 Unity 6除非你已经确认所用 PICO SDK 版本明确支持 Unity 6。
  3. 如果首要目标是严格官方支持 Ubuntu 22.04 Linux Editor而不是 PICO SDK 稳定性,可以评估 Unity 6但这会偏离当前项目本文后续步骤不以 Unity 6 为默认路线。

2. Ubuntu 22.04 环境准备

2.1 系统与图形环境

建议使用:

  • Ubuntu 22.04 x86_64
  • GNOME 桌面
  • X11 会话优先
  • NVIDIA 用户使用官方 proprietary driverAMD 用户使用 Mesa 驱动
  • 至少 16 GB RAM磁盘预留 40 GB 以上

检查当前会话:

echo $XDG_SESSION_TYPE

如果输出是 wayland 且 Unity Editor 或 Hub 出现黑屏、鼠标偏移、构建窗口异常,注销后在登录界面选择 Ubuntu on Xorg

如果 Unity Editor 报 Pipe error !,先在启动 Unity 的终端里执行:

ulimit -n 4096
unityhub

2.2 安装 Unity Hub

sudo apt update
sudo apt install -y curl gpg ca-certificates

sudo install -d /etc/apt/keyrings
curl -fsSL https://hub.unity3d.com/linux/keys/public \
  | sudo gpg --dearmor -o /etc/apt/keyrings/unityhub.gpg

echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/unityhub.gpg] https://hub.unity3d.com/linux/repos/deb stable main" \
  | sudo tee /etc/apt/sources.list.d/unityhub.list

sudo apt update
sudo apt install -y unityhub

启动 Hub

unityhub

首次启动需要登录 Unity 账号并激活 Personal 或其他可用 license。

2.3 安装 Unity Editor 和 Android 模块

在 Unity Hub 中:

  1. 打开 Installs
  2. 点击 Install Editor
  3. 选择 2022.3 LTS
  4. 模块必须勾选:
    • Android Build Support
    • Android SDK & NDK Tools
    • OpenJDK
  5. 安装完成后,在 Installs 页面确认对应 Editor 存在。

不要优先使用系统 Android Studio 的 SDK、NDK、JDK。Unity Android 构建最稳的方式是使用 Unity Hub 随 Editor 安装的 embedded Android SDK/NDK/OpenJDK。

2.4 安装 ADB

ADB 用于安装 APK、查看设备和抓取 logcat

sudo apt update
sudo apt install -y android-tools-adb
adb version

2.5 准备 PICO 4 Ultra

在 PICO 4 Ultra 中:

  1. 登录设备。
  2. 开启开发者模式。
  3. 开启 USB 调试。
  4. 用 USB-C 线连接 Ubuntu 主机。
  5. 在 Ubuntu 上执行:
adb devices

PICO 内会弹出 USB 调试授权,选择允许。再次执行:

adb devices

应看到类似:

<device_serial>    device

如果是 unauthorized,重新插拔 USB 并在 PICO 内确认授权。

3. 打开当前 Unity 工程

如果你是在本仓库中继续工作,目录应类似:

XR_Realman/
  docs/
  unity/
    PICO-Unity-Integration-SDK-release_3.4.0/
    XR_RM_PICO_UDP_Sender/
  xr_rm_input/
  xr_rm_teleop/

在 Unity Hub 中:

  1. 点击 Projects
  2. 点击 Add
  3. 选择:
XR_Realman/unity/XR_RM_PICO_UDP_Sender
  1. 用 Unity 2022.3 LTS 打开。
  2. 如果提示升级工程版本,先备份或确认 git 状态,再继续。

本工程的 Packages/manifest.json 依赖:

{
  "dependencies": {
    "com.unity.xr.picoxr": "file:../../PICO-Unity-Integration-SDK-release_3.4.0",
    "com.unity.xr.management": "4.4.0",
    "com.unity.modules.androidjni": "1.0.0",
    "com.unity.modules.animation": "1.0.0",
    "com.unity.modules.imageconversion": "1.0.0",
    "com.unity.modules.jsonserialize": "1.0.0",
    "com.unity.modules.unitywebrequest": "1.0.0",
    "com.unity.modules.unitywebrequesttexture": "1.0.0",
    "com.unity.modules.xr": "1.0.0"
  }
}

如果 Unity 打开后找不到 com.unity.xr.picoxr,先确认 PICO SDK 文件夹确实位于:

XR_Realman/unity/PICO-Unity-Integration-SDK-release_3.4.0

4. Android 构建设置

当前工程已经提供菜单脚本:

Assets/Editor/XrRmUdpSenderProjectSetup.cs

在 Unity Editor 菜单中依次执行:

XR-RM -> Apply UDP Sender Android Settings
XR-RM -> Create Or Refresh UDP Sender Scene
XR-RM -> Build Android APK

这些菜单会配置或刷新:

  • Product Name = XR-RM-PICO-UDP-Sender
  • Package Name = com.local.xr_rm_udp_sender
  • Android min SDK = API 29
  • Android target SDK = Auto
  • Internet permission = enabled
  • Scripting Backend = IL2CPP
  • Target Architectures = ARM64
  • Graphics API = OpenGLES3
  • XR Management Android loader = PICO PXR_Loader
  • Assets/Scenes/Main.unity
  • 场景中的 PicoControllerUdpSender 对象
  • PicoControllerUdpSenderPicoUdpConfigPanel 组件

也可以用 batchmode 构建:

cd /path/to/XR_Realman

UNITY_EDITOR="$HOME/Unity/Hub/Editor/2022.3.31f1/Editor/Unity"

"$UNITY_EDITOR" \
  -batchmode \
  -quit \
  -projectPath "$(pwd)/unity/XR_RM_PICO_UDP_Sender" \
  -executeMethod XrRmUdpSenderProjectSetup.BuildAndroidApk \
  -logFile "$(pwd)/unity_build.log"

根据你实际安装版本修改 2022.3.31f1。构建成功后 APK 在:

unity/XR_RM_PICO_UDP_Sender/Builds/XR-RM-PICO-UDP-Sender.apk

安装:

adb install -r unity/XR_RM_PICO_UDP_Sender/Builds/XR-RM-PICO-UDP-Sender.apk

5. 网络和 ROS2 联调

5.1 找到 Ubuntu 主机 IP

PICO 和 Ubuntu 主机必须在同一个局域网中。查看 Ubuntu IP

hostname -I
ip -4 addr

假设 Ubuntu 主机 IP 是:

192.168.9.89

则 Unity APK 中 Target IP 使用 192.168.9.89Target Port 使用 15000

如果启用了 UFW

sudo ufw allow 15000/udp
sudo ufw status

5.2 启动 ROS2 mock 验证链路

在 Ubuntu 的 ROS2 workspace 根目录:

source /opt/ros/humble/setup.bash
colcon build --symlink-install
source install/setup.bash

ros2 launch xr_rm_bringup arm_debug.launch.py arm:=both use_mock:=true

另开终端检查话题:

source /opt/ros/humble/setup.bash
source install/setup.bash

ros2 topic echo /xr/left_controller
ros2 topic echo /xr/right_controller
ros2 topic echo /xr_rm/left_rm75/cmd_vel
ros2 topic echo /xr_rm/right_rm75/cmd_vel

5.3 在 PICO 内配置和操作 APK

戴上 PICO 后打开 XR-RM-PICO-UDP-Sender

面板字段:

含义 推荐值
Target IP ROS2 Ubuntu 主机 IP 例如 192.168.9.89
Target Port ROS2 UDP 接收端口 15000
Send Rate UDP 发送频率 60 Hz90 Hz
Coordinates 是否转换 Unity 坐标 Project
UDP Sending 是否发送 ON
Save & Apply 保存到 PlayerPrefs 并应用 按 trigger

手柄操作:

  • 摇杆上/下:选择行
  • 摇杆左/右:调整端口、频率、坐标模式或开关发送
  • Trigger / A / X编辑当前行或触发当前行
  • B / Y保存并应用
  • Menu显示或隐藏面板
  • GripROS 侧遥操作使能;未按下时机械臂停止

验证现象:

  • 面板中 L ok / R ok 表示 Unity 能读到左右手柄。
  • UDP Sending ONROS2 的 /xr/left_controller/xr/right_controller 应持续刷新。
  • 按住 grip 并移动手柄时mock 模式下 /xr_rm/*/cmd_vel 应出现非零速度。
  • 松开 grip 后,cmd_vel 应回到零速度。

6. UDP JSON 协议

Unity APK 每个周期发送一个双手柄 JSON 包:

{
  "t": 12.345,
  "frame_id": "xr_world",
  "controllers": {
    "left": {
      "grip": true,
      "trigger": 0.0,
      "pos": [-0.12, 1.05, 0.30],
      "quat": [0.0, 0.0, 0.0, 1.0]
    },
    "right": {
      "grip": true,
      "trigger": 0.4,
      "pos": [0.12, 1.05, 0.30],
      "quat": [0.0, 0.0, 0.0, 1.0]
    }
  }
}

字段要求:

字段 类型 说明
t number Time.realtimeSinceStartupAsDouble
frame_id string 固定 xr_world
controllers.left object 左手柄
controllers.right object 右手柄
grip bool grip 使能ROS 遥操作使用它启停
trigger float 0.0-1.0
pos float[3] [x, y, z]
quat float[4] [qx, qy, qz, qw]

坐标转换必须与当前工程保持一致:

payload.pos[0] = position.x;
payload.pos[1] = position.y;
payload.pos[2] = -position.z;

payload.quat[0] = -rotation.x;
payload.quat[1] = -rotation.y;
payload.quat[2] = rotation.z;
payload.quat[3] = rotation.w;

当禁用发送或 App 退出时,必须额外发一次左右手柄 grip=false 的包,让 ROS 侧安全停止。

7. 给代码代理的 Unity 生成 Prompt

下面整段可以直接交给 Codex 或 Claude Code让它在一个空 Unity 工程中生成与当前 XR_RM_PICO_UDP_Sender 等价的项目。

你是一个 Unity + PICO 4 Ultra + ROS2 UDP 遥操作项目的代码代理。请在 Ubuntu 22.04 上可打开和构建的 Unity Android 工程中,实现一个与 XR_RM_PICO_UDP_Sender 等价的 PICO UDP 发送端。

目标效果:

PICO 4 Ultra APK 运行后读取左右手柄 6DoF pose、grip、trigger以 60 Hz 或用户配置频率向 ROS2 Ubuntu 主机发送 UDP JSON。ROS2 侧的 xr_rm_input/udp_controller_receiver 能直接解析,并发布 /xr/left_controller 与 /xr/right_controller。用户在 PICO 内可以通过世界空间 UI 面板修改 Target IP、Target Port、Send Rate、坐标转换模式、UDP Sending 开关,并保存到 PlayerPrefs。松开 grip、暂停发送或退出 App 时ROS 侧必须能收到 grip=false 或因超时安全停止。

开发环境约束:

- Unity 版本优先使用 2022.3 LTS。
- Android 平台。
- PICO 4 Ultra。
- PICO Unity Integration SDK 使用本地 package 引用。
- 不引入额外第三方依赖。
- 使用 UnityEngine.XR.InputDevices / CommonUsages 获取手柄输入。
- 使用 System.Net.Sockets.UdpClient 发送 UDP。
- 使用 Unity JsonUtility 序列化 JSON。
- 使用内置 UGUI Text/Image/Canvas 生成配置面板,不依赖 TextMeshPro。

工程结构要求:

Assets/
  Scripts/
    PicoControllerUdpSender.cs
    PicoUdpConfigPanel.cs
  Editor/
    XrRmUdpSenderProjectSetup.cs
  Scenes/
    Main.unity

Packages/manifest.json 需要包含:

{
  "dependencies": {
    "com.unity.xr.picoxr": "file:../../PICO-Unity-Integration-SDK-release_3.4.0",
    "com.unity.xr.management": "4.4.0",
    "com.unity.modules.androidjni": "1.0.0",
    "com.unity.modules.animation": "1.0.0",
    "com.unity.modules.imageconversion": "1.0.0",
    "com.unity.modules.jsonserialize": "1.0.0",
    "com.unity.modules.unitywebrequest": "1.0.0",
    "com.unity.modules.unitywebrequesttexture": "1.0.0",
    "com.unity.modules.xr": "1.0.0"
  }
}

一、实现 PicoControllerUdpSender.cs

public 字段:

- host默认 "192.168.9.89"
- port默认 15000
- sendHz默认 60.0f
- convertUnityToProjectCoordinates默认 true
- sendOnStart默认 true

只读状态属性:

- SendEnabled
- HasEndpoint
- LeftDeviceValid
- RightDeviceValid
- LastError
- LastSendTime

PlayerPrefs key

- xr_rm_udp_sender.host
- xr_rm_udp_sender.port
- xr_rm_udp_sender.send_hz
- xr_rm_udp_sender.convert_coordinates

生命周期:

- OnEnable:
  - LoadConfig()
  - ReopenClient()
  - sendEnabled = sendOnStart
  - nextSendTime = 0
- Update:
  - 如果 sendEnabled=false直接 return
  - 按 sendHz 节流
  - packet.t = Time.realtimeSinceStartupAsDouble
  - FillController(XRNode.LeftHand, left payload)
  - FillController(XRNode.RightHand, right payload)
  - SendPacket()
- OnDisable:
  - 将左右 payload.grip=false
  - SendPacket()
  - 关闭 UdpClient

JSON 数据结构:

Packet:
- double t
- string frame_id = "xr_world"
- Controllers controllers

Controllers:
- ControllerPayload left
- ControllerPayload right

ControllerPayload:
- bool grip
- float trigger
- float[] pos = new float[] {0.0f, 1.0f, 0.0f}
- float[] quat = new float[] {0.0f, 0.0f, 0.0f, 1.0f}

ApplyConfig(newHost, newPort, newSendHz, newConvert, save):

- Trim host
- IPAddress.TryParse 校验 IP
- port 必须在 1-65535
- sendHz clamp 到 1-120
- 更新字段并 ReopenClient(address)
- save=true 时写 PlayerPrefs
- 失败时写 LastError 并返回 false

SetSending(enabled):

- 如果从 true 切到 false先发送一次左右 grip=false
- 更新 sendEnabled
- nextSendTime = 0

FillController:

- InputDevice device = InputDevices.GetDeviceAtXRNode(node)
- 更新 LeftDeviceValid / RightDeviceValid
- device invalid 时 payload.grip=false, payload.trigger=0, return
- 读取:
  - CommonUsages.devicePosition -> Vector3 position
  - CommonUsages.deviceRotation -> Quaternion rotation
  - CommonUsages.trigger -> float trigger
  - CommonUsages.grip -> float gripValue
  - CommonUsages.gripButton -> bool gripButton
- payload.grip = gripButton || gripValue > 0.5f
- payload.trigger = Mathf.Clamp01(trigger)
- 如果 convertUnityToProjectCoordinates=true:
  - pos = [position.x, position.y, -position.z]
  - quat = [-rotation.x, -rotation.y, rotation.z, rotation.w]
- 否则:
  - pos = [position.x, position.y, position.z]
  - quat = [rotation.x, rotation.y, rotation.z, rotation.w]

SendPacket:

- client 或 endpoint 为空时 return
- JsonUtility.ToJson(packet)
- UTF8 编码
- client.Send(bytes, bytes.Length, endpoint)
- 成功时 LastSendTime=Time.realtimeSinceStartupAsDoubleLastError=""
- 异常时 LastError=exception.Message

二、实现 PicoUdpConfigPanel.cs

功能:

- 和 PicoControllerUdpSender 放在同一个 GameObject。
- Awake 时查找 sender缺失则 AddComponent。
- Start 时:
  - Application.targetFrameRate = targetFrameRate默认 90
  - QualitySettings.vSyncCount = 0
  - Screen.sleepTimeout = SleepTimeout.NeverSleep
  - XRSettings.eyeTextureResolutionScale = 1.0f
  - 创建世界空间配置面板
  - 从 sender 加载 draft
  - showOnStart 控制面板初始显示
- Update 时处理系统键盘、手柄输入、刷新面板。

public 字段:

- targetFrameRate = 90
- showOnStart = true
- togglePanelWithMenuButton = true

面板:

- 如果没有 Camera.main创建 "XR-RM Main Camera"tag=MainCameranear=0.05far=100SolidColor 深色背景,并尽量添加 TrackedPoseDriver。
- 创建 "XR-RM UDP Config Canvas"WorldSpace挂在 camera 下localPosition=(0,0,2)localScale=0.0014sizeDelta=(980,640)。
- 背景 Image 深色半透明。
- 标题:"XR-RM PICO UDP Sender"
- 状态行显示:
  - endpoint
  - sending/paused
  - L ok / --, R ok / --
  - panelMessage 或 sender.LastError
- 6 行配置:
  0. Target IP
  1. Target Port
  2. Send Rate
  3. Coordinates
  4. UDP Sending
  5. Save & Apply
- 页脚:
  "Stick Up/Down: select   Stick Left/Right: adjust   Trigger/A/X: edit   B/Y: save   Menu: show/hide"

输入:

- CommonUsages.menuButton显示/隐藏面板。
- CommonUsages.primary2DAxis
  - y > 0.55 上移选择
  - y < -0.55 下移选择
  - x > 0.65 当前值增加或切换
  - x < -0.65 当前值减少或切换
  - 需要 AxisRepeatDelay=0.22f 防连发
- Trigger / primaryButton / triggerButton / trigger value > 0.75:编辑或激活当前行。
- secondaryButton保存并应用。

编辑:

- Target IP 使用 TouchScreenKeyboardType.URL。
- Target Port 使用 NumberPad。
- Send Rate 使用 NumberPad。
- 端口 clamp 1-65535。
- Send Rate clamp 1-120。
- Coordinates 行切换 convertDraft。
- UDP Sending 行调用 sender.SetSending(!sender.SendEnabled)。
- Save & Apply 行调用 sender.ApplyConfig(hostDraft, portDraft, sendHzDraft, convertDraft, true)。

UI 文本:

- 使用 Resources.GetBuiltinResource<Font>("Arial.ttf")。
- Text 支持 wrap、truncate、best fit。
- selected 行用亮蓝色和 bold普通行用浅色。

三、实现 XrRmUdpSenderProjectSetup.cs

仅在 UNITY_EDITOR 下编译。

菜单:

1. XR-RM/Apply UDP Sender Android Settings
2. XR-RM/Create Or Refresh UDP Sender Scene
3. XR-RM/Build Android APK

Apply UDP Sender Android Settings

- PlayerSettings.productName = "XR-RM-PICO-UDP-Sender"
- Android application identifier = "com.local.xr_rm_udp_sender"
- minSdkVersion = AndroidApiLevel29
- targetSdkVersion = AndroidApiLevelAuto
- forceInternetPermission = true
- Scripting Backend = IL2CPP
- Android targetArchitectures = ARM64
- Graphics API = OpenGLES3
- SwitchActiveBuildTarget Android
- EnsurePicoSettings()
- EnablePicoLoader()
- CreateOrRefreshScene()
- EditorBuildSettings.scenes = Main.unity
- AssetDatabase.SaveAssets()

Create Or Refresh UDP Sender Scene

- 确保 Assets/Scenes 存在。
- 打开或新建 Assets/Scenes/Main.unity。
- 找到或创建 GameObject "PicoControllerUdpSender"。
- 添加/配置 PicoControllerUdpSender
  - host="192.168.9.89"
  - port=15000
  - sendHz=60
  - convertUnityToProjectCoordinates=true
  - sendOnStart=true
- 添加/配置 PicoUdpConfigPanel
  - targetFrameRate=90
  - showOnStart=true
  - togglePanelWithMenuButton=true
- 保存 scene。

EnsurePicoSettings

- 确保 Assets/XR/Settings 存在。
- 创建或加载 Assets/XR/Settings/PXR_Settings.asset。
- 默认 stereoRenderingModeAndroid = MultiPass。
- EditorBuildSettings.AddConfigObject("Unity.XR.PXR.Settings", settings, true)。

EnablePicoLoader

- 查找或创建 XRGeneralSettingsPerBuildTarget。
- 获取 Android 的 XRGeneralSettings。
- 确保 XRManagerSettings 存在。
- 移除当前 active loaders。
- 使用 XRPackageMetadataStore.AssignLoader(generalSettings.Manager, "PXR_Loader", BuildTargetGroup.Android)。
- 失败时 Debug.LogWarning 提醒检查 PICO Integration package。

Build Android APK

- 调用 ApplyAndroidSettings()
- 确保 Builds 目录存在。
- BuildPlayerOptions:
  - scenes = Assets/Scenes/Main.unity
  - locationPathName = Builds/XR-RM-PICO-UDP-Sender.apk
  - target = Android
  - targetGroup = Android
  - options = None
- BuildPipeline.BuildPlayer(options)
- 如果 result 不是 Succeededthrow Exception。

四、验收标准

1. Unity Editor 打开工程无编译错误。
2. XR-RM/Apply UDP Sender Android Settings 能执行。
3. XR-RM/Create Or Refresh UDP Sender Scene 后Main.unity 中有 PicoControllerUdpSender 对象和两个组件。
4. XR-RM/Build Android APK 能生成 Builds/XR-RM-PICO-UDP-Sender.apk。
5. adb install -r 安装到 PICO 4 Ultra 后能启动。
6. PICO 内能看到世界空间配置面板。
7. 面板可修改 Target IP、Port、Send Rate、Coordinates、UDP Sending 并保存。
8. 左右手柄有效时面板显示 L ok / R ok。
9. UDP Sending ON 时ROS2 端 udp_controller_receiver 能收到双手柄 JSON。
10. /xr/left_controller 和 /xr/right_controller 持续刷新。
11. 按住 grip 时 ROS2 遥操作链路输出速度;松开 grip、暂停发送、退出 App 时安全停止。

五、不要实现的内容

- 不实现 XRoboToolkit PC-Service。
- 不实现视频流。
- 不实现夹爪控制。
- 不实现手势识别、hand tracking 或 motion tracker。
- 不引入 XR Interaction Toolkit除非 PICO SDK 必须要求。
- 不引入 TextMeshPro。
- 不改 ROS2 端协议。

8. 常见问题排查

Unity 找不到 PICO package

检查 Packages/manifest.json 的相对路径是否和实际目录一致:

XR_RM_PICO_UDP_Sender/Packages/manifest.json
../../PICO-Unity-Integration-SDK-release_3.4.0

也就是从 unity/XR_RM_PICO_UDP_Sender/Packages 往上两级到 unity/,再进入 PICO-Unity-Integration-SDK-release_3.4.0

Gradle 或 Android 构建失败

优先检查:

  1. Unity Editor 是否安装了 Android Build SupportAndroid SDK & NDK ToolsOpenJDK
  2. Project Settings -> Player -> Android 是否是 IL2CPP + ARM64。
  3. 是否已切换到 Android Build Target。
  4. 是否使用 Unity embedded SDK/NDK/JDK。
  5. PICO SDK package 是否无编译错误。

PICO 收不到 APK 或安装失败

adb kill-server
adb start-server
adb devices
adb install -r unity/XR_RM_PICO_UDP_Sender/Builds/XR-RM-PICO-UDP-Sender.apk

如果设备显示 unauthorized,在 PICO 内重新授权 USB 调试。

ROS2 收不到 UDP

按顺序检查:

  1. PICO 和 Ubuntu 是否同一个 Wi-Fi。
  2. Target IP 是否是 Ubuntu 主机 IP不是路由器 IP也不是 PICO IP。
  3. Target Port 是否是 15000
  4. udp_controller_receiver 是否已启动。
  5. UFW 是否允许 UDP 15000。
  6. PICO 面板是否显示 UDP Sending ON
  7. 面板是否显示 L ok / R ok

可以临时关闭 ROS2 receiver用 netcat 独占端口看是否有 UDP 包:

nc -ul 15000

注意:nc 和 ROS2 receiver 不能同时绑定同一个 UDP 端口。

有 UDP 但机械臂不动

先在 mock 模式验证:

ros2 launch xr_rm_bringup arm_debug.launch.py arm:=both use_mock:=true

然后检查:

ros2 topic echo /xr/left_controller
ros2 topic echo /xr/right_controller
ros2 topic echo /xr_rm/left_rm75/cmd_vel
ros2 topic echo /xr_rm/right_rm75/cmd_vel

如果 /xr/*_controller 有数据但 cmd_vel 为零,多半是 grip 没按下、UDP 超时、工作空间限幅、或 xr_to_robot_matrix 方向/尺度需要调整。

9. 参考链接

  • Unity Hub Linux 安装文档:https://docs.unity.com/en-us/hub/install-hub-linux
  • Unity 2022.3 系统要求:https://docs.unity.cn/Documentation/Manual/system-requirements.html
  • Unity 6.0 系统要求:https://docs.unity3d.com/6000.0/Documentation/Manual/system-requirements.html
  • PICO 4 Ultra 开发资源:https://developer.picoxr.com/pico4-ultra/
  • PICO Unity Integration SDK GitHubhttps://github.com/Pico-Developer/PICO-Unity-Integration-SDK