Skip to main content

xcore_api Introduction

xcore_api is the C++ API set used for controller plugin development. Plugins use these interfaces to integrate with controller capabilities. Typical uses include plugin lifecycle management, custom RL command registration, motion command submission, robot state queries, IO and register read/write, EtherCAT/fieldbus communication, client–controller plugin messaging, log reporting, and more.

The current header version is 0.0.3. The matching controller version is described in the interface package README.md. During development, ensure the plugin’s xcore_api version matches the target controller version.

Usage overview

Controller plugins typically use xcore_api as follows:

  1. Include the required headers in the plugin project, for example launch/launch_api.hpp, rl_cmd/morden_rl_cmd_api.hpp.
  2. Implement an entry module that inherits xcore_api::launch::LaunchAPI.
  3. In Init(), perform initialization such as config loading, log setup, and Hook registration.
  4. In Start(), register commands, services, log codes, or start background tasks as needed.
  5. In Stop(), release resources, stop threads, or close bus connections.
  6. Use the LAUNCH_MODULE or LAUNCH_MODULE_PRIORITY macro to auto-register the entry module with the controller.

Entry module example:

#include "launch/launch_api.hpp"

class ExamplePlugin : public xcore_api::launch::LaunchAPI {
public:
void Init() override {
// Plugin init, e.g. read config, init logging
}

void Start() override {
// Runs after all plugins finish Init; e.g. register commands, services, Hooks
}

void Stop() override {
// Runs when the controller stops the plugin; release resources
}
};

LAUNCH_MODULE(ExamplePlugin)

Module overview

Module directoryMain headersRole
launchlaunch_api.hppPlugin entry and lifecycle management.
rl_cmdmorden_rl_cmd_api.hppRegister custom RL commands, parse parameters, return execution results.
motion_cmdmotion_cmd_api.hppBuild and send motion commands; supports linear, joint, arc, spiral, etc.
sdksdk_cmd_api.hppSDK custom command API; motion and non-motion commands can enter the SDK command queue.
hookshooks_api.hpp, hooks_args_api.hppRegister controller event callbacks, e.g. point changes, program jumps, start, pause, e-stop.
statesstates_api.hppQuery and set controller state, e.g. auto/manual, power, task space, simulation mode.
rl_taskrl_task_api.hppQuery and control RL tasks, e.g. start, pause, stop, jump line, get execution pointer.
ioanalog_api.hppRead/write AI/AO/DI/DO/GI/GO and internal registers.
registersfunction_code_api.hppExtended register function codes; custom read/write logic.
ethercatecat_base_api.hppOperate EtherCAT slave PDO/SDO.
fieldbusfieldbus_api.hppCreate and operate fieldbus devices such as Modbus, Profinet, EIP, CC-Link, etc.
endtoolendtool_api.hppEnd-protocol passthrough for grippers and end tools; currently mainly Modbus RTU.
serviceservice_api.hppRegister controller plugin services for JSON messaging between client and controller plugins.
loglog_api.hppInitialize per-plugin logging and provide log macros.
user_loguser_log_api.hppRegister and report multilingual user logs and run logs.
const_datapose_api.hpp, ecat_api.hppCommon data: pose, points, speed, tool, work object, triggers, PDO/SDO, etc.
utilsfilesystem_api.hpp, thread_pool_api.hpp, singleton_api.hppJSON/file IO, thread pool, singleton template, etc.

launch: plugin entry module

The launch module registers the plugin’s entry object with the controller. The entry class must inherit LaunchAPI and implement Init(), Start(), and Stop().

Execution order:

  1. The controller loads the plugin shared library and constructs the entry object.
  2. All plugin entry modules’ Init() run in priority order.
  3. After all Init() complete, Start() runs in priority order.
  4. On stop or unload, Stop() runs.
  5. The plugin object is destroyed.

Common APIs and macros:

API / macroDescription
LaunchAPI::Init()Init phase; suitable for config, logging, data structures.
LaunchAPI::Start()Start phase; suitable for registering commands, services, log codes.
LaunchAPI::Stop()Stop phase; suitable for releasing resources, stopping threads, closing devices.
LaunchAPI::Register(priority, ptr)Register entry module; higher priority runs first.
LAUNCH_MODULE(ClassName)Register entry at default priority 0.
LAUNCH_MODULE_PRIORITY(ClassName, priority)Register entry at the given priority.

