4.7 轨迹控制
4.7.1 设置待执行的离线轨迹文件
| 方法名 | Trajectory.SetOffLineTrajectoryFile(string path ) |
|---|---|
| 描述 | 设置待执行的离线轨迹文件 |
| 请求参数 | path : string 离线轨迹文件路径,如示例文件 A.trajectoryA.trajectory 轨迹文件格式为文本文件,说明如下: - 第 1 行:6 代表 6 个轴,0.001 代表两个点之间间隔 1ms,8093 代表一共 8093 个轨迹点 - 第二行:表示 6 个轴的起始位置 - 3-8095 行:表示轨迹点,包括 6 个轴的位置、速度、加速度、力矩前馈、do 端口、do 端口的值 - do_port 代表使用的 do 端口(取值范围 1-24) - do_port 为 - 1,表示在该位置不会触发 IO 信号 - do_port 为 1,do_state 为 1,则表明 do1 端口会在该位置触发 ON 信号 - do_port 为 1,do_state 为 0,则表明 do1 端口会在该位置触发 OFF 信号 用户通过 FileManager.upload 将离线文件发送到机器人控制器根目录,用 4.7.2 和 4.7.3 指令执行轨迹 |
| 返回值 | StatusCode: 设置操作执行结果 |
| 兼容的机器人软件版本 | 协作 (Copper): v7.5.0.0+ 工业 (Bronze): v7.5.0.0+ |
4.7.2 机器人移动到离线轨迹中的起始点
| 方法名 | Trajectory.PrepareOfflineTrajectory() |
|---|---|
| 描述 | 让机器人以安全速度移动到离线轨迹的起始点 |
| 请求参数 | 无参数 |
| 返回值 | StatusCode: 准备操作执行结果 |
| 兼容的机器人软件版本 | 协作 (Copper): v7.5.0.0+ 工业 (Bronze): v7.5.0.0+ |
4.7.3 机器人开始执行离线轨迹文件
| 方法名 | Trajectory.ExecuteOfflineTrajectory() |
|---|---|
| 描述 | 让机器人开始执行离线轨迹文件 |
| 请求参数 | 无参数 |
| 返回值 | StatusCode: 执行操作执行结果 |
| 兼容的机器人软件版本 | 协作 (Copper): v7.5.0.0+ 工业 (Bronze): v7.5.0.0+ |
4.7.4 将 CSV 轨迹文件转换为 Trajectory 格式
| 方法名 | Trajectory.TransformCsvToTrajectory(string fileName ) |
|---|---|
| 描述 | 将轨迹 CSV 文件转换成 trajectory 格式的轨迹文件并存放在控制柜的轨迹文件目录上 |
| 请求参数 | fileName : string CSV 轨迹文件名 |
| 返回值 | string: 成功转换后的 trajectory 文件路径 StatusCode: 转换操作执行结果 |
| 兼容的机器人软件版本 | 协作 (Copper): v7.5.0.0+ 工业 (Bronze): v7.5.0.0+ |
4.7.5 查询轨迹转换状态
| 方法名 | Trajectory.CheckTransformStatus(string fileName ) |
|---|---|
| 描述 | 查询 TransformCsvToTrajectory 流程工作状态 |
| 请求参数 | fileName : string TransformCsvToTrajectory 接口返回的结果 |
| 返回值 | TransformState: 转换状态 StatusCode: 查询操作执行结果 |
| 兼容的机器人软件版本 | 协作 (Copper): v7.5.0.0+ 工业 (Bronze): v7.5.0.0+ |
示例代码
cs
using System.IO;
using Agilebot.IR;
using Agilebot.IR.Trajectory;
using Agilebot.IR.Types;
public class OfflineTrajectory
{
public static StatusCode Run(string controllerIP, bool useLocalProxy = true)
{
// [ZH] 初始化捷勃特机器人
// [EN] Initialize the Agilebot robot
Arm controller = new Arm(controllerIP, useLocalProxy);
// [ZH] 连接捷勃特机器人
// [EN] Connect to the Agilebot robot
StatusCode code = controller.ConnectSync();
Console.WriteLine(code != StatusCode.OK ? code.GetDescription() : "连接成功/Successfully connected.");
if (code != StatusCode.OK)
{
return code;
}
try
{
// [ZH] 获取机器人模式
// [EN] Get robot mode
(UserOpMode opMode, StatusCode opCode) = controller.GetOpMode();
if (opCode == StatusCode.OK)
{
Console.WriteLine($"当前机器人模式/Current robot mode: {opMode}");
if (opMode != UserOpMode.AUTO)
{
Console.WriteLine(
$"离线轨迹执行必须在机器人自动模式下/Offline trajectory execution must be in automatic mode"
);
return StatusCode.OtherReason;
}
}
else
{
Console.WriteLine($"获取机器人模式失败/Failed to get robot mode: {opCode.GetDescription()}");
}
// [ZH] 添加程序文件到机器人中
// [EN] Add program file to robot
string file_user_program = GetTestFilePath("test.csv");
StatusCode ret_code = controller.FileManager.Upload(file_user_program, FileType.TmpFile, true);
if (ret_code != StatusCode.OK)
{
Console.WriteLine($"上传文件失败/Upload file failed: {ret_code.GetDescription()}");
return ret_code;
}
Console.WriteLine("文件上传成功/File upload success");
// [ZH] 测试CSV转换为轨迹文件功能
// [EN] Test CSV to trajectory file conversion functionality
string csvFilename = "test.csv";
(string trajFileName, StatusCode transformCode) = controller.Trajectory.TransformCsvToTrajectory(
csvFilename
);
if (transformCode != StatusCode.OK)
{
Console.WriteLine($"CSV转换失败/CSV conversion failed: {transformCode.GetDescription()}");
return transformCode;
}
Console.WriteLine($"CSV转换成功/CSV conversion success, trajectory file: {trajFileName}");
// [ZH] 检查转换状态
// [EN] Check conversion status
var startTime = System.DateTime.Now;
TransformState state;
StatusCode statusCode;
do
{
(state, statusCode) = controller.Trajectory.CheckTransformStatus(
System.IO.Path.GetFileName(trajFileName)
);
if (statusCode != StatusCode.OK)
{
Console.WriteLine($"检查转换状态失败/Check transform status failed: {statusCode.GetDescription()}");
return statusCode;
}
Console.WriteLine($"转换状态/Transform state: {state}");
Thread.Sleep(2000); // 等待2秒
if (System.DateTime.Now - startTime > System.TimeSpan.FromSeconds(60))
{
Console.WriteLine("转换状态检查超时/Transform status check timeout");
break;
}
} while (state != TransformState.TRANSFORM_SUCCESS && state != TransformState.TRANSFORM_FAILED);
if (state == TransformState.TRANSFORM_FAILED)
{
Console.WriteLine("CSV转换失败/CSV conversion failed");
return StatusCode.OtherReason;
}
// [ZH] 转换任务成功并进行了结果查询后 服务端不会继续保存转换任务的状态
// [EN] After the conversion task is successful and the result is queried, the server will not continue to save the conversion task status
(TransformState finalState, StatusCode finalCode) = controller.Trajectory.CheckTransformStatus(
System.IO.Path.GetFileName(trajFileName)
);
if (finalCode != StatusCode.OK)
{
Console.WriteLine($"最终状态检查失败/Final status check failed: {finalCode.GetDescription()}");
return finalCode;
}
Console.WriteLine($"最终转换状态/Final transform state: {finalState}");
// [ZH] 设置轨迹文件
// [EN] Set trajectory file
code = controller.Trajectory.SetOffLineTrajectoryFile("test_torque.trajectory");
if (code != StatusCode.OK)
{
Console.WriteLine($"设置轨迹文件失败/Set trajectory file failed: {code.GetDescription()}");
return code;
}
Console.WriteLine("设置轨迹文件成功/Set trajectory file success");
// [ZH] 准备离线轨迹
// [EN] Prepare offline trajectory
code = controller.Trajectory.PrepareOfflineTrajectory();
if (code != StatusCode.OK)
{
Console.WriteLine($"准备离线轨迹失败/Prepare offline trajectory failed: {code.GetDescription()}");
return code;
}
Console.WriteLine("准备离线轨迹成功/Prepare offline trajectory success");
// [ZH] 等待机器人和伺服器空闲
// [EN] Wait for robot and servo to be idle
startTime = System.DateTime.Now;
RobotState robotStatus;
ServoState servoStatus;
StatusCode robotStatusCode;
StatusCode servoStatusCode;
do
{
(robotStatus, robotStatusCode) = controller.GetRobotState();
if (robotStatusCode != StatusCode.OK)
{
Console.WriteLine($"获取机器人状态失败/Get robot state failed: {robotStatusCode.GetDescription()}");
return robotStatusCode;
}
(servoStatus, servoStatusCode) = controller.GetServoState();
if (servoStatusCode != StatusCode.OK)
{
Console.WriteLine($"获取伺服状态失败/Get servo state failed: {servoStatusCode.GetDescription()}");
return servoStatusCode;
}
Console.WriteLine($"机器人状态/Robot state: {robotStatus}, 伺服状态/Servo state: {servoStatus}");
if (robotStatus == RobotState.ROBOT_IDLE && servoStatus == ServoState.SERVO_IDLE)
{
Console.WriteLine("机器人和伺服器已空闲/Robot and servo are idle");
break;
}
Thread.Sleep(2000); // 等待2秒
if (System.DateTime.Now - startTime > System.TimeSpan.FromSeconds(60))
{
Console.WriteLine("等待机器人和伺服器空闲超时/Waiting for robot and servo idle timeout");
break;
}
} while (true);
// [ZH] 执行离线轨迹
// [EN] Execute offline trajectory
code = controller.Trajectory.ExecuteOfflineTrajectory();
if (code == StatusCode.OK)
{
Console.WriteLine("执行离线轨迹成功/Execute offline trajectory success");
Console.WriteLine("机器人开始执行轨迹程序/Robot started executing trajectory program");
}
else
{
Console.WriteLine($"执行离线轨迹失败/Execute offline trajectory failed: {code.GetDescription()}");
}
}
catch (Exception ex)
{
Console.WriteLine(
$"执行过程中发生异常/Exception occurred during execution/Exception occurred during execution: {ex.Message}"
);
code = StatusCode.OtherReason;
}
finally
{
// [ZH] 关闭连接
// [EN] Close the connection
StatusCode disconnectCode = controller.Disconnect();
if (disconnectCode != StatusCode.OK)
{
Console.WriteLine(disconnectCode.GetDescription());
if (code == StatusCode.OK)
code = disconnectCode;
}
}
return code;
}
/// <summary>
/// 获取test_files文件夹中文件的路径示例方法
/// 展示如何获取当前程序目录下的test_files文件夹中的文件路径
/// </summary>
private static string GetTestFilePath(string fileName)
{
// 获取当前程序集的目录
string? codeFilePath = new System.Diagnostics.StackTrace(true).GetFrame(0)?.GetFileName();
if (string.IsNullOrEmpty(codeFilePath))
{
throw new InvalidOperationException("无法获取当前文件路径/Cannot get current file path");
}
string? codeDirectory = Path.GetDirectoryName(codeFilePath);
if (string.IsNullOrEmpty(codeDirectory))
{
throw new InvalidOperationException("无法获取当前目录路径/Cannot get current directory path");
}
// 构建test_files文件夹路径
string testFilesDirectory = Path.Combine(codeDirectory, "test_files");
// 构建文件完整路径
string filePath = Path.Combine(testFilesDirectory, fileName);
return filePath;
}
}