ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

在PX4中把iris模型替换成自定义无人机并挂载D435i深度相机:TaoToken统一Key配置与仿真验证

在PX4中把iris模型替换成自定义无人机并挂载D435i深度相机:TaoToken统一Key配置与仿真验证 1. 为什么要把 iris 换成自定义机型并挂 D435iPX4 的 Gazebo 仿真默认给的是 iris 四旋翼它结构简单、参数齐全拿来跑通 mavros_posix_sitl.launch 没问题。但只要你开始做视觉相关的算法验证比如 VINS、ORB-SLAM、深度避障、点云建图iris 就不够用了它没有相机更没有深度传感器你没法在仿真里拿到 RGB 图和深度图去喂给感知节点。这时候就需要两件事同时做——把 iris 换成你自己设计的无人机模型再在机身上挂一个 D435i 深度相机。我试过直接改 iris.sdf 里的 mesh 路径结果模型是换了但相机没挂上rostopic list 里根本看不到 /camera/depth/image_raw。后来才明白模型替换和传感器挂载是两条独立的线前者改的是可视化几何体和惯量后者要在 sdf 里加 sensor 标签并配好 Gazebo 插件。这篇就把这两条线合在一起讲清楚从目录结构、sdf 关键参数、airframe 配置到启动脚本最后用 rostopic 和 Gazebo 界面验证深度图与点云真的出来了。适合谁看已经装好 PX4 和 ROS、能跑通默认 iris 仿真、现在想换成自定义机型并加深度相机的同学。环境我用的是 ROS Noetic PX4 1.13.3其他版本原理一致路径可能略有差异。核心检索词就是 px4 替换 iris 模型、D435i 深度相机仿真、自定义无人机模型挂载下面按可跟做的步骤展开。在动手之前先明确一个概念PX4 的 sitl_gazebo 模型目录里每个机型是一个文件夹里面有 .sdf 描述文件、meshes 网格、可能还有配置文件。iris 就是其中一个。你要做的自定义机型本质上就是复制一份 iris 文件夹改名字、换 mesh、调惯量然后在 airframe 里注册一个新的机型 ID让启动脚本能按名字加载它。D435i 则是一个独立的 model 文件夹通过 sdf 里的 include 或者直接内联 sensor 挂到机体上。2. TaoToken 统一 Key 配置让仿真里的模型调用不再到处找 Key做视觉仿真的时候很多人会顺手接一个视觉语言模型或者云端推理服务用来做场景理解、目标检测的结果复核。这时候就会遇到一个很烦的问题每个脚本、每个节点都要配一遍 API Key 和 Base URL改一次要翻好几个文件。TaoToken 的思路是给你一个统一的 Key 和统一的入口模型对话、coding-plan、console、api-keys 都在一个地方管理省得你在仿真工程里散落一堆配置。先说清楚它是什么、能做什么。TaoToken 提供统一的 API 接入地址 https://taotoken.net/api你拿一个 Key 就能调用多种模型不用为每个模型单独申请账号、单独记 endpoint。对做 PX4 仿真的同学来说典型用法是仿真跑起来后把 Gazebo 里相机的截图或者深度统计信息发给模型做分析或者用 coding-plan 辅助写 Gazebo 插件和 launch 文件。适合谁需要频繁切换模型、又不想在工程里维护多套 Key 的人。前置准备很简单。先去官网 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 注册然后在 console 里创建一个 API Key。地址是 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 。创建完在 api-keys 页面能看到你的 Key页面是 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。想先试试模型对话效果可以直接去 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite 体验。这里要强调一点TaoToken 是正规的 API 聚合接入服务Base URL 就是 https://taotoken.net/api不要把它理解成什么中转或者代理它就是一个统一的模型调用入口。你在仿真工程里配置的时候只需要记住三件套Base URL、API Key、Model ID。这三样配齐任何支持 OpenAI 兼容接口的客户端都能连上。为什么要在 PX4 仿真场景里提这个因为当你把 D435i 挂上去、开始跑视觉算法之后下一步往往就是接一个模型来做决策或者做数据标注。如果这时候你还在用硬编码的 Key换一次模型就要改代码、重新编译非常影响调试节奏。统一 Key 的好处是仿真工程里只存一个环境变量模型切换只改 Model ID 一个字符串。具体到操作你可以把 Key 写进环境变量而不是写死在代码里。这样 launch 文件、Python 节点、shell 脚本都能读到同一个值。下面给一个可复制的配置片段路径和原文一致放在你的工作空间或者 ~/.bashrc 里都行。注意不要提交到 git用 .gitignore 排除掉。# ~/.bashrc 或 ~/.zshrc 末尾追加 export TAOTOKEN_API_KEYsk-你的Key export TAOTOKEN_BASE_URLhttps://taotoken.net/api export TAOTOKEN_MODEL_ID你的ModelID配好之后 source 一下用 echo 验证source ~/.bashrc echo $TAOTOKEN_BASE_URL # 期望输出https://taotoken.net/api如果你用的是 Python 节点去调用可以这样读import os from openai import OpenAI client OpenAI( api_keyos.environ[TAOTOKEN_API_KEY], base_urlos.environ[TAOTOKEN_BASE_URL], ) resp client.chat.completions.create( modelos.environ[TAOTOKEN_MODEL_ID], messages[{role: user, content: 描述一张无人机俯拍图里可能出现的障碍物类型}], ) print(resp.choices[0].message.content)这段代码的关键就是 base_url 指向 https://taotoken.net/apiKey 从环境变量读。这样你在仿真里做视觉分析时模型调用和 PX4 的模型文件互不干扰。想深入看接入细节文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。如果你长期做编码和 Agent 类任务可以考虑 Coding Plan入口 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 。需要提醒的是TaoToken 是辅助你写代码、分析仿真数据的工具它不替代 Gazebo也不替代 PX4 本身。仿真能不能跑起来还是取决于你的模型文件和 launch 配置对不对。下面进入正题先把自定义机型和 D435i 的目录结构搭好。3. 可复制配置自定义机型目录、D435i 挂载与 airframe 注册这一节是全文的核心所有路径都以 PX4-Autopilot 根目录为基准。假设你的 PX4 装在 /home/user/PX4-Autopilot下面用 $PX4_DIR 代替。先备份原始 iris这是必须做的第一步改坏了能回滚。cd $PX4_DIR/Tools/sitl_gazebo/models/iris cp iris.sdf iris.sdf.bk3.1 自定义机型目录结构复制一份 iris 作为你的新机型比如叫 mydronecd $PX4_DIR/Tools/sitl_gazebo/models/ cp -r iris mydrone cd mydrone ls # 你会看到 mydrone.sdf需要重命名、meshes/ 等 mv iris.sdf mydrone.sdf目录结构大致是这样mydrone/ ├── mydrone.sdf ├── meshes/ │ ├── mydrone.stl # 你的机体网格 │ └── ... # 桨叶等其他网格 └── mydrone.png # 可选Gazebo 里显示的缩略图如果你用 SolidWorks 导出推荐用 sw2urdf 插件生成 urdf再用官方工具转 sdfgz sdf -p mydrone.urdf mydrone.sdf转出来的 sdf 里 link 和 joint 的位置、姿态、惯量都是按你的装配体来的比手动改 mesh 路径省事得多。注意 sw2urdf 使用时每个 link 要设为子装配体坐标系原点要和子装配体原点重合所有坐标系和关节轴放在装配体根目录保存路径不要有中文否则模型会散架。3.2 sdf 关键参数机体与 D435i打开 mydrone.sdf找到 model name 和 base_link 部分。把 mesh 的 uri 指向你自己的网格model namemydrone link namebase_link visual namebase_link_inertia_visual geometry mesh scale1 1 1/scale urimodel://mydrone/meshes/mydrone.stl/uri /mesh /geometry /visual inertial mass1.5/mass inertia ixx0.029125/ixx ixy0/ixy ixz0/ixz iyy0.029125/iyy iyz0/iyz izz0.055225/izz /inertia /inertial /link /model惯量参数要和你的实际质量匹配否则飞控调参和仿真动力学会对不上。质量改了ixx/iyy/izz 也要按比例调不然悬停会飘。接下来挂 D435i。推荐把 D435i 做成独立的 model 文件夹然后在机体 sdf 里 include 进来这样复用性好。先建 D435i 模型目录mkdir -p $PX4_DIR/Tools/sitl_gazebo/models/D435iD435i 的 sdf 里核心是 depth camera sensor 和对应的 Gazebo 插件。关键片段如下sensor typedepth namecamera_depth always_on1/always_on update_rate30/update_rate visualizetrue/visualize camera named435i_depth horizontal_fov1.5184/horizontal_fov image width640/width height480/height formatR8G8B8/format /image clip near0.1/near far10.0/far /clip noise typegaussian/type mean0.0/mean stddev0.005/stddev /noise /camera plugin namedepth_camera_controller filenamelibgazebo_ros_openni_kinect.so alwaysOntrue/alwaysOn updateRate30.0/updateRate cameraNamecamera/cameraName imageTopicNamecolor/image_raw/imageTopicName depthImageTopicNamedepth/image_raw/depthImageTopicName pointCloudTopicNamedepth/points/pointCloudTopicName cameraInfoTopicNamecolor/camera_info/cameraInfoTopicName depthImageCameraInfoTopicNamedepth/camera_info/depthImageCameraInfoTopicName frameNamecamera_link/frameName pointCloudCutoff0.1/pointCloudCutoff pointCloudCutoffMax10.0/pointCloudCutoffMax /plugin /sensor然后在 mydrone.sdf 的 base_link 里加一个 joint 把相机固定上去或者直接在 base_link 下加一个 link 引用 D435iinclude urimodel://D435i/uri pose0.1 0 -0.05 0 0 0/pose /includepose 里的 0.1 是前向偏移-0.05 是下移按你的机体尺寸调。相机朝向默认是 X和 PX4 机头方向一致。3.3 airframe 注册与启动脚本光有模型文件还不够PX4 需要知道这个机型。在 $PX4_DIR/ROMFS/px4fmu_common/init.d-posix/airframes/ 下新建一个文件比如 4001_mydronecd $PX4_DIR/ROMFS/px4fmu_common/init.d-posix/airframes/ cp 4001_quad_x 4001_mydrone编辑 4001_mydrone把机型名改成你的#!/bin/sh PX4_SIM_MODELmydrone然后在同目录的 CMakeLists.txt 里加上 4001_mydrone否则编译时不会打包进去。改完重新编译cd $PX4_DIR make px4_sitl_default启动脚本方面复制一份默认的 launch 改成你的cp $PX4_DIR/launch/mavros_posix_sitl.launch $PX4_DIR/launch/mydrone_d435i.launch在 launch 里把 vehicle 参数改成 mydronesdf 指向你的模型arg namevehicle defaultmydrone/ arg namesdf default$(find mavlink_sitl_gazebo)/models/mydrone/mydrone.sdf/环境变量也要配好方便 launch 找到模型和插件export PX4_DIR/home/user/PX4-Autopilot source $PX4_DIR/Tools/setup_gazebo.bash $PX4_DIR $PX4_DIR/build/px4_sitl_default export ROS_PACKAGE_PATH$ROS_PACKAGE_PATH:$PX4_DIR export ROS_PACKAGE_PATH$ROS_PACKAGE_PATH:$PX4_DIR/Tools/sitl_gazebo export GAZEBO_PLUGIN_PATH$GAZEBO_PLUGIN_PATH:$PX4_DIR/plugin到这里配置就齐了。下面验证。4. 验证请求与成功结果rostopic 看深度图、Gazebo 看点云启动仿真roslaunch px4 mydrone_d435i.launch如果一切正常Gazebo 界面会加载你的自定义机型机头下方能看到 D435i 的相机模型。等几秒让 PX4 完成初始化然后新开一个终端验证话题。先看话题列表里有没有相机相关rostopic list | grep camera期望看到/camera/color/image_raw /camera/color/camera_info /camera/depth/image_raw /camera/depth/camera_info /camera/depth/points如果这几个都在说明 D435i 插件加载成功。接着看深度图的实际数据rostopic hz /camera/depth/image_raw期望输出类似subscribed to [/camera/depth/image_raw] average rate: 29.98 min: 0.033s max: 0.034s std dev: 0.00031s window: 30频率稳定在 30Hz 左右就对了。再看点云rostopic hz /camera/depth/points同样应该是 30Hz 上下。想直观看点云用 rvizrosrun rviz rviz在 rviz 里 Add - PointCloud2Topic 选 /camera/depth/pointsFixed Frame 设成 camera_link 或者 base_link。你应该能看到机体前方一片彩色的点云距离越近颜色越暖。如果点云是空的检查 pointCloudCutoff 是不是设得太大或者相机前方确实没有物体。再验证一下图像内容rosrun image_view image_view image:/camera/depth/image_raw会弹出一个窗口显示深度图近处亮、远处暗。如果窗口是黑的可能是相机朝向不对或者 Gazebo 里相机被机体挡住了。回到 Gazebo 界面选中相机 link看它的 pose 是不是在机体外侧。最后确认 PX4 和 mavros 的连接正常rostopic echo /mavros/state期望看到 connected: Truemode 是 STABILIZED 或 OFFBOARD。如果 connected 是 False说明 mavros 没连上检查 launch 里的 fcu_url 参数。到这里自定义机型 D435i 深度相机的仿真链路就通了。你可以在这个基础上跑 VINS、跑避障算法或者把深度图发给 TaoToken 的模型做场景分析。模型对话入口在 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite 接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。5. 本篇常见错排查401、local proxy failed、reading choices、OAuth这一节把仿真和模型调用两条线上最容易踩的坑列出来对照真实报错给解法。先说仿真侧的报错。第一个高频问题是模型加载失败Gazebo 报[Err] [ModelDatabase.cc] Unable to find model[model://mydrone]原因通常是 GAZEBO_MODEL_PATH 没包含你的模型目录或者模型文件夹名字和 sdf 里的 model name 不一致。解法确认 $PX4_DIR/Tools/sitl_gazebo/models 在 GAZEBO_MODEL_PATH 里且文件夹名、sdf 文件名、model name 三者一致。改完 source 一下环境变量再启动。第二个是相机话题不出现rostopic list 里没有 /camera/depth/image_raw。先检查 sdf 里 sensor 的 plugin filename 是不是 libgazebo_ros_openni_kinect.so这个库在 ROS Noetic 里是有的。如果报[Err] [Plugin.hh:178] Failed to load plugin libgazebo_ros_openni_kinect.so说明 GAZEBO_PLUGIN_PATH 没配好或者这个 so 文件不在系统路径。用 find 找一下find /opt/ros/noetic -name libgazebo_ros_openni_kinect.so找到后把所在目录加进 GAZEBO_PLUGIN_PATH。第三个是模型散架Gazebo 里机体零件飞得到处都是。这是 sw2urdf 导出时坐标系没对齐导致的回到第 3 节的注意事项每个 link 设为子装配体坐标系原点重合所有轴放根目录路径无中文。重新导出 urdf 再转 sdf。再说模型调用侧的报错。如果你在仿真脚本里调 TaoToken可能遇到Error code: 401 - {error: {message: Invalid API key}}这是 Key 不对或者没读到环境变量。检查 echo $TAOTOKEN_API_KEY 有没有值Key 有没有多余空格以及是不是在正确的 shell 里 source 过。注意 Key 只在创建时显示一次丢了就重新建一个。第二个local proxy failed这个报错通常出现在客户端配置了本地代理但代理没起来。TaoToken 的 Base URL 是 https://taotoken.net/api直连即可不需要额外配代理。把客户端里的 proxy 设置清掉或者检查环境变量里有没有残留的 http_proxy。第三个Error code: 500 - reading choices这个多半是返回体解析失败常见于 Model ID 写错或者模型名不存在。确认你填的 Model ID 和 api-keys 页面里列出的可用模型一致。如果用的是 coding-plan 的额度确认 Model ID 在 coding-plan 支持的范围内。第四个OAuth error: invalid_grant这个出现在用 OAuth 方式登录或者刷新 token 的时候通常是 token 过期或者时钟不同步。检查系统时间重新走一遍授权流程。如果你用的是 API Key 方式一般不会碰到这个。还有一个容易忽略的仿真里 Python 节点读环境变量时launch 文件不会自动继承你 shell 里的 export。需要在 launch 里显式传node pkgyour_pkg typeyour_node.py nameyour_node outputscreen env nameTAOTOKEN_API_KEY value$(env TAOTOKEN_API_KEY)/ env nameTAOTOKEN_BASE_URL value$(env TAOTOKEN_BASE_URL)/ /node这样节点才能拿到 Key。踩过的坑基本就这些核心思路是仿真报错看路径和插件模型报错看 Key 和 Model ID两边分开排查不要混在一起。6. 继续往下走从仿真验证到长期编码仿真跑通只是第一步。接下来你大概率要做的是把深度图接到 SLAM 节点、写避障逻辑、或者用模型辅助生成测试用例。这时候如果每次都要手动配 Key、手动切模型效率会很低。TaoToken 的 Coding Plan 就是为这种长期编码和 Agent 场景准备的入口在 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 。它适合你反复迭代代码、让模型帮你读 Gazebo 插件源码、生成 launch 模板的场景。如果你更偏向直接调 API 做推理那就用 API Keys 页面管理你的 Key地址 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。想先验证模型效果去模型对话页面 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite 试几句。回到 PX4 这边一个实用技巧是把 D435i 的深度图和点云话题名固定下来写进你的算法配置里这样换机型的时候只要保证话题名不变上层代码不用动。另一个技巧是 airframe 文件里可以加参数覆盖比如调相机的 update_rate不用改 sdf 重新编译。最后模型文件改完记得 make px4_sitl_default 重新编译否则 airframe 不会生效。这些细节做顺了你的仿真迭代速度会快很多。
返回列表