rl_cmd: custom RL commands

The rl_cmd module registers C++ implementations as custom commands callable from RL programs. The plugin can declare command name, parameter types, defaults, lookahead behavior, task limits, step-back behavior, and in the executor read parameters, call controller features, or set return values.

Core concepts:

Type / APIDescription
ValueTypeAPIParameter types, e.g. VALUE_INT, VALUE_DOUBLE, VALUE_STRING, VALUE_POSE, VALUE_TOOL, VALUE_WOBJ, etc.
ArgTypeAPIDescribes a single parameter; optional default and whether omitted args are allowed.
RLCmdConfigAPICommand config: function name, lookahead, task limits, step-back behavior.
ModernRLCmdAPIBuilder for custom commands; sets parameters and executor.
RLCallFrameAPICurrent command context, e.g. task name, file name, line number; can set return value.
SymbolVarBaseAPIParameter access; reads primitives, points, speed, tool, work object, etc.
RegPluginCmdsAPI()Registers commands with the controller.

Common return values:

ReturnMeaning
CMD_PROCESS_SUCCESSSuccess; RL continues.
CMD_PROCESS_ERRORFailure; current task pauses.
CMD_PROCESS_FATALFatal; RL stops.
CMD_PROCESS_IGNOREAsync command; task waits asynchronously.
CMD_PROCESS_EXTRAExtra execution path, often for motion commands.
CMD_PROCESS_RESCHEDULERequest reschedule.

Simplified example:

#include "rl_cmd/morden_rl_cmd_api.hpp"

void RegisterExampleCmd() {
xcore_api::rl_cmd::RLCmdConfigAPI cfg;
cfg.SetFuncName("ExampleCmd");
cfg.SetLookAhead(xcore_api::rl_cmd::WAIT_MOVE_PAUSE);

BEGIN_COMMAND_API(cfg)
PARAMS_API(xcore_api::rl_cmd::ArgTypeAPI(xcore_api::rl_cmd::ValueTypeAPI::VALUE_INT))

xcore_api::rl_cmd::RLCmdActionAPI action =
[](std::shared_ptr<xcore_api::rl_cmd::RLCallFrameAPI> frame,
std::vector<std::shared_ptr<xcore_api::rl_cmd::SymbolVarBaseAPI>> args) {
return [frame, args]() {
int value = args[0]->GetIntVal();
// Plugin logic here
return xcore_api::rl_cmd::CMD_PROCESS_SUCCESS;
};
};

EXECUTE_API(action)
REGISTER_COMMAND_API
}

Recommendations:

  1. Prefer registering commands in the entry module’s Start().
  2. Keep parameter types aligned with RL usage; know types before reading.
  3. For motion-related commands, set lookahead correctly to avoid breaking scheduling.
  4. Use RLCallFrameAPI::SetReturnValue() when a return value is needed.

motion_cmd: motion commands

The motion_cmd module builds and sends motion trajectories. It is often used with custom RL commands: after parsing parameters, wrap point, speed, tool, work object, zone, etc. in MotionCmdArgsAPI, then send via MotionCmdAPI to the controller motion queue.

Supported motion types:

TypeDescription
MOVE_ABSJJoint absolute move.
MOVE_JJoint move.
MOVE_LLinear move.
MOVE_CCircular move.
MOVE_CFFull circle; requires full-circle extra parameters.
MOVE_TCycloidal move; requires cycloid parameters.
MOVE_SPSpiral move; requires spiral parameters.

Common configuration:

APIDescription
SetTargetPoint()Set target point.
SetAuxPoint()Set auxiliary point (e.g. for arc moves).
SetMoveType()Set motion type.
SetTool() / SetWobj()Set tool and work object.
SetSpeed() / SetZone()Set speed and zone.
SetTriggers()Set trajectory triggers.
SetCallback()Set motion start, pause, complete, error callbacks.
SetFinishInAdvance()End trajectory early; can pair with Trigger/IO for search-style commands.
SendCmd()Send a single motion command.
SendSegmentCmds()Send multi-segment discontinuous continuous motion.
SendStepBackCmd()Generate step-back command.

