Files
Uni-Lab-OS/dummy2_debug/test_moveit_action.py
2025-08-14 16:03:13 +08:00

226 lines
7.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""
Dummy2 MoveIt2控制测试修复版本
解决设备名称映射和action问题
"""
import json
import time
import sys
import os
import threading
import signal
# 添加Unilab路径
sys.path.insert(0, '/home/hh/Uni-Lab-OS')
def test_direct_moveit_action():
"""直接测试MoveIt action服务"""
print("🔧 直接测试MoveIt action服务...")
try:
import rclpy
from rclpy.node import Node
from rclpy.action import ActionClient
from moveit_msgs.action import MoveGroup
from moveit_msgs.msg import (
MotionPlanRequest,
PlanningOptions,
Constraints,
JointConstraint
)
from geometry_msgs.msg import PoseStamped
# 初始化ROS2
rclpy.init()
# 创建节点
node = Node('moveit_test_client')
# 创建action客户端
action_client = ActionClient(node, MoveGroup, '/move_action')
# 启动executor
executor = rclpy.executors.MultiThreadedExecutor()
executor.add_node(node)
executor_thread = threading.Thread(target=executor.spin, daemon=True)
executor_thread.start()
print("✓ 节点和action客户端创建成功")
# 等待action服务
if not action_client.wait_for_server(timeout_sec=10.0):
print("❌ MoveIt action服务连接超时")
return False
print("✅ MoveIt action服务连接成功")
# 创建运动规划请求
goal_msg = MoveGroup.Goal()
# 设置请求参数
goal_msg.request.group_name = "dummy2_arm" # 注意这里的组名
goal_msg.request.num_planning_attempts = 3
goal_msg.request.allowed_planning_time = 5.0
goal_msg.request.max_velocity_scaling_factor = 0.2
goal_msg.request.max_acceleration_scaling_factor = 0.2
# 设置关节约束简单的home位置
joint_constraint = JointConstraint()
joint_constraint.joint_name = "Joint1"
joint_constraint.position = 0.0
joint_constraint.tolerance_above = 0.01
joint_constraint.tolerance_below = 0.01
joint_constraint.weight = 1.0
constraints = Constraints()
constraints.joint_constraints = [joint_constraint]
goal_msg.request.goal_constraints = [constraints]
# 设置规划选项
goal_msg.planning_options.planning_scene_diff.is_diff = True
goal_msg.planning_options.planning_scene_diff.robot_state.is_diff = True
goal_msg.planning_options.plan_only = False # 执行规划结果
print("📤 发送MoveIt规划请求...")
print(f" 目标组: {goal_msg.request.group_name}")
print(f" 关节约束: {joint_constraint.joint_name} = {joint_constraint.position}")
# 发送目标
future = action_client.send_goal_async(goal_msg)
# 等待结果
rclpy.spin_until_future_complete(node, future, timeout_sec=3.0)
if future.result() is not None:
goal_handle = future.result()
if goal_handle.accepted:
print("✅ 规划请求被接受")
# 等待执行结果
result_future = goal_handle.get_result_async()
rclpy.spin_until_future_complete(node, result_future, timeout_sec=10.0)
if result_future.result() is not None:
result = result_future.result().result
print(f"📊 规划结果: {result.error_code.val}")
if result.error_code.val == 1: # SUCCESS
print("🎉 MoveIt规划和执行成功")
return True
else:
print(f"❌ MoveIt执行失败错误代码: {result.error_code.val}")
return False
else:
print("❌ 等待执行结果超时")
return False
else:
print("❌ 规划请求被拒绝")
return False
else:
print("❌ 发送规划请求超时")
return False
except Exception as e:
print(f"❌ MoveIt测试失败: {e}")
import traceback
traceback.print_exc()
return False
finally:
try:
executor.shutdown()
rclpy.shutdown()
except:
pass
def check_moveit_groups():
"""检查MoveIt规划组"""
print("\n🔍 检查MoveIt规划组...")
try:
import subprocess
# 获取规划组信息
result = subprocess.run([
'ros2', 'service', 'call', '/query_planner_params',
'moveit_msgs/srv/QueryPlannerParams', '{}'
], capture_output=True, text=True, timeout=10)
if result.returncode == 0:
print("✅ 成功查询规划器参数")
print("响应:")
print(result.stdout)
else:
print("❌ 查询规划器参数失败")
print(result.stderr)
except Exception as e:
print(f"❌ 检查规划组失败: {e}")
def check_robot_description():
"""检查机器人描述"""
print("\n🔍 检查机器人描述...")
try:
import subprocess
# 获取机器人描述参数
result = subprocess.run([
'ros2', 'param', 'get', '/move_group', 'robot_description'
], capture_output=True, text=True, timeout=10)
if result.returncode == 0:
urdf_content = result.stdout
# 检查关节名称
joint_names = []
for line in urdf_content.split('\n'):
if 'joint name=' in line and 'type=' in line:
# 简单解析关节名称
start = line.find('name="') + 6
end = line.find('"', start)
if start > 5 and end > start:
joint_name = line[start:end]
if 'Joint' in joint_name:
joint_names.append(joint_name)
print(f"✅ 找到关节: {joint_names}")
return joint_names
else:
print("❌ 获取机器人描述失败")
return []
except Exception as e:
print(f"❌ 检查机器人描述失败: {e}")
return []
def main():
"""主函数"""
print("🔧 MoveIt2控制测试修复版本")
print("=" * 50)
# 1. 检查机器人描述和关节
joint_names = check_robot_description()
# 2. 检查规划组
check_moveit_groups()
# 3. 直接测试MoveIt action
print("\n" + "="*30)
print("开始MoveIt Action测试")
print("="*30)
if test_direct_moveit_action():
print("\n🎉 MoveIt2控制测试成功")
print("Dummy2可以通过MoveIt2进行规划和控制")
else:
print("\n❌ MoveIt2控制测试失败")
print("需要进一步调试配置问题")
print("\n📋 下一步建议:")
print("1. 检查SRDF文件中的规划组配置")
print("2. 验证关节名称映射")
print("3. 调试运动学求解器配置")
if __name__ == "__main__":
main()