4.7 궤도 제어
개요
Trajectory 모듈은 오프라인 궤도 실행 및 궤도 파일 변환을 위한 인터페이스를 제공하여 복잡한 궤도 재생을 지원합니다.
핵심 기능
- 오프라인 궤적 파일 설정 및 실행
- 안전한 속도로 로봇을 궤적 시작점으로 이동
- CSV 궤적 파일을
.trajectory형식으로 변환 - 궤적 변환 상태 쿼리
사용 사례
- 복잡한 궤적을 정확하게 재현
- 외부 궤적 데이터를 실행 가능한 로봇 형식으로 변환
4.7.1 실행할 오프라인 궤적 파일 설정
| 메서드 이름 | Trajectory.SetOffLineTrajectoryFile(string path ) |
|---|---|
| 설명 | 실행할 오프라인 궤적 파일을 설정합니다. |
| 요청 매개변수 | path : 문자열 오프라인 궤적 파일 프로그램 이름(형식 설명은 아래 설명 참조) |
| 반환 값 | StatusCode: 작업 실행 결과 |
| 비고 | A.trajectory trajectory file format is a text file: - Line 1: 6 represents 6 axes, 0.001 represents 1ms interval between two points, 8093 represents a total of 8093 trajectory points - Line 2: Represents the initial positions of the 6 axes - Lines 3-8095: Represent trajectory points, including positions, velocities, accelerations, torque feedforward, do ports, and values of do ports for the 6 axes - do_port represents the used do port (range 1-24) - do_port is -1, indicating no IO signal will be triggered at this position - do_port is 1, do_state is 1, indicating do1 port will trigger ON signal at this position - do_port is 1, do_state is 0, indicating do1 port will trigger OFF signal at this position Users upload the offline file to the robot controller root directory using FileManager.upload, then execute the trajectory using instructions 4.7.2 and 4.7.3 |
| 호환 로봇 소프트웨어 버전 | 협업(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 궤적 파일 변환 기능
| 메서드 이름 | Trajectory.TransformCsvToTrajectory(string fileName ) |
|---|---|
| 설명 | 궤적 CSV 파일을 궤적 형식으로 변환하여 컨트롤러의 궤적 파일 디렉터리에 저장합니다. |
| 요청 매개변수 | fileName : 문자열 CSV 궤적 파일 이름(.csv 접미사가 필요 없음) |
| 오버로드 메서드 | Trajectory.TransformCsvToTrajectory(string fileName , string separator , string ioFlag ) separator : 문자열 구분자, 공백 또는 쉼표 지원 ioFlag : 문자열 IO 소스 식별자, "1"은 기본 IO 값 사용, "2"는 사용자 지정 IO 사용 |
| 반환 값 | string : 변환된 궤적 파일 경로 StatusCode: 연산 실행 결과 |
| 호환 로봇 소프트웨어 버전 | 협업(Copper): v7.5.0.0+ 산업용(Bronze): v7.5.0.0+ |
4.7.5 궤적 파일 변환 상태 조회
| 메서드 이름 | Trajectory.CheckTransformStatus(string fileName ) |
|---|---|
| 설명 | 궤적 파일 변환 현황을 조회합니다. |
| 요청 매개변수 | fileName : 문자열 궤적 파일 경로(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;
}
}4.7.6 궤적 기록 시작
| 메서드 이름 | Trajectory.TrajectoryRecordBegin(string name ) |
|---|---|
| 설명 | 궤적 재현 기능의 궤적 기록을 시작합니다. |
| 요청 매개변수 | name : 문자열 궤적 프로그램 이름 |
| 반환 값 | StatusCode: 기록 시작 작업 실행 결과 |
| 호환 로봇 소프트웨어 버전 | 협업(Copper): v7.5.0.0+ 산업용(Bronze): v7.5.0.0+ |
4.7.7 궤적 기록 종료
| 메서드 이름 | Trajectory.TrajectoryRecordFinish(string name ) |
|---|---|
| 설명 | 궤적 재현 기능의 궤적 기록을 종료합니다. |
| 요청 매개변수 | name : 문자열 궤적 프로그램 이름 |
| 반환 값 | StatusCode: 기록 종료 작업 실행 결과 |
| 호환 로봇 소프트웨어 버전 | 협업(Copper): v7.5.0.0+ 산업용(Bronze): v7.5.0.0+ |
4.7.8 궤적 재생 시작
| 메서드 이름 | Trajectory.TrajectoryReplayStart(string name ) |
|---|---|
| 설명 | 지정된 궤적 재생을 시작합니다. |
| 요청 매개변수 | name : 문자열 궤적 프로그램 이름 |
| 반환 값 | StatusCode: 재생 시작 작업 실행 결과 |
| 호환 로봇 소프트웨어 버전 | 협업(Copper): v7.5.0.0+ 산업용(Bronze): v7.5.0.0+ |
4.7.9 궤적 재생 중지
| 메서드 이름 | Trajectory.TrajectoryReplayStop(string name ) |
|---|---|
| 설명 | 지정된 궤적 재생을 중지합니다. |
| 요청 매개변수 | name : 문자열 궤적 프로그램 이름 |
| 반환 값 | StatusCode: 재생 중지 작업 실행 결과 |
| 호환 로봇 소프트웨어 버전 | 협업(Copper): v7.5.0.0+ 산업용(Bronze): v7.5.0.0+ |
4.7.10 궤적 삭제
| 메서드 이름 | Trajectory.TrajectoryRecordDelete(string name ) |
|---|---|
| 설명 | 지정된 궤적을 삭제합니다. |
| 요청 매개변수 | name : 문자열 궤적 프로그램 이름 |
| 반환 값 | StatusCode: 삭제 작업 실행 결과 |
| 호환 로봇 소프트웨어 버전 | 협업(Copper): v7.5.0.0+ 산업용(Bronze): v7.5.0.0+ |
4.7.11 궤적 목록 조회
| 메서드 이름 | Trajectory.GetTrajectoryRecordList() |
|---|---|
| 설명 | 현재 기록된 궤적 이름 목록을 조회합니다. |
| 요청 매개변수 | 없음 |
| 반환 값 | List<string>: 궤적 이름 목록 StatusCode: 조회 작업 실행 결과 |
| 호환 로봇 소프트웨어 버전 | 협업(Copper): v7.5.0.0+ 산업용(Bronze): v7.5.0.0+ |
4.7.12 궤적 시작 위치 조회
| 메서드 이름 | Trajectory.GetTrajectoryRecordStartPose(string name ) |
|---|---|
| 설명 | 지정된 기록 궤적의 시작 위치를 조회합니다. |
| 요청 매개변수 | name : 문자열 궤적 프로그램 이름 |
| 반환 값 | MotionPose: 궤적 시작 위치 StatusCode: 조회 작업 실행 결과 |
| 호환 로봇 소프트웨어 버전 | 협업(Copper): v7.5.0.0+ 산업용(Bronze): v7.5.0.0+ |
4.7.13 궤적 테이블/경로 테이블 기록 시작
| 메서드 이름 | Trajectory.PathRecordBegin(string name , string comment , double param , double angle = 1) |
|---|---|
| 설명 | 궤적 테이블( .traj ) 또는 경로 테이블( .path ) 기록을 시작합니다. |
| 요청 매개변수 | name : 문자열 궤적 테이블/경로 테이블 파일명, 반드시 .path 또는 .traj 로 끝나야 함 comment : 문자열 설명 정보 param : double 기록 파라미터( .path 는 거리 임계값, >=0.5 필요; .traj 는 기록 간격, >=2 필요) angle : double 경로 테이블 회전 각도 임계값( .path 에만 적용, >=1 필요) |
| 반환 값 | StatusCode: 기록 시작 작업 실행 결과 |
| 호환 로봇 소프트웨어 버전 | 협업(Copper): v7.7.I.0+ 산업용(Bronze): 지원 안 함 |
4.7.14 궤적 테이블/경로 테이블 기록 종료
| 메서드 이름 | Trajectory.PathRecordFinish() |
|---|---|
| 설명 | 현재 궤적 테이블/경로 테이블 기록을 종료합니다. |
| 요청 매개변수 | 없음 |
| 반환 값 | StatusCode: 기록 종료 작업 실행 결과 |
| 호환 로봇 소프트웨어 버전 | 협업(Copper): v7.7.I.0+ 산업용(Bronze): 지원 안 함 |
4.7.15 궤적 테이블/경로 테이블 시작 자세 조회
| 메서드 이름 | Trajectory.GetPathStartPose(string name ) |
|---|---|
| 설명 | 지정된 궤적 테이블/경로 테이블의 시작 자세를 조회합니다. |
| 요청 매개변수 | name : 문자열 궤적 테이블/경로 테이블 이름 |
| 반환 값 | MotionPose: 시작 자세 StatusCode: 조회 작업 실행 결과 |
| 호환 로봇 소프트웨어 버전 | 협업(Copper): v7.7.I.0+ 산업용(Bronze): 지원 안 함 |
4.7.16 궤적 테이블/경로 테이블 상태 조회
| 메서드 이름 | Trajectory.GetPathState(List<string> pathList ) |
|---|---|
| 설명 | 궤적 테이블/경로 테이블의 현재 기록 상태를 일괄 조회합니다. |
| 요청 매개변수 | pathList : List<string> 궤적 테이블/경로 테이블 이름 목록 |
| 반환 값 | Dictionary<string, MotionTableState>: 파일명과 상태 매핑 StatusCode: 조회 작업 실행 결과 |
| 호환 로봇 소프트웨어 버전 | 협업(Copper): v7.7.I.0+ 산업용(Bronze): 지원 안 함 |
4.7.17 경로 계획 파라미터 설정
| 메서드 이름 | Trajectory.SetPathPlannerParameter(double transitionTime , double scalingFactor ) |
|---|---|
| 설명 | 경로 계획기 파라미터를 설정합니다. 궤적 전환 및 평활성에 영향을 줍니다. |
| 요청 매개변수 | transitionTime : double 시작/정지 전환 시간, >=0.2 필요 값이 작을수록 가·감속이 빨라지며 최소값은 0.2 scalingFactor : double 스케일링 계수, 범위 [0,1] =0이면 로봇은 일정한 시간 간격으로 각 경로점을 통과하며 점 간 시간 간격을 우선 보장 =1이면 엄격한 스케일링으로 로봇은 일정한 선속도로 각 경로점을 통과하며 각 점의 등속 통과를 우선 보장 0과 1 사이의 값은 절충된 동작 |
| 반환 값 | StatusCode: 설정 작업 실행 결과 |
| 호환 로봇 소프트웨어 버전 | 협업(Copper): v7.7.I.0+ 산업용(Bronze): 지원 안 함 |
4.7.18 경로 계획 파라미터 조회
| 메서드 이름 | Trajectory.GetPathPlannerParameter() |
|---|---|
| 설명 | 현재 경로 계획기 파라미터를 조회합니다. |
| 요청 매개변수 | 없음 |
| 반환 값 | double: transitionTime 시작/정지 전환 시간, 값이 작을수록 가·감속이 빨라지며 최소값은 0.2 double: scalingFactor 스케일링 계수, =0이면 일정한 시간으로 각 경로점 통과, =1이면 일정한 선속도로 통과, 0~1 사이는 절충 동작 StatusCode: 조회 작업 실행 결과 |
| 호환 로봇 소프트웨어 버전 | 협업(Copper): v7.8.0.0+ 산업용(Bronze): 지원 안 함 |
4.7.19 궤적 테이블/경로 테이블을 따라 이동
| 메서드 이름 | Trajectory.MovePath(string name , double vel = 100, double acc = 1) |
|---|---|
| 설명 | 로봇 말단이 지정된 궤적 테이블/경로 테이블을 따라 이동하도록 합니다. |
| 요청 매개변수 | name : 문자열 궤적 테이블/경로 테이블 이름 vel : double 이동 속도, 범위 [0,5000] (mm/s) acc : double 가속도 계수, 범위 [0,1.2] |
| 반환 값 | StatusCode: 이동 작업 실행 결과 |
| 호환 로봇 소프트웨어 버전 | 협업(Copper): v7.7.I.0+ 산업용(Bronze): 지원 안 함 |