Notes:

  1. Pose, speed, distance use SI units; position in meters; angles usually radians.
  2. MOVE_CF, MOVE_T, MOVE_SP need the corresponding extended parameters.
  3. Custom motion commands should respect lookahead, zone, and callback timing.
  4. Choose SendCmd() vs SendSegmentCmds() per application.

sdk: SDK custom commands

The sdk module adds plugin-defined SDK commands to the controller SDK command queue. It supports both motion and non-motion commands.

Core APIs:

APIDescription
SDKCmdAPIBase class for non-motion SDK commands.
BeforeProcess()Optional pre-execution callback.
DerivedProcess()Core logic; returns SUCCESS, PENDING, or ERROR.
AfterProcess()Optional post-execution callback.
MordenSDKCmdAPI::SendSDKMotionCmd()Send SDK motion command.
MordenSDKCmdAPI::SendSDKCmd()Send ordinary SDK command.
MordenSDKCmdAPI::SetFinalSDKCmd()Set command that breaks lookahead.

hooks: controller event callbacks

The hooks module listens for internal controller events. After registration, the controller invokes the plugin callback when the event occurs.

Supported events:

EventDescription
POINT_CHANGEPoint added, removed, or modified.
PP_TO_MAINProgram pointer jumps to main.
PP_TO_LINEProgram pointer jumps to a line.
B_START_RUNStart run.
B_PAUSE_RUNPause run.
E_STOP_RUNEmergency stop.

Run modes:

Run modeDescription
SYNC_RUNSynchronous; blocks the corresponding controller event path.
ASYNC_RUN_IN_THREAD_POOLAsync in thread pool.
ASYNC_RUN_IN_RT_THREADAsync on RT thread.

Registration flow:

  1. Create HookDataAPI.
  2. SetEvent() for the event.
  3. SetHook() for the callback.
  4. SetRunType() for sync/async.
  5. SetPriority() for priority.
  6. RegisterHooksAPI() to register.

Note: Hooks cannot be registered dynamically after plugin Start(). Avoid long work in synchronous hooks so controller event flow is not blocked.

states: robot and controller state

The states module queries or sets controller run state.

Common capabilities:

APIDescription
IsAutoMode() / SetAutoMode()Auto/manual mode.
IsPowerOn() / SetPowerOn()Power on/off.
IsTaskSpaceReady() / SetTaskSpace()Task space query/claim.
IsRobotBusy() / SetRobotBusy()Robot busy state.
GetRunningState()Current run phase, e.g. start, pause, step, collision, e-stop.
IsSimuMode()Whether simulation mode is active.

Recommendations:

  1. Before changing controller state, confirm current mode and task state.
  2. Pair acquire/release for SetRobotBusy(), SetTaskSpace(), etc., or other modules may be affected.
  3. When combined with motion or task control, verify that execution is allowed.

rl_task: RL task control

The rl_task module controls and queries RL program tasks.

Common APIs:

APIDescription
PPToMain()Reset program pointer to main.
IsProgramResetDone()Whether program reset finished.
PPToLine()Jump to task, file, line.
PPToFunc()Jump to function (mainly for debugging).
ModifyProgramLoop()Change program loop mode.
AlarmRLTask()Wake a task.
StartRun() / PauseRun() / StopRun()Start, pause, stop program.
PauseRunAndWaitIdle()Pause and wait until robot is idle.
GetPointedLine() / SetPointedLine()Get/set program pointer.
GetExecLine() / SetExecLine()Get/set motion pointer.
IsTaskExists() / IsTaskRunning()Task existence / running state.

Note: After a failed jump, interpreter state may be undefined; reload the task if necessary.

io: signals and registers

The io module is mainly provided by the Analog singleton for AI/AO/DI/DO/GI/GO and internal registers.

Signal APIs:

