系统ubuntu22.04
ros2 humble
1 安装MoveIt2
安装参照在ROS2中,通过MoveIt2控制Gazebo中的自定义机械手
-
安装
MoveIt2可以选择自己编译源码安装,或者直接从二进制安装。
个人建议直接二进制安装,可以省很多事。sudo apt install ros-humble-moveit
-
moveit-setup-assistant
这是一个配套moveit的配置助手,有了它就可以方便地进行很多初始化的工作。
sudo apt install ros-humble-moveit-setup-assistant
顺便把别的东西也装了:
sudo apt install ros-humble-moveit-*
-
启动moveit_setup_assistant
ros2 run moveit_setup_assistant moveit_setup_assistant
弹出如下界面表示安装成功!
2 运行并学习MoveIt2的tutorials
参照MoveIt教程
2.1 源码准备
- 创建工作空间
mkdir -p ~/ws_moveit/src
- 下载教程源码
cd ~/ws_moveit/src git clone -b humble https://github.com/moveit/moveit2_tutorials
- 下载剩余源码
出现红色字表示拉取失败,我重复到第3次才拉取成功。。。拉取成功是这样的:vcs import --recursive < moveit2_tutorials/moveit2_tutorials.repos
在tutorials同一层文件夹多出了刚刚拉取成功的文件夹:
2.2 开始编译–好多错 @_@
安装colcon mixin,不然编译报错
sudo apt install python3-colcon-common-extensions
sudo apt install python3-colcon-mixin
colcon mixin add default https://raw.githubusercontent.com/colcon/colcon-mixin-repository/master/index.yaml
colcon mixin update default
开始编译:
cd ~/ws_moveit
colcon build --mixin release
报错了。。。。
2.2.1. No module named ‘catkin_pkg’ (已解决)
ModuleNotFoundError: No module named 'catkin_pkg'
奇怪!pip list
明明有catkin_pkg
啊
这是python环境的原因,有catkin_pkg的是系统自带的python环境,但是不知道为什么colcon build自动用的是anaconda的base环境,而base环境里没有catkin_pkg,所以报错了。。。
在base环境中安装
conda activate base
pip install catkin_pkg
或者:为 ROS 2 强制指定 Python 解释器
如果需要同时使用 Anaconda 和 ROS 2,可以为 ROS 2 工具链强制指定 Python 解释器路径。
在运行 colcon build 前,设置以下环境变量:
export PYTHON_EXECUTABLE=/usr/bin/python3
再次
colcon build --mixin release
2.2.2. No module named ‘em’(错的,对的在2.2.3)
ModuleNotFoundError: No module named 'em'
安装em
pip install em
再次
colcon build --mixin release
2.2.3. module ‘em’ has no attribute ‘Interpreter’(已解决)
AttributeError: module 'em' has no attribute 'Interpreter'
附带另一个错
AttributeError: 'NoneType' object has no attribute 'shutdown'
嘻嘻,2.2.2 错了
应该是
pip uninstall em
pip uninstall empy
pip install empy==3.3.4
2.2.4 No module named ‘lark’(已解决)
ModuleNotFoundError: No module named 'lark'
安装
pip install lark
多个python环境共存,容易分不清是在哪个环境里,所以我把anaconda卸载了
2.2.5 error: no matching function for call to ‘hardware_interface::(已解决)
终于不是缺包的错了!
[ 87%] Built target test_crc_utils
[ 87%] Built target test_data_utils
/home/xj/ws_moveit/src/ros2_robotiq_gripper/robotiq_driver/tests/test_robotiq_gripper_hardware_interface.cpp: In member function ‘virtual void robotiq_driver::test::TestRobotiqGripperHardwareInterface_load_urdf_Test::TestBody()’:
/home/xj/ws_moveit/src/ros2_robotiq_gripper/robotiq_driver/tests/test_robotiq_gripper_hardware_interface.cpp:79:114: error: no matching function for call to ‘hardware_interface::ResourceManager::ResourceManager(std::string&, rclcpp::node_interfaces::NodeClockInterface::SharedPtr, rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr)’79 | hardware_interface::ResourceManager rm(urdf, node.get_node_clock_interface(), node.get_node_logging_interface());| ^
In file included from /home/xj/ws_moveit/src/ros2_robotiq_gripper/robotiq_driver/tests/test_robotiq_gripper_hardware_interface.cpp:31:
/opt/ros/humble/include/hardware_interface/resource_manager.hpp:66:12: note: candidate: ‘hardware_interface::ResourceManager::ResourceManager(const string&, bool, bool)’66 | explicit ResourceManager(| ^~~~~~~~~~~~~~~
/opt/ros/humble/include/hardware_interface/resource_manager.hpp:67:36: note: no known conversion for argument 2 from ‘rclcpp::node_interfaces::NodeClockInterface::SharedPtr’ {aka ‘std::shared_ptr<rclcpp::node_interfaces::NodeClockInterface>’} to ‘bool’67 | const std::string & urdf, bool validate_interfaces = true, bool activate_all = false);| ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/ros/humble/include/hardware_interface/resource_manager.hpp:49:3: note: candidate: ‘hardware_interface::ResourceManager::ResourceManager()’49 | ResourceManager();| ^~~~~~~~~~~~~~~
/opt/ros/humble/include/hardware_interface/resource_manager.hpp:49:3: note: candidate expects 0 arguments, 3 provided
目前这个错我还看不懂,请教一下chatgpt:
这个错误是因为
hardware_interface::ResourceManager
的构造函数在 ROS 2 Humble
版本中发生了变化。在你的代码中,调用的ResourceManager
构造函数与当前 ROS 2 Humble 提供的 API 不匹配。
问题原因
根据 Humble 版本的 hardware_interface::ResourceManager,其构造函数定义如下:
explicit ResourceManager(
const std::string & urdf,
bool validate_interfaces = true,
bool activate_all = false);
参数变化:不再接受 rclcpp::node_interfaces::NodeClockInterface::SharedPtr
和 rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr
。
解决方法:更新代码,调用当前的 ResourceManager 构造函数签名。
解决方案
你需要修改 test_robotiq_gripper_hardware_interface.cpp
文件的第 79 行,将错误的参数调整为符合 Humble API。
- 原始代码:
hardware_interface::ResourceManager rm( urdf, node.get_node_clock_interface(), node.get_node_logging_interface());
- 修改后的代码:
根据 Humble 版本的构造函数,去掉多余的参数,只传递 urdf 字符串:hardware_interface::ResourceManager rm(urdf);
完整解释
validate_interfaces
和 activate_all
的默认值分别是 true
和 false
。因此,除非你有特殊需求,否则直接传入 urdf 字符串即可。
如果需要自定义 validate_interfaces
和 activate_all
,可以显式传入:
hardware_interface::ResourceManager rm(urdf, true, false);
验证修改
保存修改后的文件。
重新编译项目:
总结
原因:ROS 2 Humble 中 hardware_interface::ResourceManager 的 API 已更改。
解决:调整构造函数调用,移除多余的参数,符合新的函数签名。
2.2.6 ImportError: cannot import name ‘soft_unicode’ from ‘markupsafe’
ImportError: cannot import name 'soft_unicode' from 'markupsafe' (/usr/local/lib/python3.10/dist-packages/markupsafe/__init__.py)
这个错误是由于 markupsafe 版本不兼容 导致的。在较新的 markupsafe 版本(如 2.1.0 及以上)中,soft_unicode 已被移除,而某些旧版本的 jinja2 依赖于它。
解决方案
-
降级 markupsafe 版本(我降级的这个)
将 markupsafe 降级到兼容的版本(如 2.0.1):pip install 'markupsafe==2.0.1' --user
-
升级 jinja2 版本
如果你的项目依赖较新版本的 markupsafe,可以通过升级 jinja2 来解决兼容性问题。pip install --upgrade jinja2 --user
jinja2 的新版本(如 3.1.0 及以上)已经去除了对 soft_unicode 的依赖。
3. 检查 Python 包版本
确保你的环境中 jinja2 和 markupsafe 版本正确。使用以下命令查看当前版本:pip show jinja2 markupsafe
我的输出:
Name: Jinja2 Version: 2.10.3Name: MarkupSafe Version: 3.0.2
总结
降级 markupsafe 到 2.0.1。(我降级的这个)
升级 jinja2 到最新版本(推荐)。
确保正确的 Python 包被加载,避免多环境冲突。
2.2.7 编译成功辣!
然后source一下,
source ~/ws_moveit/install/setup.bash
或者添加路径到.bashrc
echo 'source ~/ws_moveit/install/setup.bash' >> ~/.bashrc
3. 导入urdf文件,控制机器人
由于目前还没有找到专用于MoveIt2的视频教程,先参照这个教程:4.ROS机械臂开发中的主角MoveIt!
没有错误略过,有错误记录解决方案~~
3.1 在Solidworks中配置并导出机器人的urdf文件
urdf的配置方法与视频教程3.如何从零创建一个机器人模型 完全一致。
用到的小工具:sw_urdf_exporter
注意用这个小工具的坐标系是自动生成的,由于坐标系错了会导致机器人的关节轴也出错,所以除了为每个joint配置旋转轴之外,还要定义轴对应的坐标系,这里要注意:(1)基座坐标系默认 Origin_global;(2)为了与机器人理论研究保持一致,关节坐标系的z轴必须与旋转轴平行,如果已经确定了运动学求解模型,最好z轴方向也要与求解模型里的z轴方向一致,这样方便后面关节角度–末端位姿的对应。 也可以在配置完后,导出文件前检查坐标系和旋转轴,然后再导出文件,这样修改也是有效的。
sw_urdf_exporter导出的文件夹是用于 ROS1 系统的,他的display.launch文件还不能用于ROS 2,因此要按照ROS 2的格式修改成display.launch.py文件。修改过程见下一节:
3.2 在RViz2中可视化机械臂(未完待续。。。)
在Rviz2中正常启动。
3.3 在MoveIt2中对机械臂进行运动控制
3.3.1 plan&execute成功
类似于Moveit1 教程的配置方法不再适用于ROS2,不想踩雷请严格按照鱼香ROS的 动手学Moveit2|使用配置助手创建自己机械臂的功能包 + 动手学Moveit2 | 运行配置好的机械臂功能demo 操作。
我按照上述教程操作后依然报了两个小错误,都是出现在同一个文件里:
就是在/home/xj/ws_ok/src/ok3_moveit_config/config/joint_limits.yaml
这里,必须要把has_velocity_limits
和has_acceleration_limits
都设置为true
,且max_velocity和max_acceleration的值设置如下:
joint_limits:Joint_1:has_velocity_limits: truemax_velocity: 2.3has_acceleration_limits: truemax_acceleration: 0.1
1. 报错:Unable to parse SRDF
如果max_acceleration: 1
或者 max_acceleration: 1 .0
或者max_velocity: 3
joint_limits:Joint_1:has_velocity_limits: truemax_velocity: 3has_acceleration_limits: truemax_acceleration: 1
会报错:
[rviz2-3] Warning: class_loader.impl: SEVERE WARNING!!! A namespace collision has occurred with plugin factory for class rviz_default_plugins::displays::InteractiveMarkerDisplay. New factory will OVERWRITE existing one. This situation occurs when libraries containing plugins are directly linked against an executable (the one running right now generating this message). Please separate plugins out into their own library or just don't link against the library and use either class_loader::ClassLoader/MultiLibraryClassLoader to open.
[rviz2-3] at line 253 in /opt/ros/humble/include/class_loader/class_loader/class_loader_core.hpp
[rviz2-3] [ERROR] [1734678557.975532421] [moveit_998031724.moveit.ros.motion_planning_frame]: Action server: /recognize_objects not available
[rviz2-3] [INFO] [1734678558.032235496] [moveit_998031724.moveit.ros.motion_planning_frame]: MoveGroup namespace changed: / -> . Reloading params.
[rviz2-3] [ERROR] [1734678568.149085150] [rviz]: Could not find parameter robot_description_semantic and did not receive robot_description_semantic via std_msgs::msg::String subscription within 10.000000 seconds.
[rviz2-3] Error: Could not parse the SRDF XML File. Error=XML_ERROR_EMPTY_DOCUMENT ErrorID=13 (0xd) Line number=0
[rviz2-3] at line 732 in ./src/model.cpp
[rviz2-3] [ERROR] [1734678568.162749863] [moveit_998031724.moveit.ros.rdf_loader]: Unable to parse SRDF
[rviz2-3] [ERROR] [1734678568.187814200] [moveit_998031724.moveit.ros.planning_scene_monitor]: Robot model not loaded
而且RViz无法导入机械臂模型
2. 报错:No acceleration limit was defined for joint Joint_1!
如果has_acceleration_limits
或者 has_velocity_limits
设置为 false
,如下
joint_limits:Joint_1:has_velocity_limits: truemax_velocity: 2.3has_acceleration_limits: falsemax_acceleration: 0.1
会报错:
[move_group-2] [ERROR] [1734678853.623106632] [move_group.moveit.moveit.core.time_optimal_trajectory_generation]: No acceleration limit was defined for joint Joint_1! You have to define acceleration limits in the URDF or joint_limits.yaml
[move_group-2] [ERROR] [1734678853.623120629] [move_group.moveit.moveit.ros.add_time_optimal_parameterization]: Response adapter 'AddTimeOptimalParameterization' failed to generate a trajectory.
[move_group-2] [ERROR] [1734678853.623146872] [move_group]: PlanningResponseAdapter 'AddTimeOptimalParameterization' failed with error code FAILURE
[move_group-2] [ERROR] [1734678853.623161388] [move_group.moveit.moveit.ros.move_group.move_action]: Generating a plan with planning pipeline failed.
[move_group-2] [INFO] [1734678853.623209470] [move_group.moveit.moveit.ros.move_group.move_action]: FAILURE
[rviz2-3] [INFO] [1734678853.623573204] [moveit_2530242924.moveit.ros.move_group_interface]: Planning request aborted
[rviz2-3] [ERROR] [1734678853.623784226] [moveit_2530242924.moveit.ros.move_group_interface]: MoveGroupInterface::plan() failed or timeout reached
RViz能够导入机械臂模型,但是plan&execute failed了。如下:
3.3.2 plan&execute失败:不按上面教程操作报错了
一定要按照教程操作!!
一定要按照教程操作!!
一定要按照教程操作!!
刚开始以为moveit2 setup assistant和版本1的一样,结果报了很罕见的错。。。
哪里都找不到解决方案,浪费了我一天的时间。。。。
按照moveit1的setup assistant配置,就直接跳过了moveit2的 动手学Moveit2|使用配置助手创建自己机械臂的功能包 中的 3.6 配置ros_control URDF Modiificatoins,3.7 ROS 2 COntrollers 和 3.8 Moveit 控制器,结果plan failed,天塌了。。。。
RViz plan failed:
终端打印信息非常多,这里有一行红字:Failed loading controller joint_state_broadcaster
最醒目:
这些打印信息大概分三段:
第一段:Failed loading controller joint_state_broadcaster
,这个是刚启动,还没有plan&execute的时候报的错,说明是配置除了问题。
[ros2_control_node-4] [ERROR] [1734669356.123441962] [controller_manager]: The 'type' param was not defined for 'joint_state_broadcaster'.
[spawner-5] [FATAL] [1734669356.162457358] [spawner_joint_state_broadcaster]: Failed loading controller joint_state_broadcaster
[ERROR] [spawner-5]: process has died [pid 73897, exit code 1, cmd '/opt/ros/humble/lib/controller_manager/spawner joint_state_broadcaster --ros-args'].
第二段:Failed to fetch current robot state.
[move_group-2] [INFO] [1734669368.456217221] [move_group.moveit.moveit.ros.current_state_monitor]: Didn't receive robot state (joint angles) with recent timestamp within 1.000000 seconds. Requested time 1734669367.456026, but latest received state has time 0.000000.
[move_group-2] Check clock synchronization if your are running ROS across multiple machines!
[move_group-2] [WARN] [1734669368.456343615] [move_group.moveit.moveit.ros.planning_scene_monitor]: Failed to fetch current robot state.
[move_group-2] [INFO] [1734669368.456489498] [move_group.moveit.moveit.ros.move_group.move_action]: Planning request received for MoveGroup action. Forwarding to planning pipeline.
第三段:Generating a plan with planning pipeline failed.
[move_group-2] [ERROR] [1734669368.474156127] [move_group.moveit.moveit.core.time_optimal_trajectory_generation]: No velocity limit was defined for joint joint1! You have to define velocity limits in the URDF or joint_limits.yaml
[move_group-2] [ERROR] [1734669368.474166641] [move_group.moveit.moveit.ros.add_time_optimal_parameterization]: Response adapter 'AddTimeOptimalParameterization' failed to generate a trajectory.
[move_group-2] [ERROR] [1734669368.474184827] [move_group]: PlanningResponseAdapter 'AddTimeOptimalParameterization' failed with error code FAILURE
[move_group-2] [ERROR] [1734669368.474195083] [move_group.moveit.moveit.ros.move_group.move_action]: Generating a plan with planning pipeline failed.
[move_group-2] [INFO] [1734669368.474232312] [move_group.moveit.moveit.ros.move_group.move_action]: FAILURE
[rviz2-3] [INFO] [1734669368.474520536] [moveit_165564864.moveit.ros.move_group_interface]: Planning request aborted
分析:Failed loading controller joint_state_broadcaster
,这个是刚启动,还没有plan&execute的时候报的错,说明是配置出了问题。joint_state_broadcaster
是一个 ros2 controller
,作为一个节点用于发布关节状态信息,没有这个,其他节点无法获取机械臂的当前关节角度,因此导致了plan&execute时报错Failed to fetch current robot state.(获取当前机器人状态失败)
3.3.3 终端话题消息对比(失败版和成功版)
在一个终端输入ros2 launch ok3_moveit_config demo.launch.py
,然后在另一个终端输入以下ros2命令:
ros2 topic list //打印话题列表
ros2 topic info /joint_states //打印话题相关的信息
ros2 topic echo /joint_states //打印关节状态
失败(左图)和成功(右图)的话题和消息对比: