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.3 Name: 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文件
配置方法与视频教程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中对机械臂进行运动控制
是因为这里报错吗????
打开Global Status Warn
查看报错详情:
奇怪,Global Options
的 Fixed Frame
明明有 base_link
呀,为什么Global Status
里面没有 base_link
呢?
报错详情:
Global Status: Warn
Fixed Frame
No tf data. Actual error: Frame [base_link] does not exist
打印信息非常多,这里有一行红字,不知道会不会影响机器人功能:
报错:获取机器人当前状态失败
[move_group-2] [INFO] [1734573869.409753231] [move_group.moveit.moveit.ros.current_state_monitor]: Didn't receive robot state (joint angles) with recent timestamp within 1.000000 seconds. Requested time 1734573868.409614, 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] [1734573869.409812549] [move_group.moveit.moveit.ros.planning_scene_monitor]: Failed to fetch current robot state.
[move_group-2] [INFO] [1734573869.409865499] [move_group.moveit.moveit.ros.move_group.move_action]: Planning request received for MoveGroup action. Forwarding to planning pipeline.
ros2 run robot_state_publisher robot_state_publisher --ros-args -p robot_description:="$(cat /home/xj/ws_ok/src/ok3_moveit_config/config/ok3.urdf)"
ros2 topic echo /tf_static
但是! 正常应该是下图这样的啊!!!
在一个终端输入ros2 launch ros2_control_demo_example_7 view_r6bot.launch.py
,然后在另一个终端应该显示:
ros2 topic info /joint_states //打印话题相关的信息
ros2 topic echo /tf_static //打印话题消息内容
以及
ros2 topic echo /joint_states