SignalReadWrite
AIGetAIValue()Not supported
AOGetAOValue()SetAOValue()
DIGetDIValue()Not supported
DOGetDOValue()SetDOValue()
GIGetGIValue()Not supported
GOGetGOValue()SetGOValue()

Register APIs:

TypeReadWrite
int16ReadInt16Register()WriteInt16Register()
boolReadBoolRegister()WriteBoolRegister()
floatReadFloatRegister()WriteFloatRegister()
bitReadBitRegister()WriteBitRegister()
int32ReadInt32Register()WriteInt32Register()
byteReadByteRegister()WriteByteRegister()

Helper APIs:

APIDescription
IsAiExist() / IsAoExist()Whether analog signals exist.
IsDiExist() / IsDoExist()Whether digital signals exist.
IsGiExist() / IsGoExist()Whether group signals exist.
RegisterType()Register type query.
RegisterWriteable()Whether register is writable.
CheckRegisterCanUsedAsIO()Whether register can substitute for given IO type.

registers: register function codes

The registers module extends register function codes. The plugin declares a function-code class with supported types, length, read/write attributes, and implements execution.

Core types:

Type / APIDescription
RegTypeAPIRegister data types: BIT, BOOL, BYTE, INT16, INT32, FLOAT.
FuncCodeCfgAPIConfig: name, supported types, length, writable flag.
FuncCodeAPIBase class; implement ExecFuncCode() and Clone().
ReadIntRegValue() / ReadFloatRegValue()Read values tied to the function code.
WriteIntRegValue() / WriteFloatRegValue()Write values tied to the function code.
RegFuncCodeAPI()Register function code with the controller.

Use DECLARE_FUNCTION_CODE_API and FUNCTION_CODE_EXECUTE_API to simplify declaration and implementation.

ethercat: EtherCAT slave access

The ethercat module operates EtherCAT slave PDO and SDO.

Data structures are defined in const_data/ecat_api.hpp:

StructureDescription
PdoAPIPDO description: baseIndex, byteOffs, byteSize, name.
SdoAPISDO description: index, subIndex, dateLen, timeOut, callbacks, etc.

Core APIs:

APIDescription
EcatBaseAPI(slave_id)EtherCAT handle for slave slave_id.
GetPdoValue() / SetPdoValue()Read/write PDO.
GetSdoValue() / SetSdoValue()Read/write SDO.
RegisterPdo() / RegisterSdo()Register PDO/SDO at offset or index.

Note: When reading/writing PDO/SDO, buffer size must match object length.

fieldbus: fieldbus

The fieldbus module wraps device create/configure/open/close, register read/write, and DI/DO access.

Supported device types:

TypeDescription
MODBUS_TCP_MASTER / MODBUS_TCP_SLAVERModbus TCP master/slave.
MODBUS_RTU_MASTER / MODBUS_RTU_SLAVERModbus RTU master/slave.
PROFINET_SLAVERProfinet slave.
EIP_SLAVEREtherNet/IP slave.
CCLINK_IE_SLAVER / CCLINK_ECAT_SLAVERCC-Link related slaves.

Config classes:

ClassDescription
FieldbusCfgAPIBase config: device type, name, endianness.
ModbusCfgAPIModbus: IP, port, serial, slave ID, start address, count.
ProfinetCfgAPIProfinet: station name, NIC, update cycle, slot/module IDs.
EipCfgAPIEIP: read/write register counts, NIC.
CCLinkCfgAPICC-Link: protocol, NIC, occupied stations, baud, protocol version.

FieldbusAPI unified access:

APIDescription
Open() / Close()Open/close bus device.
ReadRegisters() / WriteRegisters()Register read/write.
GetDINum() / GetDONum()DI/DO counts.
GetDI() / SetDO()Read DI / set DO.

endtool: end effector

The endtool module uses end-protocol passthrough for grippers and similar devices. ModbusRTUEndtoolAPI wraps common Modbus function codes:

APIModbus FCDescription
RWData()PassthroughRaw send/receive.
ReadCoil_01()01Read coils.
ReadDiscreteInput_02()02Read discrete inputs.
ReadRegister_03()03Read holding registers.
ReadRegister_04()04Read input registers.
WriteCoil_05()05Write single coil.
WriteRegister_06()06Write single register.
WriteCoil_0F()15Write multiple coils.
WriteRegister_10()16Write multiple registers.

