3.9 TrajectoryManager Class
Overview
TrajectoryManager handles offline trajectories, CSV conversion, recording/playback, path execution, and real-time trajectories.
3.9.1 Offline Trajectory
cpp
SetOfflineTrajectoryFile(const std::string& path) -> STATUS_CODE
PrepareOfflineTrajectory() -> STATUS_CODE
ExecuteOfflineTrajectory() -> STATUS_CODE| Method | Description | Return |
|---|---|---|
SetOfflineTrajectoryFile | Sets the offline trajectory file path | STATUS_CODE |
PrepareOfflineTrajectory | Moves to the start point | STATUS_CODE |
ExecuteOfflineTrajectory | Executes the offline trajectory | STATUS_CODE |
3.9.2 CSV Conversion
cpp
TransformCsvToTrajectory(const std::string& fileName, const std::string& separator = " ", const std::string& ioFlag = "2") -> std::pair<std::string, STATUS_CODE>
CheckTransformStatus(const std::string& fileName) -> std::pair<TransformStatusEnum, STATUS_CODE>| Method | Description | Return |
|---|---|---|
TransformCsvToTrajectory | Converts a CSV file | std::pair<std::string, STATUS_CODE> |
CheckTransformStatus | Queries conversion status | std::pair<TransformStatusEnum, STATUS_CODE> |
3.9.3 Trajectory Recording and Playback
cpp
TrajectoryRecordBegin(const std::string& name) -> STATUS_CODE
TrajectoryRecordFinish(const std::string& name) -> STATUS_CODE
TrajectoryReplayStart(const std::string& name) -> STATUS_CODE
TrajectoryReplayStop(const std::string& name) -> STATUS_CODE
TrajectoryRecordDelete(const std::string& name) -> STATUS_CODE
GetTrajectoryRecordList() -> std::pair<std::vector<std::string>, STATUS_CODE>
GetTrajectoryRecordStartPose(const std::string& name) -> std::pair<MotionPose, STATUS_CODE>| Method | Description | Return |
|---|---|---|
TrajectoryRecordBegin | Starts recording | STATUS_CODE |
TrajectoryRecordFinish | Finishes recording | STATUS_CODE |
TrajectoryReplayStart | Starts playback | STATUS_CODE |
TrajectoryReplayStop | Stops playback | STATUS_CODE |
TrajectoryRecordDelete | Deletes the recording file | STATUS_CODE |
GetTrajectoryRecordList | Queries the recording list | std::pair<std::vector<std::string>, STATUS_CODE> |
GetTrajectoryRecordStartPose | Gets the first-point pose | std::pair<MotionPose, STATUS_CODE> |
3.9.4 Path Recording and Execution
cpp
PathRecordBegin(const std::string& name, const std::string& comment, Float64 param, Float64 angle = 1.0) -> STATUS_CODE
PathRecordFinish() -> STATUS_CODE
GetPathStartPose(const std::string& name) -> std::pair<MotionPose, STATUS_CODE>
GetPathState(const std::vector<std::string>& pathList) -> std::pair<std::map<std::string, int32_t>, STATUS_CODE>
SetPathPlannerParameter(Float64 transitionTime, Float64 scalingFactor) -> STATUS_CODE
GetPathPlannerParameter() -> std::tuple<Float64, Float64, STATUS_CODE>
MovePath(const std::string& name, Float64 vel = 100.0, Float64 acc = 1.0) -> STATUS_CODE| Method | Description | Return |
|---|---|---|
PathRecordBegin | Starts recording .path/.traj | STATUS_CODE |
PathRecordFinish | Finishes recording | STATUS_CODE |
GetPathStartPose | Gets the start pose | std::pair<MotionPose, STATUS_CODE> |
GetPathState | Batch-queries state | std::pair<std::map<std::string, int32_t>, STATUS_CODE> |
SetPathPlannerParameter | Sets path planner parameters | STATUS_CODE |
GetPathPlannerParameter | Gets path planner parameters | std::tuple<Float64, Float64, STATUS_CODE> |
MovePath | Executes by path file | STATUS_CODE |
3.9.5 Real-time Trajectory
cpp
EnterTrajectoryControl() -> STATUS_CODE
SetFifoSize(int32_t size) -> STATUS_CODE
SendTrajectory(const TrajectorySegment& segment) -> STATUS_CODE
StopTrajectoryControl() -> STATUS_CODE
ExitTrajectoryControl() -> STATUS_CODE
SubscribeJointStream() -> STATUS_CODE
UnsubscribeJointStream() -> STATUS_CODE| Method | Description | Return |
|---|---|---|
EnterTrajectoryControl | Enters real-time trajectory control mode | STATUS_CODE |
SetFifoSize | Sets the real-time trajectory FIFO size | STATUS_CODE |
SendTrajectory | Sends a trajectory segment | STATUS_CODE |
StopTrajectoryControl | Stops real-time trajectory control | STATUS_CODE |
ExitTrajectoryControl | Exits real-time trajectory control mode | STATUS_CODE |
SubscribeJointStream | Subscribes to the joint stream | STATUS_CODE |
UnsubscribeJointStream | Unsubscribes from the joint stream | STATUS_CODE |
Minimal Call Example
cpp
#include <iostream> // Standard output stream for printing trajectory query results
#include "arm_api.h" // Arm entry point; after connection, trajectory APIs are accessed through arm.trajectoryManager
#include "status_code.h" // STATUS_CODE for checking SDK call results
int main()
{
Arm arm;
STATUS_CODE connectRet = arm.Connect("192.168.110.2", "");
if (connectRet != STATUS_CODE::OK) {
return 1;
}
auto [recordNames, listRet] = arm.trajectoryManager.GetTrajectoryRecordList();
auto [transitionTime, scalingFactor, plannerRet] =
arm.trajectoryManager.GetPathPlannerParameter();
if (listRet != STATUS_CODE::OK || plannerRet != STATUS_CODE::OK) {
return 1;
}
std::cout << "record_count=" << recordNames.size() << "\n";
std::cout << "transition_time=" << transitionTime << "\n";
std::cout << "scaling_factor=" << scalingFactor << "\n";
return 0;
}Scenario Examples
The snippets below cover CSV conversion, offline trajectories, recording/playback, path motion, and real-time trajectory control. They assume the arm object from the minimal example is already connected. Calls that move the robot or change trajectory file state remain commented out; run them only after checking the site.
CSV Conversion and Conversion Status
cpp
const std::string csvName = "demo.csv";
auto [transformName, transformRet] = arm.trajectoryManager.TransformCsvToTrajectory(csvName, ",", "2");
if (transformRet == STATUS_CODE::OK) {
auto [transformStatus, statusRet] = arm.trajectoryManager.CheckTransformStatus(transformName);
std::cout << "transform_status=" << static_cast<int>(transformStatus) << " status_ret=" << static_cast<int>(statusRet) << "\n";
}Execute an Offline Trajectory File
cpp
// STATUS_CODE offlineFileRet = arm.trajectoryManager.SetOfflineTrajectoryFile("/root/robot_data/progs/robot_tmp/demo.traj");
// STATUS_CODE prepareRet = arm.trajectoryManager.PrepareOfflineTrajectory();
// STATUS_CODE executeRet = arm.trajectoryManager.ExecuteOfflineTrajectory();Trajectory Recording, Playback, and Deletion
cpp
const std::string recordName = "demo_record";
auto [recordNames, listRet] = arm.trajectoryManager.GetTrajectoryRecordList();
auto [recordStartPose, recordPoseRet] = arm.trajectoryManager.GetTrajectoryRecordStartPose(recordName);
if (listRet == STATUS_CODE::OK || recordPoseRet == STATUS_CODE::OK) {
std::cout << "record_count=" << recordNames.size() << "\n";
}
// STATUS_CODE recordBeginRet = arm.trajectoryManager.TrajectoryRecordBegin(recordName);
// STATUS_CODE recordFinishRet = arm.trajectoryManager.TrajectoryRecordFinish(recordName);
// STATUS_CODE replayStartRet = arm.trajectoryManager.TrajectoryReplayStart(recordName);
// STATUS_CODE replayStopRet = arm.trajectoryManager.TrajectoryReplayStop(recordName);
// STATUS_CODE recordDeleteRet = arm.trajectoryManager.TrajectoryRecordDelete(recordName);Path Recording and Path Motion
cpp
const std::string pathName = "demo_path";
auto [pathStartPose, pathPoseRet] = arm.trajectoryManager.GetPathStartPose(pathName);
auto [pathState, pathStateRet] = arm.trajectoryManager.GetPathState(std::vector<std::string>{pathName});
auto [transitionTime, scalingFactor, plannerRet] = arm.trajectoryManager.GetPathPlannerParameter();
if (pathPoseRet == STATUS_CODE::OK || pathStateRet == STATUS_CODE::OK || plannerRet == STATUS_CODE::OK) {
std::cout << "transition=" << transitionTime << " scaling=" << scalingFactor << "\n";
}
// STATUS_CODE pathBeginRet = arm.trajectoryManager.PathRecordBegin(pathName, "sdk demo", 100.0, 1.0);
// STATUS_CODE pathFinishRet = arm.trajectoryManager.PathRecordFinish();
// STATUS_CODE setPlannerRet = arm.trajectoryManager.SetPathPlannerParameter(0.2, 1.0);
// STATUS_CODE movePathRet = arm.trajectoryManager.MovePath(pathName, 100.0, 1.0);Real-Time Trajectory Control
cpp
TrajectorySegment segment;
// STATUS_CODE enterRtRet = arm.realTimeTrajectory.EnterTrajectoryControl();
// STATUS_CODE fifoRet = arm.realTimeTrajectory.SetFifoSize(64);
// STATUS_CODE sendRet = arm.realTimeTrajectory.SendTrajectory(segment);
// STATUS_CODE subJointRet = arm.realTimeTrajectory.SubscribeJointStream();
// STATUS_CODE unsubJointRet = arm.realTimeTrajectory.UnsubscribeJointStream();
// STATUS_CODE stopRtRet = arm.realTimeTrajectory.StopTrajectoryControl();
// STATUS_CODE exitRtRet = arm.realTimeTrajectory.ExitTrajectoryControl();Example code:
cpp
#include "offline_trajectory/run.h"
#include "record_and_replay/run.h"
#include "path_api/run.h"
#include "realtime_trajectory/run.h"
int main(void)
{
// [ZH] 默认只调用一个门面方法;如需体验其他接口,请把下一行替换成下面任意一行。
// [EN] The main function calls only one facade by default. Replace the next line with any line below to try other APIs.
return RunTrajectoryBasicOfflineTrajectory();
// return RunTrajectoryBasicRecordAndReplay();
// return RunTrajectoryBasicPathApi();
// return RunTrajectoryBasicRealtimeTrajectory();
}Firmware Compatibility Notes
| Feature | Minimum Firmware Version | Notes |
|---|---|---|
| PathRecordBegin / PathRecordFinish | 1.5.x | Recording works, but in version 1.5.6 and earlier, a readViaPoints bug causes MovePath playback to read 0 points and return MOTION_TABLE_READ_FAILED |
| MovePath (.path / .traj) | > 1.5.6 | Requires firmware with the readViaPoints fix for normal playback |
| TrajectoryRecordBegin / Finish / Replay | 1.5.x | CSV trajectory recording and playback work normally |
| SetPathPlannerParameter / GetPathPlannerParameter | 1.5.x | Works normally |