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:
- Include the required headers in the plugin project, for example
launch/launch_api.hpp,rl_cmd/morden_rl_cmd_api.hpp. - Implement an entry module that inherits
xcore_api::launch::LaunchAPI. - In
Init(), perform initialization such as config loading, log setup, and Hook registration. - In
Start(), register commands, services, log codes, or start background tasks as needed. - In
Stop(), release resources, stop threads, or close bus connections. - Use the
LAUNCH_MODULEorLAUNCH_MODULE_PRIORITYmacro 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 directory | Main headers | Role |
|---|---|---|
launch | launch_api.hpp | Plugin entry and lifecycle management. |
rl_cmd | morden_rl_cmd_api.hpp | Register custom RL commands, parse parameters, return execution results. |
motion_cmd | motion_cmd_api.hpp | Build and send motion commands; supports linear, joint, arc, spiral, etc. |
sdk | sdk_cmd_api.hpp | SDK custom command API; motion and non-motion commands can enter the SDK command queue. |
hooks | hooks_api.hpp, hooks_args_api.hpp | Register controller event callbacks, e.g. point changes, program jumps, start, pause, e-stop. |
states | states_api.hpp | Query and set controller state, e.g. auto/manual, power, task space, simulation mode. |
rl_task | rl_task_api.hpp | Query and control RL tasks, e.g. start, pause, stop, jump line, get execution pointer. |
io | analog_api.hpp | Read/write AI/AO/DI/DO/GI/GO and internal registers. |
registers | function_code_api.hpp | Extended register function codes; custom read/write logic. |
ethercat | ecat_base_api.hpp | Operate EtherCAT slave PDO/SDO. |
fieldbus | fieldbus_api.hpp | Create and operate fieldbus devices such as Modbus, Profinet, EIP, CC-Link, etc. |
endtool | endtool_api.hpp | End-protocol passthrough for grippers and end tools; currently mainly Modbus RTU. |
service | service_api.hpp | Register controller plugin services for JSON messaging between client and controller plugins. |
log | log_api.hpp | Initialize per-plugin logging and provide log macros. |
user_log | user_log_api.hpp | Register and report multilingual user logs and run logs. |
const_data | pose_api.hpp, ecat_api.hpp | Common data: pose, points, speed, tool, work object, triggers, PDO/SDO, etc. |
utils | filesystem_api.hpp, thread_pool_api.hpp, singleton_api.hpp | JSON/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:
- The controller loads the plugin shared library and constructs the entry object.
- All plugin entry modules’
Init()run in priority order. - After all
Init()complete,Start()runs in priority order. - On stop or unload,
Stop()runs. - The plugin object is destroyed.
Common APIs and macros:
| API / macro | Description |
|---|---|
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 / API | Description |
|---|---|
ValueTypeAPI | Parameter types, e.g. VALUE_INT, VALUE_DOUBLE, VALUE_STRING, VALUE_POSE, VALUE_TOOL, VALUE_WOBJ, etc. |
ArgTypeAPI | Describes a single parameter; optional default and whether omitted args are allowed. |
RLCmdConfigAPI | Command config: function name, lookahead, task limits, step-back behavior. |
ModernRLCmdAPI | Builder for custom commands; sets parameters and executor. |
RLCallFrameAPI | Current command context, e.g. task name, file name, line number; can set return value. |
SymbolVarBaseAPI | Parameter access; reads primitives, points, speed, tool, work object, etc. |
RegPluginCmdsAPI() | Registers commands with the controller. |
Common return values:
| Return | Meaning |
|---|---|
CMD_PROCESS_SUCCESS | Success; RL continues. |
CMD_PROCESS_ERROR | Failure; current task pauses. |
CMD_PROCESS_FATAL | Fatal; RL stops. |
CMD_PROCESS_IGNORE | Async command; task waits asynchronously. |
CMD_PROCESS_EXTRA | Extra execution path, often for motion commands. |
CMD_PROCESS_RESCHEDULE | Request 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:
- Prefer registering commands in the entry module’s
Start(). - Keep parameter types aligned with RL usage; know types before reading.
- For motion-related commands, set lookahead correctly to avoid breaking scheduling.
- 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:
| Type | Description |
|---|---|
MOVE_ABSJ | Joint absolute move. |
MOVE_J | Joint move. |
MOVE_L | Linear move. |
MOVE_C | Circular move. |
MOVE_CF | Full circle; requires full-circle extra parameters. |
MOVE_T | Cycloidal move; requires cycloid parameters. |
MOVE_SP | Spiral move; requires spiral parameters. |
Common configuration:
| API | Description |
|---|---|
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:
- Pose, speed, distance use SI units; position in meters; angles usually radians.
MOVE_CF,MOVE_T,MOVE_SPneed the corresponding extended parameters.- Custom motion commands should respect lookahead, zone, and callback timing.
- Choose
SendCmd()vsSendSegmentCmds()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:
| API | Description |
|---|---|
SDKCmdAPI | Base 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:
| Event | Description |
|---|---|
POINT_CHANGE | Point added, removed, or modified. |
PP_TO_MAIN | Program pointer jumps to main. |
PP_TO_LINE | Program pointer jumps to a line. |
B_START_RUN | Start run. |
B_PAUSE_RUN | Pause run. |
E_STOP_RUN | Emergency stop. |
Run modes:
| Run mode | Description |
|---|---|
SYNC_RUN | Synchronous; blocks the corresponding controller event path. |
ASYNC_RUN_IN_THREAD_POOL | Async in thread pool. |
ASYNC_RUN_IN_RT_THREAD | Async on RT thread. |
Registration flow:
- Create
HookDataAPI. SetEvent()for the event.SetHook()for the callback.SetRunType()for sync/async.SetPriority()for priority.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:
| API | Description |
|---|---|
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:
- Before changing controller state, confirm current mode and task state.
- Pair acquire/release for
SetRobotBusy(),SetTaskSpace(), etc., or other modules may be affected. - 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:
| API | Description |
|---|---|
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:
| Signal | Read | Write |
|---|---|---|
| AI | GetAIValue() | Not supported |
| AO | GetAOValue() | SetAOValue() |
| DI | GetDIValue() | Not supported |
| DO | GetDOValue() | SetDOValue() |
| GI | GetGIValue() | Not supported |
| GO | GetGOValue() | SetGOValue() |
Register APIs:
| Type | Read | Write |
|---|---|---|
int16 | ReadInt16Register() | WriteInt16Register() |
bool | ReadBoolRegister() | WriteBoolRegister() |
float | ReadFloatRegister() | WriteFloatRegister() |
bit | ReadBitRegister() | WriteBitRegister() |
int32 | ReadInt32Register() | WriteInt32Register() |
byte | ReadByteRegister() | WriteByteRegister() |
Helper APIs:
| API | Description |
|---|---|
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 / API | Description |
|---|---|
RegTypeAPI | Register data types: BIT, BOOL, BYTE, INT16, INT32, FLOAT. |
FuncCodeCfgAPI | Config: name, supported types, length, writable flag. |
FuncCodeAPI | Base 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:
| Structure | Description |
|---|---|
PdoAPI | PDO description: baseIndex, byteOffs, byteSize, name. |
SdoAPI | SDO description: index, subIndex, dateLen, timeOut, callbacks, etc. |
Core APIs:
| API | Description |
|---|---|
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:
| Type | Description |
|---|---|
MODBUS_TCP_MASTER / MODBUS_TCP_SLAVER | Modbus TCP master/slave. |
MODBUS_RTU_MASTER / MODBUS_RTU_SLAVER | Modbus RTU master/slave. |
PROFINET_SLAVER | Profinet slave. |
EIP_SLAVER | EtherNet/IP slave. |
CCLINK_IE_SLAVER / CCLINK_ECAT_SLAVER | CC-Link related slaves. |
Config classes:
| Class | Description |
|---|---|
FieldbusCfgAPI | Base config: device type, name, endianness. |
ModbusCfgAPI | Modbus: IP, port, serial, slave ID, start address, count. |
ProfinetCfgAPI | Profinet: station name, NIC, update cycle, slot/module IDs. |
EipCfgAPI | EIP: read/write register counts, NIC. |
CCLinkCfgAPI | CC-Link: protocol, NIC, occupied stations, baud, protocol version. |
FieldbusAPI unified access:
| API | Description |
|---|---|
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:
| API | Modbus FC | Description |
|---|---|---|
RWData() | Passthrough | Raw send/receive. |
ReadCoil_01() | 01 | Read coils. |
ReadDiscreteInput_02() | 02 | Read discrete inputs. |
ReadRegister_03() | 03 | Read holding registers. |
ReadRegister_04() | 04 | Read input registers. |
WriteCoil_05() | 05 | Write single coil. |
WriteRegister_06() | 06 | Write single register. |
WriteCoil_0F() | 15 | Write multiple coils. |
WriteRegister_10() | 16 | Write 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:
- Client reads controller plugin state.
- Client pushes configuration to the controller plugin.
- Controller returns device status, diagnostics, or business data.
- Lightweight inter-plugin messaging via custom JSON.
log and user_log: logging
The log module initializes per-plugin logging and provides macros:
| Macro | Description |
|---|---|
LOG_DEBUG | Debug. |
LOG_INFO | Info. |
LOG_WARNING | Warning. |
LOG_ERROR | Error. |
LOG_FATAL | Fatal. |
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:
| API | Description |
|---|---|
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):
| Structure | Description |
|---|---|
PositionAPI | Position in meters. |
QuaternionAPI | Orientation quaternion. |
ConfDataAPI | Robot configuration data for reaching the target. |
PoseAPI | Pose/frame; supports right multiply and inverse. |
PointAPI | Point; Cartesian or joint. |
ZoneAPI | Zone; distance and percentage. |
SpeedAPI | Speed; TCP, orientation, arm angle, percentage, etc. |
LoadAPI | Payload; mass, CoM, inertia. |
TriggerAPI | Trajectory trigger; distance or time. |
ToolAPI | Tool frame and tool load. |
WobjAPI | Work 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:
| API | Description |
|---|---|
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:
| API | Description |
|---|---|
RunInThreadPoolAPI() | Run void function in pool. |
RunInThreadPoolIntAPI() | Run function returning int in pool. |
Singleton:
| API / macro | Description |
|---|---|
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
- Register the entry with
LAUNCH_MODULEorLAUNCH_MODULE_PRIORITY; avoid ad-hoc init not covered by the contract. - Register RL commands, Hooks, Service, log codes, etc. in the appropriate lifecycle phase.
- Do not block for long periods in synchronous Hooks, custom command bodies, or motion callbacks; use the thread pool for heavy work.
- Use motion, power, task space, and busy-state APIs carefully; check controller state first.
- For IO, registers, bus, and EtherCAT, verify names, addresses, lengths, types, and target architecture.
- Prefer
logmacros for plugin logs to simplify filtering and troubleshooting. - Match API version, controller version, and build architecture to avoid load failures or inconsistent behavior.