# Unity-MoveIt2 API 接口文档 ## 📋 目录 - [1. API概览](#1-api概览) - [2. Unity端API](#2-unity端api) - [3. ROS2端API](#3-ros2端api) - [4. 消息定义](#4-消息定义) - [5. 服务接口](#5-服务接口) - [6. 话题列表](#6-话题列表) - [7. 错误码定义](#7-错误码定义) - [8. 使用示例](#8-使用示例) ## 1. API概览 ### 1.1 通信架构 ``` Unity前端 ←→ ROS TCP Bridge ←→ ROS2后端 ↓ ↓ ↓ Unity API TCP Protocol ROS2 API ``` ### 1.2 支持的通信模式 - **实时控制**:高频率位姿控制(30Hz) - **路径规划**:请求-响应模式 - **状态监控**:订阅-发布模式 - **配置管理**:服务调用模式 ## 2. Unity端API ### 2.1 机器人控制API #### RobotController类 ```csharp public class RobotController : MonoBehaviour { /// /// 设置末端执行器目标位姿 /// /// 目标位置 (世界坐标系) /// 目标旋转 (四元数) /// 是否成功发送命令 public bool SetEndEffectorPose(Vector3 position, Quaternion rotation) /// /// 设置关节角度 /// /// 关节角度数组 (弧度) /// 是否成功发送命令 public bool SetJointAngles(float[] jointAngles) /// /// 获取当前关节状态 /// /// 关节状态信息 public JointState GetCurrentJointState() /// /// 获取当前末端位姿 /// /// 末端位姿信息 public Pose GetCurrentEndEffectorPose() } ``` #### 使用示例 ```csharp // 设置末端位姿 Vector3 targetPosition = new Vector3(0.5f, 0.2f, 0.3f); Quaternion targetRotation = Quaternion.Euler(0, 90, 0); robotController.SetEndEffectorPose(targetPosition, targetRotation); // 设置关节角度 float[] jointAngles = {0.0f, -1.57f, 1.57f, 0.0f, 1.57f, 0.0f}; robotController.SetJointAngles(jointAngles); ``` ### 2.2 路径规划API #### PathPlannerInterface类 ```csharp public class PathPlannerInterface : MonoBehaviour { /// /// 规划路径到目标位姿 /// /// 目标位姿 /// 路径约束 /// 规划完成回调 public void PlanToTarget(Pose targetPose, PlanningConstraints constraints, System.Action callback) /// /// 规划通过路径点的轨迹 /// /// 路径点列表 /// 规划完成回调 public void PlanThroughWaypoints(List waypoints, System.Action callback) /// /// 执行规划的轨迹 /// /// 轨迹数据 /// 执行完成回调 public void ExecuteTrajectory(Trajectory trajectory, System.Action callback) } ``` #### 使用示例 ```csharp // 规划路径 Pose targetPose = new Pose(new Vector3(0.6f, 0.0f, 0.4f), Quaternion.identity); PlanningConstraints constraints = new PlanningConstraints { maxVelocity = 0.5f, maxAcceleration = 1.0f, allowCollisions = false }; pathPlanner.PlanToTarget(targetPose, constraints, (result) => { if (result.success) { Debug.Log($"规划成功,轨迹点数:{result.trajectory.points.Count}"); pathPlanner.ExecuteTrajectory(result.trajectory, OnExecutionComplete); } else { Debug.LogError($"规划失败:{result.errorMessage}"); } }); ``` ### 2.3 可行性分析API #### FeasibilityAnalyzer类 ```csharp public class FeasibilityAnalyzer : MonoBehaviour { /// /// 分析装配任务可行性 /// /// 装配任务定义 /// 分析完成回调 public void AnalyzeAssemblyTask(AssemblyTask assemblyTask, System.Action callback) /// /// 分析工作空间可达性 /// /// 工作空间定义 /// 分析完成回调 public void AnalyzeWorkspace(WorkspaceDefinition workspace, System.Action callback) /// /// 优化装配序列 /// /// 装配步骤 /// 优化完成回调 public void OptimizeAssemblySequence(List assemblySteps, System.Action callback) } ``` ### 2.4 可视化API #### VisualizationManager类 ```csharp public class VisualizationManager : MonoBehaviour { /// /// 显示轨迹 /// /// 轨迹数据 /// 显示颜色 public void ShowTrajectory(Trajectory trajectory, Color color) /// /// 显示碰撞热图 /// /// 碰撞数据 public void ShowCollisionHeatmap(CollisionData collisionData) /// /// 显示工作空间 /// /// 工作空间数据 /// 透明度 public void ShowWorkspace(WorkspaceData workspace, float transparency) /// /// 清除所有可视化 /// public void ClearAllVisualizations() } ``` ## 3. ROS2端API ### 3.1 规划服务 #### 服务定义 ```yaml # PlanPath.srv --- # 请求 geometry_msgs/Pose start_pose geometry_msgs/Pose goal_pose geometry_msgs/Pose[] waypoints moveit_msgs/Constraints path_constraints moveit_msgs/Constraints goal_constraints float64 max_velocity_scaling_factor float64 max_acceleration_scaling_factor string planner_id float64 planning_time int32 planning_attempts bool allow_replanning --- # 响应 bool success string error_message moveit_msgs/RobotTrajectory trajectory moveit_msgs/MoveItErrorCodes error_code float64 planning_time ``` #### Python客户端示例 ```python import rclpy from rclpy.node import Node from unity_moveit_msgs.srv import PlanPath from geometry_msgs.msg import Pose, Point, Quaternion class PlanningClient(Node): def __init__(self): super().__init__('planning_client') self.client = self.create_client(PlanPath, 'plan_path') def plan_to_pose(self, target_pose): request = PlanPath.Request() request.goal_pose = target_pose request.max_velocity_scaling_factor = 0.5 request.max_acceleration_scaling_factor = 0.5 request.planner_id = "RRTConnect" request.planning_time = 5.0 request.planning_attempts = 10 future = self.client.call_async(request) return future ``` ### 3.2 控制话题 #### 关节控制 ```yaml # 话题:/joint_command # 消息类型:sensor_msgs/JointState Header header string[] name float64[] position float64[] velocity float64[] effort ``` #### 末端控制 ```yaml # 话题:/end_effector_command # 消息类型:geometry_msgs/PoseStamped Header header Pose pose Point position float64 x float64 y float64 z Quaternion orientation float64 x float64 y float64 z float64 w ``` ### 3.3 状态发布 #### 机器人状态 ```python class RobotStatePublisher(Node): def __init__(self): super().__init__('robot_state_publisher') self.joint_state_pub = self.create_publisher( JointState, '/joint_states', 10) self.ee_pose_pub = self.create_publisher( PoseStamped, '/end_effector_pose', 10) # 定时发布状态 self.timer = self.create_timer(0.033, self.publish_states) # 30Hz def publish_states(self): # 发布关节状态 joint_msg = JointState() joint_msg.header.stamp = self.get_clock().now().to_msg() joint_msg.name = self.joint_names joint_msg.position = self.current_joint_positions joint_msg.velocity = self.current_joint_velocities self.joint_state_pub.publish(joint_msg) # 发布末端位姿 ee_msg = PoseStamped() ee_msg.header.stamp = self.get_clock().now().to_msg() ee_msg.header.frame_id = "base_link" ee_msg.pose = self.current_ee_pose self.ee_pose_pub.publish(ee_msg) ``` ## 4. 消息定义 ### 4.1 Unity消息类型 ```csharp [System.Serializable] public class JointState { public string[] jointNames; public float[] positions; public float[] velocities; public float[] efforts; public float timestamp; } [System.Serializable] public class Pose { public Vector3 position; public Quaternion orientation; } [System.Serializable] public class Trajectory { public TrajectoryPoint[] points; public float totalTime; } [System.Serializable] public class TrajectoryPoint { public float[] jointPositions; public float[] jointVelocities; public float timeFromStart; } [System.Serializable] public class PlanningResult { public bool success; public string errorMessage; public Trajectory trajectory; public float planningTime; } ``` ### 4.2 装配任务消息 ```csharp [System.Serializable] public class AssemblyTask { public string taskName; public AssemblyStep[] steps; public CollisionObject[] environment; public AssemblyConstraints constraints; } [System.Serializable] public class AssemblyStep { public int stepId; public Pose targetPose; public string[] requiredTools; public float maxForce; public float maxTorque; } [System.Serializable] public class FeasibilityResult { public bool feasible; public float feasibilityScore; public CollisionRisk[] collisionRisks; public string[] recommendations; } ``` ## 5. 服务接口 ### 5.1 配置管理服务 ```yaml # LoadRobotConfiguration.srv --- # 请求 string robot_name string config_path bool validate_config --- # 响应 bool success string error_message int32 degrees_of_freedom string[] joint_names geometry_msgs/Pose[] joint_origins ``` ### 5.2 可行性分析服务 ```yaml # AnalyzeFeasibility.srv --- # 请求 string task_name geometry_msgs/Pose[] target_poses shape_msgs/SolidPrimitive[] obstacles moveit_msgs/Constraints constraints --- # 响应 bool feasible float64 feasibility_score float64 collision_probability geometry_msgs/Point[] collision_points string[] optimization_suggestions ``` ## 6. 话题列表 ### 6.1 控制话题 | 话题名称 | 消息类型 | 方向 | 频率 | 描述 | |---------|---------|------|------|------| | `/joint_command` | `sensor_msgs/JointState` | Unity→ROS2 | 30Hz | 关节控制命令 | | `/end_effector_command` | `geometry_msgs/PoseStamped` | Unity→ROS2 | 30Hz | 末端位姿命令 | | `/velocity_command` | `geometry_msgs/Twist` | Unity→ROS2 | 30Hz | 速度控制命令 | ### 6.2 状态话题 | 话题名称 | 消息类型 | 方向 | 频率 | 描述 | |---------|---------|------|------|------| | `/joint_states` | `sensor_msgs/JointState` | ROS2→Unity | 30Hz | 关节状态反馈 | | `/end_effector_pose` | `geometry_msgs/PoseStamped` | ROS2→Unity | 30Hz | 末端位姿反馈 | | `/robot_status` | `unity_moveit_msgs/RobotStatus` | ROS2→Unity | 10Hz | 机器人状态 | ### 6.3 可视化话题 | 话题名称 | 消息类型 | 方向 | 频率 | 描述 | |---------|---------|------|------|------| | `/trajectory_display` | `moveit_msgs/DisplayTrajectory` | ROS2→Unity | 按需 | 轨迹显示 | | `/collision_objects` | `moveit_msgs/CollisionObject` | ROS2→Unity | 按需 | 碰撞对象 | | `/workspace_display` | `unity_moveit_msgs/WorkspaceDisplay` | ROS2→Unity | 按需 | 工作空间显示 | ## 7. 错误码定义 ### 7.1 通用错误码 ```csharp public enum ErrorCode { SUCCESS = 0, // 通信错误 (1000-1099) CONNECTION_FAILED = 1001, TIMEOUT = 1002, MESSAGE_PARSE_ERROR = 1003, // 配置错误 (1100-1199) INVALID_ROBOT_CONFIG = 1101, UNSUPPORTED_DOF = 1102, MISSING_URDF = 1103, // 运动学错误 (1200-1299) IK_SOLUTION_NOT_FOUND = 1201, JOINT_LIMITS_EXCEEDED = 1202, SINGULARITY_DETECTED = 1203, // 规划错误 (1300-1399) PLANNING_FAILED = 1301, PATH_NOT_FOUND = 1302, COLLISION_DETECTED = 1303, GOAL_UNREACHABLE = 1304, // 执行错误 (1400-1499) EXECUTION_FAILED = 1401, TRAJECTORY_INVALID = 1402, SAFETY_VIOLATION = 1403 } ``` ### 7.2 错误处理 ```csharp public class ErrorHandler { public static void HandleError(ErrorCode errorCode, string context) { switch (errorCode) { case ErrorCode.CONNECTION_FAILED: Debug.LogError($"连接失败:{context}"); // 尝试重连 break; case ErrorCode.PLANNING_FAILED: Debug.LogWarning($"规划失败:{context}"); // 尝试其他规划器 break; case ErrorCode.COLLISION_DETECTED: Debug.LogError($"检测到碰撞:{context}"); // 停止运动 break; default: Debug.LogError($"未知错误 {errorCode}:{context}"); break; } } } ``` ## 8. 使用示例 ### 8.1 完整控制流程 ```csharp public class RobotControlExample : MonoBehaviour { public RobotController robotController; public PathPlannerInterface pathPlanner; public VisualizationManager visualizer; async void Start() { // 1. 初始化机器人 await InitializeRobot(); // 2. 规划路径 var targetPose = new Pose(new Vector3(0.5f, 0.2f, 0.3f), Quaternion.identity); await PlanAndExecutePath(targetPose); // 3. 实时控制 StartRealTimeControl(); } async Task InitializeRobot() { // 加载机器人配置 var config = await LoadRobotConfiguration("niryo_one"); robotController.Initialize(config); // 移动到初始位置 var homePosition = new float[] {0, 0, 0, 0, 0, 0}; robotController.SetJointAngles(homePosition); } async Task PlanAndExecutePath(Pose targetPose) { var constraints = new PlanningConstraints { maxVelocity = 0.5f, maxAcceleration = 1.0f }; var result = await pathPlanner.PlanToTargetAsync(targetPose, constraints); if (result.success) { // 显示轨迹 visualizer.ShowTrajectory(result.trajectory, Color.green); // 执行轨迹 await pathPlanner.ExecuteTrajectoryAsync(result.trajectory); } else { Debug.LogError($"规划失败:{result.errorMessage}"); } } void StartRealTimeControl() { // 启用拖拽控制 var dragController = GetComponent(); dragController.OnDrag += OnEndEffectorDrag; } void OnEndEffectorDrag(Vector3 position, Quaternion rotation) { robotController.SetEndEffectorPose(position, rotation); } } ``` ### 8.2 装配任务示例 ```csharp public class AssemblyTaskExample : MonoBehaviour { public FeasibilityAnalyzer analyzer; async void AnalyzeAssemblyTask() { // 定义装配任务 var assemblyTask = new AssemblyTask { taskName = "插入螺栓", steps = new AssemblyStep[] { new AssemblyStep { stepId = 1, targetPose = new Pose(new Vector3(0.3f, 0.1f, 0.2f), Quaternion.identity), maxForce = 10.0f }, new AssemblyStep { stepId = 2, targetPose = new Pose(new Vector3(0.3f, 0.1f, 0.15f), Quaternion.identity), maxForce = 50.0f } } }; // 分析可行性 var result = await analyzer.AnalyzeAssemblyTaskAsync(assemblyTask); if (result.feasible) { Debug.Log($"任务可行,可行性评分:{result.feasibilityScore}"); } else { Debug.LogWarning("任务不可行,建议:"); foreach (var recommendation in result.recommendations) { Debug.Log($"- {recommendation}"); } } } } ``` --- ## 总结 本API文档详细定义了Unity-MoveIt2系统的所有接口,包括Unity端的控制API、ROS2端的服务接口、消息定义和通信协议。通过这些API,开发者可以: 1. **实现实时机器人控制**:通过关节角度或末端位姿控制 2. **执行路径规划**:使用MoveIt2的强大规划能力 3. **进行可行性分析**:评估装配任务的可行性 4. **实现丰富的可视化**:显示轨迹、碰撞、工作空间等 所有API都提供了详细的使用示例和错误处理机制,确保系统的稳定性和可靠性。