import os from glob import glob from setuptools import find_packages, setup package_name = 'arm_sim_gazebo' def _existing(paths): """过滤掉不存在的路径。 glob() 会把**悬空符号链接**也列出来,而 colcon 在拷贝阶段会因此直接失败 ("can't copy ... doesn't exist or not a regular file")。 arm_application 的 setup.py 就因这个问题挂过一次构建,这里从一开始就防住。 """ return [p for p in paths if os.path.isfile(p)] setup( name=package_name, version='0.1.0', packages=find_packages(exclude=['test']), data_files=[ ('share/ament_index/resource_index/packages', ['resource/' + package_name]), ('share/' + package_name, ['package.xml']), # launch 文件必须显式安装,否则 ros2 launch arm_sim_gazebo ... 找不到 (os.path.join('share', package_name, 'launch'), _existing(glob('launch/*.py'))), ], install_requires=['setuptools', 'PyYAML'], zip_safe=True, maintainer='arm_dev', maintainer_email='dev@example.com', description='Gazebo 仿真后端:描述归一化 + 启动 Gazebo 与 ros2_control 桥接', license='Apache-2.0', entry_points={ 'console_scripts': [ # devices/sim/gazebo/manifest.yaml 里声明的那个可执行名,别改。 # 它只做"准备描述 + 转发给 launch 文件",逻辑在 # arm_sim_gazebo/gazebo_sim_launcher.py。 'gazebo_sim_launcher = arm_sim_gazebo.gazebo_sim_launcher:main', # 仿真相机适配器:把桥接过来的 gz 相机变成应用期望的 realsense # 话题(改名 + 光学系 frame_id + 深度 米→毫米)。 # 由 gazebo_sim.launch.py 拉起,一般不手跑;单独调试时可以用。 'sim_camera_adapter = arm_sim_gazebo.sim_camera_adapter:main', # 仿真触觉适配器:把桥接过来的 gz 关节力/接触传感器变成 # arm_msgs/TactileStatus(轴向投影 + 基线相减 + 恒定发布)。 # 由 gazebo_sim.launch.py 拉起;单独调试时可以用。 'sim_tactile_adapter = arm_sim_gazebo.sim_tactile_adapter:main', # 仿真夹爪适配器:把 GripperExecute 服务(开口 mm)变成 # 7 个夹爪关节的目标位置(含 mimic 耦合换算),让仿真能走 # 真机那一套夹爪接口。由 gazebo_sim.launch.py 拉起。 'sim_gripper_adapter = arm_sim_gazebo.sim_gripper_adapter:main', # 独立小工具:只看归一化做了什么,不启动 Gazebo。 # 排查"为什么 Gazebo 说我的 link 不存在"时非常省时间。 'urdf_normalize = arm_sim_gazebo.urdf_normalize:main', ], }, )