Suitable for grippers, tool changers, sensors, and other end-device protocols.

service: client and controller plugin communication

The service module registers custom service protocols on the controller. When the client plugin sends JSON with a given plugin_name and key, the controller invokes the registered callback and returns the JSON produced by the callback.

API:

int RegServiceAPI(
const std::string& plugin_name,
const std::string& key,
const std::function<Json::Value(const Json::Value&)>& func
);

Typical uses:

  1. Client reads controller plugin state.
  2. Client pushes configuration to the controller plugin.
  3. Controller returns device status, diagnostics, or business data.
  4. Lightweight inter-plugin messaging via custom JSON.

log and user_log: logging

The log module initializes per-plugin logging and provides macros:

MacroDescription
LOG_DEBUGDebug.
LOG_INFOInfo.
LOG_WARNINGWarning.
LOG_ERRORError.
LOG_FATALFatal.

Init API:

xcore_api::log::InitLogAPI("log_dir", 10, 5);

Arguments: log directory, max size per file (MB), and file count. Total log storage must stay within API limits.

The user_log module registers and reports user logs:

APIDescription
ConfigReportLogAPI()Configure multilingual plugin logs.
ConfigEnglishReportLogAPI()Configure English fallback logs.
RegisterReportLogAPI()Register log config with the controller.
ReportUserLogAPI()Report multilingual user logs.
ReportRunLogAPI()Report user run logs.

Prefer loading log config in Init() and registering log codes in Start().

const_data: common data structures

const_data/pose_api.hpp defines common motion-related structures (SI units):

StructureDescription
PositionAPIPosition in meters.
QuaternionAPIOrientation quaternion.
ConfDataAPIRobot configuration data for reaching the target.
PoseAPIPose/frame; supports right multiply and inverse.
PointAPIPoint; Cartesian or joint.
ZoneAPIZone; distance and percentage.
SpeedAPISpeed; TCP, orientation, arm angle, percentage, etc.
LoadAPIPayload; mass, CoM, inertia.
TriggerAPITrajectory trigger; distance or time.
ToolAPITool frame and tool load.
WobjAPIWork object frame, user frame, work object load.

const_data/ecat_api.hpp defines EtherCAT PDO/SDO structures for the ethercat module.

utils: utilities

The utils module provides common helpers for plugin development.

File and JSON:

APIDescription
WriteBinaryToFileAPI() / ReadBinaryFromFileAPI()Binary file write/read.
LoadFromFileAPI() / SaveToFileAPI()JSON file load/save.
LoadFromStringAPI() / SaveToStringAPI()JSON string parse/serialize.
SaveToStringInLineAPI()Save JSON as line-oriented string.
CreateEmptyJsonFileAPI()Create empty JSON file.
IsJsonFileAPI()Whether file is JSON.
GetPluginNameAPI()Current plugin name.

Thread pool:

APIDescription
RunInThreadPoolAPI()Run void function in pool.
RunInThreadPoolIntAPI()Run function returning int in pool.

Singleton:

API / macroDescription
SingletonBaseAPI<T>Singleton base template.
DECLARE_SINGLETON(type)Declare singleton friend in class.
SINGLETON_INSTANCE(type)Get singleton pointer.
INIT_SINGLETON(type)Initialize singleton.

Development notes

  1. Register the entry with LAUNCH_MODULE or LAUNCH_MODULE_PRIORITY; avoid ad-hoc init not covered by the contract.
  2. Register RL commands, Hooks, Service, log codes, etc. in the appropriate lifecycle phase.
  3. Do not block for long periods in synchronous Hooks, custom command bodies, or motion callbacks; use the thread pool for heavy work.
  4. Use motion, power, task space, and busy-state APIs carefully; check controller state first.
  5. For IO, registers, bus, and EtherCAT, verify names, addresses, lengths, types, and target architecture.
  6. Prefer log macros for plugin logs to simplify filtering and troubleshooting.
  7. Match API version, controller version, and build architecture to avoid load failures or inconsistent behavior.